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