3:3
scgi: Web Server HTTP SCGI and CGI
Link to this document with
@other-doc['(lib "scgi/scgi.scrbl")]
Link to this document with
@other-doc['(lib "scgi/scgi.scrbl")]
1 Introduction
Link to this section with
@secref["Introduction" #:doc '(lib "scgi/scgi.scrbl")]
Link to this section with
@secref["Introduction" #:doc '(lib "scgi/scgi.scrbl")]
The scgi library implements fast Web CGI using the SCGI protocol. This
library is used in conjunction with an HTTP server supporting SCGI, such as
Apache HTTP Server with the mod_scgi module.
The scgi library also supports running as normal Web CGI without any change
to the source code of the app, such as during development of an application
intended to be deployed using SCGI. This also gives flexibility in deployment,
allowing a system administrator to switch between either mode just by editing
the HTTP server configuration.
An example use of this library:
(require scgi) |
|
(cgi #:startup (lambda () |
(printf "Startup for cgi-type ~S..." |
(cgi-type))) |
|
#:request (lambda () |
(display "Content-type: text/html\r\n\r\n") |
(display "<p>Hello, world!</p>") |
(printf "<p>Your IP address is: ~S</p>" |
(cgi-remote-addr))) |
|
#:shutdown (lambda () |
(printf "Shutdown for cgi-type ~S..." |
(cgi-type)))) |
The procedure provided to the
#:request is the one that gets called for each request. Within that procedure, is the
CGI request context, in which procedures like
cgi-remote-addr may be called to get information about that particular request. All three procedures are called within
CGI context, in which procedures concerning the CGI mechanism separate from individual requests, such as
cgi-type may be called. Many programs will need to provide only the
#:request procedure.
2 Interface
Link to this section with
@secref["Interface" #:doc '(lib "scgi/scgi.scrbl")]
Link to this section with
@secref["Interface" #:doc '(lib "scgi/scgi.scrbl")]
(cgi | [ | #:startup startup-proc] | | | | | | | #:request request-proc | | | | | | [ | #:shutdown shutdown-proc | | | | | | | #:scgi-hostname scgi-hostname | | | | | | | #:scgi-max-allow-wait scgi-max-allow-wait | | | | | | | #:scgi-portnum scgi-portnum | | | | | | | #:reuse-scgi-port? reuse-scgi-port?]) | | → | | void? |
|
startup-proc : (-> any) = void |
request-proc : (-> any) |
shutdown-proc : (-> any) = void |
scgi-hostname : (or/c string? #f) = "127.0.0.1" |
scgi-max-allow-wait : exact-nonnegative-integer? = 4 |
| scgi-portnum | | : | | (and/c exact-nonnegative-integer? | (integer-in 0 65535)) |
| | = | | 4000 |
|
reuse-scgi-port? : boolean? = #t |
Implement CGI. Normal CGI is used if the REQUEST_URI environment variable is defined (which suggests that the code is
being called in a CGI context); otherwise, SCGI is used.
startup-proc is a thunk that is evaluated once (before listener starts). request-proc is evaluated once for each request (which, in normal CGI, is once). shutdown-proc is evaluated once, as processing of all CGI requests has finished.
For evaluation of request-proc, the default input and output ports are as with normal CGI, regardless
of whether normal CGI or SCGI is in use.
This procedure also accepts a few optional keyword arguments, all of
which apply to SCGI mode only. scgi-hostname is the hostname or IP address (as a string) for the interface on which
to listen. scgi-portnum is the TCP port number on that interface. scgi-max-allow-wait is the maximum number of unaccepted connections to permit waiting. reuse-scgi-port? is whether or not to reuse the TCP port number, such as if a previous
server exited and the port is in a TIME_WAIT state.
(cgi-content-length) → exact-nonnegative-integer?
|
In a CGI request context, returns the CGI content length – the
number of bytes that can be read from the default input port – as integer.
(make-cgi-variable-proc | | proc-name-sym | | | | | | | name-bytes) | | → | | (-> string?) |
|
proc-name-sym : symbol? |
name-bytes : bytes? |
Produces a procedure for getting a CGI environment variable value
as a string. Works whether in normal CGI or SCGI. This is useful for
accessing non-standard variables, such as might be provided by an unusual
Apache module. Argument proc-name-sym is a symbol for the name of the procedure, which is used in
error reporting. Argument name-bytes is the name of the environment variable, as a byte string.
For example, were the cgi-remote-user procedure not already defined, it could be defined as:
(define cgi-remote-user |
(make-cgi-variable-proc 'cgi-remote-user |
#"REMOTE_USER")) |
(cgi-content-type) → string?
|
(cgi-document-root) → string? |
(cgi-http-cookie) → string? |
(cgi-http-host) → string? |
(cgi-http-referer) → string? |
(cgi-http-user-agent) → string? |
(cgi-https) → string? |
(cgi-path-info) → string? |
(cgi-path-translated) → string? |
(cgi-query-string) → string? |
(cgi-remote-addr) → string? |
(cgi-remote-host) → string? |
(cgi-remote-user) → string? |
(cgi-request-method) → string? |
(cgi-request-uri) → string? |
(cgi-script-name) → string? |
(cgi-server-name) → string? |
(cgi-server-port) → string? |
In a CGI request context, returns the corresponding CGI value as
a string. Note that cgi-content-length is not in this list, and it returns a number rather than a string.
(scgi-variables) → (list/c (cons/c bytes? bytes?))
|
When called in SCGI mode, this procedure yields an alist of SCGI
variables with both the key and value of each pair being byte strings. Calling
this procedure in normal CGI mode is an error.
Note that normally you will not need to use this procedure, and will
instead use procedures like cgi-request-uri, which work in both SCGI and normal CGI modes.
(cgi-type) → (or/c 'normal 'scgi)
|
Returns a symbol indicating the CGI type: 'normal or 'scgi. Behavior outside of the procedures of the cgi procedure is undefined.
In CGI request context, yields a printable identifying object for
the current request that is unique at least for the current requests being
handled. This identifying object is intended to be used in debugging
messages.
(stop-cgi-service-immediately) → void?
|
Stops processing all CGI requests. This works only within the #:request procedure of the cgi procedure.
3 Apache mod_scgi
Link to this section with
@secref["Apache_mod_scgi" #:doc '(lib "scgi/scgi.scrbl")]
Link to this section with
@secref["Apache_mod_scgi" #:doc '(lib "scgi/scgi.scrbl")]
3.1 Apache mod_scgi Configuration
Link to this section with
@secref["Apache_mod_scgi_Configuration" #:doc '(lib "scgi/scgi.scrbl")]
Link to this section with
@secref["Apache_mod_scgi_Configuration" #:doc '(lib "scgi/scgi.scrbl")]
Apache HTTP Server is one way to run SCGI, though not the only way.
Note that your Apache installation might not have the mod_scgi module installed or enabled by default. If you happen to be
running Debian GNU/Linux, this module can be installed via the Debian package libapache2-mod-scgi.
Once you’ve installed mod_scgi, you need some standard SCGI directives to end up in your Apache
config files, whether you accomplish that by editing config files manually,
making symbolic links in a "mods-enabled" directory, or clicking in a GUI.
For example, the following loads mod_scgi, maps URL paths under "/mypath" to the SCGI server on the local machine at the standard SCGI TCP
port, and sets a 60-second timeout for the SCGI server to respond to a request
before Apache drops the connection:
LoadModule scgi_module /usr/lib/apache2/modules/mod_scgi.so |
SCGIMount /mypath 127.0.0.1:4000 |
SCGIServerTimeout 60 |
|
There are additional mod_scgi Apache config directives, including SCGIHandler and SCGIServer.
3.2 Apache mod_scgi Troubleshooting
Link to this section with
@secref["Apache_mod_scgi_Troubleshooting" #:doc '(lib "scgi/scgi.scrbl")]
Link to this section with
@secref["Apache_mod_scgi_Troubleshooting" #:doc '(lib "scgi/scgi.scrbl")]
This section has some troubleshooting tips. Currently, these come from
use with mod_scgi atop Apache 2.2.9 atop Debian GNU/Linux.
Racket error “tcp-write: error writing (Broken pipe; errno=32)”
or “tcp-write: error writing (Connection reset by peer; errno=104)” is likely
due to the HTTP request having been dropped by the HTTP client (e.g., user
stops a page load in their browser before page finishes loading) or by Apache
hitting SCGIServerTimeout for the request. Note that buffered I/O means that you won’t
necessarily get this error even if the request is aborted this way.
Apache error log entry “Premature end of script headers: PATH” followed by “(500)Unknown error 500: scgi: Unknown error 500:
error reading response headers” can mean that SCGIServerTimeout was hit before any HTTP headers from the SCGI request handler
were started or completed. Note that buffered I/O can mean that some of the
Racket code of the handler wrote some text, but it was not yet flushed to the
SCGI client.
Apache error log entry “(70007)The timeout specified has expired:
ap_content_length_filter: apr_bucket_read() failed” followed by “(70007)The
timeout specified has expired: scgi: The timeout specified has expired:
ap_pass_brigade()” can mean that SCGIServerTimeout was hit after HTTP headers from the request handler had been
received by the SCGI client.
Apache error log entry “(32)Broken pipe: scgi: Broken pipe: error
sending request body” might be due to a request handler finished without
consuming all of the HTTP POST data.
Apache error log entry “(103)Software caused connection abort:
scgi: Software caused connection abort: ap_pass_brigade()” is another one that
can be caused by the HTTP client dropping the connection before the handler
finishes.
4 History
Link to this section with
@secref["History" #:doc '(lib "scgi/scgi.scrbl")]
Link to this section with
@secref["History" #:doc '(lib "scgi/scgi.scrbl")]
Version 3:3 — 2016-03-02
Version 3:2 — 2016-02-25
Version 3:1 — 2016-02-25
Version 3:0 — 2016-02-21
Version 2:4 — 2015-04-02
Version 2:3 — 2014-11-23
Version 2:2 — 2013-04-19
Version 2:1 — 2013-04-12
Version 2:0 — 2012-06-12
The three main procedures arguments to the cgi procedure now have keywords. What are now the #:startup and #:shutdown arguments are now also optional.
Converted to McFly.
Changed internal-only identifiers from having a % prefix to a %scgi: prefix, to help disambiguate when identifiers appear in
error messages in large systems.
Documentation changes.
Improvement to the internal debugging macro.
Version 0.6 — Version 1:5 — 2011-08-22
Version 0.5 — Version 1:4 — 2011-05-16
Version 0.4 — Version 1:3 — 2011-05-16
Added #:reuse-scgi-port? argument to procedure cgi. Added several new CGI environment variable procedures.
Added make-cgi-variable-proc.
The cgi procedure now uses tcp-accept/enable-break rather than tcp-accept.
Added more log-debug.
Added documentation about mod_scgi configuration, troubleshooting,and the keyword
arguments to the cgi procedure.
Removed documentation placeholders for end-cgi-request for now.
Various additional quality assurance testing has been
done, and more is the works.
Version 0.3 — Version 1:2 — 2010-11-14
Version 0.2 — Version 1:1 — 2010-10-11
Version 0.1 — Version 1:0 — 2010-05-25
5 Legal
Link to this section with
@secref["Legal" #:doc '(lib "scgi/scgi.scrbl")]
Link to this section with
@secref["Legal" #:doc '(lib "scgi/scgi.scrbl")]
Copyright 2010–2013, 2015, 2016 Neil Van Dyke. This program is Free
Software; you can redistribute it and/or modify it under the terms of the GNU
Lesser General Public License as published by the Free Software Foundation;
either version 3 of the License, or (at your option) any later version. This
program is distributed in the hope that it will be useful, but without any
warranty; without even the implied warranty of merchantability or fitness for a
particular purpose. See http://www.gnu.org/licenses/ for details. For other
licenses and consulting, please contact the author.