Calling newlisp from Javascript

Machine-specific discussion
Unix, Linux, OS X, OS/2, Windows, ..?
Locked
abbat
Posts: 8
Joined: Tue Nov 03, 2009 7:49 pm

Calling newlisp from Javascript

Post by abbat »

I use newLISP as local http server on Windows platform:
newlisp.exe -c -d 1235

It is possible send some string (like "(+ 2 3)") from Javascript to newLISP session
for evaluate and get back answer?

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Re: Calling newlisp from Javascript

Post by cormullion »

Don't know. Wouldn't that be a security problem?

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: Calling newlisp from Javascript

Post by Lutz »

It should be possible to do this from JavaScript. Connect to port 1235 and send the string "(+ 3 4)\n", then wait for an answer which should be "7\n" (7 plus line-feed). And yes, there is a big potential for security problems; so carefully check each string received for evaluation.

abbat
Posts: 8
Joined: Tue Nov 03, 2009 7:49 pm

Re: Calling newlisp from Javascript

Post by abbat »

Thanks you for reply.
I am beginner in newLisp and Javascritp.
Please, give me an example.
I try run newlisp:
newlisp.exe. -c -d 8080
and open in browser this document:

Code: Select all

<html>
<body>
<h3>newLISP server and JS demo</h3>

<script type="text/javascript" language="javascript">

if (window.XMLHttpRequest) { 
    xmlHttp = new XMLHttpRequest();
} else if (window.ActiveXObject) { 
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}

function newLispEval(expr) {
  xmlHttp.open("GET", "http://localhost:8080", false);
  try {
    xmlHttp.send(expr);
  } catch (e) { alert(e.message); }
  return xmlHttp.responseText;
}

var answer = newLispEval("(+ 3 4)\n");

document.write(answer);
document.write("<BR>ok.");
</script>
</body>
</html>
<!-- end of file -->
but get NS_ERROR_FAILURE for "xmlHttp.send(expr);"

abbat
Posts: 8
Joined: Tue Nov 03, 2009 7:49 pm

Re: Calling newlisp from Javascript

Post by abbat »

Sorry, misprint:
I run newLISP with line:
newlisp.exe -c -d

abbat
Posts: 8
Joined: Tue Nov 03, 2009 7:49 pm

Re: Calling newlisp from Javascript

Post by abbat »

Sorry again :)
newlisp.exe -c -d 8080

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: Calling newlisp from Javascript

Post by Lutz »

newLISP when started: newlisp -c -d 8080, answers to two different protocols. What I was demonstrating is the simple command line protocol, but xmlHttp.open() is using the HTTP protocol.

So with: newlisp -c -d 8080, the newLISP server handles the HTTP protocol too. But you would need to initiate some kind of CGI process and pass the expression to evaluate as a parameter in a GET or POST request.

Cormullion is doing this here:

http://unbalanced-parentheses.nfshost.c ... ator/index

If your emphasis is on asynchronous update then look at this example:

http://www.newlisp.org/index.cgi?page=AJAX_and_newLISP

You could merge both approaches passing the expression to evaluate as parameter in the xmlHttp GET request.

abbat
Posts: 8
Joined: Tue Nov 03, 2009 7:49 pm

Re: Calling newlisp from Javascript

Post by abbat »

Sorry for long silent.

I create file "eval.cgi":

Code: Select all

#!/usr/bin/newlisp

(define (url-translate str)
   (replace "%([0-9A-F][0-9A-F])" str (format "%c" (int (append "0x" $1))) 1))

(print "Content-type: text/html\r\n\r\n")
(print (eval-string (url-translate (env "QUERY_STRING"))))
(exit)

# end of file
and file "test1.html":

Code: Select all

<html>
<body>
<h3>newLISP server and JS demo</h3>

<script type="text/javascript" language="javascript">

if (window.XMLHttpRequest) { 
    xmlHttp = new XMLHttpRequest();
} else if (window.ActiveXObject) { 
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}

function newLispEval(expr) {
  xmlHttp.open("GET", "eval.cgi?" + expr, false);
  try {
    xmlHttp.send(null);
  } catch (e) { alert(e.message); }
  return xmlHttp.responseText;
}

var answer;
answer = newLispEval("(+ 3 4)");
document.write(answer);
document.write("<BR>ok.");
</script>
</body>
</html>
<!-- end of file -->
then I run

Code: Select all

newlisp.exe -c -d 1235
and open browser for location:

Code: Select all

http://localhost:1235//tmp/1/test1.html
and... it's work!
Thanks you.

But I still have some small problems:
1. Newlisp session not saved between requests:
after

Code: Select all

newLispEval("(set 'x 3)");
evaluation of

Code: Select all

newLispEval("(+ 'x 4)");
give me error "ERR: value expected in function + : x".
It is possible work form Javascript with one newlisp session?

2. Newlisp in server mode not support names with spaces?
Location like:
http://localhost:1235//my projects/q1/test1.html
not work for me.

3. It is possible explicit specify Windows drive letter in location?
Location like:
not work for me.

abbat
Posts: 8
Joined: Tue Nov 03, 2009 7:49 pm

Re: Calling newlisp from Javascript

Post by abbat »

Sorry, misprint:
instead
"newLispEval("(+ 'x 4)");"
must be
"newLispEval("(+ x 4)");"

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: Calling newlisp from Javascript

Post by Lutz »

1. Newlisp session not saved between requests:
You could save the session doing a (save "session.lsp") in the CGI program after evaluating and doing (load "session.lsp") at the beginning of each CGI process.

But a better/faster solution would be to start a second newlisp server process, which stays in memory, and use 'net-eval' to connect from it from the CGI process. newLISP processes use very little memory, so starting just another one is the preferred solution. It is also the more secured solution, because you could preload the serve with statements disabling all dangerous commands. E.g:

Code: Select all

(constant 'delete-file (fn () "not allowed"))
2. Newlisp in server mode not support names with spaces?
Currently not supported. newLISP server mode is not meant to be a full featured web server, it doesn't do any URL back translation.
3. It is possible explicit specify Windows drive letter in location?
Drive switching works like this on Windows:

Code: Select all

http://localhost:1235/D:/tmp/1/test1.html
If D would be the current drive, you could do:

Code: Select all

http://localhost:1235//tmp/1/test1.html

abbat
Posts: 8
Joined: Tue Nov 03, 2009 7:49 pm

Re: Calling newlisp from Javascript

Post by abbat »

This is suitable for me.
Many thanks!

Locked