aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.ws.transport.http; aoqi@0: aoqi@0: import com.oracle.webservices.internal.api.message.BasePropertySet; aoqi@0: import com.oracle.webservices.internal.api.message.PropertySet; aoqi@0: import com.sun.istack.internal.NotNull; aoqi@0: import com.sun.istack.internal.Nullable; aoqi@0: import com.sun.xml.internal.ws.api.message.Packet; aoqi@0: import com.sun.xml.internal.ws.api.server.WebServiceContextDelegate; aoqi@0: aoqi@0: import javax.xml.ws.WebServiceContext; aoqi@0: import java.io.IOException; aoqi@0: import java.io.InputStream; aoqi@0: import java.io.OutputStream; aoqi@0: import java.net.HttpURLConnection; aoqi@0: import java.security.Principal; aoqi@0: import java.util.Collections; aoqi@0: import java.util.List; aoqi@0: import java.util.Map; aoqi@0: import java.util.Set; aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * The view of an HTTP exchange from the point of view of JAX-WS. aoqi@0: * aoqi@0: *

aoqi@0: * Different HTTP server layer uses different implementations of this class aoqi@0: * so that JAX-WS can be shielded from individuality of such layers. aoqi@0: * This is an interface implemented as an abstract class, so that aoqi@0: * future versions of the JAX-WS RI can add new methods. aoqi@0: * aoqi@0: *

