1 /*
   2  * Copyright (c) 2005, 2013, 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.*;
  29 import java.nio.*;
  30 import java.nio.channels.*;
  31 import java.net.*;
  32 import javax.net.ssl.*;
  33 import java.util.*;
  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  * <p>
  41  * The typical life-cycle of a HttpExchange is shown in the sequence
  42  * below.
  43  * <ol><li>{@link #getRequestMethod()} to determine the command
  44  * <li>{@link #getRequestHeaders()} to examine the request headers (if needed)
  45  * <li>{@link #getRequestBody()} returns a {@link java.io.InputStream} for reading the request body.
  46  *     After reading the request body, the stream is close.
  47  * <li>{@link #getResponseHeaders()} to set any response headers, except content-length
  48  * <li>{@link #sendResponseHeaders(int,long)} to send the response headers. Must be called before
  49  * next step.
  50  * <li>{@link #getResponseBody()} to get a {@link java.io.OutputStream} to send the response body.
  51  *      When the response body has been written, the stream must be closed to terminate the exchange.
  52  * </ol>
  53  * <b>Terminating exchanges</b>
  54  * <br>
  55  * Exchanges are terminated when both the request InputStream and response OutputStream are closed.
  56  * Closing the OutputStream, implicitly closes the InputStream (if it is not already closed).
  57  * However, it is recommended
  58  * to consume all the data from the InputStream before closing it.
  59  * The convenience method {@link #close()} does all of these tasks.
  60  * Closing an exchange without consuming all of the request body is not an error
  61  * but may make the underlying TCP connection unusable for following exchanges.
  62  * The effect of failing to terminate an exchange is undefined, but will typically
  63  * result in resources failing to be freed/reused.
  64  * @since 1.6
  65  */
  66 
  67 @jdk.Exported
  68 public abstract class HttpExchange {
  69 
  70     protected HttpExchange () {
  71     }
  72 
  73     /**
  74      * Returns an immutable Map containing the HTTP headers that were
  75      * included with this request. The keys in this Map will be the header
  76      * names, while the values will be a List of Strings containing each value
  77      * that was included (either for a header that was listed several times,
  78      * or one that accepts a comma-delimited list of values on a single line).
  79      * In either of these cases, the values for the header name will be
  80      * presented in the order that they were included in the request.
  81      * <p>
  82      * The keys in Map are case-insensitive.
  83      * @return a read-only Map which can be used to access request headers
  84      */
  85     public abstract Headers getRequestHeaders () ;
  86 
  87     /**
  88      * Returns a mutable Map into which the HTTP response headers can be stored
  89      * and which will be transmitted as part of this response. The keys in the
  90      * Map will be the header names, while the values must be a List of Strings
  91      * containing each value that should be included multiple times
  92      * (in the order that they should be included).
  93      * <p>
  94      * The keys in Map are case-insensitive.
  95      * @return a writable Map which can be used to set response headers.
  96      */
  97     public abstract Headers getResponseHeaders () ;
  98 
  99     /**
 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:<ol>
 120      * <li>close the request InputStream, if not already closed;</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     /**
 162      * Starts sending the response back to the client using the current set of response headers
 163      * and the numeric response code as specified in this method. The response body length is also specified
 164      * as follows. If the response length parameter is greater than zero, this specifies an exact
 165      * number of bytes to send and the application must send that exact amount of data.
 166      * If the response length parameter is {@code zero}, then chunked transfer encoding is
 167      * used and an arbitrary amount of data may be sent. The application terminates the
 168      * response body by closing the OutputStream. If response length has the value {@code -1}
 169      * then no response body is being sent.
 170      * <p>
 171      * If the content-length response header has not already been set then
 172      * this is set to the appropriate value depending on the response length parameter.
 173      * <p>
 174      * This method must be called prior to calling {@link #getResponseBody()}.
 175      * @param rCode the response code to send
 176      * @param responseLength if {@literal > 0}, specifies a fixed response
 177      *        body length and that exact number of bytes must be written
 178      *        to the stream acquired from getResponseBody(), or else
 179      *        if equal to 0, then chunked encoding is used,
 180      *        and an arbitrary number of bytes may be written.
 181      *        if {@literal <= -1}, then no response body length is specified and
 182      *        no response body may be written.
 183      * @see HttpExchange#getResponseBody()
 184      */
 185     public abstract void sendResponseHeaders (int rCode, 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} 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}
 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}
 235      * value is permitted.
 236      * @throws NullPointerException if name is {@code null}
 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} if no change.
 252      * @param o the filtered output stream to set as this object's outputstream,
 253      *          or {@code null} if no change.
 254      */
 255     public abstract void setStreams (InputStream i, OutputStream o);
 256 
 257 
 258     /**
 259      * If an authenticator is set on the HttpContext that owns this exchange,
 260      * then this method will return the {@link HttpPrincipal} that represents
 261      * the authenticated user for this HttpExchange.
 262      * @return the HttpPrincipal, or {@code null} if no authenticator is set.
 263      */
 264     public abstract HttpPrincipal getPrincipal ();
 265 }