001: /*
002: * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.net.httpserver;
027:
028: import java.io.*;
029: import java.nio.*;
030: import java.nio.channels.*;
031: import java.net.*;
032: import javax.net.ssl.*;
033: import java.util.*;
034: import sun.net.www.MessageHeader;
035:
036: /**
037: * This class encapsulates a HTTP request received and a
038: * response to be generated in one exchange. It provides methods
039: * for examining the request from the client, and for building and
040: * sending the response.
041: * <p>
042: * The typical life-cycle of a HttpExchange is shown in the sequence
043: * below.
044: * <ol><li>{@link #getRequestMethod()} to determine the command
045: * <li>{@link #getRequestHeaders()} to examine the request headers (if needed)
046: * <li>{@link #getRequestBody()} returns a {@link java.io.InputStream} for reading the request body.
047: * After reading the request body, the stream is close.
048: * <li>{@link #getResponseHeaders()} to set any response headers, except content-length
049: * <li>{@link #sendResponseHeaders(int,long)} to send the response headers. Must be called before
050: * next step.
051: * <li>{@link #getResponseBody()} to get a {@link java.io.OutputStream} to send the response body.
052: * When the response body has been written, the stream must be closed to terminate the exchange.
053: * </ol>
054: * <b>Terminating exchanges</b>
055: * <br>
056: * Exchanges are terminated when both the request InputStream and response OutputStream are closed.
057: * Closing the OutputStream, implicitly closes the InputStream (if it is not already closed).
058: * However, it is recommended
059: * to consume all the data from the InputStream before closing it.
060: * The convenience method {@link #close()} does all of these tasks.
061: * Closing an exchange without consuming all of the request body is not an error
062: * but may make the underlying TCP connection unusable for following exchanges.
063: * The effect of failing to terminate an exchange is undefined, but will typically
064: * result in resources failing to be freed/reused.
065: * @since 1.6
066: */
067:
068: public abstract class HttpExchange {
069:
070: protected HttpExchange() {
071: }
072:
073: /**
074: * Returns an immutable Map containing the HTTP headers that were
075: * included with this request. The keys in this Map will be the header
076: * names, while the values will be a List of Strings containing each value
077: * that was included (either for a header that was listed several times,
078: * or one that accepts a comma-delimited list of values on a single line).
079: * In either of these cases, the values for the header name will be
080: * presented in the order that they were included in the request.
081: * <p>
082: * The keys in Map are case-insensitive.
083: * @return a read-only Map which can be used to access request headers
084: */
085: public abstract Headers getRequestHeaders();
086:
087: /**
088: * Returns a mutable Map into which the HTTP response headers can be stored
089: * and which will be transmitted as part of this response. The keys in the
090: * Map will be the header names, while the values must be a List of Strings
091: * containing each value that should be included multiple times
092: * (in the order that they should be included).
093: * <p>
094: * The keys in Map are case-insensitive.
095: * @return a writable Map which can be used to set response headers.
096: */
097: public abstract Headers getResponseHeaders();
098:
099: /**
100: * Get the request URI
101: *
102: * @return the request URI
103: */
104: public abstract URI getRequestURI();
105:
106: /**
107: * Get the request method
108: * @return the request method
109: */
110: public abstract String getRequestMethod();
111:
112: /**
113: * Get the HttpContext for this exchange
114: * @return the HttpContext
115: */
116: public abstract HttpContext getHttpContext();
117:
118: /**
119: * Ends this exchange by doing the following in sequence:<p><ol>
120: * <li>close the request InputStream, if not already closed<p></li>
121: * <li>close the response OutputStream, if not already closed. </li>
122: * </ol>
123: */
124: public abstract void close();
125:
126: /**
127: * returns a stream from which the request body can be read.
128: * Multiple calls to this method will return the same stream.
129: * It is recommended that applications should consume (read) all of the
130: * data from this stream before closing it. If a stream is closed
131: * before all data has been read, then the close() call will
132: * read and discard remaining data (up to an implementation specific
133: * number of bytes).
134: * @return the stream from which the request body can be read.
135: */
136: public abstract InputStream getRequestBody();
137:
138: /**
139: * returns a stream to which the response body must be
140: * written. {@link #sendResponseHeaders(int,long)}) must be called prior to calling
141: * this method. Multiple calls to this method (for the same exchange)
142: * will return the same stream. In order to correctly terminate
143: * each exchange, the output stream must be closed, even if no
144: * response body is being sent.
145: * <p>
146: * Closing this stream implicitly
147: * closes the InputStream returned from {@link #getRequestBody()}
148: * (if it is not already closed).
149: * <P>
150: * If the call to sendResponseHeaders() specified a fixed response
151: * body length, then the exact number of bytes specified in that
152: * call must be written to this stream. If too many bytes are written,
153: * then write() will throw an IOException. If too few bytes are written
154: * then the stream close() will throw an IOException. In both cases,
155: * the exchange is aborted and the underlying TCP connection closed.
156: * @return the stream to which the response body is written
157: */
158: public abstract OutputStream getResponseBody();
159:
160: /**
161: * Starts sending the response back to the client using the current set of response headers
162: * and the numeric response code as specified in this method. The response body length is also specified
163: * as follows. If the response length parameter is greater than zero, this specifies an exact
164: * number of bytes to send and the application must send that exact amount of data.
165: * If the response length parameter is <code>zero</code>, then chunked transfer encoding is
166: * used and an arbitrary amount of data may be sent. The application terminates the
167: * response body by closing the OutputStream. If response length has the value <code>-1</code>
168: * then no response body is being sent.
169: * <p>
170: * If the content-length response header has not already been set then
171: * this is set to the apropriate value depending on the response length parameter.
172: * <p>
173: * This method must be called prior to calling {@link #getResponseBody()}.
174: * @param rCode the response code to send
175: * @param responseLength if > 0, specifies a fixed response body length
176: * and that exact number of bytes must be written
177: * to the stream acquired from getResponseBody(), or else
178: * if equal to 0, then chunked encoding is used,
179: * and an arbitrary number of bytes may be written.
180: * if <= -1, then no response body length is specified and
181: * no response body may be written.
182: * @see HttpExchange#getResponseBody()
183: */
184: public abstract void sendResponseHeaders(int rCode,
185: long responseLength) throws IOException;
186:
187: /**
188: * Returns the address of the remote entity invoking this request
189: * @return the InetSocketAddress of the caller
190: */
191: public abstract InetSocketAddress getRemoteAddress();
192:
193: /**
194: * Returns the response code, if it has already been set
195: * @return the response code, if available. <code>-1</code> if not available yet.
196: */
197: public abstract int getResponseCode();
198:
199: /**
200: * Returns the local address on which the request was received
201: * @return the InetSocketAddress of the local interface
202: */
203: public abstract InetSocketAddress getLocalAddress();
204:
205: /**
206: * Returns the protocol string from the request in the form
207: * <i>protocol/majorVersion.minorVersion</i>. For example,
208: * "HTTP/1.1"
209: * @return the protocol string from the request
210: */
211: public abstract String getProtocol();
212:
213: /**
214: * Filter modules may store arbitrary objects with HttpExchange
215: * instances as an out-of-band communication mechanism. Other Filters
216: * or the exchange handler may then access these objects.
217: * <p>
218: * Each Filter class will document the attributes which they make
219: * available.
220: * @param name the name of the attribute to retrieve
221: * @return the attribute object, or null if it does not exist
222: * @throws NullPointerException if name is <code>null</code>
223: */
224: public abstract Object getAttribute(String name);
225:
226: /**
227: * Filter modules may store arbitrary objects with HttpExchange
228: * instances as an out-of-band communication mechanism. Other Filters
229: * or the exchange handler may then access these objects.
230: * <p>
231: * Each Filter class will document the attributes which they make
232: * available.
233: * @param name the name to associate with the attribute value
234: * @param value the object to store as the attribute value. <code>null</code>
235: * value is permitted.
236: * @throws NullPointerException if name is <code>null</code>
237: */
238: public abstract void setAttribute(String name, Object value);
239:
240: /**
241: * Used by Filters to wrap either (or both) of this exchange's InputStream
242: * and OutputStream, with the given filtered streams so
243: * that subsequent calls to {@link #getRequestBody()} will
244: * return the given {@link java.io.InputStream}, and calls to
245: * {@link #getResponseBody()} will return the given
246: * {@link java.io.OutputStream}. The streams provided to this
247: * call must wrap the original streams, and may be (but are not
248: * required to be) sub-classes of {@link java.io.FilterInputStream}
249: * and {@link java.io.FilterOutputStream}.
250: * @param i the filtered input stream to set as this object's inputstream,
251: * or <code>null</code> if no change.
252: * @param o the filtered output stream to set as this object's outputstream,
253: * or <code>null</code> if no change.
254: */
255: public abstract void setStreams(InputStream i, OutputStream o);
256:
257: /**
258: * If an authenticator is set on the HttpContext that owns this exchange,
259: * then this method will return the {@link HttpPrincipal} that represents
260: * the authenticated user for this HttpExchange.
261: * @return the HttpPrincipal, or <code>null</code> if no authenticator is set.
262: */
263: public abstract HttpPrincipal getPrincipal();
264: }
|