From faulstic@inf.fu-berlin.de Mon Apr 3 11:40:14 2000 Received: from math.fu-berlin.de (leibniz.math.fu-berlin.de [160.45.40.10]) by swi.psy.uva.nl (8.9.3/8.9.3) with SMTP id LAA28722 for ; Mon, 3 Apr 2000 11:40:14 +0200 (MET DST) Received: (qmail 6355 invoked from network); 3 Apr 2000 11:40:31 +0200 Received: from goliath.inf.fu-berlin.de (160.45.110.46) by leibniz.math.fu-berlin.de with QMQP; 3 Apr 2000 11:40:31 +0200 From: Lukas Faulstich MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="7/ZKyvzVh+" Content-Transfer-Encoding: 7bit Message-ID: <14568.26436.13071.661572@inf.fu-berlin.de> Date: Mon, 3 Apr 2000 11:41:23 +0200 (MET DST) To: Lionel Ains CC: prolog@swi.psy.uva.nl Subject: CGI with SWI-Prolog In-Reply-To: <954749064008022@caramail.com> References: <954749064008022@caramail.com> X-Mailer: VM 6.75 under Emacs 20.3.1 Reply-To: faulstic@inf.fu-berlin.de --7/ZKyvzVh+ Content-Type: text/plain; charset=us-ascii Content-Description: message body and .signature Content-Transfer-Encoding: 7bit Lionel Ains writes: > Hello, > > I am trying to use SWI-Prolog as a CGI script. > To get the post parameters, I would like to read from the > stdin without Prolog printing ':|'. > I found out that this was possible by trying to get the > input when not on an empty line. > How could I do that in any cases (when the cursor is at the > begining of the line)? % switch off the prompt: prompt(_, '') > Is there a non-blocking way to detect the when nothing is > sent to the user input (script called without parameter)? > Are there available librairies to handle the URL > encoding/decoding? it is easier to use Java Servlets to let them do this job. This has the advantage that you can maintain a stateful prolog process that handles multiple http requests. While there is the jpl library for calling prolog from within java , I found it easier to use standard input/output for communication. You might have a look at the attached Java/Prolog source code. Hope that helps- Lukas -- Lukas C. Faulstich faulstic@inf.fu-berlin.de Institut fuer Informatik +49 (30) 838 - 75 123 Freie Universitaet Berlin +49 (30) 838 - 75 109 (fax) Takustr. 9 http://www.inf.fu-berlin.de/~faulstic D-14195 Berlin, Germany PGP key: see my homepage --7/ZKyvzVh+ Content-Type: text/plain Content-Description: prolog backend Content-Disposition: inline; filename="servlet.pl" Content-Transfer-Encoding: 7bit /* * $Id: servlet.pl,v 1.9 1999/11/14 21:31:46 faulstic Exp $ * * (c) Lukas Faulstich * * Description: backend for servlet * */ :- module(servlet, [ servlet_loop/0 ]). servlet_loop:- % redirect user_error to current output current_output(CurrentOut), dup_stream(CurrentOut, user_error), % switch off the prompt: prompt(_, ''), % start the loop next. next:- read_action(Action, Bindings), handle(Action, Bindings). handle(http_request(Parameters), _):- !, http_request(Parameters), next. handle(syntax_error, _):- !, error('Syntax Error', []). handle(welcome, _):- !, welcome, next. handle(next, _):- !, fail. handle(halt,_):- !, halt. handle(end_of_file,_):- !, halt. handle(done,_):- !. handle(Action,_):- error('Don\'t understand ~w', [Action]), next. http_request(Attributes):- member(halt=true, Attributes), !, base_url(BaseURL), format('Halt

Halt

The system has been halted. ~n~n', []), halt. http_request(Attributes):- http_request(Attributes):- decode_attributes(Attributes, DecodedAttributes) % use DecodedAttributes = [Attr1=Val1,...,Attrn=Valn] % to generate HTML page and % print it to standard output, e.g.: format('Attributes

Attributes:

~w~n~n', [DecodedAttributes]), decode_attributes([], []). decode_attributes([A=V|AVs], [A=T|ATs]):- (atom_to_term(V,T,_) -> true; T=V), decode_attributes(AVs, ATs). error(Message, Args):- format('Error~n

