1 /* 2 * Copyright (c) 2005, 2015, 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 javax.xml.ws.spi.http; 27 28 import javax.xml.ws.handler.MessageContext; 29 import java.io.InputStream; 30 import java.io.OutputStream; 31 import java.io.IOException; 32 import java.net.InetSocketAddress; 33 import java.util.List; 34 import java.util.Map; 35 import java.util.Set; 36 import java.security.Principal; 37 38 /** 39 * This class encapsulates a HTTP request received and a 40 * response to be generated in one exchange. It provides methods 41 * for examining the request from the client, and for building and 42 * sending the response. 43 * <p> 44 * A {@code HttpExchange} must be closed to free or reuse 45 * underlying resources. The effect of failing to close an exchange 46 * is undefined. 47 * 48 * @author Jitendra Kotamraju 49 * @since 1.7, JAX-WS 2.2 50 */ 51 public abstract class HttpExchange { 52 53 /** 54 * Standard property: cipher suite value when the request is received 55 * over HTTPS 56 * <p>Type: String 57 */ 58 public static final String REQUEST_CIPHER_SUITE = 59 "javax.xml.ws.spi.http.request.cipher.suite"; 60 61 /** 62 * Standard property: bit size of the algorithm when the request is 63 * received over HTTPS 64 * <p>Type: Integer 65 */ 66 public static final String REQUEST_KEY_SIZE = 67 "javax.xml.ws.spi.http.request.key.size"; 68 69 /** 70 * Standard property: A SSL certificate, if any, associated with the request 71 * 72 * <p>Type: java.security.cert.X509Certificate[] 73 * The order of this array is defined as being in ascending order of trust. 74 * The first certificate in the chain is the one set by the client, the next 75 * is the one used to authenticate the first, and so on. 76 */ 77 public static final String REQUEST_X509CERTIFICATE = 78 "javax.xml.ws.spi.http.request.cert.X509Certificate"; 79 80 /** 81 * Returns an immutable Map containing the HTTP headers that were 82 * included with this request. The keys in this Map will be the header 83 * names, while the values will be a List of Strings containing each value 84 * that was included (either for a header that was listed several times, 85 * or one that accepts a comma-delimited list of values on a single line). 86 * In either of these cases, the values for the header name will be 87 * presented in the order that they were included in the request. 88 * <p> 89 * The keys in Map are case-insensitive. 90 * 91 * @return an immutable Map which can be used to access request headers 92 */ 93 public abstract Map<String, List<String>> getRequestHeaders(); 94 95 /** 96 * Returns the value of the specified request header. If the request 97 * did not include a header of the specified name, this method returns 98 * null. If there are multiple headers with the same name, this method 99 * returns the first header in the request. The header name is 100 * case-insensitive. This is a convienence method to get a header 101 * (instead of using the {@link #getRequestHeaders}). 102 * 103 * @param name the name of the request header 104 * @return returns the value of the requested header, 105 * or null if the request does not have a header of that name 106 */ 107 public abstract String getRequestHeader(String name); 108 109 /** 110 * Returns a mutable Map into which the HTTP response headers can be stored 111 * and which will be transmitted as part of this response. The keys in the 112 * Map will be the header names, while the values must be a List of Strings 113 * containing each value that should be included multiple times 114 * (in the order that they should be included). 115 * <p> 116 * The keys in Map are case-insensitive. 117 * 118 * @return a mutable Map which can be used to set response headers. 119 */ 120 public abstract Map<String, List<String>> getResponseHeaders(); 121 122 /** 123 * Adds a response header with the given name and value. This method 124 * allows a response header to have multiple values. This is a 125 * convenience method to add a response header(instead of using the 126 * {@link #getResponseHeaders()}). 127 * 128 * @param name the name of the header 129 * @param value the additional header value. If it contains octet string, 130 * it should be encoded according to 131 * RFC 2047 (http://www.ietf.org/rfc/rfc2047.txt) 132 * 133 * @see #getResponseHeaders 134 */ 135 public abstract void addResponseHeader(String name, String value); 136 137 /** 138 * Returns the part of the request's URI from the protocol 139 * name up to the query string in the first line of the HTTP request. 140 * Container doesn't decode this string. 141 * 142 * @return the request URI 143 */ 144 public abstract String getRequestURI(); 145 146 /** 147 * Returns the context path of all the endpoints in an application. 148 * This path is the portion of the request URI that indicates the 149 * context of the request. The context path always comes first in a 150 * request URI. The path starts with a "/" character but does not 151 * end with a "/" character. If this method returns "", the request 152 * is for default context. The container does not decode this string. 153 * 154 * <p> 155 * Context path is used in computing the endpoint address. See 156 * {@link HttpContext#getPath} 157 * 158 * @return context path of all the endpoints in an application 159 * @see HttpContext#getPath 160 */ 161 public abstract String getContextPath(); 162 163 /** 164 * Get the HTTP request method 165 * 166 * @return the request method 167 */ 168 public abstract String getRequestMethod(); 169 170 /** 171 * Returns a {@link HttpContext} for this exchange. 172 * Container matches the request with the associated Endpoint's HttpContext 173 * 174 * @return the HttpContext for this exchange 175 */ 176 public abstract HttpContext getHttpContext(); 177 178 /** 179 * This must be called to end an exchange. Container takes care of 180 * closing request and response streams. This must be called so that 181 * the container can free or reuse underlying resources. 182 * 183 * @throws IOException if any i/o error 184 */ 185 public abstract void close() throws IOException; 186 187 /** 188 * Returns a stream from which the request body can be read. 189 * Multiple calls to this method will return the same stream. 190 * 191 * @return the stream from which the request body can be read. 192 * @throws IOException if any i/o error during request processing 193 */ 194 public abstract InputStream getRequestBody() throws IOException; 195 196 /** 197 * Returns a stream to which the response body must be 198 * written. {@link #setStatus}) must be called prior to calling 199 * this method. Multiple calls to this method (for the same exchange) 200 * will return the same stream. 201 * 202 * @return the stream to which the response body is written 203 * @throws IOException if any i/o error during response processing 204 */ 205 public abstract OutputStream getResponseBody() throws IOException; 206 207 /** 208 * Sets the HTTP status code for the response. 209 * 210 * <p> 211 * This method must be called prior to calling {@link #getResponseBody}. 212 * 213 * @param status the response code to send 214 * @see #getResponseBody 215 */ 216 public abstract void setStatus(int status); 217 218 /** 219 * Returns the unresolved address of the remote entity invoking 220 * this request. 221 * 222 * @return the InetSocketAddress of the caller 223 */ 224 public abstract InetSocketAddress getRemoteAddress(); 225 226 /** 227 * Returns the unresolved local address on which the request was received. 228 * 229 * @return the InetSocketAddress of the local interface 230 */ 231 public abstract InetSocketAddress getLocalAddress(); 232 233 /** 234 * Returns the protocol string from the request in the form 235 * <i>protocol/majorVersion.minorVersion</i>. For example, 236 * "HTTP/1.1" 237 * 238 * @return the protocol string from the request 239 */ 240 public abstract String getProtocol(); 241 242 /** 243 * Returns the name of the scheme used to make this request, 244 * for example: http, or https. 245 * 246 * @return name of the scheme used to make this request 247 */ 248 public abstract String getScheme(); 249 250 /** 251 * Returns the extra path information that follows the web service 252 * path but precedes the query string in the request URI and will start 253 * with a "/" character. 254 * 255 * <p> 256 * This can be used for {@link MessageContext#PATH_INFO} 257 * 258 * @return decoded extra path information of web service. 259 * It is the path that comes 260 * after the web service path but before the query string in the 261 * request URI 262 * <tt>null</tt> if there is no extra path in the request URI 263 */ 264 public abstract String getPathInfo(); 265 266 /** 267 * Returns the query string that is contained in the request URI 268 * after the path. 269 * 270 * <p> 271 * This can be used for {@link MessageContext#QUERY_STRING} 272 * 273 * @return undecoded query string of request URI, or 274 * <tt>null</tt> if the request URI doesn't have one 275 */ 276 public abstract String getQueryString(); 277 278 /** 279 * Returns an attribute that is associated with this 280 * {@code HttpExchange}. JAX-WS handlers and endpoints may then 281 * access the attribute via {@link MessageContext}. 282 * <p> 283 * Servlet containers must expose {@link MessageContext#SERVLET_CONTEXT}, 284 * {@link MessageContext#SERVLET_REQUEST}, and 285 * {@link MessageContext#SERVLET_RESPONSE} 286 * as attributes. 287 * 288 * <p>If the request has been received by the container using HTTPS, the 289 * following information must be exposed as attributes. These attributes 290 * are {@link #REQUEST_CIPHER_SUITE}, and {@link #REQUEST_KEY_SIZE}. 291 * If there is a SSL certificate associated with the request, it must 292 * be exposed using {@link #REQUEST_X509CERTIFICATE} 293 * 294 * @param name attribute name 295 * @return the attribute value, or <tt>null</tt> if the attribute doesn't 296 * exist 297 */ 298 public abstract Object getAttribute(String name); 299 300 /** 301 * Gives all the attribute names that are associated with 302 * this {@code HttpExchange}. 303 * 304 * @return set of all attribute names 305 * @see #getAttribute(String) 306 */ 307 public abstract Set<String> getAttributeNames(); 308 309 /** 310 * Returns the {@link Principal} that represents the authenticated 311 * user for this {@code HttpExchange}. 312 * 313 * @return Principal for an authenticated user, or 314 * <tt>null</tt> if not authenticated 315 */ 316 public abstract Principal getUserPrincipal(); 317 318 /** 319 * Indicates whether an authenticated user is included in the specified 320 * logical "role". 321 * 322 * @param role specifies the name of the role 323 * @return <tt>true</tt> if the user making this request belongs to a 324 * given role 325 */ 326 public abstract boolean isUserInRole(String role); 327 328 }