Did you know ... Search Documentation:
http_cgi.pl -- Run CGI scripts from the SWI-Prolog web-server
PublicShow source

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.
Source 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([])]).
Source http_run_cgi(+Script, +Options, +Request) is det
Execute the given CGI script. Options processed:
Argument vector to give to the CGI script. Defaults to no arguments.
Emit a Transfer-encoding header
Set buffering of the CGI output stream. Typically used together with transfer_encoding(chunked).
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.
Source header_option(+Option) is det[private]
Write additional HTTP headers.
Source 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.
Source 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.
Source setup_input(+ScriptInput, +Request) is det[private]
Setup passing of the POST/PUT data to the script.
Source copy_post_data(+DataIn, -ScriptIn, :Close) is det[private]
Copy data from the CGI script to the client.
Source copy_cgi_data(+CGI, -Out, +Options) is det[private]
Source env(?Name, +Request, -Value) is nondet[private]
Enumerate the environment variables to be passed to the child process.
Source accept_to_atom(+Accept, -AcceptAtom) is det[private]
Translate back from the parsed accept specification in the HTTP header to an atom.