HTTP Client

URL-pathname [class]

  :super   pathname 

:slots server port protocol

extends pathname to allow URL notation.

url-pathname name [function]

instantiates url-pathname class object from url string or url-pathname class object.

escape-url url &optional (ss *standard-output*) (queryp t) [function]

writes percent-escaped url to stream ss (default: *standard-output*). If queryp is T, then Space in url is encoded to +, otherwise escaped as Space. This option is convenient for sending url query to server with separation.

escaped-url-string-from-namestring url-string &optional (queryp t) [function]

returns result of escape-url as string.

unescape-url url &optional (ss *standard-output*) (queryp t) [function]

unescapes percent-escaped url and writes unescaped url to stream ss.

unescaped-url-string-from-namestring url-string &optional (queryp t) [function]

returns result of unescape-url as string.

read-http url &key (timeout 10) (retry 5) [function]

makes a socket connection to the designated url, and read the html document. The result is a list of tags and plain strings. HTML tags are converted as lists consisting of the tag-name and argument lists. For example, the following html document, results in the following list. Note that tags are represented as lists, in which the directive is represented as a symbol followed by symbols or strings. Whether an argument is represented as symbol or string reflects how the original argument is described.

<body bgcolor=#ffa080>
<h1> EusLisp Title</h1>
<li> item1 </li>
<a href=""> euslisp</a>

("HTTP/1.1 200 OK"
 "Date: Sun, 21 May 2000 11:47:00 GMT"
 "Server: Apache/1.3.9 (Unix)"
 "Last-Modified: Sun, 21 May 2000 11:19:35 GMT"
 "ETag: \"4f014-c7-3927c647\""
 "Accept-Ranges: bytes"
 "Content-Length: 199"
 "Content-Type: text/html"
 (head) (title) " Toshihiro Matsui on t570" (/title) (/head)
 (body bgcolor |#FFA080|)
 (h1) " Title Line" (/h1)
 (li) " item1 " (/li)
 (a href "")
 " euslisp"

extract-html tag html-list [function]

returns a list of strings (and tags) sandwitched by tag and /tag.

remove-html-tags html-list [function]

removes tags from the html-list leaving only texts (strings).

HTTP CGI Programming

EusLisp can be used for CGI programming. The following is a typical cgi entry to a EusLisp program. This code piece should be placed under .../cgi-bin/ or under any directories where ExecCGI is allowed. The code piece must have execute permission by the `nobody' user. Note that CGI programs are executed by httpd whose owner is nobody. You also have to set up some environment variables in the code piece, for nobody does not know anything particular for EusLisp.

#! /bin/csh
setenv EUSDIR /usr/local/eus/
setenv LD_LIBRARY_PATH /usr/local/eus/Linux/lib
/usr/local/bin/eus /usr/local/eus/lib/demo/mycgi.l

mycgi.l is a lisp source program, which should load "$EUSDIR/lib/llib/httpcgi.l" at the beginning. The CGI program is responsible for obtaining CGI arguments, generating an html header, and producing html contents. The arguments are obtained by the get-cgi-query function, and split to a list by the parse-cgi-query function. The parsed list contains pairs of argument-name and argument-value. For example, if the CGI is invoked by href to "/cgi-bin/eus.cgi?user=matsui&age=43", the parsed list gives ((user matsui) (age 43)).

All normal CGI output should go to *cgi-out*. Before any html document, a header should be generated by the html-header function. If there is any error message written to *error-output*, it appears in the httpd's error-log. When the work is done and html document finishes by '</html> tag, the process may close the connection (*cgi-out*) and may exit. Normal exit of the CGI process usually signals the httpd to send the data to http clients.

*cgi-out* is the output stream to which the generated html document should be sent.

gen string [function]

Outputs the string to *cgi-out* stream, which is then forwarded to to the client (browser).

html args ... [function]

generates args as one string.

html-table lst &key heading (table-option "") [function]

generates an html table.

get-cgi-query [function]

gets the argument to this CGI program. First, the REQUEST_METHOD environment variable is looked up, and the POST/GET method is determined. The query string is obtained from the QUERY_STRING environment variable or from the standard input. Anyways, the result is returned in one string.

parse-http-query query-string [function]

html-header [function]
generates the html header, usually a simple string of two lines, "Content-type: text/html~%~%".

qval arg query [function]

arg (symbol) is searched in the query list, and the value is returned if found. The result is converted to euc encoding from sjis encoding.


Whereas CGI is a convenient method to produce dynamic document on the server side, it is not the very best choice due to a performance reason: the cgi process must be spawned everytime a request arrives, and the process invocation time is not always negligible. In my measurement, the simplest CGI written in EusLisp needs 0.3 sec to respond. In this sense, EusLisp or any other programming system with rich runtime modules is not a very good choice for CGI writing.

Since this invocation load is a common problem for all CGI programs, there is a clever work around called Fast-CGI. The basic idea of the Fast-CGI is to allow CGI processes to keep alive even one CGI request is fulfilled. The httpd process communicates with a fast-cgi process via a TCP connection.

fcgi-connection [class]

  :super   propertied-object 

:slots cookie host

fcgi-loop &rest forms [macro]

repeats evaluation of forms each time http connection request is accepted.

Travis CI User 2017-03-07