1 /*
2  * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.net.httpserver;
27 
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.OutputStream;
31 import java.net.InetSocketAddress;
32 import java.net.URI;
33 import java.util.Map;
34 
35 /**
36  * This class encapsulates a HTTP request received and a
37  * response to be generated in one exchange. It provides methods
38  * for examining the request from the client, and for building and
39  * sending the response.
40  *
41  * <p> The typical life-cycle of a {@code HttpExchange} is shown in the sequence
42  * below:
43  * <ol>
44  *     <li>{@link #getRequestMethod()} to determine the command.
45  *     <li>{@link #getRequestHeaders()} to examine the request headers (if
46  *     needed).
47  *     <li>{@link #getRequestBody()} returns an {@link InputStream} for
48  *     reading the request body. After reading the request body, the stream
49  *     should be closed.
50  *     <li>{@link #getResponseHeaders()} to set any response headers, except
51  *     content-length.
52  *     <li>{@link #sendResponseHeaders(int,long)} to send the response headers.
53  *     Must be called before next step.
54  *     <li>{@link #getResponseBody()} to get a {@link OutputStream} to
55  *     send the response body. When the response body has been written, the
56  *     stream must be closed to terminate the exchange.
57  * </ol>
58  *
59  * <b>Terminating exchanges</b>
60  * <br>Exchanges are terminated when both the request {@code InputStream} and
61  * response {@code OutputStream} are closed. Closing the {@code OutputStream},
62  * implicitly closes the {@code InputStream} (if it is not already closed).
63  * However, it is recommended to consume all the data from the {@code InputStream}
64  * before closing it. The convenience method {@link #close()} does all of these
65  * tasks. Closing an exchange without consuming all of the request body is not
66  * an error but may make the underlying TCP connection unusable for following
67  * exchanges. The effect of failing to terminate an exchange is undefined, but
68  * will typically result in resources failing to be freed/reused.
69  *
70  * @since 1.6
71  */
72 
73 public abstract class HttpExchange implements AutoCloseable {
74 
75     /**
76      * Constructor for subclasses to call.
77      */
HttpExchange()78     protected HttpExchange() {
79     }
80 
81     /**
82      * Returns an immutable {@link Map} containing the HTTP headers that were
83      * included with this request. The keys in this {@code Map} will be the header
84      * names, while the values will be a {@link java.util.List} of
85      * {@linkplain java.lang.String Strings} containing each value that was
86      * included (either for a header that was listed several times, or one that
87      * accepts a comma-delimited list of values on a single line). In either of
88      * these cases, the values for the header name will be presented in the
89      * order that they were included in the request.
90      *
91      * <p> The keys in {@code Map} are case-insensitive.
92      *
93      * @return a read-only {@code Map} which can be used to access request headers
94      */
getRequestHeaders()95     public abstract Headers getRequestHeaders();
96 
97     /**
98      * Returns a mutable {@link Map} into which the HTTP response headers can be
99      * stored and which will be transmitted as part of this response. The keys in
100      * the {@code Map} will be the header names, while the values must be a
101      * {@link java.util.List} of {@linkplain java.lang.String Strings} containing
102      * each value that should be included multiple times (in the order that they
103      * should be included).
104      *
105      * <p> The keys in {@code Map} are case-insensitive.
106      *
107      * @return a writable {@code Map} which can be used to set response headers.
108      */
getResponseHeaders()109     public abstract Headers getResponseHeaders();
110 
111     /**
112      * Get the request {@link URI}.
113      *
114      * @return the request {@code URI}
115      */
getRequestURI()116     public abstract URI getRequestURI();
117 
118     /**
119      * Get the request method.
120      *
121      * @return the request method
122      */
getRequestMethod()123     public abstract String getRequestMethod();
124 
125     /**
126      * Get the {@link HttpContext} for this exchange.
127      *
128      * @return the {@code HttpContext}
129      */
getHttpContext()130     public abstract HttpContext getHttpContext();
131 
132     /**
133      * Ends this exchange by doing the following in sequence:
134      * <ol>
135      *      <li> close the request {@link InputStream}, if not already closed.
136      *      <li> close the response {@link OutputStream}, if not already closed.
137      * </ol>
138      */
close()139     public abstract void close();
140 
141     /**
142      * Returns a stream from which the request body can be read.
143      * Multiple calls to this method will return the same stream.
144      * It is recommended that applications should consume (read) all of the data
145      * from this stream before closing it. If a stream is closed before all data
146      * has been read, then the {@link InputStream#close()} call will read
147      * and discard remaining data (up to an implementation specific number of
148      * bytes).
149      *
150      * @return the stream from which the request body can be read
151      */
getRequestBody()152     public abstract InputStream getRequestBody();
153 
154     /**
155      * Returns a stream to which the response body must be
156      * written. {@link #sendResponseHeaders(int,long)}) must be called prior to
157      * calling this method. Multiple calls to this method (for the same exchange)
158      * will return the same stream. In order to correctly terminate each exchange,
159      * the output stream must be closed, even if no response body is being sent.
160      *
161      * <p> Closing this stream implicitly closes the {@link InputStream}
162      * returned from {@link #getRequestBody()} (if it is not already closed).
163      *
164      * <p> If the call to {@link #sendResponseHeaders(int, long)} specified a
165      * fixed response body length, then the exact number of bytes specified in
166      * that call must be written to this stream. If too many bytes are written,
167      * then the write method of {@link OutputStream} will throw an {@code IOException}.
168      * If too few bytes are written then the stream
169      * {@link OutputStream#close()} will throw an {@code IOException}.
170      * In both cases, the exchange is aborted and the underlying TCP connection
171      * closed.
172      *
173      * @return the stream to which the response body is written
174      */
getResponseBody()175     public abstract OutputStream getResponseBody();
176 
177 
178     /**
179      * Starts sending the response back to the client using the current set of
180      * response headers and the numeric response code as specified in this
181      * method. The response body length is also specified as follows. If the
182      * response length parameter is greater than {@code zero}, this specifies an
183      * exact number of bytes to send and the application must send that exact
184      * amount of data. If the response length parameter is {@code zero}, then
185      * chunked transfer encoding is used and an arbitrary amount of data may be
186      * sent. The application terminates the response body by closing the
187      * {@link OutputStream}.
188      * If response length has the value {@code -1} then no response body is
189      * being sent.
190      *
191      * <p> If the content-length response header has not already been set then
192      * this is set to the appropriate value depending on the response length
193      * parameter.
194      *
195      * <p> This method must be called prior to calling {@link #getResponseBody()}.
196      *
197      * @implNote This implementation allows the caller to instruct the
198      * server to force a connection close after the exchange terminates, by
199      * supplying a {@code Connection: close} header to the {@linkplain
200      * #getResponseHeaders() response headers} before {@code sendResponseHeaders}
201      * is called.
202      *
203      * @param rCode          the response code to send
204      * @param responseLength if {@literal > 0}, specifies a fixed response body
205      *                       length and that exact number of bytes must be written
206      *                       to the stream acquired from {@link #getResponseCode()}
207      *                       If {@literal == 0}, then chunked encoding is used,
208      *                       and an arbitrary number of bytes may be written.
209      *                       If {@literal <= -1}, then no response body length is
210      *                       specified and no response body may be written.
211      * @throws IOException   if the response headers have already been sent or an I/O error occurs
212      * @see   HttpExchange#getResponseBody()
213      */
sendResponseHeaders(int rCode, long responseLength)214     public abstract void sendResponseHeaders(int rCode, long responseLength) throws IOException;
215 
216     /**
217      * Returns the address of the remote entity invoking this request.
218      *
219      * @return the {@link InetSocketAddress} of the caller
220      */
getRemoteAddress()221     public abstract InetSocketAddress getRemoteAddress();
222 
223     /**
224      * Returns the response code, if it has already been set.
225      *
226      * @return the response code, if available. {@code -1} if not available yet.
227      */
getResponseCode()228     public abstract int getResponseCode();
229 
230     /**
231      * Returns the local address on which the request was received.
232      *
233      * @return the {@link InetSocketAddress} of the local interface
234      */
getLocalAddress()235     public abstract InetSocketAddress getLocalAddress();
236 
237     /**
238      * Returns the protocol string from the request in the form
239      * <i>protocol/majorVersion.minorVersion</i>. For example,
240      * "{@code HTTP/1.1}".
241      *
242      * @return the protocol string from the request
243      */
getProtocol()244     public abstract String getProtocol();
245 
246     /**
247      * {@link Filter} modules may store arbitrary objects with {@code HttpExchange}
248      * instances as an out-of-band communication mechanism. Other filters
249      * or the exchange handler may then access these objects.
250      *
251      * <p> Each {@code Filter} class will document the attributes which they make
252      * available.
253      *
254      * @param name the name of the attribute to retrieve
255      * @return the attribute object, or {@code null} if it does not exist
256      * @throws NullPointerException if name is {@code null}
257      */
getAttribute(String name)258     public abstract Object getAttribute(String name);
259 
260     /**
261      * {@link Filter} modules may store arbitrary objects with {@code HttpExchange}
262      * instances as an out-of-band communication mechanism. Other filters
263      * or the exchange handler may then access these objects.
264      *
265      * <p> Each {@code Filter} class will document the attributes which they make
266      * available.
267      *
268      * @param name  the name to associate with the attribute value
269      * @param value the object to store as the attribute value. {@code null}
270      *              value is permitted.
271      * @throws NullPointerException if name is {@code null}
272      */
setAttribute(String name, Object value)273     public abstract void setAttribute(String name, Object value);
274 
275     /**
276      * Used by {@linkplain com.sun.net.httpserver.Filter Filters} to wrap either
277      * (or both) of this exchange's {@link InputStream} and
278      * {@link OutputStream}, with the given filtered streams so that
279      * subsequent calls to {@link #getRequestBody()} will return the given
280      * {@code InputStream}, and calls to {@link #getResponseBody()} will return
281      * the given {@code OutputStream}. The streams provided to this call must wrap
282      * the original streams, and may be (but are not required to be) sub-classes
283      * of {@link java.io.FilterInputStream} and {@link java.io.FilterOutputStream}.
284      *
285      * @param i the filtered input stream to set as this object's
286      *          {@code Inputstream}, or {@code null} if no change
287      * @param o the filtered output stream to set as this object's
288      *          {@code Outputstream}, or {@code null} if no change
289      */
setStreams(InputStream i, OutputStream o)290     public abstract void setStreams(InputStream i, OutputStream o);
291 
292 
293     /**
294      * If an authenticator is set on the {@link HttpContext} that owns this exchange,
295      * then this method will return the {@link HttpPrincipal} that represents
296      * the authenticated user for this {@code HttpExchange}.
297      *
298      * @return the {@code HttpPrincipal}, or {@code null} if no authenticator is set
299      */
getPrincipal()300     public abstract HttpPrincipal getPrincipal();
301 }
302