Only expose the shutdown functions.
[catagits/fcgi2.git] / doc / fcgi-java.htm
CommitLineData
0198fd3c 1<html>
2<head><title>Integrating FastCGI with Java</title>
3</head>
4
5<body bgcolor="#FFFFFF" text="#000000" link="#cc0000" alink="#000011"
6vlink="#555555">
7
8<center>
6791223e 9<a href="http://fastcgi.com">
0198fd3c 10 <img border=0 src="../images/fcgi-hd.gif" alt="[[FastCGI]]"></a>
11</center>
12<br clear=all>
13<h3><center>Integrating FastCGI with Java</center></h3>
14
15<!--Copyright (c) 1996 Open Market, Inc. -->
16<!--See the file "LICENSE.TERMS" for information on usage and redistribution-->
17<!--of this file, and for a DISCLAIMER OF ALL WARRANTIES. -->
6791223e 18<!-- $Id: fcgi-java.htm,v 1.2 2001/05/14 12:59:51 robs Exp $ -->
0198fd3c 19
20<P ALIGN=CENTER>
21Steve Harris
22<BR>
23Open Market, Inc.
24<BR>
25<EM>7 May 1996</EM>
26</P>
27
28<h5 align=center>
29Copyright &copy; 1996 Open Market, Inc. 245 First Street, Cambridge,
30 MA 02142 U.S.A.<br>
31Tel: 617-621-9500 Fax: 617-621-1703 URL:
32 <a href="http://www.openmarket.com/">http://www.openmarket.com/</a><br>
33</h5>
34<hr>
35
36<H3><A NAME = "S1"> 1. Introduction</A></H3>
37Java is an object-oriented programming language developed by Sun
38Microsystems. The Java Depvelopers Kit (JDK), which contains the basic
39Java class packages, is available from Sun in both source and binary
40forms at Sun's
41<a href="http://java.sun.com/java.sun.com/JDK-1.0/index.html">JavaSoft</a>
42site. This document assumes that you have some familiarity with the
43basics of compiling and running Java programs.
44<p>
45There are two kinds of applications built using Java.
46<ul>
47 <li> <i>Java Applets</i> are graphical components which are run off
48 HTML pages via the <tt>&lt;APPLET&gt;</tt> HTML extention tag.<br><br>
49
50 <li> <i>Java Applications (Apps) </i> are stand-alone programs
51 that are run by invoking the Java interpreter directly. Like
52 C programs, they have a <tt>main()</tt> method which the interpreter
53 uses as an entry point.
54</ul>
55The initial emphasis on using Java for client side applets should not
56obscure the fact that Java is a full strength programming language
57which can be used to develop server side stand alone applications,
58including CGI and now FastCGI applications.
59<p>
60The remainder of this document explains how to write and run FastCGI Java
61applications. It also illustrates the conversion of a sample Java CGI program
62to a FastCGI program.
63
64
65
66<H3><A NAME = "S2"> 2. Writing FastCGI applications in Java</A></H3>
67
68Writing a FastCGI application in Java is as simple as writing one in C.
69
70<ol>
71 <li> Import the <tt>FCGIInterface</tt> class.
72 <li> Perform one-time initialization at the top of the
73 <tt>main()</tt> method.
74 <li> Create a new <tt>FCGIInterface</tt> object and send it an
75 <tt>FCGIaccept()</tt> message in a loop.
76 <li> Put the per-request application code inside that loop.
77</ol>
78
79On return from <tt>FCGIaccept()</tt> you can access the request's environment
80variables using <tt>System.getProperty</tt> and perform request-related
81I/O through the standard variables <tt>System.in</tt>,
82<tt>System.out</tt>, and <tt>System.err</tt>.<p>
83
84To illustrate these points, the kit includes <tt>examples/TinyCGI</tt>,
85a CGI Java application, and <tt>examples/TinyFCGI</tt>, the FastCGI
86version of TinyCGI. These programs perform the same
87functions as the C programs <tt>examples/tiny-cgi.c</tt> and
88<tt>examples/tiny-fcgi.c</tt> that are used as examples in the
89<A HREF="fcgi-devel-kit.htm#S3.1.1">FastCGI Developer's Kit document</A>.
90
91
92<h4>A. TinyCGI</h4>
93<PRE>
94class TinyCGI {
95 public static void main (String args[]) {
96 int count = 0;
97 ++count;
98 System.out.println("Content-type: text/html\n\n");
99 System.out.println("&lt;html&gt;");
100 System.out.println(
101 "&lt;head&gt;&lt;TITLE&gt;CGI Hello&lt;/TITLE&gt;&lt;/head&gt;");
102 System.out.println("&lt;body&gt;");
103 System.out.println("&lt;H3&gt;CGI-Hello&lt;/H3&gt;");
104 System.out.println("request number " + count +
105 " running on host "
106 + System.getProperty&lt;"SERVER_NAME"));
107 System.out.println("&lt;/body&gt;");
108 System.out.println("&lt;/html&gt;");
109 }
110 }
111
112</PRE>
113<h4>B. TinyFCGI</h4>
114<PRE>
115import FCGIInterface;
116
117class TinyFCGI {
118 public static void main (String args[]) {
119 int count = 0;
120 while(new FCGIInterface().FCGIaccept()>= 0) {
121 count ++;
122 System.out.println("Content-type: text/html\n\n");
123 System.out.println("&lt;html&gt;");
124 System.out.println(
125 "&lt;head&gt;&lt;TITLE&gt;FastCGI-Hello Java stdio&lt;/TITLE&gt;&lt;/head&gt;");
126 System.out.println("&lt;body&gt;");
127 System.out.println("&lt;H3&gt;FastCGI-HelloJava stdio&lt;/H3&gt;");
128 System.out.println("request number " + count +
129 " running on host "
130 + System.getProperty&lt;"SERVER_NAME"));
131 System.out.println("&lt;/body&gt;");
132 System.out.println("&lt;/html&gt;");
133 }
134 }
135 }
136
137</PRE>
138<h4>C. Running these Examples</h4>
139
140We assume that you have downloaded the JDK and the FastCGI Developer's
141Kit, and that you have a Web server running that can access the
142<tt>fcgi-devel-kit/examples</tt> directory. In all cases where we
143specify paths, we are using relative paths within
144<tt>fcgi-devel-kit</tt> or the JDK which will need to be enlarged to a
145full path by the user.
146
147<h5>Configuring</h5>
148<ol>
149 <li> Add your JDK's <tt>java/bin</tt> directory to your Unix <tt>PATH</tt>
150 if it isn't there already.<br><br>
151
152 <li> Add the directories <tt>fcgi-devel-kit/examples</tt> and
153 <tt>fcgi-devel-kit/java/classes</tt> to your Java
154 <tt>CLASSPATH</tt>.<br><br>
155
156 <li>In your Open Market Secure WebServer configuration file,
157 <tt>httpd.config</tt>, add the following two lines:<br><br>
158
159 <tt>ExternalAppClass TinyFCGI -host </tt><i>hostName:portNum</i><br>
160 <tt>Responder TinyFCGI fcgi-devel-kit/examples/TinyFCGI</tt><br><br>
161
162 <ul>
163 <li><i>hostName</i> is the name of your host machine.<br>
164 <li><i>portNum</i> is the port that you've selected for
165 communication between the Web server and the Java application.<br>
166 </ul><br>
167
168 On other servers you can use <tt>cgi-fcgi</tt> to get a
169 similar effect.
170
171 <li> Create a soft link <tt>examples/javexe</tt> to the
172 <tt>java/bin</tt> directory in your JDK.
173 This link is required only to run the
174 CGI scripts <tt>examples/TinyCGI.cgi</tt> and
175 <tt>examples/TinyFCGI.cgi</tt>, which use it to
176 invoke the Java interpreter <tt>java/bin/java</tt>.
177 It is not used by FastCGI applications.
178
179 <li> You might have to modify <tt>examples/TinyFCGI.cgi</tt> to use a
180 Unix shell for which your CLASSPATH is defined.
181</ol>
182
183<h5> Running </h5>
184
185<ul>
186 <li> To run TinyFCGI as FastCGI, you invoke the Java interpreter
187 with the -D option, giving it the <tt>FCGI_PORT</tt> environment
188 variable
189 and the same <i>portNum</i> that was used in the Web server
190 configuration. The command is:
191 <br><br>
192 <tt>java -DFCGI_PORT=portNum TinyFCGI</tt>
193 <br><br>
194 Then point your browser at <tt>fcgi-devel-kit/examples/TinyFCGI</tt>.
195 Notice that each time you reload, the count increments.<br><br>
196
197 <li> To run TinyCGI, point your browser at
198 <tt>fcgi-devel-kit/examples/TinyCGI.cgi</tt> on your host machine.
199 Notice that the count does not increment.<br><br>
200
201 <li> Finally, you can run TinyFCGI as a straight CGI program by pointing
202 your browser at <tt>fcgi-devel-kit/examplesi/TinyFCGI.cgi.</tt> The results
203 are exactly the same as when you ran TinyCGI. Invoking a FastCGI
204 program without an <tt>FCGI_PORT</tt> parameter tells the
205 FastCGI interface
206 to leave the normal CGI environment in place.
207</ul>
208<p>
209Due to gaps in the Java interpreter's support for listening
210sockets, Java FastCGI applications are currently limited to
211being started as external applications. They can't be started and
212managed by the Web server because they are incapable of using
213a listening socket that the Web server creates.
214
215
216
217<H3><A NAME = "S3"> 3. Standard I/O and Application Libraries</A></H3>
218
219As we have seen above, FastCGI for Java offers a redefinition
220of standard I/O corresponding to the the <i>fcgi_stdio</i> functionality.
221It also offers a set of directly callable I/O methods corresponding to
222the <i>fcgiapp</i> C library. To understand where these methods occur
223we need to look briefly at the FastCGI redefinition of standard I/O.<p>
224
225Java defines standard I/O in the <i>java.System</i> class as follows:<p>
226
227public static InputStream in = new BufferedInputStream(new FileInputStream(FileDescriptor.in), 128);<br>
228public static PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out), 128), true);<br>
229public static PrintStream err = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err), 128), true);<p>
230
231The File Descriptors <i>in</i>, <i>out</i>, <i>err</i> are constants set to 0, 1 and 2 respectively.<p>
232
233The FastCGI interface redefines <i>java.System in, out</i>, and <i>err</i>
234by replacing the File streams with Socket streams and inserting streams
235which know how to manage the FastCGI protocol between the Socket streams
236and the Buffered streams in the above definitions.
237<p>
238For those cases where the FCGI application needs to bypass the standard I/O
239streams, it can directly access the methods of the FCGI input and output
240streams which roughly correspond to the functions in the C <i>fcgiapp</i>
241library. These streams can be accessed via the <i>request</i> class variable
242in FCGIInterface. Each Request object has instance variables that refer to an
243FCGIInputStream, and to two FCGIOutputStreams associated with that request.
244
245<H3><A NAME = "S4"> 4. Environment Variables</A></H3>
246
6791223e 247Java does not use the C <i>environ</i> list. Nor is there a <i>getenv</i>
0198fd3c 248command that reads system environment variables. This is intentional for
249reasons of portability and security. Java has an internal dictionary of
250properties which belongs to the System class. These System properties
251are <i>name/value</i> associations that constitute the Java environment.
252When a Java application starts up, it reads in a file with default properties.
253As we have seen, additional System properties may be inserted by using
254the -D <i>Java</i> command argument.<p>
255
256For CGI, where the Java application is invoked from a .cgi script that,
257in turn, invokes the Java interpreter, this script could read the environment
258and pass the variables to the Java application either by writing a file
259or by creating -D options on the fly. Both of these methods are somewhat
260awkward.<p>
261
262For FastCGI Java applications, the environment variables are obtained from
263the FastCGI web server via <tt>FCGI_PARAMS</tt> records that are sent to the
264application at the start of each request. The FastCGI interface stores the
265original startup properties, combines these with the properties obtained
266from the server, and puts the new set of properties in the System properties
267dictionary. The only parameter that has to be specifically added at startup
268time is the FCGI_PORT parameter for the Socket creation. In the future, we
269expect that even this parameter won't be needed, since its use is due to an
270acknowledged rigidity in the JDK's implementation of sockets.<p>
271
272<H3><A NAME = "S4"> 5. Further examples: EchoFCGI and Echo2FCGI</A></H3>
273
274The next two examples illustrate the points made in the last two sections.
275EchoFCGI and Echo2FCGI both echo user input and display the application's
276environment variables. EchoFCGI reads the user input from System.in, while
277Echo2FCGI reads the user input directly from the intermediate FastCGI input
278stream.
279
280<h4>A. EchoFCGI</h4>
281<pre>
282import FCGIInterface;
283import FCGIGlobalDefs;
284import java.io.*;
285
286class EchoFCGI {
287
288 public static void main (String args[]) {
289 int status = 0;
290 while(new FCGIInterface().FCGIaccept()>= 0) {
291 System.out.println("Content-type: text/html\n\n");
292 System.out.println("&lt;html&gt;");
293 System.out.println(
294 "&lt;head%gt;&lt;TITLE&gt;FastCGI echo
295 &lt;/TITLE&gt;&lt;/head&gt;");
296 System.out.println("&lt;body&gt;");
297 System.out.println(
298 "&lt;H2&gt;FastCGI echo&lt;/H2&gt;");
299 System.out.println("&lt;H3&gt;STDIN&lt;/H3&gt;");
300 for ( int c = 0; c != -1; ) {
301 try {
302 c = System.in.read();
303 } catch(IOException e) {
304 System.out.println(
305 "&lt;br&gt;&lt;b&gt;SYSTEM EXCEPTION");
306 Runtime rt = Runtime.getRuntime();
307 rt.exit(status);
308 }
309 if (c != -1) {
310 System.out.print((char)c);
311 }
312 }
313 System.out.println(
314 "&lt;H3&gt;Environment Variables:&lt;/H3&gt;");
315
316 System.getProperties().list(System.out);
317 System.out.println("&lt;/body&gt;");
318 System.out.println("&lt;/html&gt;");
319 }
320 }
321 }
322</pre>
323<h4>B. Echo2FCGI</h4>
324<pre>
325import FCGIInterface;
326import FCGIGlobalDefs;
327import FCGIInputStream;
328import FCGIOutputStream;
329import FCGIMessage;
330import FCGIRequest;
331import java.io.*;
332
333class Echo2FCGI {
334
335 public static void main (String args[]) {
336 int status = 0;
337 FCGIInterface intf = new FCGIInterface();
338 while(intf.FCGIaccept()>= 0) {
339 System.out.println("Content-type: text/html\n\n");
340 System.out.println("&lt;html&gt;");
341 System.out.println(
342 "&lt;head&gt;&lt;TITLE&gt;FastCGI echo
343 &lt;/TITLE&gt;&lt;/head&gt;");
344 System.out.println("&lt;body&gt;");
345 System.out.println("&lt;H2&gt;FastCGI echo&lt;/H2&gt;");
346 System.out.println("&lt;H3&gt;STDIN:&lt;/H3"&gt;);
347 for ( int c = 0; c != -1; ) {
348 try {
349 c = intf.request.inStream.read();
350 } catch(IOException e) {
351 System.out.println(
352 "&lt;br&gt;&lt;b&gt;SYSTEM EXCEPTION");
353 Runtime rt = Runtime.getRuntime();
354 rt.exit(status);
355 }
356 if (c != -1) {
357 System.out.print((char)c);
358 }
359 }
360 System.out.println(
361 "&lt;H3&gt;Environment Variables:&lt;/H3&gt;");
362
363 System.getProperties().list(System.out);
364 System.out.println(&lt;"/body&gt;");
365 System.out.println("&lt;/html&gt;");
366 }
367 }
368 }
369</pre>
370<h4>C. Running these Examples</h4>
371
372<h5>Configuring</h5>
373
374As with TinyFCGI, you need to configure the web server to recognize these
375two FastCGI applications. Your configuration now looks like this:<p>
376<pre>
377ExternalAppClass java1 -host hostname:portNum
378Responder java1 fcgi-devel-kit/examples/TinyFCGI
379ExternalAppClass java2 -host hostname:portNumA
380Responder java2 fcgi-devel-kit/examples/EchoFCGI
381ExternalAppClass java3 -host hostname:porNumB
382Responder java3 fcgi-devel-kit/examples/Echo2FCGI
383</pre>
384<p>
385Note that the application classes and port numbers are different for each
386application.
387
388<h5>Running</h5>
389
390As with TinyFCGI, you need to run these programs with the -D option
391using FCGI_PORT and the appropriate port number.
392
393To get some data for standard input we have created two html pages with
394forms that use a POST method. These are echo.html and echo2.html. You must
395edit these .html files to expand the path to <i>fcgi-devel-kit/examples</i>
396to a full path. Once the appropriate Java program is running, point your browser at the corresponding HTML page, enter some data and select the <i>go_find</i> button.
397
398
399<H3><A NAME = "S6"> 6. FastCGI Java Classes</A></H3>
400
401The Java FastCGI classes are included in both source and byte code format in
402<i>fcgi-devel-kit/java/src</i> and :<i>fcgi-devel-kit/java/classes</i>
403respectively. The following is a brief description of these classes:<p>
404
405<dl>
406<dt><i>FCGIInterface</i><dd> This class contains the FCGIaccept method called
407 by the FastCGI user application. This method sets up the appropriate
408 FastCGI environment for communication with the web server and manages
409 FastCGI requests.<br>
410
411 <dt><i>FCGIInputStream</i><dd> This input stream manages FastCGI
412 internal buffers to ensure that the user gets all of the FastCGI
413 messages associated with a request. It uses FCGIMessage objects
414 to interpret these incoming messages.<br>
415
416 <dt><i>FCGIOutputStream</i><dd> This output stream manages FastCGI
417 internal buffers to send user data back to the web server
418 and to notify the server of various FCGI protocol conditions.
419 It uses FCGIMessage objects to format outgoing FastCGI messages.<br>
420
421<dt><i>FCGIMessage</i><dd> This is the only class that understands the
422 actual structure of the FastCGI messages. It interprets incoming
423 FastCGI records and constructs outgoing ones..<br>
424
425<dt><i>FCGIRequest</i><dd>This class currently contains data fields
426 used by FastCGI to manage user requests. In a multi-threaded
427 version of FastCGI, the role of this class will be expanded.<br>
428
429<dt><i>FCGIGlobalDefs</i><dd>This class contains definitions of FastCGI
430 constants.
431</dl>
432<HR>
433<ADDRESS><A HREF="mailto:harris@openmarket.com">Steve Harris // harris@openmarket.com</A></ADDRESS>
6791223e 434</i></i></body>
0198fd3c 435</html>