src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java
changeset 47216 71c04702a3d5
parent 34894 3248b89d1921
child 53720 3e451bff6f7f
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     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 public abstract class HttpExchange {
       
    68 
       
    69     protected HttpExchange () {
       
    70     }
       
    71 
       
    72     /**
       
    73      * Returns an immutable Map containing the HTTP headers that were
       
    74      * included with this request. The keys in this Map will be the header
       
    75      * names, while the values will be a List of Strings containing each value
       
    76      * that was included (either for a header that was listed several times,
       
    77      * or one that accepts a comma-delimited list of values on a single line).
       
    78      * In either of these cases, the values for the header name will be
       
    79      * presented in the order that they were included in the request.
       
    80      * <p>
       
    81      * The keys in Map are case-insensitive.
       
    82      * @return a read-only Map which can be used to access request headers
       
    83      */
       
    84     public abstract Headers getRequestHeaders () ;
       
    85 
       
    86     /**
       
    87      * Returns a mutable Map into which the HTTP response headers can be stored
       
    88      * and which will be transmitted as part of this response. The keys in the
       
    89      * Map will be the header names, while the values must be a List of Strings
       
    90      * containing each value that should be included multiple times
       
    91      * (in the order that they should be included).
       
    92      * <p>
       
    93      * The keys in Map are case-insensitive.
       
    94      * @return a writable Map which can be used to set response headers.
       
    95      */
       
    96     public abstract Headers getResponseHeaders () ;
       
    97 
       
    98     /**
       
    99      * Get the request URI
       
   100      *
       
   101      * @return the request URI
       
   102      */
       
   103     public abstract URI getRequestURI () ;
       
   104 
       
   105     /**
       
   106      * Get the request method
       
   107      * @return the request method
       
   108      */
       
   109     public abstract String getRequestMethod ();
       
   110 
       
   111     /**
       
   112      * Get the HttpContext for this exchange
       
   113      * @return the HttpContext
       
   114      */
       
   115     public abstract HttpContext getHttpContext ();
       
   116 
       
   117     /**
       
   118      * Ends this exchange by doing the following in sequence:<ol>
       
   119      * <li>close the request InputStream, if not already closed;</li>
       
   120      * <li>close the response OutputStream, if not already closed.</li>
       
   121      * </ol>
       
   122      */
       
   123     public abstract void close () ;
       
   124 
       
   125     /**
       
   126      * returns a stream from which the request body can be read.
       
   127      * Multiple calls to this method will return the same stream.
       
   128      * It is recommended that applications should consume (read) all of the
       
   129      * data from this stream before closing it. If a stream is closed
       
   130      * before all data has been read, then the close() call will
       
   131      * read and discard remaining data (up to an implementation specific
       
   132      * number of bytes).
       
   133      * @return the stream from which the request body can be read.
       
   134      */
       
   135     public abstract InputStream getRequestBody () ;
       
   136 
       
   137     /**
       
   138      * returns a stream to which the response body must be
       
   139      * written. {@link #sendResponseHeaders(int,long)}) must be called prior to calling
       
   140      * this method. Multiple calls to this method (for the same exchange)
       
   141      * will return the same stream. In order to correctly terminate
       
   142      * each exchange, the output stream must be closed, even if no
       
   143      * response body is being sent.
       
   144      * <p>
       
   145      * Closing this stream implicitly
       
   146      * closes the InputStream returned from {@link #getRequestBody()}
       
   147      * (if it is not already closed).
       
   148      * <P>
       
   149      * If the call to sendResponseHeaders() specified a fixed response
       
   150      * body length, then the exact number of bytes specified in that
       
   151      * call must be written to this stream. If too many bytes are written,
       
   152      * then write() will throw an IOException. If too few bytes are written
       
   153      * then the stream close() will throw an IOException. In both cases,
       
   154      * the exchange is aborted and the underlying TCP connection closed.
       
   155      * @return the stream to which the response body is written
       
   156      */
       
   157     public abstract OutputStream getResponseBody () ;
       
   158 
       
   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}, 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}
       
   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 appropriate 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 {@literal > 0}, specifies a fixed response
       
   176      *        body length 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 {@literal <= -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, long responseLength) throws IOException ;
       
   185 
       
   186     /**
       
   187      * Returns the address of the remote entity invoking this request
       
   188      * @return the InetSocketAddress of the caller
       
   189      */
       
   190     public abstract InetSocketAddress getRemoteAddress ();
       
   191 
       
   192     /**
       
   193      * Returns the response code, if it has already been set
       
   194      * @return the response code, if available. {@code -1} if not available yet.
       
   195      */
       
   196     public abstract int getResponseCode ();
       
   197 
       
   198     /**
       
   199      * Returns the local address on which the request was received
       
   200      * @return the InetSocketAddress of the local interface
       
   201      */
       
   202     public abstract InetSocketAddress getLocalAddress ();
       
   203 
       
   204     /**
       
   205      * Returns the protocol string from the request in the form
       
   206      * <i>protocol/majorVersion.minorVersion</i>. For example,
       
   207      * "HTTP/1.1"
       
   208      * @return the protocol string from the request
       
   209      */
       
   210     public abstract String getProtocol ();
       
   211 
       
   212     /**
       
   213      * Filter modules may store arbitrary objects with HttpExchange
       
   214      * instances as an out-of-band communication mechanism. Other Filters
       
   215      * or the exchange handler may then access these objects.
       
   216      * <p>
       
   217      * Each Filter class will document the attributes which they make
       
   218      * available.
       
   219      * @param name the name of the attribute to retrieve
       
   220      * @return the attribute object, or null if it does not exist
       
   221      * @throws NullPointerException if name is {@code null}
       
   222      */
       
   223     public abstract Object getAttribute (String name) ;
       
   224 
       
   225     /**
       
   226      * Filter modules may store arbitrary objects with HttpExchange
       
   227      * instances as an out-of-band communication mechanism. Other Filters
       
   228      * or the exchange handler may then access these objects.
       
   229      * <p>
       
   230      * Each Filter class will document the attributes which they make
       
   231      * available.
       
   232      * @param name the name to associate with the attribute value
       
   233      * @param value the object to store as the attribute value. {@code null}
       
   234      * value is permitted.
       
   235      * @throws NullPointerException if name is {@code null}
       
   236      */
       
   237     public abstract void setAttribute (String name, Object value) ;
       
   238 
       
   239     /**
       
   240      * Used by Filters to wrap either (or both) of this exchange's InputStream
       
   241      * and OutputStream, with the given filtered streams so
       
   242      * that subsequent calls to {@link #getRequestBody()} will
       
   243      * return the given {@link java.io.InputStream}, and calls to
       
   244      * {@link #getResponseBody()} will return the given
       
   245      * {@link java.io.OutputStream}. The streams provided to this
       
   246      * call must wrap the original streams, and may be (but are not
       
   247      * required to be) sub-classes of {@link java.io.FilterInputStream}
       
   248      * and {@link java.io.FilterOutputStream}.
       
   249      * @param i the filtered input stream to set as this object's inputstream,
       
   250      *          or {@code null} if no change.
       
   251      * @param o the filtered output stream to set as this object's outputstream,
       
   252      *          or {@code null} if no change.
       
   253      */
       
   254     public abstract void setStreams (InputStream i, OutputStream o);
       
   255 
       
   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} if no authenticator is set.
       
   262      */
       
   263     public abstract HttpPrincipal getPrincipal ();
       
   264 }