Path: blob/master/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java
41159 views
/*1* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.net.httpserver;2627import java.io.IOException;28import java.io.InputStream;29import java.io.OutputStream;30import java.net.InetSocketAddress;31import java.net.URI;32import java.util.Map;3334/**35* This class encapsulates a HTTP request received and a36* response to be generated in one exchange. It provides methods37* for examining the request from the client, and for building and38* sending the response.39*40* <p> The typical life-cycle of a {@code HttpExchange} is shown in the sequence41* below:42* <ol>43* <li>{@link #getRequestMethod()} to determine the command.44* <li>{@link #getRequestHeaders()} to examine the request headers (if45* needed).46* <li>{@link #getRequestBody()} returns an {@link InputStream} for47* reading the request body. After reading the request body, the stream48* should be closed.49* <li>{@link #getResponseHeaders()} to set any response headers, except50* content-length.51* <li>{@link #sendResponseHeaders(int,long)} to send the response headers.52* Must be called before next step.53* <li>{@link #getResponseBody()} to get a {@link OutputStream} to54* send the response body. When the response body has been written, the55* stream must be closed to terminate the exchange.56* </ol>57*58* <b>Terminating exchanges</b>59* <br>Exchanges are terminated when both the request {@code InputStream} and60* response {@code OutputStream} are closed. Closing the {@code OutputStream},61* implicitly closes the {@code InputStream} (if it is not already closed).62* However, it is recommended to consume all the data from the {@code InputStream}63* before closing it. The convenience method {@link #close()} does all of these64* tasks. Closing an exchange without consuming all of the request body is not65* an error but may make the underlying TCP connection unusable for following66* exchanges. The effect of failing to terminate an exchange is undefined, but67* will typically result in resources failing to be freed/reused.68*69* @since 1.670*/7172public abstract class HttpExchange implements AutoCloseable {7374/**75* Constructor for subclasses to call.76*/77protected HttpExchange() {78}7980/**81* Returns an immutable {@link Map} containing the HTTP headers that were82* included with this request. The keys in this {@code Map} will be the header83* names, while the values will be a {@link java.util.List} of84* {@linkplain java.lang.String Strings} containing each value that was85* included (either for a header that was listed several times, or one that86* accepts a comma-delimited list of values on a single line). In either of87* these cases, the values for the header name will be presented in the88* order that they were included in the request.89*90* <p> The keys in {@code Map} are case-insensitive.91*92* @return a read-only {@code Map} which can be used to access request headers93*/94public abstract Headers getRequestHeaders();9596/**97* Returns a mutable {@link Map} into which the HTTP response headers can be98* stored and which will be transmitted as part of this response. The keys in99* the {@code Map} will be the header names, while the values must be a100* {@link java.util.List} of {@linkplain java.lang.String Strings} containing101* each value that should be included multiple times (in the order that they102* should be included).103*104* <p> The keys in {@code Map} are case-insensitive.105*106* @return a writable {@code Map} which can be used to set response headers.107*/108public abstract Headers getResponseHeaders();109110/**111* Get the request {@link URI}.112*113* @return the request {@code URI}114*/115public abstract URI getRequestURI();116117/**118* Get the request method.119*120* @return the request method121*/122public abstract String getRequestMethod();123124/**125* Get the {@link HttpContext} for this exchange.126*127* @return the {@code HttpContext}128*/129public abstract HttpContext getHttpContext();130131/**132* Ends this exchange by doing the following in sequence:133* <ol>134* <li> close the request {@link InputStream}, if not already closed.135* <li> close the response {@link OutputStream}, if not already closed.136* </ol>137*/138public abstract void close();139140/**141* Returns a stream from which the request body can be read.142* Multiple calls to this method will return the same stream.143* It is recommended that applications should consume (read) all of the data144* from this stream before closing it. If a stream is closed before all data145* has been read, then the {@link InputStream#close()} call will read146* and discard remaining data (up to an implementation specific number of147* bytes).148*149* @return the stream from which the request body can be read150*/151public abstract InputStream getRequestBody();152153/**154* Returns a stream to which the response body must be155* written. {@link #sendResponseHeaders(int,long)}) must be called prior to156* calling this method. Multiple calls to this method (for the same exchange)157* will return the same stream. In order to correctly terminate each exchange,158* the output stream must be closed, even if no response body is being sent.159*160* <p> Closing this stream implicitly closes the {@link InputStream}161* returned from {@link #getRequestBody()} (if it is not already closed).162*163* <p> If the call to {@link #sendResponseHeaders(int, long)} specified a164* fixed response body length, then the exact number of bytes specified in165* that call must be written to this stream. If too many bytes are written,166* then the write method of {@link OutputStream} will throw an {@code IOException}.167* If too few bytes are written then the stream168* {@link OutputStream#close()} will throw an {@code IOException}.169* In both cases, the exchange is aborted and the underlying TCP connection170* closed.171*172* @return the stream to which the response body is written173*/174public abstract OutputStream getResponseBody();175176177/**178* Starts sending the response back to the client using the current set of179* response headers and the numeric response code as specified in this180* method. The response body length is also specified as follows. If the181* response length parameter is greater than {@code zero}, this specifies an182* exact number of bytes to send and the application must send that exact183* amount of data. If the response length parameter is {@code zero}, then184* chunked transfer encoding is used and an arbitrary amount of data may be185* sent. The application terminates the response body by closing the186* {@link OutputStream}.187* If response length has the value {@code -1} then no response body is188* being sent.189*190* <p> If the content-length response header has not already been set then191* this is set to the appropriate value depending on the response length192* parameter.193*194* <p> This method must be called prior to calling {@link #getResponseBody()}.195*196* @implNote This implementation allows the caller to instruct the197* server to force a connection close after the exchange terminates, by198* supplying a {@code Connection: close} header to the {@linkplain199* #getResponseHeaders() response headers} before {@code sendResponseHeaders}200* is called.201*202* @param rCode the response code to send203* @param responseLength if {@literal > 0}, specifies a fixed response body204* length and that exact number of bytes must be written205* to the stream acquired from {@link #getResponseCode()}206* If {@literal == 0}, then chunked encoding is used,207* and an arbitrary number of bytes may be written.208* If {@literal <= -1}, then no response body length is209* specified and no response body may be written.210* @throws IOException if the response headers have already been sent or an I/O error occurs211* @see HttpExchange#getResponseBody()212*/213public abstract void sendResponseHeaders(int rCode, long responseLength) throws IOException;214215/**216* Returns the address of the remote entity invoking this request.217*218* @return the {@link InetSocketAddress} of the caller219*/220public abstract InetSocketAddress getRemoteAddress();221222/**223* Returns the response code, if it has already been set.224*225* @return the response code, if available. {@code -1} if not available yet.226*/227public abstract int getResponseCode();228229/**230* Returns the local address on which the request was received.231*232* @return the {@link InetSocketAddress} of the local interface233*/234public abstract InetSocketAddress getLocalAddress();235236/**237* Returns the protocol string from the request in the form238* <i>protocol/majorVersion.minorVersion</i>. For example,239* "{@code HTTP/1.1}".240*241* @return the protocol string from the request242*/243public abstract String getProtocol();244245/**246* {@link Filter} modules may store arbitrary objects with {@code HttpExchange}247* instances as an out-of-band communication mechanism. Other filters248* or the exchange handler may then access these objects.249*250* <p> Each {@code Filter} class will document the attributes which they make251* available.252*253* @param name the name of the attribute to retrieve254* @return the attribute object, or {@code null} if it does not exist255* @throws NullPointerException if name is {@code null}256*/257public abstract Object getAttribute(String name);258259/**260* {@link Filter} modules may store arbitrary objects with {@code HttpExchange}261* instances as an out-of-band communication mechanism. Other filters262* or the exchange handler may then access these objects.263*264* <p> Each {@code Filter} class will document the attributes which they make265* available.266*267* @param name the name to associate with the attribute value268* @param value the object to store as the attribute value. {@code null}269* value is permitted.270* @throws NullPointerException if name is {@code null}271*/272public abstract void setAttribute(String name, Object value);273274/**275* Used by {@linkplain com.sun.net.httpserver.Filter Filters} to wrap either276* (or both) of this exchange's {@link InputStream} and277* {@link OutputStream}, with the given filtered streams so that278* subsequent calls to {@link #getRequestBody()} will return the given279* {@code InputStream}, and calls to {@link #getResponseBody()} will return280* the given {@code OutputStream}. The streams provided to this call must wrap281* the original streams, and may be (but are not required to be) sub-classes282* of {@link java.io.FilterInputStream} and {@link java.io.FilterOutputStream}.283*284* @param i the filtered input stream to set as this object's285* {@code Inputstream}, or {@code null} if no change286* @param o the filtered output stream to set as this object's287* {@code Outputstream}, or {@code null} if no change288*/289public abstract void setStreams(InputStream i, OutputStream o);290291292/**293* If an authenticator is set on the {@link HttpContext} that owns this exchange,294* then this method will return the {@link HttpPrincipal} that represents295* the authenticated user for this {@code HttpExchange}.296*297* @return the {@code HttpPrincipal}, or {@code null} if no authenticator is set298*/299public abstract HttpPrincipal getPrincipal();300}301302303