aoqi@0: * This class extends {@link PropertySet} so that a transport can aoqi@0: * expose its properties to the application and pipes. (This object aoqi@0: * will be added to {@link Packet#addSatellite(PropertySet)}.) aoqi@0: * aoqi@0: * @author Jitendra Kotamraju aoqi@0: */ aoqi@0: public abstract class WSHTTPConnection extends BasePropertySet { aoqi@0: aoqi@0: public static final int OK=200; aoqi@0: public static final int ONEWAY=202; aoqi@0: public static final int UNSUPPORTED_MEDIA=415; aoqi@0: public static final int MALFORMED_XML=400; aoqi@0: public static final int INTERNAL_ERR=500; aoqi@0: aoqi@0: /** aoqi@0: * Overwrites all the HTTP response headers written thus far. aoqi@0: * aoqi@0: *

aoqi@0: * The implementation should copy the contents of the {@link Map}, aoqi@0: * rather than retaining a reference. The {@link Map} passed as a aoqi@0: * parameter may change after this method is invoked. aoqi@0: * aoqi@0: *

aoqi@0: * This method may be called repeatedly, although in normal use aoqi@0: * case that's rare (so the implementation is encourage to take aoqi@0: * advantage of this usage pattern to improve performance, if possible.) aoqi@0: * aoqi@0: *

aoqi@0: * Initially, no header is set. aoqi@0: * aoqi@0: *

aoqi@0: * This parameter is usually exposed to {@link WebServiceContext} aoqi@0: * as {@link Packet#OUTBOUND_TRANSPORT_HEADERS}, and thus it aoqi@0: * should ignore Content-Type and Content-Length headers. aoqi@0: * aoqi@0: * @param headers aoqi@0: * See {@link HttpURLConnection#getHeaderFields()} for the format. aoqi@0: * This parameter may not be null, but since the user application aoqi@0: * code may invoke this method, a graceful error checking with aoqi@0: * an helpful error message should be provided if it's actually null. aoqi@0: * @see #setContentTypeResponseHeader(String) aoqi@0: */ aoqi@0: public abstract void setResponseHeaders(@NotNull Map> headers); aoqi@0: aoqi@0: public void setResponseHeader(String key, String value) { aoqi@0: setResponseHeader(key, Collections.singletonList(value)); aoqi@0: } aoqi@0: aoqi@0: public abstract void setResponseHeader(String key, List value); aoqi@0: aoqi@0: /** aoqi@0: * Sets the "Content-Type" header. aoqi@0: * aoqi@0: *

aoqi@0: * If the Content-Type header has already been set, this method will overwrite aoqi@0: * the previously set value. If not, this method adds it. aoqi@0: * aoqi@0: *

aoqi@0: * Note that this method and {@link #setResponseHeaders(java.util.Map)} aoqi@0: * may be invoked in any arbitrary order. aoqi@0: * aoqi@0: * @param value aoqi@0: * strings like "application/xml; charset=UTF-8" or aoqi@0: * "image/jpeg". aoqi@0: */ aoqi@0: public abstract void setContentTypeResponseHeader(@NotNull String value); aoqi@0: aoqi@0: /** aoqi@0: * Sets the HTTP response code like {@link #OK}. aoqi@0: * aoqi@0: *

aoqi@0: * While JAX-WS processes a {@link WSHTTPConnection}, it aoqi@0: * will at least call this method once to set a valid HTTP response code. aoqi@0: * Note that this method may be invoked multiple times (from user code), aoqi@0: * so do not consider the value to be final until {@link #getOutput()} aoqi@0: * is invoked. aoqi@0: */ aoqi@0: aoqi@0: public abstract void setStatus(int status); aoqi@0: aoqi@0: /** aoqi@0: * Gets the last value set by {@link #setStatus(int)}. aoqi@0: * aoqi@0: * @return aoqi@0: * if {@link #setStatus(int)} has not been invoked yet, aoqi@0: * return 0. aoqi@0: */ aoqi@0: // I know this is ugly method! aoqi@0: public abstract int getStatus(); aoqi@0: aoqi@0: /** aoqi@0: * Transport's underlying input stream. aoqi@0: * aoqi@0: *

aoqi@0: * This method will be invoked at most once by the JAX-WS RI to aoqi@0: * read the request body. If there's no request body, this method aoqi@0: * should return an empty {@link InputStream}. aoqi@0: * aoqi@0: * @return aoqi@0: * the stream from which the request body will be read. aoqi@0: */ aoqi@0: public abstract @NotNull InputStream getInput() throws IOException; aoqi@0: aoqi@0: /** aoqi@0: * Transport's underlying output stream aoqi@0: * aoqi@0: *

aoqi@0: * This method will be invoked exactly once by the JAX-WS RI aoqi@0: * to start writing the response body (unless the processing aborts abnormally.) aoqi@0: * Even if there's no response body to write, this method will aoqi@0: * still be invoked only to be closed immediately. aoqi@0: * aoqi@0: *

aoqi@0: * Once this method is called, the status code and response aoqi@0: * headers will never change (IOW {@link #setStatus(int)}, aoqi@0: * {@link #setResponseHeaders}, and {@link #setContentTypeResponseHeader(String)} aoqi@0: * will never be invoked. aoqi@0: */ aoqi@0: public abstract @NotNull OutputStream getOutput() throws IOException; aoqi@0: aoqi@0: /** aoqi@0: * Returns the {@link WebServiceContextDelegate} for this connection. aoqi@0: */ aoqi@0: public abstract @NotNull WebServiceContextDelegate getWebServiceContextDelegate(); aoqi@0: aoqi@0: /** aoqi@0: * HTTP request method, such as "GET" or "POST". aoqi@0: */ aoqi@0: public abstract @NotNull String getRequestMethod(); aoqi@0: aoqi@0: /** aoqi@0: * HTTP request headers. aoqi@0: * aoqi@0: * @deprecated aoqi@0: * This is a potentially expensive operation. aoqi@0: * Programs that want to access HTTP headers should consider using aoqi@0: * other methods such as {@link #getRequestHeader(String)}. aoqi@0: * aoqi@0: * @return aoqi@0: * can be empty but never null. aoqi@0: */ aoqi@0: public abstract @NotNull Map> getRequestHeaders(); aoqi@0: aoqi@0: /** aoqi@0: * HTTP request header names. aoqi@0: * aoqi@0: * @deprecated aoqi@0: * This is a potentially expensive operation. aoqi@0: * Programs that want to access HTTP headers should consider using aoqi@0: * other methods such as {@link #getRequestHeader(String)}. aoqi@0: * aoqi@0: * @return aoqi@0: * can be empty but never null. aoqi@0: */ aoqi@0: public abstract @NotNull Set getRequestHeaderNames(); aoqi@0: aoqi@0: /** aoqi@0: * @return aoqi@0: * HTTP response headers. aoqi@0: */ aoqi@0: public abstract Map> getResponseHeaders(); aoqi@0: aoqi@0: /** aoqi@0: * Gets an HTTP request header. aoqi@0: * aoqi@0: *

aoqi@0: * if multiple headers are present, this method returns one of them. aoqi@0: * (The implementation is free to choose which one it returns.) aoqi@0: * aoqi@0: * @return aoqi@0: * null if no header exists. aoqi@0: */ aoqi@0: public abstract @Nullable String getRequestHeader(@NotNull String headerName); aoqi@0: aoqi@0: /** aoqi@0: * Gets an HTTP request header. aoqi@0: * aoqi@0: * @return aoqi@0: * null if no header exists. aoqi@0: */ aoqi@0: public abstract @Nullable List getRequestHeaderValues(@NotNull String headerName); aoqi@0: aoqi@0: /** aoqi@0: * HTTP Query string, such as "foo=bar", or null if none exists. aoqi@0: */ aoqi@0: public abstract @Nullable String getQueryString(); aoqi@0: aoqi@0: /** aoqi@0: * Extra portion of the request URI after the end of the expected address of the service aoqi@0: * but before the query string aoqi@0: */ aoqi@0: public abstract @Nullable String getPathInfo(); aoqi@0: aoqi@0: /** aoqi@0: * Requested path. A string like "/foo/bar/baz" aoqi@0: */ aoqi@0: public abstract @NotNull String getRequestURI(); aoqi@0: aoqi@0: /** aoqi@0: * Requested scheme, e.g. "http" or "https" aoqi@0: */ aoqi@0: public abstract @NotNull String getRequestScheme(); aoqi@0: aoqi@0: /** aoqi@0: * Server name aoqi@0: */ aoqi@0: public abstract @NotNull String getServerName(); aoqi@0: aoqi@0: /** aoqi@0: * Server port aoqi@0: */ aoqi@0: public abstract int getServerPort(); aoqi@0: aoqi@0: /** aoqi@0: * Portion of the request URI that groups related service addresses. The value, if non-empty, will aoqi@0: * always begin with '/', but will never end with '/'. Environments that do not support aoqi@0: * context paths must return an empty string. aoqi@0: */ aoqi@0: public @NotNull String getContextPath() { aoqi@0: return ""; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Environment specific context , if available aoqi@0: */ aoqi@0: public Object getContext() { aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Gets the absolute URL up to the context path. aoqi@0: * @return aoqi@0: * String like "http://myhost/myapp" aoqi@0: * @since 2.1.2 aoqi@0: */ aoqi@0: public @NotNull String getBaseAddress() { aoqi@0: throw new UnsupportedOperationException(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Whether connection is HTTPS or not aoqi@0: * aoqi@0: * @return if the received request is on HTTPS, return true aoqi@0: * else false aoqi@0: */ aoqi@0: public abstract boolean isSecure(); aoqi@0: aoqi@0: /** aoqi@0: * User principal associated with the request aoqi@0: * aoqi@0: * @return user principal aoqi@0: */ aoqi@0: public Principal getUserPrincipal() { aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Whether user associated with the request holds the given role aoqi@0: * aoqi@0: * @param role Role to check aoqi@0: * @return if the caller holds the role aoqi@0: */ aoqi@0: public boolean isUserInRole(String role) { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Gets request metadata attribute aoqi@0: * @param key Request metadata key aoqi@0: * @return Value of metadata attribute or null, if no value present aoqi@0: */ aoqi@0: public Object getRequestAttribute(String key) { aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: private volatile boolean closed; aoqi@0: aoqi@0: /** aoqi@0: * Close the connection aoqi@0: */ aoqi@0: public void close() { aoqi@0: this.closed = true; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Retuns whether connection is closed or not. aoqi@0: */ aoqi@0: public boolean isClosed() { aoqi@0: return closed; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Subclasses are expected to override aoqi@0: * aoqi@0: * @return a {@link String} containing the protocol name and version number aoqi@0: */ aoqi@0: public String getProtocol() { aoqi@0: return "HTTP/1.1"; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Subclasses are expected to override aoqi@0: * aoqi@0: * @since JAX-WS RI 2.2.2 aoqi@0: * @return value of given cookie aoqi@0: */ aoqi@0: public String getCookie(String name) { aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Subclasses are expected to override aoqi@0: * aoqi@0: * aoqi@0: * @since JAX-WS RI 2.2.2 aoqi@0: */ aoqi@0: public void setCookie(String name, String value) { aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Subclasses are expected to override aoqi@0: */ aoqi@0: public void setContentLengthResponseHeader(int value) { aoqi@0: } aoqi@0: aoqi@0: }