001: // HttpMuxServer.java
002: // $Id: HttpMuxServer.java,v 1.17 2004/03/11 15:11:04 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1997.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.www.protocol.http;
007:
008: import java.io.BufferedOutputStream;
009: import java.io.DataOutputStream;
010: import java.io.IOException;
011: import java.io.InputStream;
012: import java.io.OutputStream;
013: import java.io.PrintStream;
014:
015: import org.w3c.www.mux.MuxSession;
016:
017: import org.w3c.www.mime.MimeHeaderHolder;
018: import org.w3c.www.mime.MimeParser;
019: import org.w3c.www.mime.MimeParserException;
020: import org.w3c.www.mime.MimeParserFactory;
021:
022: import org.w3c.www.http.HttpMessage;
023: import org.w3c.www.http.HttpReplyMessage;
024:
025: public class HttpMuxServer extends HttpServer {
026: private static final String PROTOCOL = "http|mux";
027:
028: protected HttpMuxConnection conn = null;
029: protected HttpManager manager = null;
030: protected String host = null;
031: protected int port = -1;
032: protected int timeout = 300000;
033: protected int conn_timeout = 000;
034:
035: protected synchronized void acquireConnection() throws IOException {
036: if (conn != null)
037: return;
038: conn = new HttpMuxConnection(this , host, port);
039: if (conn.incrUseCount())
040: manager.notifyUse(conn);
041: }
042:
043: protected synchronized void releaseConnection() {
044: if ((conn != null) && conn.decrUseCount())
045: manager.notifyIdle(conn);
046: }
047:
048: public String getProtocol() {
049: return PROTOCOL;
050: }
051:
052: public short getMajorVersion() {
053: return (short) 1;
054: }
055:
056: public short getMinorVersion() {
057: return (short) 1;
058: }
059:
060: public synchronized void setTimeout(int timeout) {
061: this .timeout = timeout;
062: }
063:
064: public synchronized void setConnTimeout(int conn_timeout) {
065: this .conn_timeout = conn_timeout;
066: }
067:
068: /**
069: * Is this request a two stage request.
070: * @return A boolean, <strong>true</strong> if the request is two
071: * stage, <strong>false</strong> otherwise.
072: */
073:
074: protected boolean isTwoStage(Request requset) {
075: return requset.hasOutputStream();
076: }
077:
078: // FIXME doc
079: protected void notifyObserver(RequestObserver obs, Request request,
080: int code) {
081: RequestEvent evt = new RequestEvent(this , request, code);
082: obs.notifyProgress(evt);
083: }
084:
085: protected void notifyObserver(RequestObserver obs, RequestEvent evt) {
086: obs.notifyProgress(evt);
087: }
088:
089: /**
090: * Run the given request.
091: * @param request The request to run.
092: * @return An instance of Reply, containing all the reply
093: * informations.
094: * @exception HttpException If something failed during request processing.
095: */
096: public Reply runRequest(Request req) throws HttpException {
097: Reply rep = null;
098: MuxSession s = null;
099: RequestObserver o = req.getObserver();
100: // Run the request, and mark the connection idle again:
101: try {
102: // Get a connection:
103: acquireConnection();
104: s = conn.connect(80);
105: OutputStream os = (new DataOutputStream(
106: new BufferedOutputStream(s.getOutputStream())));
107: MimeParser parser = new MimeParser(s.getInputStream(),
108: manager.getReplyFactory());
109: if (isTwoStage(req)) {
110: // Emit the request headers:
111: req.emit(os, Request.EMIT_HEADERS);
112: os.flush();
113: if (o != null)
114: notifyObserver(o, new ConnectedEvent(this , req, os));
115: rep = (Reply) parser.parse();
116: // Wait for a 100 status code:
117: if ((rep.getStatus() / 100) == 1) {
118: // Notify the observer if any:
119: if (o != null)
120: notifyObserver(o, new ContinueEvent(this , req,
121: rep));
122: // Finish the request normally:
123: req.emit(os, Request.EMIT_BODY
124: | Request.EMIT_FOOTERS);
125: os.flush();
126: rep = (Reply) parser.parse();
127: }
128: } else {
129: req.emit(os, Request.EMIT_HEADERS);
130: os.flush();
131: if (o != null)
132: notifyObserver(o, new ConnectedEvent(this , req, os));
133: rep = (Reply) parser.parse();
134: while ((rep.getStatus() / 100) == 1) {
135: if (o != null)
136: notifyObserver(o, new ContinueEvent(this , req,
137: rep));
138: // Finish the request normally:
139: req.emit(os, Request.EMIT_BODY
140: | Request.EMIT_FOOTERS);
141: os.flush();
142: rep = (Reply) parser.parse();
143: }
144: }
145: os.close();
146: } catch (IOException ex) {
147: ex.printStackTrace();
148: throw new HttpException(req, ex);
149: } catch (MimeParserException ex) {
150: ex.printStackTrace();
151: throw new HttpException(req, ex);
152: } finally {
153: releaseConnection();
154: }
155: return rep;
156: }
157:
158: /**
159: * Interrupt given request (that we launched).
160: * THIS METHID IS NOT IMPLEMENTED !
161: * @param request The request to interrupt.
162: */
163:
164: protected void interruptRequest(Request request) {
165: System.out.println("HttpMuxConnection.interruptRequest: "
166: + "not implemented.");
167: }
168:
169: public synchronized void deleteConnection(HttpConnection conn) {
170: conn.close();
171: conn = null;
172: }
173:
174: /**
175: * Initialize this server instance for the given target location.
176: * @param manager The central HTTP protocol manager.
177: * @param state The manager's state for that server.
178: * @param host The target server's FQDN.
179: * @param port The target server's port number.
180: * @param timeout The socket's timeout in millisec
181: */
182:
183: public void initialize(HttpManager manager, HttpServerState state,
184: String host, int port, int timeout) {
185: initialize(manager, state, host, port, timeout, conn_timeout);
186: }
187:
188: /**
189: * Initialize this server instance for the given target location.
190: * @param manager The central HTTP protocol manager.
191: * @param state The manager's state for that server.
192: * @param host The target server's FQDN.
193: * @param port The target server's port number.
194: * @param timeout The socket's timeout in millisec
195: */
196:
197: public void initialize(HttpManager manager, HttpServerState state,
198: String host, int port, int timeout, int conn_timeout) {
199: this.state = state;
200: this.manager = manager;
201: this.host = host;
202: this.port = port;
203: this.timeout = timeout;
204: this.conn_timeout = conn_timeout;
205: state.state = HttpServerState.OK;
206: }
207: }
|