Error:

'), format(Message, Args), format('~n~n'). remake:- format('Make

Make:


'), 
	make, 
	format('

~n~n'). welcome:- http_request([]). read_action(Action, Bindings):- read_line_term(Action, Bindings), !. read_action(end_of_file, []). read_line_term(Term, Bindings):- read_line(Line), (atom_to_term(Line, Term, Bindings) -> true; Term= syntax_error, Bindings=[]). read_line(Line):- get0(Char), Char \= -1, read_line_chars(Char, Chars, []), name(Line, Chars). read_line_chars(10) --> !, []. read_line_chars(-1) --> !, []. read_line_chars(C) --> [C], { get0(N) }, read_line_chars(N). --7/ZKyvzVh+ Content-Type: text/plain Content-Description: Java front end Content-Disposition: inline; filename="PrologServlet.java" Content-Transfer-Encoding: 7bit // Frontend Servlet for SWI Prolog (servlet.pl) import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; public final class PrologServlet extends HttpServlet { Process backEnd= null; PrintWriter backEndInput= null; BufferedReader backEndResults= null; PrintWriter logWriter= null; public String getServletInfo() { return "Frontend for SWI Prolog (servlet.pl)"; } public void init(ServletConfig config) throws ServletException { String logFileName; super.init(config); initBackEnd(); if ((logFileName = getInitParameter("logfile")) == null) { // throw new UnavailableException (this, "No log file given!"); } else { try { logWriter= new PrintWriter(new FileOutputStream(logFileName), true); } catch (IOException e) { throw new UnavailableException (this, "Cannot open log file " + logFileName + "!"); } } } public void initBackEnd() throws ServletException { String tmpdir=getInitParameter("tmpdir"); if (tmpdir == null) { tmpdir = "/tmp"; } String set_tmpdir="TMPDIR="+(new File(tmpdir)).getAbsolutePath(); String servletName=getInitParameter("servletname"); String[] envp; if (servletName==null) { String[] tmp_envp= {set_tmpdir}; envp= tmp_envp; } else { String[] tmp_envp= {set_tmpdir, "SERVLET_NAME="+servletName}; envp= tmp_envp; } String backEndCall=null; if ((backEndCall = getInitParameter("backend")) == null) { backEndCall = "HyperView"; } try { backEnd = Runtime.getRuntime().exec(backEndCall, envp); backEndInput = new PrintWriter(backEnd.getOutputStream(), true); backEndResults = new BufferedReader(new InputStreamReader(backEnd.getInputStream())); } catch(IOException e) { throw new UnavailableException (this, "Cannot initialize back end!"); } } public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException { doGet(req, res); } public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException { String action; boolean result; // Set Content Type: res.setContentType("text/html"); // get output stream to client PrintWriter servletOut = null; try { servletOut = res.getWriter(); } catch (IOException e) { log("Failed to establish output stream to client"); return; } if(!forwardRequest(req, servletOut)){ log("Pipe failed. Trying to restart backend..."); closeBackEnd(); initBackEnd(); log("... backend restarted."); if (!forwardRequest(req, servletOut)){ log("Pipe failed."); servletOut.println("Fatal Error

Fatal Error

Failed to (re)start the HyperView Server."); } } servletOut.close(); } public boolean forwardRequest(HttpServletRequest req, PrintWriter servletOut){ backEndInput.print("http_request("); printParameters(req, backEndInput); backEndInput.println(")."); log("Request sent."); return pipePage(backEndResults, servletOut); } public void printParameters(HttpServletRequest req, PrintWriter out){ int j=0; Enumeration e = req.getParameterNames(); log("Parameters:"); out.print('['); while (e.hasMoreElements()) { String name = (String)e.nextElement(); String vals[] = (String []) req.getParameterValues(name); if (vals != null) { for (int i = 0; i 0) { out.print(','); } out.print(name + "="); log(name + "= \"" + vals[i] + "\""); printAtom(out, vals[i]); j++; } } } out.print(']'); } public void printAtom(PrintWriter out, String atom) { int i, l=atom.length(); char c; out.print('\''); for (i=0; i