001: /*
002: * Connection.java
003: *
004: * Brazil project web application Framework,
005: * export version: 1.1
006: * Copyright (c) 1998-2000 Sun Microsystems, Inc.
007: *
008: * Sun Public License Notice
009: *
010: * The contents of this file are subject to the Sun Public License Version
011: * 1.0 (the "License"). You may not use this file except in compliance with
012: * the License. A copy of the License is included as the file "license.terms",
013: * and also available at http://www.sun.com/
014: *
015: * The Original Code is from:
016: * Brazil project web application Framework release 1.1.
017: * The Initial Developer of the Original Code is: suhler.
018: * Portions created by suhler are Copyright (C) Sun Microsystems, Inc.
019: * All Rights Reserved.
020: *
021: * Contributor(s): cstevens, suhler.
022: *
023: * Version: 1.14
024: * Created by suhler on 98/09/14
025: * Last modified by suhler on 00/05/15 12:01:47
026: */
027:
028: package sunlabs.brazil.server;
029:
030: import java.net.Socket;
031: import java.io.IOException;
032: import java.io.InterruptedIOException;
033: import java.util.Properties;
034:
035: /**
036: * Internal "helper" class to manage http connections.
037: * Create a thread that lives for the duration of the client socket and handles
038: * multiple HTTP requests. Packages each HTTP request from the socket into
039: * an HttpRequest object and passes it to the <code>respond</code> method of
040: * the server's main HttpHandler. If an error occurs while handling a
041: * request, the socket is closed and this thread ends.
042: *
043: * @author Colin Stevens
044: * @version 1.14, 05/15/00
045: */
046: class Connection implements Runnable {
047: /**
048: * The Server that created this handler.
049: */
050: Server server;
051:
052: /**
053: * The client socket.
054: */
055: Socket sock;
056:
057: /**
058: * The current request state
059: */
060: Request request;
061:
062: /**
063: * Constructs a new Connection and starts it running.
064: */
065: Connection(Server server, Socket sock) {
066: this .server = server;
067: this .sock = sock;
068:
069: request = new Request(server, sock);
070: }
071:
072: /**
073: * Loop reading HTTP requests from the socket until there is an error,
074: * the client requests that the socket be closed, or the client exceeds
075: * the maximum number of requests allowed on a single socket.
076: */
077: public void run() {
078: try {
079: sock.setSoTimeout(server.timeout);
080:
081: while (request.shouldKeepAlive()) {
082: if (request.getRequest(server.props) == false) {
083: break;
084: }
085: server.requestCount++;
086: if (server.handler.respond(request) == false) {
087: request.sendError(404, null, request.url);
088: }
089: request.out.flush();
090: server.log(Server.LOG_INFORMATIONAL, null,
091: "request done");
092: }
093: } catch (InterruptedIOException e) {
094: /*
095: * A read timed out, or (rarely) this thread was interrupted.
096: *
097: * Thread.interrupt() generates an InterruptedIOException that
098: * cannot be 100% discriminated from an InterruptedIOException
099: * caused by a read timeout.
100: *
101: * Under jdk-1.1, a Thread.interrupt() call generates an
102: * InterruptedIOException with the detail message
103: * "operation interrupted".
104: *
105: * Under jdk-1.2, a Thread.interrupt() call generates an
106: * InterruptedIOException with the detail message
107: * "Interrupted system call".
108: *
109: * In order to make the automated test scripts easier to write
110: * and run under both jdk-1.2 and jdk-1.1, suppress the varying
111: * InterruptedIOException log messages due to Thread.interrupt(),
112: * which only happens when the server is being shut down by
113: * the test script anyhow.
114: */
115:
116: String msg = e.getMessage();
117: if ((msg == null) || (msg.indexOf("terrupted") < 0)) {
118: request.sendError(408, msg, null);
119: }
120: } catch (IOException e) {
121: /*
122: * Expected exception, due to not being able to write back to
123: * client, etc.
124: */
125: server.log(Server.LOG_INFORMATIONAL, e.getMessage(),
126: "I/O error on socket");
127: } catch (Exception e) {
128: /*
129: * Unexpected exception.
130: */
131:
132: e.printStackTrace();
133: request.sendError(500, e.toString(), "unexpected error");
134: } finally {
135: server.log(Server.LOG_INFORMATIONAL, null, "socket close");
136: try {
137: request.out.flush();
138: } catch (IOException e) {
139: }
140: try {
141: sock.close();
142: } catch (IOException e) {
143: }
144: }
145: }
146: }
|