1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
**********************************************************************
*** Experimental JSERV support ***
**********************************************************************
The jserv protocol is very similar to CGI, but it does not start a new
process for every HTTP request. The request is encoded and forwarded
to a server process that handles it. The server process can be started
manually or on demand by the web server. As a picture:
BROWSER <----HTTP----> WEBSERVER <----JSERV----> JSERVD
There is a relatively old module for Apache (mod_jserv) implementing
the jserv client. You can get it from
http://java.apache.org/jserv. Note that the Java Apache project is
dead, but the jserv protocol is also used by Jakarta: Tomcat contains
the module mod_jk that supports the same jserv protocol version (1.2)
as the original implementation but with a different configuration
file. However, I am currently using mod_jserv for my experiments; it
is smaller and easier to extract from the whole distribution. The
Jakarta version will surely become important in the future.
I have written a server for jserv in O'Caml that uses the existing
netcgi infrastructure. This means that it is simple to convert an
existing CGI script into a jserv server, it is only necessary to
change the main program.
Currently, the following server architectures are supported:
- Sequential servers: One request is processed after the other
- Forking servers: For every request a new subprocess is started.
(This looks like CGI, but has still advantages, as the main process
can do expensive initializations.)
There is also a working experiment with a multi-threaded server,
but the code is not yet ready to be released (look into the CVS tree
under src/cgi/tests).
A typical CGI script is:
let cgi = new std_activation() in
... (* analyze request *)
cgi # set_header ... ();
cgi # output # output_string ...;
cgi # output # commit_work()
The corresponding jserv program is:
let process cgi =
... (* analyze request *)
cgi # set_header ... ();
cgi # output # output_string ...;
cgi # output # commit_work()
let srvtype =
`Sequential (* or `Forking *)
[ "add", { req_activate = process;
req_processing = (fun _ _ -> `Memory);
req_operating_type = buffered_transactional_optype;
}
]
jvm_emu_main
(run srvtype `Ajp_1_2)
As you can see, the request handler (once the cgi object is available) is the
same. Some explanations:
- jvm_emu_main: This is the main program. It emulates the JVM command
signature which is necessary because the jservd is started from
mod_jserv, and mod_jserv assumes it starts a JVM. The important
thing is that the second command argument is the name of the
property file to read in ( ==> props).
Apache starts the jserv server by executing a command like
/where/it/is/jservd -classpath XXX jserv.properties
jvm_emu_main ignores the classpath, but extracts the name of the
jserv.properties file from the command, and parses it to get more
information.
- In the property file the address and port of the server socket is
configured, and optionally the authentication method (the connection
betweem the web server and jservd can be secured).
See README.properties for a minimal properties file. (You have to
write one.)
- The function Netcgi_jserv_app.run starts the server. It gets two
arguments: The server type and the protocol type. The latter is
currently always `Ajp_1_2 (Apache Jserv Protocol 1.2). The server
type determines the architecture (sequential or forking), and the
mapping of the servlet names to the request handlers.
In this example, "add" is the name of the servlet, and the
record specifies how to handle requests arriving for this servlet.
The httpd.conf file defines the root URL for the servlets, e.g.
/servlets, and the servlet names are simply appended. In the example,
the servlet has the URL /servlets/add.
(Note: Alternatively, it is also possible to start several jservd
servers, for every servlet a new one.)
In this directory, you find two examples:
- add_sequential.ml: Same as ../cgi/add.cgi, but uses a sequential
jservd
- add_forking.ml: Same as ../cgi/add.cgi, but uses a forking jservd
Once you have compiled them, there are two executables: add_sequential
and add_forking. These are already the daemons. Try
./add_sequential -help
- you will see that the daemon accepts JVM-compatible arguments. The
daemon can be started manually, or by the web server. Which method is
better depends on:
- As which user the daemons run. If the user is the same as the web
server, it is preferrable to let the web server start the jserv server.
- Whether the web server acts as "watch dog" for the jserv server.
If the jservd crashes, the web server can automatically restart it.
The way the jservd is started is configured in httpd.conf. See
README.httpd.conf for details.
So the next steps to get the examples running are:
- Modify your httpd.conf
- Write jserv.properties and put the file at the right place
- Restart your web server
*** Notes on installing mod_jserv ***************************************
If you don't have already mod_jserv.so for your Apache: You need
http://java.apache.org/jserv/dist/ApacheJServ-1.1.2.tar.gz. You don't need
the JSDK classes (but a Java compiler; only to satisfy the configure script).
Do:
mkdir -p jsdk/javax/servlet
touch jsdk/javax/servlet/Servlet.class
This way the configure script thinks you have the JSDK classes.
./configure --with-apxs=/usr/sbin/apxs --prefix=/tmp/jserv --with-JSDK=jsdk
(Maybe you need --enable-EAPI, too)
Then do
cd src/c
make
The resulting mod_jserv.so was in src/c/.libs (i.e. where libtool stores
libraries before installation).
If you have already mod_jk.so for your Apache: I don't know if it works.
Eventually it is necessary to change the names of the properties in
jvm_emu_main. httpd.conf is probably different, too. Furthermore, mod_jk
seems to pass fewer variables (e.g. SCRIPT_NAME is omitted). I had a
quick look at the source code, so I know that things are slightly different.
|