1/* 2 * Copyright (c) 1997, 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 26package com.sun.xml.internal.ws.transport.http.server; 27 28import com.sun.istack.internal.NotNull; 29import com.sun.xml.internal.ws.api.message.Packet; 30import com.sun.xml.internal.ws.api.server.WSEndpoint; 31import com.sun.xml.internal.ws.api.server.WebServiceContextDelegate; 32import com.sun.xml.internal.ws.api.server.PortAddressResolver; 33import com.sun.xml.internal.ws.transport.http.HttpAdapter; 34import com.sun.xml.internal.ws.transport.http.WSHTTPConnection; 35import com.sun.xml.internal.ws.developer.JAXWSProperties; 36import com.sun.xml.internal.ws.resources.WsservletMessages; 37 38import javax.xml.ws.handler.MessageContext; 39import javax.xml.ws.WebServiceException; 40import javax.xml.ws.spi.http.HttpExchange; 41import java.io.IOException; 42import java.io.InputStream; 43import java.io.OutputStream; 44import java.security.Principal; 45import java.util.ArrayList; 46import java.util.List; 47import java.util.Map; 48import java.util.Set; 49 50/** 51 * {@link WSHTTPConnection} used with Java SE endpoints. It provides connection 52 * implementation using {@link HttpExchange} object. 53 * 54 * @author Jitendra Kotamraju 55 */ 56final class PortableConnectionImpl extends WSHTTPConnection implements WebServiceContextDelegate { 57 58 private final HttpExchange httpExchange; 59 private int status; 60 private final HttpAdapter adapter; 61 private boolean outputWritten; 62 63 public PortableConnectionImpl(@NotNull HttpAdapter adapter, @NotNull HttpExchange httpExchange) { 64 this.adapter = adapter; 65 this.httpExchange = httpExchange; 66 } 67 68 @Override 69 @Property(value = {MessageContext.HTTP_REQUEST_HEADERS, Packet.INBOUND_TRANSPORT_HEADERS}) 70 public @NotNull Map<String,List<String>> getRequestHeaders() { 71 return httpExchange.getRequestHeaders(); 72 } 73 74 @Override 75 public String getRequestHeader(String headerName) { 76 return httpExchange.getRequestHeader(headerName); 77 } 78 79 @Override 80 public void setResponseHeaders(Map<String,List<String>> headers) { 81 Map<String, List<String>> r = httpExchange.getResponseHeaders(); 82 r.clear(); 83 for(Map.Entry <String, List<String>> entry : headers.entrySet()) { 84 String name = entry.getKey(); 85 List<String> values = entry.getValue(); 86 // ignore headers that interfere with our correct operations 87 if (!name.equalsIgnoreCase("Content-Length") && !name.equalsIgnoreCase("Content-Type")) { 88 r.put(name,new ArrayList<String>(values)); 89 } 90 } 91 } 92 93 @Override 94 public void setResponseHeader(String key, List<String> value) { 95 httpExchange.getResponseHeaders().put(key, value); 96 } 97 98 @Override 99 public Set<String> getRequestHeaderNames() { 100 return httpExchange.getRequestHeaders().keySet(); 101 } 102 103 @Override 104 public List<String> getRequestHeaderValues(String headerName) { 105 return httpExchange.getRequestHeaders().get(headerName); 106 } 107 108 @Override 109 @Property({MessageContext.HTTP_RESPONSE_HEADERS,Packet.OUTBOUND_TRANSPORT_HEADERS}) 110 public Map<String,List<String>> getResponseHeaders() { 111 return httpExchange.getResponseHeaders(); 112 } 113 114 @Override 115 public void setContentTypeResponseHeader(@NotNull String value) { 116 httpExchange.addResponseHeader("Content-Type", value); 117 } 118 119 @Override 120 public void setStatus(int status) { 121 this.status = status; 122 } 123 124 @Override 125 @Property(MessageContext.HTTP_RESPONSE_CODE) 126 public int getStatus() { 127 return status; 128 } 129 130 public @Override @NotNull InputStream getInput() throws IOException { 131 return httpExchange.getRequestBody(); 132 } 133 134 public @Override @NotNull OutputStream getOutput() throws IOException { 135 assert !outputWritten; 136 outputWritten = true; 137 138 httpExchange.setStatus(getStatus()); 139 return httpExchange.getResponseBody(); 140 } 141 142 public @Override @NotNull WebServiceContextDelegate getWebServiceContextDelegate() { 143 return this; 144 } 145 146 @Override 147 public Principal getUserPrincipal(Packet request) { 148 return httpExchange.getUserPrincipal(); 149 } 150 151 @Override 152 public boolean isUserInRole(Packet request, String role) { 153 return httpExchange.isUserInRole(role); 154 } 155 156 public @Override @NotNull String getEPRAddress(Packet request, WSEndpoint endpoint) { 157 PortAddressResolver resolver = adapter.owner.createPortAddressResolver(getBaseAddress(), endpoint.getImplementationClass()); 158 String address = resolver.getAddressFor(endpoint.getServiceName(), endpoint.getPortName().getLocalPart()); 159 if(address==null) { 160 throw new WebServiceException(WsservletMessages.SERVLET_NO_ADDRESS_AVAILABLE(endpoint.getPortName())); 161 } 162 return address; 163 } 164 165 @Property(MessageContext.SERVLET_CONTEXT) 166 public Object getServletContext() { 167 return httpExchange.getAttribute(MessageContext.SERVLET_CONTEXT); 168 } 169 170 @Property(MessageContext.SERVLET_RESPONSE) 171 public Object getServletResponse() { 172 return httpExchange.getAttribute(MessageContext.SERVLET_RESPONSE); 173 } 174 175 @Property(MessageContext.SERVLET_REQUEST) 176 public Object getServletRequest() { 177 return httpExchange.getAttribute(MessageContext.SERVLET_REQUEST); 178 } 179 180 @Override 181 public String getWSDLAddress(@NotNull Packet request, @NotNull WSEndpoint endpoint) { 182 String eprAddress = getEPRAddress(request,endpoint); 183 if(adapter.getEndpoint().getPort() != null) { 184 return eprAddress+"?wsdl"; 185 } else { 186 return null; 187 } 188 } 189 190 @Override 191 public boolean isSecure() { 192 return httpExchange.getScheme().equals("https"); 193 } 194 195 @Override 196 @Property(MessageContext.HTTP_REQUEST_METHOD) 197 public @NotNull String getRequestMethod() { 198 return httpExchange.getRequestMethod(); 199 } 200 201 @Override 202 @Property(MessageContext.QUERY_STRING) 203 public String getQueryString() { 204 return httpExchange.getQueryString(); 205 } 206 207 @Override 208 @Property(MessageContext.PATH_INFO) 209 public String getPathInfo() { 210 return httpExchange.getPathInfo(); 211 } 212 213 @Property(JAXWSProperties.HTTP_EXCHANGE) 214 public HttpExchange getExchange() { 215 return httpExchange; 216 } 217 218 @Override @NotNull 219 public String getBaseAddress() { 220 StringBuilder sb = new StringBuilder(); 221 sb.append(httpExchange.getScheme()); 222 sb.append("://"); 223 sb.append(httpExchange.getLocalAddress().getHostName()); 224 sb.append(":"); 225 sb.append(httpExchange.getLocalAddress().getPort()); 226 sb.append(httpExchange.getContextPath()); 227 return sb.toString(); 228 } 229 230 @Override 231 public String getProtocol() { 232 return httpExchange.getProtocol(); 233 } 234 235 @Override 236 public void setContentLengthResponseHeader(int value) { 237 httpExchange.addResponseHeader("Content-Length", ""+value); 238 } 239 240 @Override 241 public String getRequestURI() { 242 return httpExchange.getRequestURI().toString(); 243 } 244 245 @Override 246 public String getRequestScheme() { 247 return httpExchange.getScheme(); 248 } 249 250 @Override 251 public String getServerName() { 252 return httpExchange.getLocalAddress().getHostName(); 253 } 254 255 @Override 256 public int getServerPort() { 257 return httpExchange.getLocalAddress().getPort(); 258 } 259 260 @Override 261 protected PropertyMap getPropertyMap() { 262 return model; 263 } 264 265 private static final PropertyMap model; 266 267 static { 268 model = parse(PortableConnectionImpl.class); 269 } 270} 271