/*
- * @(#)FCGIGlobalDefs.java
+ * @(#)FCGIGlobalDefs.java
*
*
* FastCGi compatibility package Interface
*
* See the file "LICENSE.TERMS" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * $Id: FCGIGlobalDefs.java,v 1.2 1998/12/12 04:42:16 roberts Exp $
*/
-
-
-
-/* This class contains FCGI global definitions corresponding to
+/* This class contains FCGI global definitions corresponding to
* the #defs in the C version.
*/
import java.io.PrintStream;
-
+
public abstract class FCGIGlobalDefs {
-public static final int def_FCGIMaxLen = 0xffff;
-/*
- * Define Length of FCGI message bodies in bytes
- */
-public static final int def_FCGIHeaderLen = 8;
-public static final int def_FCGIEndReqBodyLen = 8;
-public static final int def_FCGIBeginReqBodyLen = 8;
-public static final int def_FCGIUnknownBodyTypeBodyLen = 8;
-/*
- * Header defines
- */
-public static int def_FCGIVersion1 = 1;
- /* FCGI Record Types */
-public static final int def_FCGIBeginRequest = 1;
-public static final int def_FCGIAbortRequest = 2;
-public static final int def_FCGIEndRequest = 3;
-public static final int def_FCGIParams = 4;
-public static final int def_FCGIStdin = 5;
-public static final int def_FCGIStdout = 6;
-public static final int def_FCGIStderr = 7;
-public static final int def_FCGIData = 8;
-public static final int def_FCGIGetValues = 9;
-public static final int def_FCGIGetValuesResult = 10;
-public static final int def_FCGIUnknownType = 11;
-public static final int def_FCGIMaxType = def_FCGIUnknownType;
- /* Request ID Values */
-public static final int def_FCGINullRequestID = 0;
-/*
- * Begin Request defines
-*/
- /* Mask flags */
-public static int def_FCGIKeepConn = 1;
- /* Roles */
-public static final int def_FCGIResponder = 1;
-public static final int def_FCGIAuthorizer = 2;
-public static final int def_FCGIFilter = 3;
-/*
- * End Request defines
- */
- /* Protocol status */
-public static final int def_FCGIRequestComplete = 0;
-public static final int def_FCGICantMpxConn = 1;
-public static final int def_FCGIOverload = 2;
-public static final int def_FCGIUnknownRole = 3;
-/*
- * Get Values, Get Values Results defines
- */
-public static final String def_FCGIMaxConns = "FCGI_MAX_CONNS";
-public static final String def_FCGIMaxReqs = "FCGI_MAX_REQS";
-public static final String def_FCGIMpxsConns = "FCGI_MPXS_CONNS";
-/*
- * Return codes for Process* functions
- */
-public static final int def_FCGIStreamRecord = 0;
-public static final int def_FCGISkip = 1;
-public static final int def_FCGIBeginRecord = 2;
-public static final int def_FCGIMgmtRecord = 3;
-/*
- * Error Codes
- */
-public static final int def_FCGIUnsupportedVersion = -2;
-public static final int def_FCGIProtocolError = -3;
-public static final int def_FCGIParamsError = -4;
-public static final int def_FCGICallSeqError = -5;
-}
\ No newline at end of file
+ public static final int def_FCGIMaxLen = 0xffff;
+ /*
+ * Define Length of FCGI message bodies in bytes
+ */
+ public static final int def_FCGIHeaderLen = 8;
+ public static final int def_FCGIEndReqBodyLen = 8;
+ public static final int def_FCGIBeginReqBodyLen = 8;
+ public static final int def_FCGIUnknownBodyTypeBodyLen = 8;
+ /*
+ * Header defines
+ */
+ public static int def_FCGIVersion1 = 1;
+ /* FCGI Record Types */
+ public static final int def_FCGIBeginRequest = 1;
+ public static final int def_FCGIAbortRequest = 2;
+ public static final int def_FCGIEndRequest = 3;
+ public static final int def_FCGIParams = 4;
+ public static final int def_FCGIStdin = 5;
+ public static final int def_FCGIStdout = 6;
+ public static final int def_FCGIStderr = 7;
+ public static final int def_FCGIData = 8;
+ public static final int def_FCGIGetValues = 9;
+ public static final int def_FCGIGetValuesResult = 10;
+ public static final int def_FCGIUnknownType = 11;
+ public static final int def_FCGIMaxType = def_FCGIUnknownType;
+ /* Request ID Values */
+ public static final int def_FCGINullRequestID = 0;
+ /*
+ * Begin Request defines
+ */
+ /* Mask flags */
+ public static int def_FCGIKeepConn = 1;
+ /* Roles */
+ public static final int def_FCGIResponder = 1;
+ public static final int def_FCGIAuthorizer = 2;
+ public static final int def_FCGIFilter = 3;
+ /*
+ * End Request defines
+ */
+ /* Protocol status */
+ public static final int def_FCGIRequestComplete = 0;
+ public static final int def_FCGICantMpxConn = 1;
+ public static final int def_FCGIOverload = 2;
+ public static final int def_FCGIUnknownRole = 3;
+ /*
+ * Get Values, Get Values Results defines
+ */
+ public static final String def_FCGIMaxConns = "FCGI_MAX_CONNS";
+ public static final String def_FCGIMaxReqs = "FCGI_MAX_REQS";
+ public static final String def_FCGIMpxsConns = "FCGI_MPXS_CONNS";
+ /*
+ * Return codes for Process* functions
+ */
+ public static final int def_FCGIStreamRecord = 0;
+ public static final int def_FCGISkip = 1;
+ public static final int def_FCGIBeginRecord = 2;
+ public static final int def_FCGIMgmtRecord = 3;
+ /*
+ * Error Codes
+ */
+ public static final int def_FCGIUnsupportedVersion = -2;
+ public static final int def_FCGIProtocolError = -3;
+ public static final int def_FCGIParamsError = -4;
+ public static final int def_FCGICallSeqError = -5;
+}
/*
- * @(#)FCGIInputStream.java
+ * @(#)FCGIInputStream.java
*
* FastCGi compatibility package Interface
*
*
* See the file "LICENSE.TERMS" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * $Id: FCGIInputStream.java,v 1.2 1998/12/12 04:42:17 roberts Exp $
*/
-
-
import java.io.*;
import FCGIRequest;
import FCGIGlobalDefs;
-
/**
* This stream manages buffered reads of FCGI messages.
- *
- *
*/
-public
-class FCGIInputStream extends InputStream {
+public class FCGIInputStream extends InputStream {
- /* Stream vars */
+ /* Stream vars */
public int rdNext;
public int stop;
public boolean isClosed;
-/* require methods to set, get and clear */
- private int errno;
+ /* require methods to set, get and clear */
+ private int errno;
private Exception errex;
-/* data vars */
+ /* data vars */
public byte buff[];
public int buffLen;
/**
- * Creates a new input stream to manage fcgi prototcol stuff
- * @param in the input stream bufLen length of buffer streamType
- */
- public FCGIInputStream(FileInputStream inStream, int bufLen,
- int streamType,
- FCGIRequest inReq) {
+ * Creates a new input stream to manage fcgi prototcol stuff
+ * @param in the input stream bufLen length of buffer streamType
+ */
+ public FCGIInputStream(FileInputStream inStream, int bufLen,
+ int streamType,
+ FCGIRequest inReq) {
- in = inStream;
- buffLen = Math.min(bufLen,FCGIGlobalDefs.def_FCGIMaxLen);
- buff = new byte[buffLen];
- type = streamType;
- stop = rdNext = buffStop = 0;
- isClosed = false;
- contentLen = 0;
- paddingLen = 0;
- skip = false;
- eorStop = false;
- request = inReq;
+ in = inStream;
+ buffLen = Math.min(bufLen,FCGIGlobalDefs.def_FCGIMaxLen);
+ buff = new byte[buffLen];
+ type = streamType;
+ stop = rdNext = buffStop = 0;
+ isClosed = false;
+ contentLen = 0;
+ paddingLen = 0;
+ skip = false;
+ eorStop = false;
+ request = inReq;
}
- /**
- * Reads a byte of data. This method will block if no input is
- * available.
- * @return the byte read, or -1 if the end of the
- * stream is reached.
- * @exception IOException If an I/O error has occurred.
- */
+ /**
+ * Reads a byte of data. This method will block if no input is
+ * available.
+ * @return the byte read, or -1 if the end of the
+ * stream is reached.
+ * @exception IOException If an I/O error has occurred.
+ */
public int read() throws IOException {
- if (rdNext != stop) {
- return buff[rdNext++];
- }
- if (isClosed){
- return -1;
- }
- fill();
- if (rdNext != stop){
- return buff[rdNext++];
- }
- return -1;
+ if (rdNext != stop) {
+ return buff[rdNext++];
+ }
+ if (isClosed){
+ return -1;
+ }
+ fill();
+ if (rdNext != stop){
+ return buff[rdNext++];
+ }
+ return -1;
}
/**
- * Reads into an array of bytes. This method will
- * block until some input is available.
- * @param b the buffer into which the data is read
- * @return the actual number of bytes read, -1 is
- * returned when the end of the stream is reached.
- * @exception IOException If an I/O error has occurred.
- */
+ * Reads into an array of bytes. This method will
+ * block until some input is available.
+ * @param b the buffer into which the data is read
+ * @return the actual number of bytes read, -1 is
+ * returned when the end of the stream is reached.
+ * @exception IOException If an I/O error has occurred.
+ */
public int read(byte b[]) throws IOException {
- return read(b, 0, b.length);
+ return read(b, 0, b.length);
}
-
-
- /**
- * Reads into an array of bytes.
- * Blocks until some input is available.
- * @param b the buffer into which the data is read
- * @param off the start offset of the data
- * @param len the maximum number of bytes read
- * @return the actual number of bytes read, -1 is
- * returned when the end of the stream is reached.
- * @exception IOException If an I/O error has occurred.
- */
+ /**
+ * Reads into an array of bytes.
+ * Blocks until some input is available.
+ * @param b the buffer into which the data is read
+ * @param off the start offset of the data
+ * @param len the maximum number of bytes read
+ * @return the actual number of bytes read, -1 is
+ * returned when the end of the stream is reached.
+ * @exception IOException If an I/O error has occurred.
+ */
public int read(byte b[], int off, int len) throws IOException {
- int m, bytesMoved;
-
- if (len <= 0){
- return 0;
- }
- /*
- *Fast path: len bytes already available.
- */
+ int m, bytesMoved;
+
+ if (len <= 0){
+ return 0;
+ }
+ /*
+ *Fast path: len bytes already available.
+ */
- if (len <= stop - rdNext){
- System.arraycopy(buff, rdNext, b, off, len);
- rdNext += len;
- return len;
- }
- /*
- *General case: stream is closed or fill needs to be called
- */
- bytesMoved = 0;
- for(;;){
- if (rdNext != stop){
- m = Math.min(len - bytesMoved, stop - rdNext);
- System.arraycopy(buff, rdNext, b, off, m);
- bytesMoved += m;
- rdNext += m;
- if (bytesMoved == len)
- return bytesMoved;
- off += m;
- }
- if (isClosed){
- return bytesMoved;
- }
- fill();
+ if (len <= stop - rdNext){
+ System.arraycopy(buff, rdNext, b, off, len);
+ rdNext += len;
+ return len;
+ }
+ /*
+ *General case: stream is closed or fill needs to be called
+ */
+ bytesMoved = 0;
+ for(;;){
+ if (rdNext != stop){
+ m = Math.min(len - bytesMoved, stop - rdNext);
+ System.arraycopy(buff, rdNext, b, off, m);
+ bytesMoved += m;
+ rdNext += m;
+ if (bytesMoved == len)
+ return bytesMoved;
+ off += m;
+ }
+ if (isClosed){
+ return bytesMoved;
+ }
+ fill();
- }
- }
+ }
+ }
/**
- * Reads into an array of bytes. This method will
- * block until some input is available.
- * @param b the buffer into which the data is read
- * @param off the start offset of the data
- * @param len the maximum number of bytes read
- * @return the actual number of bytes read, -1 is
- * returned when the end of the stream is reached.
- * @exception IOException If an I/O error has occurred.
- */
+ * Reads into an array of bytes. This method will
+ * block until some input is available.
+ * @param b the buffer into which the data is read
+ * @param off the start offset of the data
+ * @param len the maximum number of bytes read
+ * @return the actual number of bytes read, -1 is
+ * returned when the end of the stream is reached.
+ * @exception IOException If an I/O error has occurred.
+ */
public void fill() throws IOException {
- byte[] headerBuf = new byte[FCGIGlobalDefs.def_FCGIHeaderLen];
- int headerLen = 0;
- int status = 0;
- int count = 0;
- for(;;) {
- /*
- * If buffer is empty, do a read
- */
- if (rdNext == buffStop) {
- try {
- count = in.read(buff, 0, buffLen);
- } catch (IOException e) {
- setException(e);
- return;
- }
- if (count == 0) {
- setFCGIError(FCGIGlobalDefs.def_FCGIProtocolError);
- return;
- }
- rdNext = 0;
- buffStop = count; // 1 more than we read
- }
- /* Now buf is not empty: If the current record contains more content
- * bytes, deliver all that are present in buff to callers buffer
- * unless he asked for less than we have, in which case give him less
- */
- if (contentLen > 0) {
- count = Math.min(contentLen, buffStop - rdNext);
- contentLen -= count;
- if (!skip) {
- stop = rdNext + count;
- return;
- } else {
- rdNext += count;
- if (contentLen > 0) {
- continue;
- } else {
- skip = false;
- }
- }
- }
- /* Content has been consumed by client.
- * If record was padded, skip over padding
- */
- if (paddingLen > 0) {
- count = Math.min(paddingLen, buffStop - rdNext);
- paddingLen -= count;
- rdNext += count;
- if (paddingLen > 0) {
- continue; // more padding to read
- }
- }
- /* All done with current record, including the padding.
- * If we are in a recursive call from Process Header, deliver EOF
- */
- if (eorStop){
- stop = rdNext;
- isClosed = true;
- return;
- }
- /*
- * Fill header with bytes from input buffer - get the whole header.
- */
- count = Math.min(headerBuf.length - headerLen, buffStop - rdNext);
- System.arraycopy(buff,rdNext, headerBuf, headerLen, count);
- headerLen += count;
- rdNext += count;
- if (headerLen < headerBuf.length) {
- continue;
- }
- headerLen = 0;
- /*
- * Interperet the header. eorStop prevents ProcessHeader from
- * reading past the end of record when using stream to read content
- */
- eorStop = true;
- stop = rdNext;
- status = 0;
- status = new FCGIMessage(this).processHeader(headerBuf);
- eorStop = false;
- isClosed = false;
- switch (status){
- case FCGIGlobalDefs.def_FCGIStreamRecord:
- if (contentLen == 0) {
- stop = rdNext;
- isClosed = true;
- return;
- }
- break;
- case FCGIGlobalDefs.def_FCGISkip:
- skip = true;
- break;
- case FCGIGlobalDefs.def_FCGIBeginRecord:
- /*
- * If this header marked the beginning of a new
- * request, return role info to caller
- */
- return;
- case FCGIGlobalDefs.def_FCGIMgmtRecord:
- break;
- default:
- /*
- * ASSERT
- */
- setFCGIError(status);
- return;
-
- }
- }
- }
+ byte[] headerBuf = new byte[FCGIGlobalDefs.def_FCGIHeaderLen];
+ int headerLen = 0;
+ int status = 0;
+ int count = 0;
+ for(;;) {
+ /*
+ * If buffer is empty, do a read
+ */
+ if (rdNext == buffStop) {
+ try {
+ count = in.read(buff, 0, buffLen);
+ } catch (IOException e) {
+ setException(e);
+ return;
+ }
+ if (count == 0) {
+ setFCGIError(FCGIGlobalDefs.def_FCGIProtocolError);
+ return;
+ }
+ rdNext = 0;
+ buffStop = count; // 1 more than we read
+ }
+ /* Now buf is not empty: If the current record contains more content
+ * bytes, deliver all that are present in buff to callers buffer
+ * unless he asked for less than we have, in which case give him less
+ */
+ if (contentLen > 0) {
+ count = Math.min(contentLen, buffStop - rdNext);
+ contentLen -= count;
+ if (!skip) {
+ stop = rdNext + count;
+ return;
+ }
+ else {
+ rdNext += count;
+ if (contentLen > 0) {
+ continue;
+ }
+ else {
+ skip = false;
+ }
+ }
+ }
+ /* Content has been consumed by client.
+ * If record was padded, skip over padding
+ */
+ if (paddingLen > 0) {
+ count = Math.min(paddingLen, buffStop - rdNext);
+ paddingLen -= count;
+ rdNext += count;
+ if (paddingLen > 0) {
+ continue; // more padding to read
+ }
+ }
+ /* All done with current record, including the padding.
+ * If we are in a recursive call from Process Header, deliver EOF
+ */
+ if (eorStop){
+ stop = rdNext;
+ isClosed = true;
+ return;
+ }
+ /*
+ * Fill header with bytes from input buffer - get the whole header.
+ */
+ count = Math.min(headerBuf.length - headerLen, buffStop - rdNext);
+ System.arraycopy(buff,rdNext, headerBuf, headerLen, count);
+ headerLen += count;
+ rdNext += count;
+ if (headerLen < headerBuf.length) {
+ continue;
+ }
+ headerLen = 0;
+ /*
+ * Interperet the header. eorStop prevents ProcessHeader from
+ * reading past the end of record when using stream to read content
+ */
+ eorStop = true;
+ stop = rdNext;
+ status = 0;
+ status = new FCGIMessage(this).processHeader(headerBuf);
+ eorStop = false;
+ isClosed = false;
+ switch (status){
+ case FCGIGlobalDefs.def_FCGIStreamRecord:
+ if (contentLen == 0) {
+ stop = rdNext;
+ isClosed = true;
+ return;
+ }
+ break;
+ case FCGIGlobalDefs.def_FCGISkip:
+ skip = true;
+ break;
+ case FCGIGlobalDefs.def_FCGIBeginRecord:
+ /*
+ * If this header marked the beginning of a new
+ * request, return role info to caller
+ */
+ return;
+ case FCGIGlobalDefs.def_FCGIMgmtRecord:
+ break;
+ default:
+ /*
+ * ASSERT
+ */
+ setFCGIError(status);
+ return;
- /**
- * Skips n bytes of input.
- * @param n the number of bytes to be skipped
- * @return the actual number of bytes skipped.
- * @exception IOException If an I/O error has occurred.
- */
- public long skip(long n) throws IOException {
- byte data[] = new byte[(int)n];
- return in.read(data);
- }
+ }
+ }
+ }
- /*
- * An FCGI error has occurred. Save the error code in the stream
- * for diagnostic purposes and set the stream state so that
- * reads return EOF
- */
- public void setFCGIError(int errnum) {
- /*
- * Preserve only the first error.
- */
- if(errno == 0) {
- errno = errnum;
- }
- isClosed = true;
- }
- /*
- * An Exception has occurred. Save the Exception in the stream
- * for diagnostic purposes and set the stream state so that
- * reads return EOF
- */
- public void setException(Exception errexpt) {
- /*
- * Preserve only the first error.
- */
- if(errex == null) {
- errex = errexpt;
- }
- isClosed = true;
- }
+ /**
+ * Skips n bytes of input.
+ * @param n the number of bytes to be skipped
+ * @return the actual number of bytes skipped.
+ * @exception IOException If an I/O error has occurred.
+ */
+ public long skip(long n) throws IOException {
+ byte data[] = new byte[(int)n];
+ return in.read(data);
+ }
- /*
- * Clear the stream error code and end-of-file indication.
- */
- public void clearFCGIError() {
- errno = 0;
- /*
- * isClosed = false;
- * XXX: should clear isClosed but work is needed to make it safe
- * to do so.
- */
- }
-/*
- * Clear the stream error code and end-of-file indication.
- */
- public void clearException() {
- errex = null;
- /*
- * isClosed = false;
- * XXX: should clear isClosed but work is needed to make it safe
- * to do so.
- */
- }
+ /*
+ * An FCGI error has occurred. Save the error code in the stream
+ * for diagnostic purposes and set the stream state so that
+ * reads return EOF
+ */
+ public void setFCGIError(int errnum) {
+ /*
+ * Preserve only the first error.
+ */
+ if(errno == 0) {
+ errno = errnum;
+ }
+ isClosed = true;
+ }
+ /*
+ * An Exception has occurred. Save the Exception in the stream
+ * for diagnostic purposes and set the stream state so that
+ * reads return EOF
+ */
+ public void setException(Exception errexpt) {
+ /*
+ * Preserve only the first error.
+ */
+ if(errex == null) {
+ errex = errexpt;
+ }
+ isClosed = true;
+ }
- /*
- * accessor method since var is private
- */
- public int getFCGIError() {
- return errno;
- }
- /*
- * accessor method since var is private
- */
- public Exception getException() {
- return errex;
- }
- /*
- * Re-initializes the stream to read data of the specified type.
- */
- public void setReaderType(int streamType) {
+ /*
+ * Clear the stream error code and end-of-file indication.
+ */
+ public void clearFCGIError() {
+ errno = 0;
+ /*
+ * isClosed = false;
+ * XXX: should clear isClosed but work is needed to make it safe
+ * to do so.
+ */
+ }
+ /*
+ * Clear the stream error code and end-of-file indication.
+ */
+ public void clearException() {
+ errex = null;
+ /*
+ * isClosed = false;
+ * XXX: should clear isClosed but work is needed to make it safe
+ * to do so.
+ */
+ }
- type = streamType;
- eorStop = false;
- skip = false;
- contentLen = 0;
- paddingLen = 0;
- stop = rdNext;
- isClosed = false;
- }
+ /*
+ * accessor method since var is private
+ */
+ public int getFCGIError() {
+ return errno;
+ }
+ /*
+ * accessor method since var is private
+ */
+ public Exception getException() {
+ return errex;
+ }
+ /*
+ * Re-initializes the stream to read data of the specified type.
+ */
+ public void setReaderType(int streamType) {
+
+ type = streamType;
+ eorStop = false;
+ skip = false;
+ contentLen = 0;
+ paddingLen = 0;
+ stop = rdNext;
+ isClosed = false;
+ }
- /*
- * Close the stream. This method does not really exist for BufferedInputStream in java,
- * but is implemented here for compatibility with the FCGI structures being used. It
- * doent really throw any IOExceptions either, but that's there for compatiblity with
- * the InputStreamInterface.
- */
- public void close() throws IOException{
- isClosed = true;
- stop = rdNext;
- }
-
- /*
- * Returns the number of bytes that can be read without blocking.
- */
+ /*
+ * Close the stream. This method does not really exist for BufferedInputStream in java,
+ * but is implemented here for compatibility with the FCGI structures being used. It
+ * doent really throw any IOExceptions either, but that's there for compatiblity with
+ * the InputStreamInterface.
+ */
+ public void close() throws IOException{
+ isClosed = true;
+ stop = rdNext;
+ }
+
+ /*
+ * Returns the number of bytes that can be read without blocking.
+ */
+
+ public int available() throws IOException {
+ return stop - rdNext + in.available();
+ }
- public int available() throws IOException {
- return stop - rdNext + in.available();
- }
-
-}
\ No newline at end of file
+}
/*
- * @(#)FCGIInterface.java
+ * @(#)FCGIInterface.java
*
*
* FastCGi compatibility package Interface
* See the file "LICENSE.TERMS" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
+ * $Id: FCGIInterface.java,v 1.3 1998/12/12 04:42:18 roberts Exp $
*/
import java.net.*;
import FCGIOutputStream;
import FCGIMessage;
-
/*
* This is the FastCGI interface that the application calls to communicate with the
* FastCGI web server. This version is single threaded, and handles one request at
*/
public class FCGIInterface {
-
-
-/*
- * Class variables
- */
-public static FCGIRequest request = null;
-public static boolean acceptCalled = false;
-public static boolean isFCGI = true;
-public static Properties startupProps;
-public static ServerSocket srvSocket;
-
-
-
-
-
- /*
- * Accepts a new request from the HTTP server and creates
- * a conventional execution environment for the request.
- * If the application was invoked as a FastCGI server,
- * the first call to FCGIaccept indicates that the application
- * has completed its initialization and is ready to accept
- * a request. Subsequent calls to FCGI_accept indicate that
- * the application has completed its processing of the
- * current request and is ready to accept a new request.
- * If the application was invoked as a CGI program, the first
- * call to FCGIaccept is essentially a no-op and the second
- * call returns EOF (-1) as does an error. Application should exit.
- *
- * If the application was invoked as a FastCGI server,
- * and this is not the first call to this procedure,
- * FCGIaccept first flushes any buffered output to the HTTP server.
- *
- * On every call, FCGIaccept accepts the new request and
- * reads the FCGI_PARAMS stream into System.props. It also creates
- * streams that understand FastCGI protocol and take input from
- * the HTTP server send output and error output to the HTTP server,
- * and assigns these new streams to System.in, System.out and
- * System.err respectively.
- *
- * For now, we will just return an int to the caller, which is why
- * this method catches, but doen't throw Exceptions.
- *
- */
-
-public int FCGIaccept() {
- int acceptResult = 0;
-
- /*
- * If first call, mark it and if fcgi save original system properties,
- * If not first call, and we are cgi, we should be gone.
- */
- if (!acceptCalled){
- isFCGI = System.getProperties().containsKey("FCGI_PORT");
- acceptCalled = true;
- if (isFCGI) {
- /*
- * save original system properties (nonrequest)
- * and get a server socket
- */
- System.out.close();
- System.err.close();
- startupProps = new Properties(System.getProperties());
- String str =
- new String(System.getProperty("FCGI_PORT"));
- if (str.length() <= 0) {
- return -1;
- }
- int portNum = Integer.parseInt(str);
-
- try {
- srvSocket = new ServerSocket(portNum);
- } catch (IOException e) {
- request.socket = null;
- srvSocket = null;
- request = null;
- return -1;
- }
- }
- } else {
- if (!isFCGI){
- return -1;
- }
- }
- /*
- * If we are cgi, just leave everything as is, otherwise set up env
- */
- if (isFCGI){
- try {
- acceptResult = FCGIAccept();
- } catch (IOException e) {
- return -1;
- }
- if (acceptResult < 0){
- return -1;
- }
-
- /*
- * redirect stdin, stdout and stderr to fcgi socket
- */
- System.setIn(new BufferedInputStream(request.inStream, 8192));
- System.setOut(new PrintStream(new BufferedOutputStream(
- request.outStream, 8192)));
- System.setErr(new PrintStream(new BufferedOutputStream(
- request.errStream, 512)));
- System.setProperties(request.params);
- }
- return 0;
- }
-
- /*
- * Accepts a new request from the HTTP server.
- * Finishes the request accepted by the previous call
- * to FCGI_Accept. Sets up the FCGI environment and reads
- * saved and per request environmental varaibles into
- * the request object. (This is redundant on System.props
- * as long as we can handle only one request object.)
- */
- int FCGIAccept() throws IOException{
-
- boolean isNewConnection;
- boolean errCloseEx = false;
- boolean outCloseEx = false;
-
- if (request != null) {
- /*
- * Complete the previous request
- *
- */
- System.err.close();
- System.out.close();
- boolean prevRequestfailed = (errCloseEx || outCloseEx ||
- request.inStream.getFCGIError() != 0 ||
- request.inStream.getException() != null);
- if (prevRequestfailed || !request.keepConnection ) {
- request.socket.close();
- request.socket = null;
- }
- if (prevRequestfailed) {
- request = null;
- return -1;
- }
- } else {
- /*
- * Get a Request and initialize some variables
- */
- request = new FCGIRequest();
- request.socket = null;
- request.inStream = null;
- }
- isNewConnection = false;
-
- /*
- * if connection isnt open accept a new connection (blocking)
- */
- for(;;) {
- if (request.socket == null){
- try {
- request.socket = srvSocket.accept();
- } catch (IOException e) {
- request.socket = null;
- request = null;
- return -1;
- }
- isNewConnection = true;
- }
-
- /* Try reading from new connection. If the read fails and
- * it was an old connection the web server probably closed it;
- *try making a new connection before giving up
- */
- request.isBeginProcessed = false;
- request.inStream =
- new FCGIInputStream((FileInputStream)request.
- socket.getInputStream(),
- 8192, 0, request);
- request.inStream.fill();
- if (request.isBeginProcessed) {
- break;
- }
- request.socket.close();
-
- request.socket = null;
- if (isNewConnection) {
- return -1;
- }
- }
- /*
- * Set up the objects for the new request
-
- */
- request.params = new Properties(startupProps);
- switch(request.role) {
- case FCGIGlobalDefs.def_FCGIResponder:
- request.params.put("ROLE","RESPONDER");
- break;
- case FCGIGlobalDefs.def_FCGIAuthorizer:
- request.params.put("ROLE", "AUTHORIZER");
- break;
- case FCGIGlobalDefs.def_FCGIFilter:
- request.params.put("ROLE", "FILTER");
- break;
- default:
- return -1;
- }
- request.inStream.setReaderType(FCGIGlobalDefs.def_FCGIParams);
- /*
- * read the rest of request parameters
- */
- if (new FCGIMessage(request.inStream).readParams(request.params) < 0) {
- return -1;
- }
- request.inStream.setReaderType(FCGIGlobalDefs.def_FCGIStdin);
- request.outStream
- = new FCGIOutputStream((FileOutputStream)request.socket.
- getOutputStream(), 8192,
- FCGIGlobalDefs.def_FCGIStdout,request);
- request.errStream
- = new FCGIOutputStream((FileOutputStream)request.socket.
- getOutputStream(), 512,
- FCGIGlobalDefs.def_FCGIStderr,request);
- request.numWriters = 2;
- return 0;
- }
-}
\ No newline at end of file
+ /*
+ * Class variables
+ */
+ public static FCGIRequest request = null;
+ public static boolean acceptCalled = false;
+ public static boolean isFCGI = true;
+ public static Properties startupProps;
+ public static ServerSocket srvSocket;
+
+ /*
+ * Accepts a new request from the HTTP server and creates
+ * a conventional execution environment for the request.
+ * If the application was invoked as a FastCGI server,
+ * the first call to FCGIaccept indicates that the application
+ * has completed its initialization and is ready to accept
+ * a request. Subsequent calls to FCGI_accept indicate that
+ * the application has completed its processing of the
+ * current request and is ready to accept a new request.
+ * If the application was invoked as a CGI program, the first
+ * call to FCGIaccept is essentially a no-op and the second
+ * call returns EOF (-1) as does an error. Application should exit.
+ *
+ * If the application was invoked as a FastCGI server,
+ * and this is not the first call to this procedure,
+ * FCGIaccept first flushes any buffered output to the HTTP server.
+ *
+ * On every call, FCGIaccept accepts the new request and
+ * reads the FCGI_PARAMS stream into System.props. It also creates
+ * streams that understand FastCGI protocol and take input from
+ * the HTTP server send output and error output to the HTTP server,
+ * and assigns these new streams to System.in, System.out and
+ * System.err respectively.
+ *
+ * For now, we will just return an int to the caller, which is why
+ * this method catches, but doen't throw Exceptions.
+ *
+ */
+ public int FCGIaccept() {
+ int acceptResult = 0;
+
+ /*
+ * If first call, mark it and if fcgi save original system properties,
+ * If not first call, and we are cgi, we should be gone.
+ */
+ if (!acceptCalled){
+ isFCGI = System.getProperties().containsKey("FCGI_PORT");
+ acceptCalled = true;
+ if (isFCGI) {
+ /*
+ * save original system properties (nonrequest)
+ * and get a server socket
+ */
+ System.out.close();
+ System.err.close();
+ startupProps = new Properties(System.getProperties());
+ String str =
+ new String(System.getProperty("FCGI_PORT"));
+ if (str.length() <= 0) {
+ return -1;
+ }
+ int portNum = Integer.parseInt(str);
+
+ try {
+ srvSocket = new ServerSocket(portNum);
+ } catch (IOException e) {
+ request.socket = null;
+ srvSocket = null;
+ request = null;
+ return -1;
+ }
+ }
+ }
+ else {
+ if (!isFCGI){
+ return -1;
+ }
+ }
+ /*
+ * If we are cgi, just leave everything as is, otherwise set up env
+ */
+ if (isFCGI){
+ try {
+ acceptResult = FCGIAccept();
+ } catch (IOException e) {
+ return -1;
+ }
+ if (acceptResult < 0){
+ return -1;
+ }
+
+ /*
+ * redirect stdin, stdout and stderr to fcgi socket
+ */
+ System.setIn(new BufferedInputStream(request.inStream, 8192));
+ System.setOut(new PrintStream(new BufferedOutputStream(
+ request.outStream, 8192)));
+ System.setErr(new PrintStream(new BufferedOutputStream(
+ request.errStream, 512)));
+ System.setProperties(request.params);
+ }
+ return 0;
+ }
+
+ /*
+ * Accepts a new request from the HTTP server.
+ * Finishes the request accepted by the previous call
+ * to FCGI_Accept. Sets up the FCGI environment and reads
+ * saved and per request environmental varaibles into
+ * the request object. (This is redundant on System.props
+ * as long as we can handle only one request object.)
+ */
+ int FCGIAccept() throws IOException{
+
+ boolean isNewConnection;
+ boolean errCloseEx = false;
+ boolean outCloseEx = false;
+
+ if (request != null) {
+ /*
+ * Complete the previous request
+ */
+ System.err.close();
+ System.out.close();
+ boolean prevRequestfailed = (errCloseEx || outCloseEx ||
+ request.inStream.getFCGIError() != 0 ||
+ request.inStream.getException() != null);
+ if (prevRequestfailed || !request.keepConnection ) {
+ request.socket.close();
+ request.socket = null;
+ }
+ if (prevRequestfailed) {
+ request = null;
+ return -1;
+ }
+ }
+ else {
+ /*
+ * Get a Request and initialize some variables
+ */
+ request = new FCGIRequest();
+ request.socket = null;
+ request.inStream = null;
+ }
+ isNewConnection = false;
+
+ /*
+ * if connection isnt open accept a new connection (blocking)
+ */
+ for(;;) {
+ if (request.socket == null){
+ try {
+ request.socket = srvSocket.accept();
+ } catch (IOException e) {
+ request.socket = null;
+ request = null;
+ return -1;
+ }
+ isNewConnection = true;
+ }
+
+ /* Try reading from new connection. If the read fails and
+ * it was an old connection the web server probably closed it;
+ * try making a new connection before giving up
+ */
+ request.isBeginProcessed = false;
+ request.inStream =
+ new FCGIInputStream((FileInputStream)request.
+ socket.getInputStream(),
+ 8192, 0, request);
+ request.inStream.fill();
+ if (request.isBeginProcessed) {
+ break;
+ }
+ request.socket.close();
+
+ request.socket = null;
+ if (isNewConnection) {
+ return -1;
+ }
+ }
+ /*
+ * Set up the objects for the new request
+ */
+ request.params = new Properties(startupProps);
+ switch(request.role) {
+ case FCGIGlobalDefs.def_FCGIResponder:
+ request.params.put("ROLE","RESPONDER");
+ break;
+ case FCGIGlobalDefs.def_FCGIAuthorizer:
+ request.params.put("ROLE", "AUTHORIZER");
+ break;
+ case FCGIGlobalDefs.def_FCGIFilter:
+ request.params.put("ROLE", "FILTER");
+ break;
+ default:
+ return -1;
+ }
+ request.inStream.setReaderType(FCGIGlobalDefs.def_FCGIParams);
+ /*
+ * read the rest of request parameters
+ */
+ if (new FCGIMessage(request.inStream).readParams(request.params) < 0) {
+ return -1;
+ }
+ request.inStream.setReaderType(FCGIGlobalDefs.def_FCGIStdin);
+ request.outStream
+ = new FCGIOutputStream((FileOutputStream)request.socket.
+ getOutputStream(), 8192,
+ FCGIGlobalDefs.def_FCGIStdout,request);
+ request.errStream
+ = new FCGIOutputStream((FileOutputStream)request.socket.
+ getOutputStream(), 512,
+ FCGIGlobalDefs.def_FCGIStderr,request);
+ request.numWriters = 2;
+ return 0;
+ }
+}
/*
- * @(#)FCGIMessage.java
+ * @(#)FCGIMessage.java
*
*
* FastCGi compatibility package Interface
*
* See the file "LICENSE.TERMS" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * $Id: FCGIMessage.java,v 1.3 1998/12/12 04:42:19 roberts Exp $
*/
-
-
import java.io.*;
import java.util.Properties;
/* This class handles reading and building the fastcgi messages.
- * For reading incoming mesages, we pass the input
- * stream as a param to the constructor rather than to each method.
- * Methods that build messages use and return internal buffers, so they
+ * For reading incoming mesages, we pass the input
+ * stream as a param to the constructor rather than to each method.
+ * Methods that build messages use and return internal buffers, so they
* dont need a stream.
-*/
-
+ */
+
public class FCGIMessage {
-/*
- * Instance variables
- */
-/*
- * FCGI Message Records
- * The logical structures of the FCGI Message Records.
- * Fields are originally 1 unsigned byte in message
- * unless otherwise noted.
- */
-/*
- * FCGI Header
- */
-private int h_version;
-private int h_type;
-private int h_requestID; // 2 bytes
-private int h_contentLength; // 2 bytes
-private int h_paddingLength;
-/*
- * FCGI BeginRequest body.
-*/
-private int br_role; // 2 bytes
-private int br_flags;
+ /*
+ * Instance variables
+ */
+ /*
+ * FCGI Message Records
+ * The logical structures of the FCGI Message Records.
+ * Fields are originally 1 unsigned byte in message
+ * unless otherwise noted.
+ */
+ /*
+ * FCGI Header
+ */
+ private int h_version;
+ private int h_type;
+ private int h_requestID; // 2 bytes
+ private int h_contentLength; // 2 bytes
+ private int h_paddingLength;
+ /*
+ * FCGI BeginRequest body.
+ */
+ private int br_role; // 2 bytes
+ private int br_flags;
-private FCGIInputStream in;
+ private FCGIInputStream in;
- /*
- * constructor - Java would do this implicitly.
- */
- public FCGIMessage(){
- super();
- }
- /*
- * constructor - get the stream.
- */
- public FCGIMessage(FCGIInputStream instream){
- in = instream;
- }
+ /*
+ * constructor - Java would do this implicitly.
+ */
+ public FCGIMessage(){
+ super();
+ }
+ /*
+ * constructor - get the stream.
+ */
+ public FCGIMessage(FCGIInputStream instream){
+ in = instream;
+ }
- /*
- * Message Reading Methods
- */
+ /*
+ * Message Reading Methods
+ */
- /*
- * Interpret the FCGI Message Header. Processes FCGI
- * BeginRequest and Management messages. Param hdr is the header.
- * The calling routine has to keep track of the stream reading
- * management or use FCGIInputStream.fill() which does just that.
- */
- public int processHeader(byte[] hdr) throws IOException{
- processHeaderBytes(hdr);
- if (h_version != FCGIGlobalDefs.def_FCGIVersion1) {
- return(FCGIGlobalDefs.def_FCGIUnsupportedVersion);
- }
- in.contentLen = h_contentLength;
- in.paddingLen = h_paddingLength;
- if (h_type == FCGIGlobalDefs.def_FCGIBeginRequest) {
- return processBeginRecord(h_requestID);
- }
- if (h_requestID == FCGIGlobalDefs.def_FCGINullRequestID) {
- return processManagementRecord(h_type);
- }
- if (h_requestID != in.request.requestID) {
- return(FCGIGlobalDefs.def_FCGISkip);
- }
- if (h_type != in.type) {
- return(FCGIGlobalDefs.def_FCGIProtocolError);
- }
- return(FCGIGlobalDefs.def_FCGIStreamRecord);
- }
+ /*
+ * Interpret the FCGI Message Header. Processes FCGI
+ * BeginRequest and Management messages. Param hdr is the header.
+ * The calling routine has to keep track of the stream reading
+ * management or use FCGIInputStream.fill() which does just that.
+ */
+ public int processHeader(byte[] hdr) throws IOException{
+ processHeaderBytes(hdr);
+ if (h_version != FCGIGlobalDefs.def_FCGIVersion1) {
+ return(FCGIGlobalDefs.def_FCGIUnsupportedVersion);
+ }
+ in.contentLen = h_contentLength;
+ in.paddingLen = h_paddingLength;
+ if (h_type == FCGIGlobalDefs.def_FCGIBeginRequest) {
+ return processBeginRecord(h_requestID);
+ }
+ if (h_requestID == FCGIGlobalDefs.def_FCGINullRequestID) {
+ return processManagementRecord(h_type);
+ }
+ if (h_requestID != in.request.requestID) {
+ return(FCGIGlobalDefs.def_FCGISkip);
+ }
+ if (h_type != in.type) {
+ return(FCGIGlobalDefs.def_FCGIProtocolError);
+ }
+ return(FCGIGlobalDefs.def_FCGIStreamRecord);
+ }
- /* Put the unsigned bytes in the incoming FCGI header into
- * integer form for Java, concatinating bytes when needed.
- * Because Java has no unsigned byte type, we have to be careful
- * about signed numeric promotion to int.
- */
- private void processHeaderBytes(byte[] hdrBuf){
+ /* Put the unsigned bytes in the incoming FCGI header into
+ * integer form for Java, concatinating bytes when needed.
+ * Because Java has no unsigned byte type, we have to be careful
+ * about signed numeric promotion to int.
+ */
+ private void processHeaderBytes(byte[] hdrBuf){
h_version = hdrBuf[0] & 0xFF;
h_type = hdrBuf[1] & 0xFF;
h_requestID = ((hdrBuf[2] & 0xFF) << 8) | (hdrBuf[3] & 0xFF);
h_contentLength = ((hdrBuf[4] & 0xFF) << 8) | (hdrBuf[5] & 0xFF);
h_paddingLength = hdrBuf[6] & 0xFF;
- }
+ }
+
+ /*
+ * Reads FCGI Begin Request Record.
+ */
+ public int processBeginRecord(int requestID) throws IOException {
+ byte beginReqBody[];
+ byte endReqMsg[];
+ if (requestID == 0 || in.contentLen
+ != FCGIGlobalDefs.def_FCGIEndReqBodyLen) {
+ return FCGIGlobalDefs.def_FCGIProtocolError;
+ }
+ /*
+ * If the webserver is multiplexing the connection,
+ * this library can't deal with it, so repond with
+ * FCGIEndReq message with protocolStatus FCGICantMpxConn
+ */
+ if (in.request.isBeginProcessed) {
+ endReqMsg = new byte[FCGIGlobalDefs.def_FCGIHeaderLen
+ + FCGIGlobalDefs.def_FCGIEndReqBodyLen];
+ System.arraycopy(makeHeader(
+ FCGIGlobalDefs.def_FCGIEndRequest,
+ requestID,
+ FCGIGlobalDefs.def_FCGIEndReqBodyLen,
+ 0), 0, endReqMsg, 0,
+ FCGIGlobalDefs.def_FCGIHeaderLen);
+ System.arraycopy(makeEndrequestBody(0,
+ FCGIGlobalDefs.def_FCGICantMpxConn), 0,
+ endReqMsg,
+ FCGIGlobalDefs.def_FCGIHeaderLen,
+ FCGIGlobalDefs.def_FCGIEndReqBodyLen);
+ /*
+ * since isBeginProcessed is first set below,this
+ * can't be out first call, so request.out is properly set
+ */
+ try {
+ in.request.outStream.write(endReqMsg, 0,
+ FCGIGlobalDefs.def_FCGIHeaderLen
+ + FCGIGlobalDefs.def_FCGIEndReqBodyLen);
+ } catch (IOException e){
+ in.request.outStream.setException(e);
+ return -1;
+ }
+ }
+ /*
+ * Accept this new request. Read the record body
+ */
+ in.request.requestID = requestID;
+ beginReqBody =
+ new byte[FCGIGlobalDefs.def_FCGIBeginReqBodyLen];
+ if (in.read(beginReqBody, 0,
+ FCGIGlobalDefs.def_FCGIBeginReqBodyLen) !=
+ FCGIGlobalDefs.def_FCGIBeginReqBodyLen) {
+ return FCGIGlobalDefs.def_FCGIProtocolError;
+ }
+ br_flags = beginReqBody[2] & 0xFF;
+ in.request.keepConnection
+ = (br_flags & FCGIGlobalDefs.def_FCGIKeepConn) != 0;
+ br_role = ((beginReqBody[0] & 0xFF) << 8) | (beginReqBody[1] & 0xFF);
+ in.request.role = br_role;
+ in.request.isBeginProcessed = true;
+ return FCGIGlobalDefs.def_FCGIBeginRecord;
+ }
- /*
- * Reads FCGI Begin Request Record.
- */
- public int processBeginRecord(int requestID) throws IOException {
- byte beginReqBody[];
- byte endReqMsg[];
- if (requestID == 0 || in.contentLen
- != FCGIGlobalDefs.def_FCGIEndReqBodyLen) {
- return FCGIGlobalDefs.def_FCGIProtocolError;
- }
- /*
- * If the webserver is multiplexing the connection,
- * this library can't deal with it, so repond with
- * FCGIEndReq message with protocolStatus FCGICantMpxConn
- */
- if (in.request.isBeginProcessed) {
- endReqMsg = new byte[FCGIGlobalDefs.def_FCGIHeaderLen
- + FCGIGlobalDefs.def_FCGIEndReqBodyLen];
- System.arraycopy(makeHeader(
- FCGIGlobalDefs.def_FCGIEndRequest,
- requestID,
- FCGIGlobalDefs.def_FCGIEndReqBodyLen,
- 0), 0, endReqMsg, 0,
- FCGIGlobalDefs.def_FCGIHeaderLen);
- System.arraycopy(makeEndrequestBody(0,
- FCGIGlobalDefs.def_FCGICantMpxConn), 0,
- endReqMsg,
- FCGIGlobalDefs.def_FCGIHeaderLen,
- FCGIGlobalDefs.def_FCGIEndReqBodyLen);
- /*
- * since isBeginProcessed is first set below,this
- * can't be out first call, so request.out is properly set
- */
- try {
- in.request.outStream.write(endReqMsg, 0,
- FCGIGlobalDefs.def_FCGIHeaderLen
- + FCGIGlobalDefs.def_FCGIEndReqBodyLen);
- } catch (IOException e){
- in.request.outStream.setException(e);
- return -1;
- }
- }
- /*
- * Accept this new request. Read the record body
- */
- in.request.requestID = requestID;
- beginReqBody =
- new byte[FCGIGlobalDefs.def_FCGIBeginReqBodyLen];
- if (in.read(beginReqBody, 0,
- FCGIGlobalDefs.def_FCGIBeginReqBodyLen) !=
- FCGIGlobalDefs.def_FCGIBeginReqBodyLen) {
- return FCGIGlobalDefs.def_FCGIProtocolError;
- }
- br_flags = beginReqBody[2] & 0xFF;
- in.request.keepConnection
- = (br_flags & FCGIGlobalDefs.def_FCGIKeepConn) != 0;
- br_role = ((beginReqBody[0] & 0xFF) << 8) | (beginReqBody[1] & 0xFF);
- in.request.role = br_role;
- in.request.isBeginProcessed = true;
- return FCGIGlobalDefs.def_FCGIBeginRecord;
- }
+ /*
+ * Reads and Responds to a Management Message. The only type of
+ * management message this library understands is FCGIGetValues.
+ * The only variables that this library's FCGIGetValues understands
+ * are def_FCGIMaxConns, def_FCGIMaxReqs, and def_FCGIMpxsConns.
+ * Ignore the other management variables, and repsond to other
+ * management messages with FCGIUnknownType.
+ */
+ public int processManagementRecord(int type) throws IOException {
- /*
- * Reads and Responds to a Management Message. The only type of
- * management message this library understands is FCGIGetValues.
- * The only variables that this library's FCGIGetValues understands
- * are def_FCGIMaxConns, def_FCGIMaxReqs, and def_FCGIMpxsConns.
- * Ignore the other management variables, and repsond to other
- * management messages with FCGIUnknownType.
- */
- public int processManagementRecord(int type) throws IOException {
-
- byte[] response = new byte[64];
- int wrndx = response[FCGIGlobalDefs.def_FCGIHeaderLen];
- int value, len, plen;
- if (type == FCGIGlobalDefs.def_FCGIGetValues) {
- Properties tmpProps = new Properties();
- readParams(tmpProps);
+ byte[] response = new byte[64];
+ int wrndx = response[FCGIGlobalDefs.def_FCGIHeaderLen];
+ int value, len, plen;
+ if (type == FCGIGlobalDefs.def_FCGIGetValues) {
+ Properties tmpProps = new Properties();
+ readParams(tmpProps);
- if (in.getFCGIError() != 0 || in.contentLen != 0) {
- return FCGIGlobalDefs.def_FCGIProtocolError;
- }
- if (tmpProps.containsKey(
- FCGIGlobalDefs.def_FCGIMaxConns)) {
- makeNameVal(
- FCGIGlobalDefs.def_FCGIMaxConns, "1",
- response, wrndx);
- } else {
- if (tmpProps.containsKey(
- FCGIGlobalDefs.def_FCGIMaxReqs)) {
- makeNameVal(
- FCGIGlobalDefs.def_FCGIMaxReqs, "1",
- response, wrndx);
- } else {
- if (tmpProps.containsKey(
- FCGIGlobalDefs.def_FCGIMaxConns)) {
- makeNameVal(
- FCGIGlobalDefs.def_FCGIMpxsConns, "0",
- response, wrndx);
- }
- }}
- plen = 64 - wrndx;
- len = wrndx - FCGIGlobalDefs.def_FCGIHeaderLen;
- System.arraycopy(makeHeader(
- FCGIGlobalDefs.def_FCGIGetValuesResult,
- FCGIGlobalDefs.def_FCGINullRequestID,
- len, plen), 0,
- response, 0,
- FCGIGlobalDefs.def_FCGIHeaderLen);
- } else {
- plen = len =
- FCGIGlobalDefs.def_FCGIUnknownBodyTypeBodyLen;
- System.arraycopy(makeHeader(
- FCGIGlobalDefs.def_FCGIUnknownType,
- FCGIGlobalDefs.def_FCGINullRequestID,
- len, 0), 0,
- response, 0,
- FCGIGlobalDefs.def_FCGIHeaderLen);
- System.arraycopy(makeUnknownTypeBodyBody(h_type), 0,
- response,
- FCGIGlobalDefs.def_FCGIHeaderLen,
- FCGIGlobalDefs.def_FCGIUnknownBodyTypeBodyLen);
- }
- /*
- * No guarantee that we have a request yet, so
- * dont use fcgi output stream to reference socket, instead
- * use the FileInputStream that refrences it. Also
- * nowhere to save exception, since this is not FCGI stream.
- */
-
- try {
- in.request.socket.getOutputStream().write(response, 0,
- FCGIGlobalDefs.def_FCGIHeaderLen +
- FCGIGlobalDefs.def_FCGIUnknownBodyTypeBodyLen);
-
- } catch (IOException e){
- return -1;
- }
- return FCGIGlobalDefs.def_FCGIMgmtRecord;
- }
-
+ if (in.getFCGIError() != 0 || in.contentLen != 0) {
+ return FCGIGlobalDefs.def_FCGIProtocolError;
+ }
+ if (tmpProps.containsKey(
+ FCGIGlobalDefs.def_FCGIMaxConns)) {
+ makeNameVal(
+ FCGIGlobalDefs.def_FCGIMaxConns, "1",
+ response, wrndx);
+ }
+ else {
+ if (tmpProps.containsKey(
+ FCGIGlobalDefs.def_FCGIMaxReqs)) {
+ makeNameVal(
+ FCGIGlobalDefs.def_FCGIMaxReqs, "1",
+ response, wrndx);
+ }
+ else {
+ if (tmpProps.containsKey(
+ FCGIGlobalDefs.def_FCGIMaxConns)) {
+ makeNameVal(
+ FCGIGlobalDefs.def_FCGIMpxsConns, "0",
+ response, wrndx);
+ }
+ }
+ }
+ plen = 64 - wrndx;
+ len = wrndx - FCGIGlobalDefs.def_FCGIHeaderLen;
+ System.arraycopy(makeHeader(
+ FCGIGlobalDefs.def_FCGIGetValuesResult,
+ FCGIGlobalDefs.def_FCGINullRequestID,
+ len, plen), 0,
+ response, 0,
+ FCGIGlobalDefs.def_FCGIHeaderLen);
+ }
+ else {
+ plen = len =
+ FCGIGlobalDefs.def_FCGIUnknownBodyTypeBodyLen;
+ System.arraycopy(makeHeader(
+ FCGIGlobalDefs.def_FCGIUnknownType,
+ FCGIGlobalDefs.def_FCGINullRequestID,
+ len, 0), 0,
+ response, 0,
+ FCGIGlobalDefs.def_FCGIHeaderLen);
+ System.arraycopy(makeUnknownTypeBodyBody(h_type), 0,
+ response,
+ FCGIGlobalDefs.def_FCGIHeaderLen,
+ FCGIGlobalDefs.def_FCGIUnknownBodyTypeBodyLen);
+ }
+ /*
+ * No guarantee that we have a request yet, so
+ * dont use fcgi output stream to reference socket, instead
+ * use the FileInputStream that refrences it. Also
+ * nowhere to save exception, since this is not FCGI stream.
+ */
+
+ try {
+ in.request.socket.getOutputStream().write(response, 0,
+ FCGIGlobalDefs.def_FCGIHeaderLen +
+ FCGIGlobalDefs.def_FCGIUnknownBodyTypeBodyLen);
+
+ } catch (IOException e){
+ return -1;
+ }
+ return FCGIGlobalDefs.def_FCGIMgmtRecord;
+ }
-
- /*
- * Makes a name/value with name = string of some length, and
- * value a 1 byte integer. Pretty specific to what we are doing
- * above.
- */
- void makeNameVal(String name, String value, byte[] dest, int pos) {
- int nameLen = name.length();
- if (nameLen < 0x80) {
- dest[pos++] = (byte)nameLen;
- }else {
- dest[pos++] = (byte)(((nameLen >> 24) | 0x80) & 0xff);
- dest[pos++] = (byte)((nameLen >> 16) & 0xff);
- dest[pos++] = (byte)((nameLen >> 8) & 0xff);
- dest[pos++] = (byte)nameLen;
- }
- int valLen = value.length();
- if (valLen < 0x80) {
- dest[pos++] = (byte)valLen;
- }else {
- dest[pos++] = (byte)(((valLen >> 24) | 0x80) & 0xff);
- dest[pos++] = (byte)((valLen >> 16) & 0xff);
- dest[pos++] = (byte)((valLen >> 8) & 0xff);
- dest[pos++] = (byte)valLen;
- }
- name.getBytes(0, nameLen, dest, pos);
- pos += nameLen;
- value.getBytes(0, valLen, dest, pos);
- pos += valLen;
- }
+ /*
+ * Makes a name/value with name = string of some length, and
+ * value a 1 byte integer. Pretty specific to what we are doing
+ * above.
+ */
+ void makeNameVal(String name, String value, byte[] dest, int pos) {
+ int nameLen = name.length();
+ if (nameLen < 0x80) {
+ dest[pos++] = (byte)nameLen;
+ }else {
+ dest[pos++] = (byte)(((nameLen >> 24) | 0x80) & 0xff);
+ dest[pos++] = (byte)((nameLen >> 16) & 0xff);
+ dest[pos++] = (byte)((nameLen >> 8) & 0xff);
+ dest[pos++] = (byte)nameLen;
+ }
+ int valLen = value.length();
+ if (valLen < 0x80) {
+ dest[pos++] = (byte)valLen;
+ }else {
+ dest[pos++] = (byte)(((valLen >> 24) | 0x80) & 0xff);
+ dest[pos++] = (byte)((valLen >> 16) & 0xff);
+ dest[pos++] = (byte)((valLen >> 8) & 0xff);
+ dest[pos++] = (byte)valLen;
+ }
+ name.getBytes(0, nameLen, dest, pos);
+ pos += nameLen;
+ value.getBytes(0, valLen, dest, pos);
+ pos += valLen;
+ }
-/*
- * Read FCGI name-value pairs from a stream until EOF. Put them
- * into a Properties object, storing both as strings.
- *
- */
- public int readParams(Properties props) throws IOException{
- int nameLen, valueLen;
- byte lenBuff[] = new byte[3];
- int i = 1;
-
- while ((nameLen = in.read()) != -1) {
- i++;
- if ((nameLen & 0x80) != 0) {
- if ((in.read( lenBuff, 0, 3)) != 3) {
- in.setFCGIError(
- FCGIGlobalDefs.def_FCGIParamsError);
- return -1;
+ /*
+ * Read FCGI name-value pairs from a stream until EOF. Put them
+ * into a Properties object, storing both as strings.
+ */
+ public int readParams(Properties props) throws IOException{
+ int nameLen, valueLen;
+ byte lenBuff[] = new byte[3];
+ int i = 1;
+
+ while ((nameLen = in.read()) != -1) {
+ i++;
+ if ((nameLen & 0x80) != 0) {
+ if ((in.read( lenBuff, 0, 3)) != 3) {
+ in.setFCGIError(
+ FCGIGlobalDefs.def_FCGIParamsError);
+ return -1;
}
- nameLen = ((nameLen & 0x7f) << 24)
+ nameLen = ((nameLen & 0x7f) << 24)
| ((lenBuff[0] & 0xFF) << 16)
| ((lenBuff[1] & 0xFF) << 8)
| (lenBuff[2] & 0xFF);
}
- if ((valueLen = in.read()) == -1) {
- in.setFCGIError(
- FCGIGlobalDefs.def_FCGIParamsError);
- return -1;
- }
- if ((valueLen & 0x80) != 0) {
- if ((in.read( lenBuff, 0, 3)) != 3) {
- in.setFCGIError(
- FCGIGlobalDefs.def_FCGIParamsError);
- return -1;
+ if ((valueLen = in.read()) == -1) {
+ in.setFCGIError(
+ FCGIGlobalDefs.def_FCGIParamsError);
+ return -1;
+ }
+ if ((valueLen & 0x80) != 0) {
+ if ((in.read( lenBuff, 0, 3)) != 3) {
+ in.setFCGIError(
+ FCGIGlobalDefs.def_FCGIParamsError);
+ return -1;
}
- valueLen = ((valueLen & 0x7f) << 24)
+ valueLen = ((valueLen & 0x7f) << 24)
| ((lenBuff[0] & 0xFF) << 16)
| ((lenBuff[1] & 0xFF) << 8)
| (lenBuff[2] & 0xFF);
}
- /*
- * nameLen and valueLen are now valid; read the name
- * and the value from the stream and construct a standard
- * environmental entity
- */
- byte[] name = new byte[nameLen];
- byte[] value = new byte[valueLen];
- if (in.read(name ,0, nameLen) != nameLen) {
- in.setFCGIError(
- FCGIGlobalDefs.def_FCGIParamsError);
- return -1;
- }
-
- if(in.read(value, 0, valueLen) != valueLen) {
- in.setFCGIError(
- FCGIGlobalDefs.def_FCGIParamsError);
- return -1;
- }
- String strName = new String(name, 0, 0, name.length);
- String strValue = new String(value, 0, 0, value.length);
- props.put(strName, strValue);
- }
- return 0;
-
+ /*
+ * nameLen and valueLen are now valid; read the name
+ * and the value from the stream and construct a standard
+ * environmental entity
+ */
+ byte[] name = new byte[nameLen];
+ byte[] value = new byte[valueLen];
+ if (in.read(name ,0, nameLen) != nameLen) {
+ in.setFCGIError(
+ FCGIGlobalDefs.def_FCGIParamsError);
+ return -1;
+ }
-}
- /*
- * Message Building Methods
- */
+ if(in.read(value, 0, valueLen) != valueLen) {
+ in.setFCGIError(
+ FCGIGlobalDefs.def_FCGIParamsError);
+ return -1;
+ }
+ String strName = new String(name, 0, 0, name.length);
+ String strValue = new String(value, 0, 0, value.length);
+ props.put(strName, strValue);
+ }
+ return 0;
- /*
- * Build an FCGI Message Header -
- */
- public byte[] makeHeader(int type,
- int requestId,
- int contentLength,
- int paddingLength) {
- byte[] header = new byte[FCGIGlobalDefs.def_FCGIHeaderLen];
- header[0] = (byte)FCGIGlobalDefs.def_FCGIVersion1;
- header[1] = (byte)type;
- header[2] = (byte)((requestId >> 8) & 0xff);
- header[3] = (byte)((requestId ) & 0xff);
- header[4] = (byte)((contentLength >> 8) & 0xff);
- header[5] = (byte)((contentLength ) & 0xff);
- header[6] = (byte)paddingLength;
- header[7] = 0; //reserved byte
- return header;
- }
- /*
- * Build an FCGI Message End Request Body
- */
- public byte[] makeEndrequestBody(int appStatus,int protocolStatus){
- byte body[] = new byte[FCGIGlobalDefs.def_FCGIEndReqBodyLen];
- body[0] = (byte)((appStatus >> 24) & 0xff);
- body[1] = (byte)((appStatus >> 16) & 0xff);
- body[2] = (byte)((appStatus >> 8) & 0xff);
- body[3] = (byte)((appStatus ) & 0xff);
- body[4] = (byte)protocolStatus;
- for (int i = 5; i < 8; i++) {
- body[i] = 0;
- }
- return body;
- }
- /*
- * Build an FCGI Message UnknownTypeBodyBody
- */
- public byte[] makeUnknownTypeBodyBody(int type){
- byte body[] =
- new byte[FCGIGlobalDefs.def_FCGIUnknownBodyTypeBodyLen];
- body[0] = (byte)type;
- for (int i = 1;
- i < FCGIGlobalDefs.def_FCGIUnknownBodyTypeBodyLen; i++) {
- body[i] = 0;
- }
- return body;
- }
+ }
+ /*
+ * Message Building Methods
+ */
+ /*
+ * Build an FCGI Message Header -
+ */
+ public byte[] makeHeader(int type,
+ int requestId,
+ int contentLength,
+ int paddingLength) {
+ byte[] header = new byte[FCGIGlobalDefs.def_FCGIHeaderLen];
+ header[0] = (byte)FCGIGlobalDefs.def_FCGIVersion1;
+ header[1] = (byte)type;
+ header[2] = (byte)((requestId >> 8) & 0xff);
+ header[3] = (byte)((requestId ) & 0xff);
+ header[4] = (byte)((contentLength >> 8) & 0xff);
+ header[5] = (byte)((contentLength ) & 0xff);
+ header[6] = (byte)paddingLength;
+ header[7] = 0; //reserved byte
+ return header;
+ }
+ /*
+ * Build an FCGI Message End Request Body
+ */
+ public byte[] makeEndrequestBody(int appStatus,int protocolStatus){
+ byte body[] = new byte[FCGIGlobalDefs.def_FCGIEndReqBodyLen];
+ body[0] = (byte)((appStatus >> 24) & 0xff);
+ body[1] = (byte)((appStatus >> 16) & 0xff);
+ body[2] = (byte)((appStatus >> 8) & 0xff);
+ body[3] = (byte)((appStatus ) & 0xff);
+ body[4] = (byte)protocolStatus;
+ for (int i = 5; i < 8; i++) {
+ body[i] = 0;
+ }
+ return body;
+ }
+ /*
+ * Build an FCGI Message UnknownTypeBodyBody
+ */
+ public byte[] makeUnknownTypeBodyBody(int type){
+ byte body[] =
+ new byte[FCGIGlobalDefs.def_FCGIUnknownBodyTypeBodyLen];
+ body[0] = (byte)type;
+ for (int i = 1;
+ i < FCGIGlobalDefs.def_FCGIUnknownBodyTypeBodyLen; i++) {
+ body[i] = 0;
+ }
+ return body;
+ }
- } //end class
\ No newline at end of file
+} //end class
/*
- * @(#)FCGIOutputStream.java
+ * @(#)FCGIOutputStream.java
*
* FastCGi compatibility package Interface
*
- *
* Copyright (c) 1996 Open Market, Inc.
*
* See the file "LICENSE.TERMS" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * $Id: FCGIOutputStream.java,v 1.2 1998/12/12 04:42:21 roberts Exp $
*/
-
-
import java.io.*;
import FCGIRequest;
import FCGIGlobalDefs;
import FCGIMessage;
import FCGIInputStream;
-
/**
* This stream understands FCGI prototcol.
- *
- *
*/
- public
- class FCGIOutputStream extends OutputStream {
+public class FCGIOutputStream extends OutputStream {
- /* Stream vars */
+ /* Stream vars */
- public int wrNext;
- public int stop;
- public boolean isClosed;
+ public int wrNext;
+ public int stop;
+ public boolean isClosed;
- /* require methods to set, get and clear */
- private int errno;
- private Exception errex;
+ /* require methods to set, get and clear */
+ private int errno;
+ private Exception errex;
- /* data vars */
+ /* data vars */
- public byte buff[];
- public int buffLen;
- public int buffStop;
- public int type;
- public boolean isAnythingWritten;
- public boolean rawWrite;
- public FCGIRequest request;
+ public byte buff[];
+ public int buffLen;
+ public int buffStop;
+ public int type;
+ public boolean isAnythingWritten;
+ public boolean rawWrite;
+ public FCGIRequest request;
- public FileOutputStream out;
+ public FileOutputStream out;
- /**
- * Creates a new output stream to manage fcgi prototcol stuff
- * @param out the output stream buflen length of buffer streamType
- */
- public FCGIOutputStream(FileOutputStream outStream,
- int bufLen, int streamType,
- FCGIRequest inreq) {
- out = outStream;
- buffLen = Math.min(bufLen, FCGIGlobalDefs.def_FCGIMaxLen);
- buff = new byte[buffLen];
- type = streamType;
- stop = buffStop = buffLen;
- isAnythingWritten = false;
- rawWrite = false;
- wrNext = FCGIGlobalDefs.def_FCGIHeaderLen;
- isClosed = false;
- request = inreq;
- }
- /*
- * Writes a byte to the output stream.
- */
-
- public void write(int c) throws IOException {
- if(wrNext != stop) {
- buff[wrNext++] = (byte)c;
- return;
- }
- if(isClosed) {
- throw new EOFException();
- }
- empty(false);
- if(wrNext != stop) {
- buff[wrNext++] = (byte)c;
- return;
- }
- /* NOTE: ASSERT(stream->isClosed); */
- /* bug in emptyBuffProc if not */
- throw new EOFException();
- }
+ /**
+ * Creates a new output stream to manage fcgi prototcol stuff
+ * @param out the output stream buflen length of buffer streamType
+ */
+ public FCGIOutputStream(FileOutputStream outStream,
+ int bufLen, int streamType,
+ FCGIRequest inreq) {
+ out = outStream;
+ buffLen = Math.min(bufLen, FCGIGlobalDefs.def_FCGIMaxLen);
+ buff = new byte[buffLen];
+ type = streamType;
+ stop = buffStop = buffLen;
+ isAnythingWritten = false;
+ rawWrite = false;
+ wrNext = FCGIGlobalDefs.def_FCGIHeaderLen;
+ isClosed = false;
+ request = inreq;
+ }
- /**
- * Writes an array of bytes. This method will block until the bytes
- * are actually written.
- * @param b the data to be written
- */
- public void write(byte b[]) throws IOException{
- write(b, 0, b.length);
- }
-
+ /**
+ * Writes a byte to the output stream.
+ */
+ public void write(int c) throws IOException {
+ if(wrNext != stop) {
+ buff[wrNext++] = (byte)c;
+ return;
+ }
+ if(isClosed) {
+ throw new EOFException();
+ }
+ empty(false);
+ if(wrNext != stop) {
+ buff[wrNext++] = (byte)c;
+ return;
+ }
+ /* NOTE: ASSERT(stream->isClosed); */
+ /* bug in emptyBuffProc if not */
+ throw new EOFException();
+ }
- /*
- * Writes len consecutive bytes from off in the array b
- * into the output stream. Performs no interpretation
- * of the output bytes. Making the user convert the string to
- * bytes is in line with current Java practice.
- */
- public void write(byte b[], int off, int len) throws IOException {
- int m, bytesMoved;
- /*
- * Fast path: room for n bytes in the buffer
- */
- if(len <= (stop - wrNext)) {
- System.arraycopy(b, off, buff, wrNext, len);
- wrNext += len;
- return;
- }
- /*
- * General case: stream is closed or buffer empty procedure
- * needs to be called
- */
- bytesMoved = 0;
- for (;;) {
- if(wrNext != stop) {
- m = Math.min(len - bytesMoved, stop - wrNext);
- System.arraycopy(b, off, buff, wrNext, m);
- bytesMoved += m;
- wrNext += m;
- if(bytesMoved == len) {
- return;
- }
- off += m;
- }
- if(isClosed) {
- throw new EOFException();
- }
- empty(false);
- }
- }
+ /**
+ * Writes an array of bytes. This method will block until the bytes
+ * are actually written.
+ * @param b the data to be written
+ */
+ public void write(byte b[]) throws IOException{
+ write(b, 0, b.length);
+ }
- /*
- * Encapsulates any buffered stream content in a FastCGI
- * record. If !doClose, writes the data, making the buffer
- * empty.
- */
- public void empty(boolean doClose) throws IOException {
- int cLen;
- /*
- * Alignment padding omitted in Java
- */
- if (!rawWrite) {
- cLen = wrNext - FCGIGlobalDefs.def_FCGIHeaderLen;
- if(cLen > 0) {
- System.arraycopy(new FCGIMessage().makeHeader(type,
- request.requestID, cLen, 0),
- 0, buff, 0,
- FCGIGlobalDefs.def_FCGIHeaderLen);
- } else {
- wrNext = 0;
- }
- }
- if (doClose) {
- writeCloseRecords();
- }
- if (wrNext != 0) {
- isAnythingWritten = true;
- try {
- out.write(buff, 0, wrNext);
- } catch (IOException e) {
- setException(e);
- return;
- }
- wrNext = 0;
- }
- /*
- * The buffer is empty.
- */
- if(!rawWrite) {
- wrNext += FCGIGlobalDefs.def_FCGIHeaderLen;
- }
- }
+ /**
+ * Writes len consecutive bytes from off in the array b
+ * into the output stream. Performs no interpretation
+ * of the output bytes. Making the user convert the string to
+ * bytes is in line with current Java practice.
+ */
+ public void write(byte b[], int off, int len) throws IOException {
+ int m, bytesMoved;
+ /*
+ * Fast path: room for n bytes in the buffer
+ */
+ if(len <= (stop - wrNext)) {
+ System.arraycopy(b, off, buff, wrNext, len);
+ wrNext += len;
+ return;
+ }
+ /*
+ * General case: stream is closed or buffer empty procedure
+ * needs to be called
+ */
+ bytesMoved = 0;
+ for (;;) {
+ if(wrNext != stop) {
+ m = Math.min(len - bytesMoved, stop - wrNext);
+ System.arraycopy(b, off, buff, wrNext, m);
+ bytesMoved += m;
+ wrNext += m;
+ if(bytesMoved == len) {
+ return;
+ }
+ off += m;
+ }
+ if(isClosed) {
+ throw new EOFException();
+ }
+ empty(false);
+ }
+ }
- /*
- * Close the stream.
- */
- public void close() throws IOException {
- if (isClosed) {
- return;
- }
- empty(true); //
- /*
- * if isClosed, will return with EOFException from write.
- */
- isClosed = true;
- stop = wrNext;
- return;
- }
+ /**
+ * Encapsulates any buffered stream content in a FastCGI
+ * record. If !doClose, writes the data, making the buffer
+ * empty.
+ */
+ public void empty(boolean doClose) throws IOException {
+ int cLen;
+ /*
+ * Alignment padding omitted in Java
+ */
+ if (!rawWrite) {
+ cLen = wrNext - FCGIGlobalDefs.def_FCGIHeaderLen;
+ if(cLen > 0) {
+ System.arraycopy(new FCGIMessage().makeHeader(type,
+ request.requestID, cLen, 0),
+ 0, buff, 0,
+ FCGIGlobalDefs.def_FCGIHeaderLen);
+ }
+ else {
+ wrNext = 0;
+ }
+ }
+ if (doClose) {
+ writeCloseRecords();
+ }
+ if (wrNext != 0) {
+ isAnythingWritten = true;
+ try {
+ out.write(buff, 0, wrNext);
+ } catch (IOException e) {
+ setException(e);
+ return;
+ }
+ wrNext = 0;
+ }
+ /*
+ * The buffer is empty.
+ */
+ if(!rawWrite) {
+ wrNext += FCGIGlobalDefs.def_FCGIHeaderLen;
+ }
+ }
- /*
- * Flushes any buffered output.
- * Server-push is a legitimate application of flush.
- * Otherwise, it is not very useful, since FCGIAccept
- * does it implicitly. flush may reduce performance
- * by increasing the total number of operating system calls
- * the application makes.
- */
- public void flush() throws IOException {
- if (isClosed) {
- return;
- }
- empty(false);
- /*
- * if isClosed, will return with EOFException from write.
- */
- return;
- }
-
- /*
- * An FCGI error has occurred. Save the error code in the stream
- * for diagnostic purposes and set the stream state so that
- * reads return EOF
- */
- public void setFCGIError(int errnum) {
- /*
- * Preserve only the first error.
- */
- if (errno == 0) {
- errno = errnum;
- }
- isClosed = true;
- }
- /*
- * An Exception has occurred. Save the Exception in the stream
- * for diagnostic purposes and set the stream state so that
- * reads return EOF
- */
- public void setException(Exception errexpt) {
- /*
- * Preserve only the first error.
- */
- if (errex == null) {
- errex = errexpt;
- }
- isClosed = true;
- }
+ /**
+ * Close the stream.
+ */
+ public void close() throws IOException {
+ if (isClosed) {
+ return;
+ }
+ empty(true);
+ /*
+ * if isClosed, will return with EOFException from write.
+ */
+ isClosed = true;
+ stop = wrNext;
+ return;
+ }
- /*
- * Clear the stream error code and end-of-file indication.
- */
- public void clearFCGIError() {
- errno = 0;
- /*
- * isClosed = false;
- * XXX: should clear isClosed but work is needed to make it safe
- * to do so.
- */
- }
-/*
- * Clear the stream error code and end-of-file indication.
- */
- public void clearException() {
- errex = null;
- /*
- * isClosed = false;
- * XXX: should clear isClosed but work is needed to make it safe
- * to do so.
- */
- }
+ /**
+ * Flushes any buffered output.
+ * Server-push is a legitimate application of flush.
+ * Otherwise, it is not very useful, since FCGIAccept
+ * does it implicitly. flush may reduce performance
+ * by increasing the total number of operating system calls
+ * the application makes.
+ */
+ public void flush() throws IOException {
+ if (isClosed) {
+ return;
+ }
+ empty(false);
+ /*
+ * if isClosed, will return with EOFException from write.
+ */
+ return;
+ }
+
+ /**
+ * An FCGI error has occurred. Save the error code in the stream
+ * for diagnostic purposes and set the stream state so that
+ * reads return EOF
+ */
+ public void setFCGIError(int errnum) {
+ /*
+ * Preserve only the first error.
+ */
+ if (errno == 0) {
+ errno = errnum;
+ }
+ isClosed = true;
+ }
+
+ /**
+ * An Exception has occurred. Save the Exception in the stream
+ * for diagnostic purposes and set the stream state so that
+ * reads return EOF
+ */
+ public void setException(Exception errexpt) {
+ /*
+ * Preserve only the first error.
+ */
+ if (errex == null) {
+ errex = errexpt;
+ }
+ isClosed = true;
+ }
+
+ /**
+ * Clear the stream error code and end-of-file indication.
+ */
+ public void clearFCGIError() {
+ errno = 0;
+ /*
+ * isClosed = false;
+ * XXX: should clear isClosed but work is needed to make it safe
+ * to do so.
+ */
+ }
+
+ /**
+ * Clear the stream error code and end-of-file indication.
+ */
+ public void clearException() {
+ errex = null;
+ /*
+ * isClosed = false;
+ * XXX: should clear isClosed but work is needed to make it safe
+ * to do so.
+ */
+ }
+
+ /**
+ * accessor method since var is private
+ */
+ public int etFCGIError() {
+ return errno;
+ }
+
+ /**
+ * accessor method since var is private
+ */
+ public Exception getException() {
+ return errex;
+ }
+
+ /**
+ * Writes an EOF record for the stream content if necessary.
+ * If this is the last writer to close, writes an FCGI_END_REQUEST
+ * record.
+ */
+ public void writeCloseRecords() throws IOException {
+ FCGIMessage msg = new FCGIMessage();
+ /*
+ * Enter rawWrite mode so final records won't be
+ * encapsulated as
+ * stream data.
+ */
+ rawWrite = true;
+ /*
+ * Generate EOF for stream content if needed.
+ */
+ if(!(type == FCGIGlobalDefs.def_FCGIStderr
+ && wrNext == 0
+ && !isAnythingWritten)) {
+ byte hdr[] =
+ new byte[FCGIGlobalDefs.def_FCGIHeaderLen];
+ System.arraycopy(msg.makeHeader(type,
+ request.requestID,
+ 0, 0),
+ 0, hdr,0,
+ FCGIGlobalDefs.def_FCGIHeaderLen);
+ write(hdr, 0, hdr.length);
+ }
+ /*
+ * Generate FCGI_END_REQUEST record if needed.
+ */
+ if(request.numWriters == 1) {
+ byte endReq[] =
+ new byte[FCGIGlobalDefs.def_FCGIHeaderLen
+ + FCGIGlobalDefs.def_FCGIEndReqBodyLen];
+ System.arraycopy(msg.makeHeader(
+ FCGIGlobalDefs.def_FCGIEndRequest,
+ request.requestID,
+ FCGIGlobalDefs.def_FCGIEndReqBodyLen,0),
+ 0, endReq, 0,
+ FCGIGlobalDefs.def_FCGIHeaderLen);
+ System.arraycopy(msg.makeEndrequestBody(
+ request.appStatus,
+ FCGIGlobalDefs.def_FCGIRequestComplete),
+ 0,endReq,
+ FCGIGlobalDefs.def_FCGIHeaderLen,
+ FCGIGlobalDefs.def_FCGIEndReqBodyLen);
+ write(endReq,0, FCGIGlobalDefs.def_FCGIHeaderLen
+ + FCGIGlobalDefs.def_FCGIEndReqBodyLen);
+ }
+ request.numWriters--;
+ }
+}
- /*
- * accessor method since var is private
- */
- public int etFCGIError() {
- return errno;
- }
- /*
- * accessor method since var is private
- */
- public Exception getException() {
- return errex;
- }
- /*
- * Writes an EOF record for the stream content if necessary.
- * If this is the last writer to close, writes an FCGI_END_REQUEST
- * record.
- */
-
- public void writeCloseRecords() throws IOException {
- FCGIMessage msg = new FCGIMessage();
- /*
- * Enter rawWrite mode so final records won't be
- * encapsulated as
- * stream data.
- */
- rawWrite = true;
- /*
- * Generate EOF for stream content if needed.
- */
- if(!(type == FCGIGlobalDefs.def_FCGIStderr
- && wrNext == 0
- && !isAnythingWritten)) {
- byte hdr[] =
- new byte[FCGIGlobalDefs.def_FCGIHeaderLen];
- System.arraycopy(msg.makeHeader(type,
- request.requestID,
- 0, 0),
- 0, hdr,0,
- FCGIGlobalDefs.def_FCGIHeaderLen);
- write(hdr, 0, hdr.length);
- }
- /*
- * Generate FCGI_END_REQUEST record if needed.
- */
- if(request.numWriters == 1) {
- byte endReq[] =
- new byte[FCGIGlobalDefs.def_FCGIHeaderLen
- + FCGIGlobalDefs.def_FCGIEndReqBodyLen];
- System.arraycopy(msg.makeHeader(
- FCGIGlobalDefs.def_FCGIEndRequest,
- request.requestID,
- FCGIGlobalDefs.def_FCGIEndReqBodyLen,0),
- 0, endReq, 0,
- FCGIGlobalDefs.def_FCGIHeaderLen);
- System.arraycopy(msg.makeEndrequestBody(
- request.appStatus,
- FCGIGlobalDefs.def_FCGIRequestComplete),
- 0,endReq,
- FCGIGlobalDefs.def_FCGIHeaderLen,
- FCGIGlobalDefs.def_FCGIEndReqBodyLen);
- write(endReq,0, FCGIGlobalDefs.def_FCGIHeaderLen
- + FCGIGlobalDefs.def_FCGIEndReqBodyLen);
- }
- request.numWriters--;
- }
-}
\ No newline at end of file
/*
- * @(#)FCGIRequest.java
- *
- *
- *
- * FastCGi compatibility package Interface
+ * @(#)FCGIRequest.java
*
+ * FastCGi compatibility package Interface
*
* Copyright (c) 1996 Open Market, Inc.
*
* See the file "LICENSE.TERMS" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * $Id: FCGIRequest.java,v 1.2 1998/12/12 04:42:23 roberts Exp $
*/
-
import java.net.*;
import java.io.FileDescriptor;
import FCGIOutputStream;
public class FCGIRequest {
-/* This class has no methods. Right now we are single threaded
- * so there is only one request object at any given time which
- * is refrenced by an FCGIInterface class variable . All of this
- * object's data could just as easily be declared directly there.
- * When we thread, this will change, so we might as well use a
- * seperate class. In line with this thinking, though somewhat
- * more perversely, we kept the socket here.
- */
- /*
- * class variables
- */
-/*public static Socket socket; */
-// same for all requests
-
- /*
- * instance variables
- */
-public Socket socket;
-public boolean isBeginProcessed;
-public int requestID;
-public boolean keepConnection;
-public int role;
-public int appStatus;
-public int numWriters;
-public FCGIInputStream inStream;
-public FCGIOutputStream outStream;
-public FCGIOutputStream errStream;
-public Properties params;
-
+ /* This class has no methods. Right now we are single threaded
+ * so there is only one request object at any given time which
+ * is refrenced by an FCGIInterface class variable . All of this
+ * object's data could just as easily be declared directly there.
+ * When we thread, this will change, so we might as well use a
+ * seperate class. In line with this thinking, though somewhat
+ * more perversely, we kept the socket here.
+ */
+ /*
+ * class variables
+ */
+ /*public static Socket socket; */
+ // same for all requests
+ /*
+ * instance variables
+ */
+ public Socket socket;
+ public boolean isBeginProcessed;
+ public int requestID;
+ public boolean keepConnection;
+ public int role;
+ public int appStatus;
+ public int numWriters;
+ public FCGIInputStream inStream;
+ public FCGIOutputStream outStream;
+ public FCGIOutputStream errStream;
+ public Properties params;
+}
-}