src/share/jaxws_classes/com/sun/xml/internal/ws/transport/http/HttpAdapter.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 408
b0610cd08440
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.xml.internal.ws.transport.http;
aoqi@0 27
aoqi@0 28 import java.io.ByteArrayOutputStream;
aoqi@0 29 import java.io.IOException;
aoqi@0 30 import java.io.InputStream;
aoqi@0 31 import java.io.OutputStream;
aoqi@0 32 import java.io.OutputStreamWriter;
aoqi@0 33 import java.io.PrintWriter;
aoqi@0 34 import java.net.HttpURLConnection;
aoqi@0 35 import java.util.Collections;
aoqi@0 36 import java.util.HashMap;
aoqi@0 37 import java.util.List;
aoqi@0 38 import java.util.Map;
aoqi@0 39 import java.util.Map.Entry;
aoqi@0 40 import java.util.TreeMap;
aoqi@0 41 import java.util.logging.Level;
aoqi@0 42 import java.util.logging.Logger;
aoqi@0 43
aoqi@0 44 import javax.xml.ws.Binding;
aoqi@0 45 import javax.xml.ws.WebServiceException;
aoqi@0 46 import javax.xml.ws.http.HTTPBinding;
aoqi@0 47
aoqi@0 48 import com.oracle.webservices.internal.api.message.PropertySet;
aoqi@0 49 import com.sun.istack.internal.NotNull;
aoqi@0 50 import com.sun.istack.internal.Nullable;
aoqi@0 51 import com.sun.xml.internal.ws.api.Component;
aoqi@0 52 import com.sun.xml.internal.ws.api.EndpointAddress;
aoqi@0 53 import com.sun.xml.internal.ws.api.SOAPVersion;
aoqi@0 54 import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
aoqi@0 55 import com.sun.xml.internal.ws.api.addressing.NonAnonymousResponseProcessor;
aoqi@0 56 import com.sun.xml.internal.ws.api.ha.HaInfo;
aoqi@0 57 import com.sun.xml.internal.ws.api.message.ExceptionHasMessage;
aoqi@0 58 import com.sun.xml.internal.ws.api.message.Message;
aoqi@0 59 import com.sun.xml.internal.ws.api.message.Packet;
aoqi@0 60 import com.sun.xml.internal.ws.api.pipe.Codec;
aoqi@0 61 import com.sun.xml.internal.ws.api.pipe.ContentType;
aoqi@0 62 import com.sun.xml.internal.ws.api.server.AbstractServerAsyncTransport;
aoqi@0 63 import com.sun.xml.internal.ws.api.server.Adapter;
aoqi@0 64 import com.sun.xml.internal.ws.api.server.BoundEndpoint;
aoqi@0 65 import com.sun.xml.internal.ws.api.server.DocumentAddressResolver;
aoqi@0 66 import com.sun.xml.internal.ws.api.server.Module;
aoqi@0 67 import com.sun.xml.internal.ws.api.server.PortAddressResolver;
aoqi@0 68 import com.sun.xml.internal.ws.api.server.SDDocument;
aoqi@0 69 import com.sun.xml.internal.ws.api.server.ServiceDefinition;
aoqi@0 70 import com.sun.xml.internal.ws.api.server.TransportBackChannel;
aoqi@0 71 import com.sun.xml.internal.ws.api.server.WSEndpoint;
aoqi@0 72 import com.sun.xml.internal.ws.api.server.WebServiceContextDelegate;
aoqi@0 73 import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
aoqi@0 74 import com.sun.xml.internal.ws.resources.WsservletMessages;
aoqi@0 75 import com.sun.xml.internal.ws.server.UnsupportedMediaException;
aoqi@0 76 import com.sun.xml.internal.ws.util.ByteArrayBuffer;
aoqi@0 77 import com.sun.xml.internal.ws.util.Pool;
aoqi@0 78
aoqi@0 79
aoqi@0 80 /**
aoqi@0 81 * {@link com.sun.xml.internal.ws.api.server.Adapter} that receives messages in HTTP.
aoqi@0 82 *
aoqi@0 83 * <p>
aoqi@0 84 * This object also assigns unique query string (such as "xsd=1") to
aoqi@0 85 * each {@link com.sun.xml.internal.ws.api.server.SDDocument} so that they can be served by HTTP GET requests.
aoqi@0 86 *
aoqi@0 87 * @author Kohsuke Kawaguchi
aoqi@0 88 * @author Jitendra Kotamraju
aoqi@0 89 */
aoqi@0 90 public class HttpAdapter extends Adapter<HttpAdapter.HttpToolkit> {
aoqi@0 91
aoqi@0 92 private static final Logger LOGGER = Logger.getLogger(HttpAdapter.class.getName());
aoqi@0 93
aoqi@0 94 /**
aoqi@0 95 * {@link com.sun.xml.internal.ws.api.server.SDDocument}s keyed by the query string like "?abc".
aoqi@0 96 * Used for serving documents via HTTP GET.
aoqi@0 97 *
aoqi@0 98 * Empty if the endpoint doesn't have {@link com.sun.xml.internal.ws.api.server.ServiceDefinition}.
aoqi@0 99 * Read-only.
aoqi@0 100 */
aoqi@0 101 protected Map<String,SDDocument> wsdls;
aoqi@0 102
aoqi@0 103 /**
aoqi@0 104 * Reverse map of {@link #wsdls}. Read-only.
aoqi@0 105 */
aoqi@0 106 private Map<SDDocument,String> revWsdls;
aoqi@0 107
aoqi@0 108 /**
aoqi@0 109 * A reference to the service definition from which the map of wsdls/revWsdls
aoqi@0 110 * was created. This allows us to establish if the service definition documents
aoqi@0 111 * have changed in the meantime.
aoqi@0 112 */
aoqi@0 113 private ServiceDefinition serviceDefinition = null;
aoqi@0 114
aoqi@0 115 public final HttpAdapterList<? extends HttpAdapter> owner;
aoqi@0 116
aoqi@0 117 /**
aoqi@0 118 * Servlet URL pattern with which this {@link com.sun.xml.internal.ws.transport.http.HttpAdapter} is associated.
aoqi@0 119 */
aoqi@0 120 public final String urlPattern;
aoqi@0 121
aoqi@0 122 protected boolean stickyCookie;
aoqi@0 123
aoqi@0 124 protected boolean disableJreplicaCookie = false;
aoqi@0 125
aoqi@0 126 /**
aoqi@0 127 * Creates a lone {@link com.sun.xml.internal.ws.transport.http.HttpAdapter} that does not know of any other
aoqi@0 128 * {@link com.sun.xml.internal.ws.transport.http.HttpAdapter}s.
aoqi@0 129 *
aoqi@0 130 * This is convenient for creating an {@link com.sun.xml.internal.ws.transport.http.HttpAdapter} for an environment
aoqi@0 131 * where they don't know each other (such as JavaSE deployment.)
aoqi@0 132 *
aoqi@0 133 * @param endpoint web service endpoint
aoqi@0 134 * @return singe adapter to process HTTP messages
aoqi@0 135 */
aoqi@0 136 public static HttpAdapter createAlone(WSEndpoint endpoint) {
aoqi@0 137 return new DummyList().createAdapter("","",endpoint);
aoqi@0 138 }
aoqi@0 139
aoqi@0 140 /**
aoqi@0 141 * @deprecated
aoqi@0 142 * remove as soon as we can update the test util.
aoqi@0 143 * @param endpoint web service endpoint
aoqi@0 144 * @param owner list of related adapters
aoqi@0 145 */
aoqi@0 146 protected HttpAdapter(WSEndpoint endpoint,
aoqi@0 147 HttpAdapterList<? extends HttpAdapter> owner) {
aoqi@0 148 this(endpoint,owner,null);
aoqi@0 149 }
aoqi@0 150
aoqi@0 151 protected HttpAdapter(WSEndpoint endpoint,
aoqi@0 152 HttpAdapterList<? extends HttpAdapter> owner,
aoqi@0 153 String urlPattern) {
aoqi@0 154 super(endpoint);
aoqi@0 155 this.owner = owner;
aoqi@0 156 this.urlPattern = urlPattern;
aoqi@0 157
aoqi@0 158 initWSDLMap(endpoint.getServiceDefinition());
aoqi@0 159 }
aoqi@0 160
aoqi@0 161 /**
aoqi@0 162 * Return the last known service definition of the endpoint.
aoqi@0 163 *
aoqi@0 164 * @return The service definition of the endpoint
aoqi@0 165 */
aoqi@0 166 public ServiceDefinition getServiceDefinition() {
aoqi@0 167 return this.serviceDefinition;
aoqi@0 168 }
aoqi@0 169
aoqi@0 170 /**
aoqi@0 171 * Fill in WSDL map.
aoqi@0 172 *
aoqi@0 173 * @param sdef service definition
aoqi@0 174 */
aoqi@0 175 public final void initWSDLMap(ServiceDefinition sdef) {
aoqi@0 176 this.serviceDefinition = sdef;
aoqi@0 177 if(sdef==null) {
aoqi@0 178 wsdls = Collections.emptyMap();
aoqi@0 179 revWsdls = Collections.emptyMap();
aoqi@0 180 } else {
aoqi@0 181 wsdls = new HashMap<String, SDDocument>(); // wsdl=1 --> Doc
aoqi@0 182 // Sort WSDL, Schema documents based on SystemId so that the same
aoqi@0 183 // document gets wsdl=x mapping
aoqi@0 184 Map<String, SDDocument> systemIds = new TreeMap<String, SDDocument>();
aoqi@0 185 for (SDDocument sdd : sdef) {
aoqi@0 186 if (sdd == sdef.getPrimary()) { // No sorting for Primary WSDL
aoqi@0 187 wsdls.put("wsdl", sdd);
aoqi@0 188 wsdls.put("WSDL", sdd);
aoqi@0 189 } else {
aoqi@0 190 systemIds.put(sdd.getURL().toString(), sdd);
aoqi@0 191 }
aoqi@0 192 }
aoqi@0 193
aoqi@0 194 int wsdlnum = 1;
aoqi@0 195 int xsdnum = 1;
aoqi@0 196 for (Entry<String, SDDocument> e : systemIds.entrySet()) {
aoqi@0 197 SDDocument sdd = e.getValue();
aoqi@0 198 if (sdd.isWSDL()) {
aoqi@0 199 wsdls.put("wsdl="+(wsdlnum++),sdd);
aoqi@0 200 }
aoqi@0 201 if (sdd.isSchema()) {
aoqi@0 202 wsdls.put("xsd="+(xsdnum++),sdd);
aoqi@0 203 }
aoqi@0 204 }
aoqi@0 205
aoqi@0 206 revWsdls = new HashMap<SDDocument,String>(); // Doc --> wsdl=1
aoqi@0 207 for (Entry<String,SDDocument> e : wsdls.entrySet()) {
aoqi@0 208 if (!e.getKey().equals("WSDL")) { // map Doc --> wsdl, not WSDL
aoqi@0 209 revWsdls.put(e.getValue(),e.getKey());
aoqi@0 210 }
aoqi@0 211 }
aoqi@0 212 }
aoqi@0 213 }
aoqi@0 214
aoqi@0 215 /**
aoqi@0 216 * Returns the "/abc/def/ghi" portion if
aoqi@0 217 * the URL pattern is "/abc/def/ghi/*".
aoqi@0 218 */
aoqi@0 219 public String getValidPath() {
aoqi@0 220 if (urlPattern.endsWith("/*")) {
aoqi@0 221 return urlPattern.substring(0, urlPattern.length() - 2);
aoqi@0 222 } else {
aoqi@0 223 return urlPattern;
aoqi@0 224 }
aoqi@0 225 }
aoqi@0 226
aoqi@0 227 @Override
aoqi@0 228 protected HttpToolkit createToolkit() {
aoqi@0 229 return new HttpToolkit();
aoqi@0 230 }
aoqi@0 231
aoqi@0 232 /**
aoqi@0 233 * Receives the incoming HTTP connection and dispatches
aoqi@0 234 * it to JAX-WS. This method returns when JAX-WS completes
aoqi@0 235 * processing the request and the whole reply is written
aoqi@0 236 * to {@link WSHTTPConnection}.
aoqi@0 237 *
aoqi@0 238 * <p>
aoqi@0 239 * This method is invoked by the lower-level HTTP stack,
aoqi@0 240 * and "connection" here is an HTTP connection.
aoqi@0 241 *
aoqi@0 242 * <p>
aoqi@0 243 * To populate a request {@link com.sun.xml.internal.ws.api.message.Packet} with more info,
aoqi@0 244 * define {@link com.oracle.webservices.internal.api.message.PropertySet.Property properties} on
aoqi@0 245 * {@link WSHTTPConnection}.
aoqi@0 246 *
aoqi@0 247 * @param connection to receive/send HTTP messages for web service endpoints
aoqi@0 248 * @throws java.io.IOException when I/O errors happen
aoqi@0 249 */
aoqi@0 250 public void handle(@NotNull WSHTTPConnection connection) throws IOException {
aoqi@0 251 if (handleGet(connection)) {
aoqi@0 252 return;
aoqi@0 253 }
aoqi@0 254
aoqi@0 255 // Make sure the Toolkit is recycled by the same pool instance from which it was taken
aoqi@0 256 final Pool<HttpToolkit> currentPool = getPool();
aoqi@0 257 // normal request handling
aoqi@0 258 final HttpToolkit tk = currentPool.take();
aoqi@0 259 try {
aoqi@0 260 tk.handle(connection);
aoqi@0 261 } finally {
aoqi@0 262 currentPool.recycle(tk);
aoqi@0 263 }
aoqi@0 264 }
aoqi@0 265
aoqi@0 266 public boolean handleGet(@NotNull WSHTTPConnection connection) throws IOException {
aoqi@0 267 if (connection.getRequestMethod().equals("GET")) {
aoqi@0 268 // metadata query. let the interceptor run
aoqi@0 269 for (Component c : endpoint.getComponents()) {
aoqi@0 270 HttpMetadataPublisher spi = c.getSPI(HttpMetadataPublisher.class);
aoqi@0 271 if (spi != null && spi.handleMetadataRequest(this, connection)) {
aoqi@0 272 return true;
aoqi@0 273 } // handled
aoqi@0 274 }
aoqi@0 275
aoqi@0 276 if (isMetadataQuery(connection.getQueryString())) {
aoqi@0 277 // Sends published WSDL and schema documents as the default action.
aoqi@0 278 publishWSDL(connection);
aoqi@0 279 return true;
aoqi@0 280 }
aoqi@0 281
aoqi@0 282 Binding binding = getEndpoint().getBinding();
aoqi@0 283 if (!(binding instanceof HTTPBinding)) {
aoqi@0 284 // Writes HTML page with all the endpoint descriptions
aoqi@0 285 writeWebServicesHtmlPage(connection);
aoqi@0 286 return true;
aoqi@0 287 }
aoqi@0 288 } else if (connection.getRequestMethod().equals("HEAD")) {
aoqi@0 289 connection.getInput().close();
aoqi@0 290 Binding binding = getEndpoint().getBinding();
aoqi@0 291 if (isMetadataQuery(connection.getQueryString())) {
aoqi@0 292 SDDocument doc = wsdls.get(connection.getQueryString());
aoqi@0 293 connection.setStatus(doc != null
aoqi@0 294 ? HttpURLConnection.HTTP_OK
aoqi@0 295 : HttpURLConnection.HTTP_NOT_FOUND);
aoqi@0 296 connection.getOutput().close();
aoqi@0 297 connection.close();
aoqi@0 298 return true;
aoqi@0 299 } else if (!(binding instanceof HTTPBinding)) {
aoqi@0 300 connection.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
aoqi@0 301 connection.getOutput().close();
aoqi@0 302 connection.close();
aoqi@0 303 return true;
aoqi@0 304 }
aoqi@0 305 // Let the endpoint handle for HTTPBinding
aoqi@0 306 }
aoqi@0 307
aoqi@0 308 return false;
aoqi@0 309
aoqi@0 310 }
aoqi@0 311 /*
aoqi@0 312 *
aoqi@0 313 * @param con
aoqi@0 314 * @param codec
aoqi@0 315 * @return
aoqi@0 316 * @throws IOException
aoqi@0 317 * ExceptionHasMessage exception that contains particular fault message
aoqi@0 318 * UnsupportedMediaException to indicate to send 415 error code
aoqi@0 319 */
aoqi@0 320 private Packet decodePacket(@NotNull WSHTTPConnection con, @NotNull Codec codec) throws IOException {
aoqi@0 321 String ct = con.getRequestHeader("Content-Type");
aoqi@0 322 InputStream in = con.getInput();
aoqi@0 323 Packet packet = new Packet();
aoqi@0 324 packet.soapAction = fixQuotesAroundSoapAction(con.getRequestHeader("SOAPAction"));
aoqi@0 325 packet.wasTransportSecure = con.isSecure();
aoqi@0 326 packet.acceptableMimeTypes = con.getRequestHeader("Accept");
aoqi@0 327 packet.addSatellite(con);
aoqi@0 328 addSatellites(packet);
aoqi@0 329 packet.isAdapterDeliversNonAnonymousResponse = true;
aoqi@0 330 packet.component = this;
aoqi@0 331 packet.transportBackChannel = new Oneway(con);
aoqi@0 332 packet.webServiceContextDelegate = con.getWebServiceContextDelegate();
aoqi@0 333 packet.setState(Packet.State.ServerRequest);
aoqi@0 334 if (dump || LOGGER.isLoggable(Level.FINER)) {
aoqi@0 335 ByteArrayBuffer buf = new ByteArrayBuffer();
aoqi@0 336 buf.write(in);
aoqi@0 337 in.close();
aoqi@0 338 dump(buf, "HTTP request", con.getRequestHeaders());
aoqi@0 339 in = buf.newInputStream();
aoqi@0 340 }
aoqi@0 341 codec.decode(in, ct, packet);
aoqi@0 342 return packet;
aoqi@0 343 }
aoqi@0 344
aoqi@0 345 protected void addSatellites(Packet packet) {
aoqi@0 346 }
aoqi@0 347
aoqi@0 348 /**
aoqi@0 349 * Some stacks may send non WS-I BP 1.2 conforming SoapAction.
aoqi@0 350 * Make sure SOAPAction is quoted as {@link com.sun.xml.internal.ws.api.message.Packet#soapAction} expects quoted soapAction value.
aoqi@0 351 *
aoqi@0 352 * @param soapAction SoapAction HTTP Header
aoqi@0 353 * @return quoted SOAPAction value
aoqi@0 354 */
aoqi@0 355 static public String fixQuotesAroundSoapAction(String soapAction) {
aoqi@0 356 if(soapAction != null && (!soapAction.startsWith("\"") || !soapAction.endsWith("\"")) ) {
aoqi@0 357 if (LOGGER.isLoggable(Level.INFO)) {
aoqi@0 358 LOGGER.log(Level.INFO, "Received WS-I BP non-conformant Unquoted SoapAction HTTP header: {0}", soapAction);
aoqi@0 359 }
aoqi@0 360 String fixedSoapAction = soapAction;
aoqi@0 361 if(!soapAction.startsWith("\"")) {
aoqi@0 362 fixedSoapAction = "\"" + fixedSoapAction;
aoqi@0 363 }
aoqi@0 364 if(!soapAction.endsWith("\"")) {
aoqi@0 365 fixedSoapAction = fixedSoapAction + "\"";
aoqi@0 366 }
aoqi@0 367 return fixedSoapAction;
aoqi@0 368 }
aoqi@0 369 return soapAction;
aoqi@0 370 }
aoqi@0 371
aoqi@0 372 protected NonAnonymousResponseProcessor getNonAnonymousResponseProcessor() {
aoqi@0 373 return NonAnonymousResponseProcessor.getDefault();
aoqi@0 374 }
aoqi@0 375
aoqi@0 376 /**
aoqi@0 377 * This method is added for the case of the sub-class wants to override the method to
aoqi@0 378 * print details. E.g. convert soapfault as HTML msg for 403 error connstatus.
aoqi@0 379 * @param os
aoqi@0 380 */
aoqi@0 381 protected void writeClientError(int connStatus, @NotNull OutputStream os, @NotNull Packet packet) throws IOException {
aoqi@0 382 //do nothing
aoqi@0 383 }
aoqi@0 384
aoqi@0 385 private boolean isClientErrorStatus(int connStatus)
aoqi@0 386 {
aoqi@0 387 return (connStatus == HttpURLConnection.HTTP_FORBIDDEN); // add more for future.
aoqi@0 388 }
aoqi@0 389
aoqi@0 390 private boolean isNonAnonymousUri(EndpointAddress addr){
aoqi@0 391 return (addr != null) && !addr.toString().equals(AddressingVersion.W3C.anonymousUri) &&
aoqi@0 392 !addr.toString().equals(AddressingVersion.MEMBER.anonymousUri);
aoqi@0 393 }
aoqi@0 394
aoqi@0 395 private void encodePacket(@NotNull Packet packet, @NotNull WSHTTPConnection con, @NotNull Codec codec) throws IOException {
aoqi@0 396 if (isNonAnonymousUri(packet.endpointAddress) && packet.getMessage() != null) {
aoqi@0 397 try {
aoqi@0 398 // Message is targeted to non-anonymous response endpoint.
aoqi@0 399 // After call to non-anonymous processor, typically, packet.getMessage() will be null
aoqi@0 400 // however, processors could use this pattern to modify the response sent on the back-channel,
aoqi@0 401 // e.g. send custom HTTP headers with the HTTP 202
aoqi@0 402 packet = getNonAnonymousResponseProcessor().process(packet);
aoqi@0 403 } catch (RuntimeException re) {
aoqi@0 404 // if processing by NonAnonymousResponseProcessor fails, new SOAPFaultMessage is created to be sent
aoqi@0 405 // to back-channel client
aoqi@0 406 SOAPVersion soapVersion = packet.getBinding().getSOAPVersion();
aoqi@0 407 Message faultMsg = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, re);
aoqi@0 408 packet = packet.createServerResponse(faultMsg, packet.endpoint.getPort(), null, packet.endpoint.getBinding());
aoqi@0 409 }
aoqi@0 410 }
aoqi@0 411
aoqi@0 412 if (con.isClosed()) {
aoqi@0 413 return; // Connection is already closed
aoqi@0 414 }
aoqi@0 415 Message responseMessage = packet.getMessage();
aoqi@0 416 addStickyCookie(con);
aoqi@0 417 addReplicaCookie(con, packet);
aoqi@0 418 if (responseMessage == null) {
aoqi@0 419 if (!con.isClosed()) {
aoqi@0 420 // set the response code if not already set
aoqi@0 421 // for example, 415 may have been set earlier for Unsupported Content-Type
aoqi@0 422 if (con.getStatus() == 0) {
aoqi@0 423 con.setStatus(WSHTTPConnection.ONEWAY);
aoqi@0 424 }
aoqi@0 425 OutputStream os = con.getProtocol().contains("1.1") ? con.getOutput() : new Http10OutputStream(con);
aoqi@0 426 if (dump || LOGGER.isLoggable(Level.FINER)) {
aoqi@0 427 ByteArrayBuffer buf = new ByteArrayBuffer();
aoqi@0 428 codec.encode(packet, buf);
aoqi@0 429 dump(buf, "HTTP response " + con.getStatus(), con.getResponseHeaders());
aoqi@0 430 buf.writeTo(os);
aoqi@0 431 } else {
aoqi@0 432 codec.encode(packet, os);
aoqi@0 433 }
aoqi@0 434 // close the response channel now
aoqi@0 435 try {
aoqi@0 436 os.close(); // no payload
aoqi@0 437 } catch (IOException e) {
aoqi@0 438 throw new WebServiceException(e);
aoqi@0 439 }
aoqi@0 440 }
aoqi@0 441 } else {
aoqi@0 442 if (con.getStatus() == 0) {
aoqi@0 443 // if the appliation didn't set the status code,
aoqi@0 444 // set the default one.
aoqi@0 445 con.setStatus(responseMessage.isFault()
aoqi@0 446 ? HttpURLConnection.HTTP_INTERNAL_ERROR
aoqi@0 447 : HttpURLConnection.HTTP_OK);
aoqi@0 448 }
aoqi@0 449
aoqi@0 450 if (isClientErrorStatus(con.getStatus())) {
aoqi@0 451 OutputStream os = con.getOutput();
aoqi@0 452 if (dump || LOGGER.isLoggable(Level.FINER)) {
aoqi@0 453 ByteArrayBuffer buf = new ByteArrayBuffer();
aoqi@0 454 writeClientError(con.getStatus(), buf, packet);
aoqi@0 455 dump(buf, "HTTP response " + con.getStatus(), con.getResponseHeaders());
aoqi@0 456 buf.writeTo(os);
aoqi@0 457 } else {
aoqi@0 458 writeClientError(con.getStatus(), os, packet);
aoqi@0 459 }
aoqi@0 460 os.close();
aoqi@0 461 return;
aoqi@0 462 }
aoqi@0 463
aoqi@0 464 ContentType contentType = codec.getStaticContentType(packet);
aoqi@0 465 if (contentType != null) {
aoqi@0 466 con.setContentTypeResponseHeader(contentType.getContentType());
aoqi@0 467 OutputStream os = con.getProtocol().contains("1.1") ? con.getOutput() : new Http10OutputStream(con);
aoqi@0 468 if (dump || LOGGER.isLoggable(Level.FINER)) {
aoqi@0 469 ByteArrayBuffer buf = new ByteArrayBuffer();
aoqi@0 470 codec.encode(packet, buf);
aoqi@0 471 dump(buf, "HTTP response " + con.getStatus(), con.getResponseHeaders());
aoqi@0 472 buf.writeTo(os);
aoqi@0 473 } else {
aoqi@0 474 codec.encode(packet, os);
aoqi@0 475 }
aoqi@0 476 os.close();
aoqi@0 477 } else {
aoqi@0 478
aoqi@0 479 ByteArrayBuffer buf = new ByteArrayBuffer();
aoqi@0 480 contentType = codec.encode(packet, buf);
aoqi@0 481 con.setContentTypeResponseHeader(contentType.getContentType());
aoqi@0 482 if (dump || LOGGER.isLoggable(Level.FINER)) {
aoqi@0 483 dump(buf, "HTTP response " + con.getStatus(), con.getResponseHeaders());
aoqi@0 484 }
aoqi@0 485 OutputStream os = con.getOutput();
aoqi@0 486 buf.writeTo(os);
aoqi@0 487 os.close();
aoqi@0 488 }
aoqi@0 489 }
aoqi@0 490 }
aoqi@0 491
aoqi@0 492 /*
aoqi@0 493 * GlassFish Load-balancer plugin always add a header proxy-jroute on
aoqi@0 494 * request being send from load-balancer plugin to server
aoqi@0 495 *
aoqi@0 496 * JROUTE cookie need to be stamped in two cases
aoqi@0 497 * 1 : At the time of session creation. In this case, request will not have
aoqi@0 498 * any JROUTE cookie.
aoqi@0 499 * 2 : At the time of fail-over. In this case, value of proxy-jroute
aoqi@0 500 * header(will point to current instance) and JROUTE cookie(will point to
aoqi@0 501 * previous failed instance) will be different. This logic can be used
aoqi@0 502 * to determine fail-over scenario.
aoqi@0 503 */
aoqi@0 504 private void addStickyCookie(WSHTTPConnection con) {
aoqi@0 505 if (stickyCookie) {
aoqi@0 506 String proxyJroute = con.getRequestHeader("proxy-jroute");
aoqi@0 507 if (proxyJroute == null) {
aoqi@0 508 // Load-balancer plugin is not front-ending this instance
aoqi@0 509 return;
aoqi@0 510 }
aoqi@0 511
aoqi@0 512 String jrouteId = con.getCookie("JROUTE");
aoqi@0 513 if (jrouteId == null || !jrouteId.equals(proxyJroute)) {
aoqi@0 514 // Initial request or failover
aoqi@0 515 con.setCookie("JROUTE", proxyJroute);
aoqi@0 516 }
aoqi@0 517 }
aoqi@0 518 }
aoqi@0 519
aoqi@0 520 private void addReplicaCookie(WSHTTPConnection con, Packet packet) {
aoqi@0 521 if (stickyCookie) {
aoqi@0 522 HaInfo haInfo = null;
aoqi@0 523 if (packet.supports(Packet.HA_INFO)) {
aoqi@0 524 haInfo = (HaInfo)packet.get(Packet.HA_INFO);
aoqi@0 525 }
aoqi@0 526 if (haInfo != null) {
aoqi@0 527 con.setCookie("METRO_KEY", haInfo.getKey());
aoqi@0 528 if (!disableJreplicaCookie) {
aoqi@0 529 con.setCookie("JREPLICA", haInfo.getReplicaInstance());
aoqi@0 530 }
aoqi@0 531 }
aoqi@0 532 }
aoqi@0 533 }
aoqi@0 534
aoqi@0 535 public void invokeAsync(final WSHTTPConnection con) throws IOException {
aoqi@0 536 invokeAsync(con, NO_OP_COMPLETION_CALLBACK);
aoqi@0 537 }
aoqi@0 538
aoqi@0 539 public void invokeAsync(final WSHTTPConnection con, final CompletionCallback callback) throws IOException {
aoqi@0 540
aoqi@0 541 if (handleGet(con)) {
aoqi@0 542 callback.onCompletion();
aoqi@0 543 return;
aoqi@0 544 }
aoqi@0 545 final Pool<HttpToolkit> currentPool = getPool();
aoqi@0 546 final HttpToolkit tk = currentPool.take();
aoqi@0 547 final Packet request;
aoqi@0 548
aoqi@0 549 try {
aoqi@0 550
aoqi@0 551 request = decodePacket(con, tk.codec);
aoqi@0 552 } catch (ExceptionHasMessage e) {
aoqi@0 553 LOGGER.log(Level.SEVERE, e.getMessage(), e);
aoqi@0 554 Packet response = new Packet();
aoqi@0 555 response.setMessage(e.getFaultMessage());
aoqi@0 556 encodePacket(response, con, tk.codec);
aoqi@0 557 currentPool.recycle(tk);
aoqi@0 558 con.close();
aoqi@0 559 callback.onCompletion();
aoqi@0 560 return;
aoqi@0 561 } catch (UnsupportedMediaException e) {
aoqi@0 562 LOGGER.log(Level.SEVERE, e.getMessage(), e);
aoqi@0 563 Packet response = new Packet();
aoqi@0 564 con.setStatus(WSHTTPConnection.UNSUPPORTED_MEDIA);
aoqi@0 565 encodePacket(response, con, tk.codec);
aoqi@0 566 currentPool.recycle(tk);
aoqi@0 567 con.close();
aoqi@0 568 callback.onCompletion();
aoqi@0 569 return;
aoqi@0 570 }
aoqi@0 571
aoqi@0 572 endpoint.process(request, new WSEndpoint.CompletionCallback() {
aoqi@0 573 @Override
aoqi@0 574 public void onCompletion(@NotNull Packet response) {
aoqi@0 575 try {
aoqi@0 576 try {
aoqi@0 577 encodePacket(response, con, tk.codec);
aoqi@0 578 } catch (IOException ioe) {
aoqi@0 579 LOGGER.log(Level.SEVERE, ioe.getMessage(), ioe);
aoqi@0 580 }
aoqi@0 581 currentPool.recycle(tk);
aoqi@0 582 } finally {
aoqi@0 583 con.close();
aoqi@0 584 callback.onCompletion();
aoqi@0 585
aoqi@0 586 }
aoqi@0 587 }
aoqi@0 588 },null);
aoqi@0 589
aoqi@0 590 }
aoqi@0 591
aoqi@0 592 public static final CompletionCallback NO_OP_COMPLETION_CALLBACK = new CompletionCallback() {
aoqi@0 593
aoqi@0 594 @Override
aoqi@0 595 public void onCompletion() {
aoqi@0 596 //NO-OP
aoqi@0 597 }
aoqi@0 598 };
aoqi@0 599
aoqi@0 600 public interface CompletionCallback{
aoqi@0 601 void onCompletion();
aoqi@0 602 }
aoqi@0 603
aoqi@0 604 final class AsyncTransport extends AbstractServerAsyncTransport<WSHTTPConnection> {
aoqi@0 605
aoqi@0 606 public AsyncTransport() {
aoqi@0 607 super(endpoint);
aoqi@0 608 }
aoqi@0 609
aoqi@0 610 public void handleAsync(WSHTTPConnection con) throws IOException {
aoqi@0 611 super.handle(con);
aoqi@0 612 }
aoqi@0 613
aoqi@0 614 @Override
aoqi@0 615 protected void encodePacket(WSHTTPConnection con, @NotNull Packet packet, @NotNull Codec codec) throws IOException {
aoqi@0 616 HttpAdapter.this.encodePacket(packet, con, codec);
aoqi@0 617 }
aoqi@0 618
aoqi@0 619 protected @Override @Nullable String getAcceptableMimeTypes(WSHTTPConnection con) {
aoqi@0 620 return null;
aoqi@0 621 }
aoqi@0 622
aoqi@0 623 protected @Override @Nullable TransportBackChannel getTransportBackChannel(WSHTTPConnection con) {
aoqi@0 624 return new Oneway(con);
aoqi@0 625 }
aoqi@0 626
aoqi@0 627 protected @Override @NotNull
aoqi@0 628 PropertySet getPropertySet(WSHTTPConnection con) {
aoqi@0 629 return con;
aoqi@0 630 }
aoqi@0 631
aoqi@0 632 protected @Override @NotNull WebServiceContextDelegate getWebServiceContextDelegate(WSHTTPConnection con) {
aoqi@0 633 return con.getWebServiceContextDelegate();
aoqi@0 634 }
aoqi@0 635 }
aoqi@0 636
aoqi@0 637 static final class Oneway implements TransportBackChannel {
aoqi@0 638 WSHTTPConnection con;
aoqi@0 639 boolean closed;
aoqi@0 640
aoqi@0 641 Oneway(WSHTTPConnection con) {
aoqi@0 642 this.con = con;
aoqi@0 643 }
aoqi@0 644 @Override
aoqi@0 645 public void close() {
aoqi@0 646 if (!closed) {
aoqi@0 647 closed = true;
aoqi@0 648 // close the response channel now
aoqi@0 649 if (con.getStatus() == 0) {
aoqi@0 650 // if the appliation didn't set the status code,
aoqi@0 651 // set the default one.
aoqi@0 652 con.setStatus(WSHTTPConnection.ONEWAY);
aoqi@0 653 }
aoqi@0 654
aoqi@0 655 OutputStream output = null;
aoqi@0 656 try {
aoqi@0 657 output = con.getOutput();
aoqi@0 658 } catch (IOException e) {
aoqi@0 659 // no-op
aoqi@0 660 }
aoqi@0 661
aoqi@0 662 if (dump || LOGGER.isLoggable(Level.FINER)) {
aoqi@0 663 try {
aoqi@0 664 ByteArrayBuffer buf = new ByteArrayBuffer();
aoqi@0 665 dump(buf, "HTTP response " + con.getStatus(), con.getResponseHeaders());
aoqi@0 666 } catch (Exception e) {
aoqi@0 667 throw new WebServiceException(e.toString(), e);
aoqi@0 668 }
aoqi@0 669 }
aoqi@0 670
aoqi@0 671 if (output != null) {
aoqi@0 672 try {
aoqi@0 673 output.close(); // no payload
aoqi@0 674 } catch (IOException e) {
aoqi@0 675 throw new WebServiceException(e);
aoqi@0 676 }
aoqi@0 677 }
aoqi@0 678 con.close();
aoqi@0 679 }
aoqi@0 680 }
aoqi@0 681 }
aoqi@0 682
aoqi@0 683 final class HttpToolkit extends Adapter.Toolkit {
aoqi@0 684 public void handle(WSHTTPConnection con) throws IOException {
aoqi@0 685 try {
aoqi@0 686 boolean invoke = false;
aoqi@0 687 Packet packet;
aoqi@0 688 try {
aoqi@0 689 packet = decodePacket(con, codec);
aoqi@0 690 invoke = true;
aoqi@0 691 } catch(Exception e) {
aoqi@0 692 packet = new Packet();
aoqi@0 693 if (e instanceof ExceptionHasMessage) {
aoqi@0 694 LOGGER.log(Level.SEVERE, e.getMessage(), e);
aoqi@0 695 packet.setMessage(((ExceptionHasMessage)e).getFaultMessage());
aoqi@0 696 } else if (e instanceof UnsupportedMediaException) {
aoqi@0 697 LOGGER.log(Level.SEVERE, e.getMessage(), e);
aoqi@0 698 con.setStatus(WSHTTPConnection.UNSUPPORTED_MEDIA);
aoqi@0 699 } else {
aoqi@0 700 LOGGER.log(Level.SEVERE, e.getMessage(), e);
aoqi@0 701 con.setStatus(HttpURLConnection.HTTP_INTERNAL_ERROR);
aoqi@0 702 }
aoqi@0 703 }
aoqi@0 704 if (invoke) {
aoqi@0 705 try {
aoqi@0 706 packet = head.process(packet, con.getWebServiceContextDelegate(),
aoqi@0 707 packet.transportBackChannel);
aoqi@0 708 } catch(Throwable e) {
aoqi@0 709 LOGGER.log(Level.SEVERE, e.getMessage(), e);
aoqi@0 710 if (!con.isClosed()) {
aoqi@0 711 writeInternalServerError(con);
aoqi@0 712 }
aoqi@0 713 return;
aoqi@0 714 }
aoqi@0 715 }
aoqi@0 716 encodePacket(packet, con, codec);
aoqi@0 717 } finally {
aoqi@0 718 if (!con.isClosed()) {
aoqi@0 719 if (LOGGER.isLoggable(Level.FINE)) {
aoqi@0 720 LOGGER.log(Level.FINE, "Closing HTTP Connection with status: {0}", con.getStatus());
aoqi@0 721 }
aoqi@0 722 con.close();
aoqi@0 723 }
aoqi@0 724 }
aoqi@0 725 }
aoqi@0 726 }
aoqi@0 727
aoqi@0 728 /**
aoqi@0 729 * Returns true if the given query string is for metadata request.
aoqi@0 730 *
aoqi@0 731 * @param query
aoqi@0 732 * String like "xsd=1" or "perhaps=some&amp;unrelated=query".
aoqi@0 733 * Can be null.
aoqi@0 734 * @return true for metadata requests
aoqi@0 735 * false for web service requests
aoqi@0 736 */
aoqi@0 737 private boolean isMetadataQuery(String query) {
aoqi@0 738 // we intentionally return true even if documents don't exist,
aoqi@0 739 // so that they get 404.
aoqi@0 740 return query != null && (query.equals("WSDL") || query.startsWith("wsdl") || query.startsWith("xsd="));
aoqi@0 741 }
aoqi@0 742
aoqi@0 743 /**
aoqi@0 744 * Sends out the WSDL (and other referenced documents)
aoqi@0 745 * in response to the GET requests to URLs like "?wsdl" or "?xsd=2".
aoqi@0 746 *
aoqi@0 747 * @param con
aoqi@0 748 * The connection to which the data will be sent.
aoqi@0 749 *
aoqi@0 750 * @throws java.io.IOException when I/O errors happen
aoqi@0 751 */
aoqi@0 752 public void publishWSDL(@NotNull WSHTTPConnection con) throws IOException {
aoqi@0 753 con.getInput().close();
aoqi@0 754
aoqi@0 755 SDDocument doc = wsdls.get(con.getQueryString());
aoqi@0 756 if (doc == null) {
aoqi@0 757 writeNotFoundErrorPage(con,"Invalid Request");
aoqi@0 758 return;
aoqi@0 759 }
aoqi@0 760
aoqi@0 761 con.setStatus(HttpURLConnection.HTTP_OK);
aoqi@0 762 con.setContentTypeResponseHeader("text/xml;charset=utf-8");
aoqi@0 763
aoqi@0 764 OutputStream os = con.getProtocol().contains("1.1") ? con.getOutput() : new Http10OutputStream(con);
aoqi@0 765
aoqi@0 766 PortAddressResolver portAddressResolver = getPortAddressResolver(con.getBaseAddress());
aoqi@0 767 DocumentAddressResolver resolver = getDocumentAddressResolver(portAddressResolver);
aoqi@0 768
aoqi@0 769 doc.writeTo(portAddressResolver, resolver, os);
aoqi@0 770 os.close();
aoqi@0 771 }
aoqi@0 772
aoqi@0 773 public PortAddressResolver getPortAddressResolver(String baseAddress) {
aoqi@0 774 return owner.createPortAddressResolver(baseAddress, endpoint.getImplementationClass());
aoqi@0 775 }
aoqi@0 776
aoqi@0 777 public DocumentAddressResolver getDocumentAddressResolver(
aoqi@0 778 PortAddressResolver portAddressResolver) {
aoqi@0 779 final String address = portAddressResolver.getAddressFor(endpoint.getServiceName(), endpoint.getPortName().getLocalPart());
aoqi@0 780 assert address != null;
aoqi@0 781 return new DocumentAddressResolver() {
aoqi@0 782 @Override
aoqi@0 783 public String getRelativeAddressFor(@NotNull SDDocument current, @NotNull SDDocument referenced) {
aoqi@0 784 // the map on endpoint should account for all SDDocument
aoqi@0 785 assert revWsdls.containsKey(referenced);
aoqi@0 786 return address+'?'+ revWsdls.get(referenced);
aoqi@0 787 }
aoqi@0 788 };
aoqi@0 789 }
aoqi@0 790
aoqi@0 791 /**
aoqi@0 792 * HTTP/1.0 connections require Content-Length. So just buffer to find out
aoqi@0 793 * the length.
aoqi@0 794 */
aoqi@0 795 private final static class Http10OutputStream extends ByteArrayBuffer {
aoqi@0 796 private final WSHTTPConnection con;
aoqi@0 797
aoqi@0 798 Http10OutputStream(WSHTTPConnection con) {
aoqi@0 799 this.con = con;
aoqi@0 800 }
aoqi@0 801
aoqi@0 802 @Override
aoqi@0 803 public void close() throws IOException {
aoqi@0 804 super.close();
aoqi@0 805 con.setContentLengthResponseHeader(size());
aoqi@0 806 OutputStream os = con.getOutput();
aoqi@0 807 writeTo(os);
aoqi@0 808 os.close();
aoqi@0 809 }
aoqi@0 810 }
aoqi@0 811
aoqi@0 812 private void writeNotFoundErrorPage(WSHTTPConnection con, String message) throws IOException {
aoqi@0 813 con.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
aoqi@0 814 con.setContentTypeResponseHeader("text/html; charset=utf-8");
aoqi@0 815
aoqi@0 816 PrintWriter out = new PrintWriter(new OutputStreamWriter(con.getOutput(),"UTF-8"));
aoqi@0 817 out.println("<html>");
aoqi@0 818 out.println("<head><title>");
aoqi@0 819 out.println(WsservletMessages.SERVLET_HTML_TITLE());
aoqi@0 820 out.println("</title></head>");
aoqi@0 821 out.println("<body>");
aoqi@0 822 out.println(WsservletMessages.SERVLET_HTML_NOT_FOUND(message));
aoqi@0 823 out.println("</body>");
aoqi@0 824 out.println("</html>");
aoqi@0 825 out.close();
aoqi@0 826 }
aoqi@0 827
aoqi@0 828 private void writeInternalServerError(WSHTTPConnection con) throws IOException {
aoqi@0 829 con.setStatus(HttpURLConnection.HTTP_INTERNAL_ERROR);
aoqi@0 830 con.getOutput().close(); // Sets the status code
aoqi@0 831 }
aoqi@0 832
aoqi@0 833 private static final class DummyList extends HttpAdapterList<HttpAdapter> {
aoqi@0 834 @Override
aoqi@0 835 protected HttpAdapter createHttpAdapter(String name, String urlPattern, WSEndpoint<?> endpoint) {
aoqi@0 836 return new HttpAdapter(endpoint,this,urlPattern);
aoqi@0 837 }
aoqi@0 838 }
aoqi@0 839
aoqi@0 840 private static void dump(ByteArrayBuffer buf, String caption, Map<String, List<String>> headers) throws IOException {
aoqi@0 841 ByteArrayOutputStream baos = new ByteArrayOutputStream();
aoqi@0 842 PrintWriter pw = new PrintWriter(baos, true);
aoqi@0 843 pw.println("---["+caption +"]---");
aoqi@0 844 if (headers != null) {
aoqi@0 845 for (Entry<String, List<String>> header : headers.entrySet()) {
aoqi@0 846 if (header.getValue().isEmpty()) {
aoqi@0 847 // I don't think this is legal, but let's just dump it,
aoqi@0 848 // as the point of the dump is to uncover problems.
aoqi@0 849 pw.println(header.getValue());
aoqi@0 850 } else {
aoqi@0 851 for (String value : header.getValue()) {
aoqi@0 852 pw.println(header.getKey() + ": " + value);
aoqi@0 853 }
aoqi@0 854 }
aoqi@0 855 }
aoqi@0 856 }
aoqi@0 857 if (buf.size() > dump_threshold) {
aoqi@0 858 byte[] b = buf.getRawData();
aoqi@0 859 baos.write(b, 0, dump_threshold);
aoqi@0 860 pw.println();
aoqi@0 861 pw.println(WsservletMessages.MESSAGE_TOO_LONG(HttpAdapter.class.getName() + ".dumpTreshold"));
aoqi@0 862 } else {
aoqi@0 863 buf.writeTo(baos);
aoqi@0 864 }
aoqi@0 865 pw.println("--------------------");
aoqi@0 866
aoqi@0 867 String msg = baos.toString();
aoqi@0 868 if (dump) {
aoqi@0 869 System.out.println(msg);
aoqi@0 870 }
aoqi@0 871 if (LOGGER.isLoggable(Level.FINER)) {
aoqi@0 872 LOGGER.log(Level.FINER, msg);
aoqi@0 873 }
aoqi@0 874 }
aoqi@0 875
aoqi@0 876 /*
aoqi@0 877 * Generates the listing of all services.
aoqi@0 878 */
aoqi@0 879 private void writeWebServicesHtmlPage(WSHTTPConnection con) throws IOException {
aoqi@0 880 if (!publishStatusPage) {
aoqi@0 881 return;
aoqi@0 882 }
aoqi@0 883
aoqi@0 884 // TODO: resurrect the ability to localize according to the current request.
aoqi@0 885
aoqi@0 886 con.getInput().close();
aoqi@0 887
aoqi@0 888 // standard browsable page
aoqi@0 889 con.setStatus(WSHTTPConnection.OK);
aoqi@0 890 con.setContentTypeResponseHeader("text/html; charset=utf-8");
aoqi@0 891
aoqi@0 892 PrintWriter out = new PrintWriter(new OutputStreamWriter(con.getOutput(),"UTF-8"));
aoqi@0 893 out.println("<html>");
aoqi@0 894 out.println("<head><title>");
aoqi@0 895 // out.println("Web Services");
aoqi@0 896 out.println(WsservletMessages.SERVLET_HTML_TITLE());
aoqi@0 897 out.println("</title></head>");
aoqi@0 898 out.println("<body>");
aoqi@0 899 // out.println("<h1>Web Services</h1>");
aoqi@0 900 out.println(WsservletMessages.SERVLET_HTML_TITLE_2());
aoqi@0 901
aoqi@0 902 // what endpoints do we have in this system?
aoqi@0 903 Module module = getEndpoint().getContainer().getSPI(Module.class);
aoqi@0 904 List<BoundEndpoint> endpoints = Collections.emptyList();
aoqi@0 905 if(module!=null) {
aoqi@0 906 endpoints = module.getBoundEndpoints();
aoqi@0 907 }
aoqi@0 908
aoqi@0 909 if (endpoints.isEmpty()) {
aoqi@0 910 // out.println("<p>No JAX-WS context information available.</p>");
aoqi@0 911 out.println(WsservletMessages.SERVLET_HTML_NO_INFO_AVAILABLE());
aoqi@0 912 } else {
aoqi@0 913 out.println("<table width='100%' border='1'>");
aoqi@0 914 out.println("<tr>");
aoqi@0 915 out.println("<td>");
aoqi@0 916 // out.println("Endpoint");
aoqi@0 917 out.println(WsservletMessages.SERVLET_HTML_COLUMN_HEADER_PORT_NAME());
aoqi@0 918 out.println("</td>");
aoqi@0 919
aoqi@0 920 out.println("<td>");
aoqi@0 921 // out.println("Information");
aoqi@0 922 out.println(WsservletMessages.SERVLET_HTML_COLUMN_HEADER_INFORMATION());
aoqi@0 923 out.println("</td>");
aoqi@0 924 out.println("</tr>");
aoqi@0 925
aoqi@0 926 for (BoundEndpoint a : endpoints) {
aoqi@0 927 String endpointAddress = a.getAddress(con.getBaseAddress()).toString();
aoqi@0 928 out.println("<tr>");
aoqi@0 929
aoqi@0 930 out.println("<td>");
aoqi@0 931 out.println(WsservletMessages.SERVLET_HTML_ENDPOINT_TABLE(
aoqi@0 932 a.getEndpoint().getServiceName(),
aoqi@0 933 a.getEndpoint().getPortName()
aoqi@0 934 ));
aoqi@0 935 out.println("</td>");
aoqi@0 936
aoqi@0 937 out.println("<td>");
aoqi@0 938 out.println(WsservletMessages.SERVLET_HTML_INFORMATION_TABLE(
aoqi@0 939 endpointAddress,
aoqi@0 940 a.getEndpoint().getImplementationClass().getName()
aoqi@0 941 ));
aoqi@0 942 out.println("</td>");
aoqi@0 943
aoqi@0 944 out.println("</tr>");
aoqi@0 945 }
aoqi@0 946 out.println("</table>");
aoqi@0 947 }
aoqi@0 948 out.println("</body>");
aoqi@0 949 out.println("</html>");
aoqi@0 950 out.close();
aoqi@0 951 }
aoqi@0 952
aoqi@0 953 /**
aoqi@0 954 * Dumps what goes across HTTP transport.
aoqi@0 955 */
aoqi@0 956 public static volatile boolean dump = false;
aoqi@0 957
aoqi@0 958 public static volatile int dump_threshold = 4096;
aoqi@0 959
aoqi@0 960 public static volatile boolean publishStatusPage = true;
aoqi@0 961
aoqi@0 962 public static synchronized void setPublishStatus(boolean publish) {
aoqi@0 963 publishStatusPage = publish;
aoqi@0 964 }
aoqi@0 965
aoqi@0 966 static {
aoqi@0 967 try {
aoqi@0 968 dump = Boolean.getBoolean(HttpAdapter.class.getName() + ".dump");
aoqi@0 969 } catch (SecurityException se) {
aoqi@0 970 if (LOGGER.isLoggable(Level.CONFIG)) {
aoqi@0 971 LOGGER.log(Level.CONFIG, "Cannot read ''{0}'' property, using defaults.",
aoqi@0 972 new Object[] {HttpAdapter.class.getName() + ".dump"});
aoqi@0 973 }
aoqi@0 974 }
aoqi@0 975 try {
aoqi@0 976 dump_threshold = Integer.getInteger(HttpAdapter.class.getName() + ".dumpTreshold", 4096);
aoqi@0 977 } catch (SecurityException se) {
aoqi@0 978 if (LOGGER.isLoggable(Level.CONFIG)) {
aoqi@0 979 LOGGER.log(Level.CONFIG, "Cannot read ''{0}'' property, using defaults.",
aoqi@0 980 new Object[] {HttpAdapter.class.getName() + ".dumpTreshold"});
aoqi@0 981 }
aoqi@0 982 }
aoqi@0 983 try {
aoqi@0 984 setPublishStatus(Boolean.getBoolean(HttpAdapter.class.getName() + ".publishStatusPage"));
aoqi@0 985 } catch (SecurityException se) {
aoqi@0 986 if (LOGGER.isLoggable(Level.CONFIG)) {
aoqi@0 987 LOGGER.log(Level.CONFIG, "Cannot read ''{0}'' property, using defaults.",
aoqi@0 988 new Object[] {HttpAdapter.class.getName() + ".publishStatusPage"});
aoqi@0 989 }
aoqi@0 990 }
aoqi@0 991 }
aoqi@0 992
aoqi@0 993 public static void setDump(boolean dumpMessages) {
aoqi@0 994 HttpAdapter.dump = dumpMessages;
aoqi@0 995 }
aoqi@0 996 }

mercurial