Permalink
Browse files

cgi support

  • Loading branch information...
klacke committed Jul 10, 2009
1 parent 034faa4 commit 2fa66b064d72205ef4886199a043bedb083bb78c
Showing with 1,183 additions and 204 deletions.
  1. +107 −0 doc/yaws.tex
  2. +25 −11 include/yaws.hrl
  3. +1 −1 include/yaws_api.hrl
  4. +25 −3 man/yaws.conf.5
  5. +73 −0 man/yaws_api.5
  6. +1 −0 src/Makefile
  7. +4 −0 src/mime_type_c.erl
  8. +12 −1 src/yaws.erl
  9. +55 −0 src/yaws_api.erl
  10. +14 −0 src/yaws_appmod_fcgi.erl
  11. +760 −145 src/yaws_cgi.erl
  12. +90 −42 src/yaws_config.erl
  13. +16 −1 src/yaws_server.erl
View
@@ -1600,6 +1600,113 @@ \chapter{External scripts via CGI}
feature is therefore interested in hearing about your experiences with
it. He can be contacted as \verb+carsten@codimi.de+.
+\chapter{FastCGI}
+
+Yaws supports the responder role and the authorizer role of the
+FastCGI protocol. See www.fastcgi.com for details on the FastCGI
+protocol.
+
+The benefits of using FastCGI include:
+\begin{enumerate}
+\item Unlike CGI, it is not necessary to spawn a new process for
+every request; the application server can handle multiple requests
+in a single process.
+\item The fact that the application server can run on a different
+computer benefits scalability and security.
+\item The application server can be written in any language for
+which a FastCGI library is available. Existing applications
+which have been written for other web servers can be used with
+Yaws.
+\item FastCGI can also be used to implement external authentication
+servers (in addition to generating dynamic content).
+\end{enumerate}
+
+Support for FastCGI was added to Yaws by Bruno Rijsman
+(brunorijsman@hotmail.com).
+
+\section{The FastCGI responder role}
+
+The FastCGI responder role allows Yaws to communicate with an
+application server running on a different (or on the same) computer
+to generate dynamic content.
+
+The FastCGI protocol (which runs over TCP) is used to send the request
+information from Yaws to the application server and to send the
+response information (e.g. the generated dynamic content) from
+the application server back to Yaws.
+
+FastCGI responders can be invoked in two ways:
+
+\begin{enumerate}
+
+\item
+By including \verb+fcgi+ in the \verb+allowed_scripts+ line
+in the configuration file (note that the default value for
+\verb+allowed_scripts+ includes \verb+fcgi+).
+
+In this case a request for any resource with the
+.fcgi extension will result in a FastCGI call to the application
+server to dynamically generate the content.
+
+Note: the Yaws server
+will only call the application server if a file corresponding to
+the resource name (i.e. a file with the .fcgi extension)
+exists locally on the Yaws server. The contents of that
+file are not relevant.
+
+\item
+By creating an appmod which calls \verb+yaws_api:call_fcgi_responder+.
+See the \verb+yaws_api (5)+ man page for details.
+
+\end{enumerate}
+
+\section{The FastCGI authorizer role}
+
+The FastCGI authorizer role allows Yaws to communicate with an
+authentication server to authenticate requests.
+
+The FastCGI protocol is used to send the request
+information from Yaws to the authentication server and the
+authentication respone back from the authentication server to
+Yaws.
+
+If access is allowed, Yaws processing of the request proceeds
+normally.
+
+If access is denied, the authentication server provides the
+response which is sent back to the client. This is typically
+a not authorized response or a redirect to a login page.
+
+FastCGI authorizers are invoked by creating an appmod which
+calls \verb+yaws_api:call_fcgi_authorizer+.
+See the \verb+yaws_api (5)+ man page for details.
+
+\section{The FastCGI filter role}
+
+FastCGI defines a third role, the filter role, which
+is currently not supported by Yaws.
+
+
+\section{FastCGI configuration}
+
+The following commands in the \verb+yaws.conf+ file control the
+operation of FastCGI.
+
+If you use FastCGI, you \emph{must} include the \verb+fcgi_app_server+
+command in the configuration file to specify the host name (or IP address)
+and TCP port of the FastCGI application server.
+
+You may include the \verb+fcgi_trace_protocol+ command to enable or disable
+tracing of FastCGI protocol messages. This is useful for debugging.
+
+You may include the \verb+fcgi_log_app_error+ command to enable or disable
+logging application errors (any output to stderr and non-zero exit codes).
+
+You may include the \verb+extra_cgi_vars+ command to pass additional
+environment variables to the application.
+
+
+
\chapter{Security}
\Yaws\ is of course susceptible to intrusions. \Yaws\ has the
View
@@ -78,7 +78,7 @@
max_num_cached_bytes = 1000000, %% 1 MEG
max_size_cached_file = 8000,
large_file_chunk_size = 10240,
- mnesia_dir = [],
+ mnesia_dir = [],
log_wrap_size = 10000000, % wrap logs after 10M
cache_refresh_secs = 30, % seconds (auto zero when debug)
include_dir = [], %% list of inc dirs for .yaws files
@@ -103,14 +103,16 @@
%% flags for sconfs
--define(SC_ACCESS_LOG, 1).
--define(SC_ADD_PORT, 2).
+-define(SC_ACCESS_LOG, 1).
+-define(SC_ADD_PORT, 2).
-define(SC_STATISTICS, 4).
--define(SC_TILDE_EXPAND, 8).
--define(SC_DIR_LISTINGS, 16).
--define(SC_DEFLATE, 32).
--define(SC_DIR_ALL_ZIP, 64).
--define(SC_DAV, 128).
+-define(SC_TILDE_EXPAND, 8).
+-define(SC_DIR_LISTINGS, 16).
+-define(SC_DEFLATE, 32).
+-define(SC_DIR_ALL_ZIP, 64).
+-define(SC_DAV, 128).
+-define(SC_FCGI_TRACE_PROTOCOL, 512).
+-define(SC_FCGI_LOG_APP_ERROR, 1024).
-define(SC_DEF, ?SC_ACCESS_LOG bor ?SC_ADD_PORT).
@@ -130,6 +132,10 @@
(((SC)#sconf.flags band ?SC_DIR_ALL_ZIP) /= 0)).
-define(sc_has_dav(SC),
(((SC)#sconf.flags band ?SC_DAV) /= 0)).
+-define(sc_fcgi_trace_protocol(SC),
+ (((SC)#sconf.flags band ?SC_FCGI_TRACE_PROTOCOL) /= 0)).
+-define(sc_fcgi_log_app_error(SC),
+ (((SC)#sconf.flags band ?SC_FCGI_LOG_APP_ERROR) /= 0)).
-define(sc_set_access_log(SC, Bool),
@@ -150,6 +156,10 @@
SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_DIR_ALL_ZIP, Bool)}).
-define(sc_set_dav(SC, Bool),
SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_DAV, Bool)}).
+-define(sc_set_fcgi_trace_protocol(SC, Bool),
+ SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_FCGI_TRACE_PROTOCOL, Bool)}).
+-define(sc_set_fcgi_log_app_error(SC, Bool),
+ SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_FCGI_LOG_APP_ERROR, Bool)}).
@@ -173,17 +183,21 @@
partial_post_size = nolimit,
appmods = [], %% list of modules for this app
errormod_401 = yaws_outmod, %% the default 401 error module
- errormod_404 = yaws_outmod, %% the default 404 error module
+ errormod_404 = yaws_outmod, %% the default 404 error module
errormod_crash = yaws_outmod, %% use the same module for crashes
arg_rewrite_mod = yaws,
opaque = [], %% useful in embedded mode
start_mod, %% user provided module to be started
- allowed_scripts = [yaws,php,cgi],
+ allowed_scripts = [yaws,php,cgi,fcgi],
tilde_allowed_scripts = [],
revproxy = [],
soptions = [],
extra_cgi_vars = [],
stats, %% raw traffic statistics
+ fcgi_app_server_host, %% FastCGI application server host name or IP address
+
+ fcgi_app_server_port, %% FastCGI application server port number
+
%% [{Extension:string(), Mod:atom()]
%% work in progress .....
extension_mods = [{"ys", yaws_ext_handler_yaws}]
@@ -199,7 +213,7 @@
{dir = [],
realm = "",
type = "Basic",
- headers = [], %% headers to send on 401
+ headers = [], %% headers to send on 401
users = [], %% list of {User, Password} tuples
mod = [], %% authentication module callback
pam = false %% should we use pam to auth a user
View
@@ -32,7 +32,7 @@
prepath, %% Path prior to 'dynamic' segment of URI.
%% ie http://some.host/<prepath>/<script-point>/d/e
%% where <script-point> is an appmod mount point,
- %% or .yaws,.php,.cgi etc script file.
+ %% or .yaws,.php,.cgi,.fcgi etc script file.
pathinfo %% Set to '/d/e' when calling c.yaws for the request
%% http://some.host/a/b/c.yaws/d/e
%% equiv of cgi PATH_INFO
View
@@ -229,7 +229,7 @@ Set to true_nozip to avoid the auto-generated all.zip entries.
.TP
\fBextra_cgi_vars = .....\fR
-Add additional CGI variables. For example:
+Add additional CGI or FastCGI variables. For example:
.nf
<extra_cgi_vars dir='/path/to/some/scripts'>
@@ -242,6 +242,24 @@ var = val
\fBstatistics = true | false\fR
Turns on/off statistics gathering for a virtual server.
+.TP
+\fBfcgi_app_server = Host:Port \fR
+The hostname and TCP port number of the FastCGI aplication server.
+The TCP port number is not optional.
+There is no default value.
+
+.TP
+\fBfcgi_trace_protocol = true | false \fR
+Enable or disable tracing of FastCGI protocol messages as info
+log messages.
+Disabled by default.
+
+.TP
+\fBfcgi_log_app_error = true | false \fR
+Enable or disable logging of application error messages: output
+to stderr and non-zero exit value.
+Disabled by default.
+
.TP
\fBdeflate = true | false\fR
Turns on or off deflate compression for a server.
@@ -280,13 +298,17 @@ The default value is false.
.TP
\fBallowed_scripts = [ListOfSuffixes]\fR
The allowed script types for this server. Recognized are `yaws',
-`cgi', `php'. Default is \fIallowed_scripts = [yaws,php,cgi]\fR.
+`cgi', `fcgi', `php'. Default is \fIallowed_scripts = [yaws,php,cgi,fcgi]\fR.
+
+Note: for fcgi scripts, the FastCGI application server is only
+called if a local file with the .fcgi extension exists. However,
+the contents of the local .fcgi file are ignored.
.TP
\fBtilde_allowed_scripts = [ListOfSuffixes]\fR
The allowed script types for this server when executing files in
a users public_html folder Recognized are `yaws',
-`cgi', `php'. Default is \fItilde_allowed_scripts = []\fR.
+`cgi', `fcgi', `php'. Default is \fItilde_allowed_scripts = []\fR.
.TP
View
@@ -400,6 +400,79 @@ Like before, but
calls \fIExefilename\fR to handle the script. The file name of the
script is handed to the executable via a CGI meta variable.
+.TP
+\fBcall_fcgi_responder(Arg)\fR
+Calls a FastCGI responder.
+The address and port of the FastCGI application server are taken
+from the server configuration (see yaws.conf).
+Used to make `.yaws' wrappers for FastCGI responders.
+Returns the same return values as out/1 (see below).
+
+.TP
+\fBcall_fcgi_responder(Arg, Options)\fR
+Same as above, but Options overrides the defaults from the server
+configuration:
+
+\fI
+.nf
+Options = [Option]
+Option -- one of the following:
+.fi
+\fR
+
+\fB{app_server_host, string() | ip_address()}\fR
+The hostname or the IP address of the FastCGI application server.
+
+\fB{app_server_port, 0..65535}\fR
+The TCP port number of the FastCGI application server.
+
+\fB{path_info, string()}\fR
+Override default pathinfo in Arg#arg.pathinfo.
+
+\fB{extra_env, ExtraEnv}\fR
+Override default pathinfo in Arg#arg.pathinfo.
+
+\fI
+.nf
+ExtraEnv = [Var]
+Var = {Name, Value}
+Name = string()
+Value = string()
+.fi
+\fR
+
+\fB{trace_protocol, boolean()}\fR
+Enable or disable tracing of FastCGI protocol messages as info
+log messages.
+
+\fB{log_app_error, boolean()}\fR
+Enable or disable logging of application error messages: output
+to stderr and non-zero exit value.
+
+.TP
+\fBcall_fcgi_authorizer(Arg) -> {allowed, Variables} | {denied, Out}\fR
+Calls a FastCGI authorizer.
+The address and port of the FastCGI application server are taken
+from the server configuration (see yaws.conf).
+Used to make `.yaws' wrappers for FastCGI authorizers.
+Variables contains the values of the variables returned by the FastCGI
+application server in the "Variable-XXX: YYY" headers.
+
+\fI
+.nf
+Out -- See return values for out/1 below
+Variables = {Name, Value}
+Name = string()
+Value = string()
+.fi
+\fR
+
+.TP
+\fBcall_fcgi_authorizer(Arg, Options)\fR
+Same as above, but Options overrides the defaults from the server
+configuration. See call_fcgi_responder/2 above for a description
+of Options.
+
.TP
\fBdir_listing(Arg)\fR
Perform a directory listing. Can be used in special directories
View
@@ -38,6 +38,7 @@ MODULES=yaws \
yaws_soap_srv yaws_soap_lib \
authmod_gssapi \
yaws_appmod_cgi \
+ yaws_appmod_fcgi \
yaws_sendfile yaws_sendfile_compat \
yaws_sup_restarts \
yaws_stats
View
@@ -103,8 +103,10 @@ gen(T) ->
special(Fd, "yaws", yaws),
special(Fd, "php", php),
special(Fd, "cgi", cgi),
+ special(Fd, "fcgi", fcgi),
special(Fd, "PHP", php),
special(Fd, "CGI", cgi),
+ special(Fd, "FCGI", fcgi),
lists:foreach(
fun({Ext, MT0}) ->
MT = case MT0 of
@@ -123,8 +125,10 @@ gen(T) ->
revspecial(Fd, "yaws", yaws),
revspecial(Fd, "php", php),
revspecial(Fd, "cgi", cgi),
+ revspecial(Fd, "fcgi", fcgi),
revspecial(Fd, "PHP", php),
revspecial(Fd, "CGI", cgi),
+ revspecial(Fd, "FCGI", fcgi),
lists:foreach(
fun({Ext, MT0}) ->
MT = case MT0 of
Oops, something went wrong.

2 comments on commit 2fa66b0

This is a great commit. With FCGI support, Rails now can run under Yaws.

Please sign in to comment.