The Prolog HTTP server is primarily designed to be able to handle HTTP
requests from a running Prolog process, which avoids the Prolog startup
time and, at least as interesting, allows you to keep state in the
Prolog database. It is not designed to run as a generic web server.
There are tools that are much better for that job. Nevertheless, it is
useful to host a complete server in one process, mainly to simplify
deployment. For this reason, the SWI-Prolog HTTP server provides
libraries to serve static files (http_reply_file/3,
http_reply_from_files/3) and this library, which allows executing CGI
scripts.
A sensible alternative setup for a mixed server is to use a normal
server such as Apache as main server, serving files, CGI scripts,
modules, etc., and use Apache's proxy facilities to host a subdirectory
of the server using a Prolog server. That approach is most likely more
efficient for production environments, but harder to setup for
development purposes.
This module provides two interfaces:
- http_run_cgi/3 can be used to call a CGI script located exernally.
This is typically used for an individual script used to extend the
server functionality. For example, the handler declaration below
runs the PHP script
myscript.php
from the location =/myscript/=.
Note that this requires the commandline version of PHP to be
installed as php
in the current PATH
.
:- http_handler(root(myscript),
http_run_cgi(path(php), [argv('myscript.php')]),
[]).
- Setup a path
cgi_bin
for absolute_file_name/3. If this path is
present, calls to /cgi-bin/... are translated into calling the script.
For example, if programs in the directory cgi-bin
must be accessible
as CGI services, add a rule
:- multifile user:file_search_path/2.
user:file_search_path(cgi_bin, 'cgi-bin').
- See also
- - http://wiht.link/CGIaccessvariables
- To be done
- - complete environment translation. See env/3.
- - testing. Notably for POST and PUT commands.
- http_cgi_handler(+Alias, +Request)
- Locate a CGI script in the file-search-path Alias from the
path_info
in Request and execute the script using
http_run_cgi/3. This library installs one handler using:
:- http_handler(root('cgi-bin'), http_run_cgi(cgi_bin, []),
[prefix, spawn([])]).
- http_run_cgi(+Script, +Options, +Request) is det
- Execute the given CGI script. Options processed:
- argv(+List)
- Argument vector to give to the CGI script. Defaults to
no arguments.
- transfer_encoding(Encoding)
- Emit a
Transfer-encoding
header
- buffer(+Buffer)
- Set buffering of the CGI output stream. Typically used
together with
transfer_encoding(chunked)
.
- Arguments:
-
Script | - specifies the location of the script as a
specification for absolute_file_name/3. |
Request | - holds the current HTTP request passed from
the HTTP handler. |
- header_option(+Option) is det[private]
- Write additional HTTP headers.
- cgi_cleanup(+Script, +ScriptStream, +PID) is det[private]
- Cleanup the CGI process and close the stream use to read the
output of the CGI process. Note that we close the output first.
This deals with the possibility that the client reset the
connection, copy_cgi_data/3 returns and exception and we wait
for the process that never ends. By closing our stream, the
process will receive a sigpipe if it continues writing.
- input_handle(+Request, -Handle) is det[private]
- Decide what to do with the input stream of the CGI process. If
this is a PUT/POST request, we must send data. Otherwise we do
not redirect the script's input.
- setup_input(+ScriptInput, +Request) is det[private]
- Setup passing of the POST/PUT data to the script.
- copy_post_data(+DataIn, -ScriptIn, :Close) is det[private]
- Copy data from the CGI script to the client.
- copy_cgi_data(+CGI, -Out, +Options) is det[private]
- env(?Name, +Request, -Value) is nondet[private]
- Enumerate the environment variables to be passed to the child
process.
- accept_to_atom(+Accept, -AcceptAtom) is det[private]
- Translate back from the parsed accept specification in the HTTP
header to an atom.