Mon, 20 Apr 2009 15:14:39 -0700
6831313: update jaxws in OpenJDK7 to 2.1 plus bug fixes from OpenJDK 6
6672868: Package javax.xml.ws.wsaddressing not included in make/docs/CORE_PKGS.gmk
Reviewed-by: darcy
duke@1 | 1 | /* |
tbell@45 | 2 | * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. |
duke@1 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@1 | 4 | * |
duke@1 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@1 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@1 | 7 | * published by the Free Software Foundation. Sun designates this |
duke@1 | 8 | * particular file as subject to the "Classpath" exception as provided |
duke@1 | 9 | * by Sun in the LICENSE file that accompanied this code. |
duke@1 | 10 | * |
duke@1 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@1 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@1 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@1 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@1 | 15 | * accompanied this code). |
duke@1 | 16 | * |
duke@1 | 17 | * You should have received a copy of the GNU General Public License version |
duke@1 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@1 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@1 | 20 | * |
duke@1 | 21 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
duke@1 | 22 | * CA 95054 USA or visit www.sun.com if you need additional information or |
duke@1 | 23 | * have any questions. |
duke@1 | 24 | */ |
tbell@45 | 25 | /* |
tbell@45 | 26 | * $Id: HttpSOAPConnection.java,v 1.41 2006/01/27 12:49:17 vj135062 Exp $ |
tbell@45 | 27 | * $Revision: 1.41 $ |
tbell@45 | 28 | * $Date: 2006/01/27 12:49:17 $ |
tbell@45 | 29 | */ |
tbell@45 | 30 | |
tbell@45 | 31 | |
duke@1 | 32 | package com.sun.xml.internal.messaging.saaj.client.p2p; |
duke@1 | 33 | |
duke@1 | 34 | import java.io.*; |
duke@1 | 35 | import java.lang.reflect.Method; |
duke@1 | 36 | import java.net.*; |
duke@1 | 37 | import java.security.*; |
duke@1 | 38 | import java.util.Iterator; |
duke@1 | 39 | import java.util.StringTokenizer; |
duke@1 | 40 | import java.util.logging.Level; |
duke@1 | 41 | import java.util.logging.Logger; |
duke@1 | 42 | |
duke@1 | 43 | import javax.xml.soap.*; |
duke@1 | 44 | |
duke@1 | 45 | import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl; |
duke@1 | 46 | import com.sun.xml.internal.messaging.saaj.util.*; |
duke@1 | 47 | |
duke@1 | 48 | /** |
duke@1 | 49 | * This represents a "connection" to the simple HTTP-based provider. |
duke@1 | 50 | * |
duke@1 | 51 | * @author Anil Vijendran (akv@eng.sun.com) |
duke@1 | 52 | * @author Rajiv Mordani (rajiv.mordani@sun.com) |
duke@1 | 53 | * @author Manveen Kaur (manveen.kaur@sun.com) |
duke@1 | 54 | * |
duke@1 | 55 | */ |
duke@1 | 56 | public class HttpSOAPConnection extends SOAPConnection { |
duke@1 | 57 | |
duke@1 | 58 | protected static Logger log = |
duke@1 | 59 | Logger.getLogger(LogDomainConstants.HTTP_CONN_DOMAIN, |
duke@1 | 60 | "com.sun.xml.internal.messaging.saaj.client.p2p.LocalStrings"); |
duke@1 | 61 | |
duke@1 | 62 | public static String defaultProxyHost = null; |
duke@1 | 63 | public static int defaultProxyPort = -1; |
duke@1 | 64 | |
duke@1 | 65 | MessageFactory messageFactory = null; |
duke@1 | 66 | |
duke@1 | 67 | boolean closed = false; |
duke@1 | 68 | |
duke@1 | 69 | public HttpSOAPConnection() throws SOAPException { |
duke@1 | 70 | proxyHost = defaultProxyHost; |
duke@1 | 71 | proxyPort = defaultProxyPort; |
duke@1 | 72 | |
duke@1 | 73 | try { |
duke@1 | 74 | messageFactory = MessageFactory.newInstance(SOAPConstants.DYNAMIC_SOAP_PROTOCOL); |
duke@1 | 75 | } catch (Exception ex) { |
duke@1 | 76 | log.log(Level.SEVERE, "SAAJ0001.p2p.cannot.create.msg.factory", ex); |
duke@1 | 77 | throw new SOAPExceptionImpl("Unable to create message factory", ex); |
duke@1 | 78 | } |
duke@1 | 79 | } |
duke@1 | 80 | |
duke@1 | 81 | public void close() throws SOAPException { |
duke@1 | 82 | if (closed) { |
duke@1 | 83 | log.severe("SAAJ0002.p2p.close.already.closed.conn"); |
duke@1 | 84 | throw new SOAPExceptionImpl("Connection already closed"); |
duke@1 | 85 | } |
duke@1 | 86 | |
duke@1 | 87 | messageFactory = null; |
duke@1 | 88 | closed = true; |
duke@1 | 89 | } |
duke@1 | 90 | |
duke@1 | 91 | public SOAPMessage call(SOAPMessage message, Object endPoint) |
duke@1 | 92 | throws SOAPException { |
duke@1 | 93 | if (closed) { |
duke@1 | 94 | log.severe("SAAJ0003.p2p.call.already.closed.conn"); |
duke@1 | 95 | throw new SOAPExceptionImpl("Connection is closed"); |
duke@1 | 96 | } |
duke@1 | 97 | |
duke@1 | 98 | Class urlEndpointClass = null; |
duke@1 | 99 | |
duke@1 | 100 | try { |
duke@1 | 101 | urlEndpointClass = Class.forName("javax.xml.messaging.URLEndpoint"); |
duke@1 | 102 | } catch (Exception ex) { |
duke@1 | 103 | //Do nothing. URLEndpoint is available only when JAXM is there. |
duke@1 | 104 | log.finest("SAAJ0090.p2p.endpoint.available.only.for.JAXM"); |
duke@1 | 105 | } |
duke@1 | 106 | |
duke@1 | 107 | if (urlEndpointClass != null) { |
duke@1 | 108 | if (urlEndpointClass.isInstance(endPoint)) { |
duke@1 | 109 | String url = null; |
duke@1 | 110 | |
duke@1 | 111 | try { |
duke@1 | 112 | Method m = urlEndpointClass.getMethod("getURL", (Class[])null); |
duke@1 | 113 | url = (String) m.invoke(endPoint, (Object[])null); |
duke@1 | 114 | } catch (Exception ex) { |
duke@1 | 115 | // TBD -- exception chaining |
duke@1 | 116 | log.log(Level.SEVERE,"SAAJ0004.p2p.internal.err",ex); |
duke@1 | 117 | throw new SOAPExceptionImpl( |
duke@1 | 118 | "Internal error: " + ex.getMessage()); |
duke@1 | 119 | } |
duke@1 | 120 | try { |
duke@1 | 121 | endPoint = new URL(url); |
duke@1 | 122 | } catch (MalformedURLException mex) { |
duke@1 | 123 | log.log(Level.SEVERE,"SAAJ0005.p2p.", mex); |
duke@1 | 124 | throw new SOAPExceptionImpl("Bad URL: " + mex.getMessage()); |
duke@1 | 125 | } |
duke@1 | 126 | } |
duke@1 | 127 | } |
duke@1 | 128 | |
duke@1 | 129 | if (endPoint instanceof java.lang.String) { |
duke@1 | 130 | try { |
duke@1 | 131 | endPoint = new URL((String) endPoint); |
duke@1 | 132 | } catch (MalformedURLException mex) { |
duke@1 | 133 | log.log(Level.SEVERE, "SAAJ0006.p2p.bad.URL", mex); |
duke@1 | 134 | throw new SOAPExceptionImpl("Bad URL: " + mex.getMessage()); |
duke@1 | 135 | } |
duke@1 | 136 | } |
duke@1 | 137 | |
duke@1 | 138 | if (endPoint instanceof URL) |
duke@1 | 139 | try { |
duke@1 | 140 | PriviledgedPost pp = |
duke@1 | 141 | new PriviledgedPost(this, message, (URL) endPoint); |
duke@1 | 142 | SOAPMessage response = |
duke@1 | 143 | (SOAPMessage) AccessController.doPrivileged(pp); |
duke@1 | 144 | |
duke@1 | 145 | return response; |
duke@1 | 146 | } catch (Exception ex) { |
duke@1 | 147 | // TBD -- chaining? |
duke@1 | 148 | throw new SOAPExceptionImpl(ex); |
duke@1 | 149 | } else { |
duke@1 | 150 | log.severe("SAAJ0007.p2p.bad.endPoint.type"); |
duke@1 | 151 | throw new SOAPExceptionImpl("Bad endPoint type " + endPoint); |
duke@1 | 152 | } |
duke@1 | 153 | } |
duke@1 | 154 | |
duke@1 | 155 | static class PriviledgedPost implements PrivilegedExceptionAction { |
duke@1 | 156 | |
duke@1 | 157 | HttpSOAPConnection c; |
duke@1 | 158 | SOAPMessage message; |
duke@1 | 159 | URL endPoint; |
duke@1 | 160 | |
duke@1 | 161 | PriviledgedPost( |
duke@1 | 162 | HttpSOAPConnection c, |
duke@1 | 163 | SOAPMessage message, |
duke@1 | 164 | URL endPoint) { |
duke@1 | 165 | this.c = c; |
duke@1 | 166 | this.message = message; |
duke@1 | 167 | this.endPoint = endPoint; |
duke@1 | 168 | } |
duke@1 | 169 | |
duke@1 | 170 | public Object run() throws Exception { |
duke@1 | 171 | return c.post(message, endPoint); |
duke@1 | 172 | } |
duke@1 | 173 | } |
duke@1 | 174 | |
duke@1 | 175 | // TBD |
duke@1 | 176 | // Fix this to do things better. |
duke@1 | 177 | |
duke@1 | 178 | private String proxyHost = null; |
duke@1 | 179 | |
duke@1 | 180 | static class PriviledgedSetProxyAction implements PrivilegedExceptionAction { |
duke@1 | 181 | |
duke@1 | 182 | String proxyHost = null; |
duke@1 | 183 | int proxyPort = 0; |
duke@1 | 184 | |
duke@1 | 185 | PriviledgedSetProxyAction(String host, int port) { |
duke@1 | 186 | this.proxyHost = host; |
duke@1 | 187 | this.proxyPort = port; |
duke@1 | 188 | } |
duke@1 | 189 | |
duke@1 | 190 | public Object run() throws Exception { |
duke@1 | 191 | System.setProperty("http.proxyHost", proxyHost); |
duke@1 | 192 | System.setProperty("http.proxyPort", new Integer(proxyPort).toString()); |
duke@1 | 193 | log.log(Level.FINE, "SAAJ0050.p2p.proxy.host", |
duke@1 | 194 | new String[] { proxyHost }); |
duke@1 | 195 | log.log(Level.FINE, "SAAJ0051.p2p.proxy.port", |
duke@1 | 196 | new String[] { new Integer(proxyPort).toString() }); |
duke@1 | 197 | return proxyHost; |
duke@1 | 198 | } |
duke@1 | 199 | } |
duke@1 | 200 | |
duke@1 | 201 | |
duke@1 | 202 | public void setProxy(String host, int port) { |
duke@1 | 203 | try { |
duke@1 | 204 | proxyPort = port; |
duke@1 | 205 | PriviledgedSetProxyAction ps = new PriviledgedSetProxyAction(host, port); |
duke@1 | 206 | proxyHost = (String) AccessController.doPrivileged(ps); |
duke@1 | 207 | } catch (Exception e) { |
duke@1 | 208 | throw new RuntimeException(e); |
duke@1 | 209 | } |
duke@1 | 210 | } |
duke@1 | 211 | |
duke@1 | 212 | public String getProxyHost() { |
duke@1 | 213 | return proxyHost; |
duke@1 | 214 | } |
duke@1 | 215 | |
duke@1 | 216 | private int proxyPort = -1; |
duke@1 | 217 | |
duke@1 | 218 | public int getProxyPort() { |
duke@1 | 219 | return proxyPort; |
duke@1 | 220 | } |
duke@1 | 221 | |
duke@1 | 222 | SOAPMessage post(SOAPMessage message, URL endPoint) throws SOAPException { |
duke@1 | 223 | boolean isFailure = false; |
duke@1 | 224 | |
duke@1 | 225 | URL url = null; |
duke@1 | 226 | HttpURLConnection httpConnection = null; |
duke@1 | 227 | |
duke@1 | 228 | int responseCode = 0; |
duke@1 | 229 | try { |
duke@1 | 230 | if (endPoint.getProtocol().equals("https")) |
duke@1 | 231 | //if(!setHttps) |
duke@1 | 232 | initHttps(); |
duke@1 | 233 | // Process the URL |
duke@1 | 234 | JaxmURI uri = new JaxmURI(endPoint.toString()); |
duke@1 | 235 | String userInfo = uri.getUserinfo(); |
duke@1 | 236 | |
duke@1 | 237 | url = endPoint; |
duke@1 | 238 | |
duke@1 | 239 | if (dL > 0) |
duke@1 | 240 | d("uri: " + userInfo + " " + url + " " + uri); |
duke@1 | 241 | |
duke@1 | 242 | // TBD |
duke@1 | 243 | // Will deal with https later. |
duke@1 | 244 | if (!url.getProtocol().equalsIgnoreCase("http") |
duke@1 | 245 | && !url.getProtocol().equalsIgnoreCase("https")) { |
duke@1 | 246 | log.severe("SAAJ0052.p2p.protocol.mustbe.http.or.https"); |
duke@1 | 247 | throw new IllegalArgumentException( |
duke@1 | 248 | "Protocol " |
duke@1 | 249 | + url.getProtocol() |
duke@1 | 250 | + " not supported in URL " |
duke@1 | 251 | + url); |
duke@1 | 252 | } |
duke@1 | 253 | httpConnection = (HttpURLConnection) createConnection(url); |
duke@1 | 254 | |
duke@1 | 255 | httpConnection.setRequestMethod("POST"); |
duke@1 | 256 | |
duke@1 | 257 | httpConnection.setDoOutput(true); |
duke@1 | 258 | httpConnection.setDoInput(true); |
duke@1 | 259 | httpConnection.setUseCaches(false); |
duke@1 | 260 | HttpURLConnection.setFollowRedirects(true); |
duke@1 | 261 | |
duke@1 | 262 | if (message.saveRequired()) |
duke@1 | 263 | message.saveChanges(); |
duke@1 | 264 | |
duke@1 | 265 | MimeHeaders headers = message.getMimeHeaders(); |
duke@1 | 266 | |
duke@1 | 267 | Iterator it = headers.getAllHeaders(); |
duke@1 | 268 | boolean hasAuth = false; // true if we find explicit Auth header |
duke@1 | 269 | while (it.hasNext()) { |
duke@1 | 270 | MimeHeader header = (MimeHeader) it.next(); |
duke@1 | 271 | |
duke@1 | 272 | String[] values = headers.getHeader(header.getName()); |
duke@1 | 273 | |
duke@1 | 274 | if (values.length == 1) |
duke@1 | 275 | httpConnection.setRequestProperty( |
duke@1 | 276 | header.getName(), |
duke@1 | 277 | header.getValue()); |
duke@1 | 278 | else { |
duke@1 | 279 | StringBuffer concat = new StringBuffer(); |
duke@1 | 280 | int i = 0; |
duke@1 | 281 | while (i < values.length) { |
duke@1 | 282 | if (i != 0) |
duke@1 | 283 | concat.append(','); |
duke@1 | 284 | concat.append(values[i]); |
duke@1 | 285 | i++; |
duke@1 | 286 | } |
duke@1 | 287 | |
duke@1 | 288 | httpConnection.setRequestProperty( |
duke@1 | 289 | header.getName(), |
duke@1 | 290 | concat.toString()); |
duke@1 | 291 | } |
duke@1 | 292 | |
duke@1 | 293 | if ("Authorization".equals(header.getName())) { |
duke@1 | 294 | hasAuth = true; |
duke@1 | 295 | log.fine("SAAJ0091.p2p.https.auth.in.POST.true"); |
duke@1 | 296 | } |
duke@1 | 297 | } |
duke@1 | 298 | |
duke@1 | 299 | if (!hasAuth && userInfo != null) { |
duke@1 | 300 | initAuthUserInfo(httpConnection, userInfo); |
duke@1 | 301 | } |
duke@1 | 302 | |
duke@1 | 303 | OutputStream out = httpConnection.getOutputStream(); |
duke@1 | 304 | message.writeTo(out); |
duke@1 | 305 | |
duke@1 | 306 | out.flush(); |
duke@1 | 307 | out.close(); |
duke@1 | 308 | |
duke@1 | 309 | httpConnection.connect(); |
duke@1 | 310 | |
duke@1 | 311 | try { |
duke@1 | 312 | |
duke@1 | 313 | responseCode = httpConnection.getResponseCode(); |
duke@1 | 314 | |
duke@1 | 315 | // let HTTP_INTERNAL_ERROR (500) through because it is used for SOAP faults |
duke@1 | 316 | if (responseCode == HttpURLConnection.HTTP_INTERNAL_ERROR) { |
duke@1 | 317 | isFailure = true; |
duke@1 | 318 | } |
duke@1 | 319 | //else if (responseCode != HttpURLConnection.HTTP_OK) |
duke@1 | 320 | //else if (!(responseCode >= HttpURLConnection.HTTP_OK && responseCode < 207)) |
duke@1 | 321 | else if ((responseCode / 100) != 2) { |
duke@1 | 322 | log.log(Level.SEVERE, |
duke@1 | 323 | "SAAJ0008.p2p.bad.response", |
duke@1 | 324 | new String[] {httpConnection.getResponseMessage()}); |
duke@1 | 325 | throw new SOAPExceptionImpl( |
duke@1 | 326 | "Bad response: (" |
duke@1 | 327 | + responseCode |
duke@1 | 328 | + httpConnection.getResponseMessage()); |
duke@1 | 329 | |
duke@1 | 330 | } |
duke@1 | 331 | } catch (IOException e) { |
duke@1 | 332 | // on JDK1.3.1_01, we end up here, but then getResponseCode() succeeds! |
duke@1 | 333 | responseCode = httpConnection.getResponseCode(); |
duke@1 | 334 | if (responseCode == HttpURLConnection.HTTP_INTERNAL_ERROR) { |
duke@1 | 335 | isFailure = true; |
duke@1 | 336 | } else { |
duke@1 | 337 | throw e; |
duke@1 | 338 | } |
duke@1 | 339 | |
duke@1 | 340 | } |
duke@1 | 341 | |
duke@1 | 342 | } catch (SOAPException ex) { |
duke@1 | 343 | throw ex; |
duke@1 | 344 | } catch (Exception ex) { |
duke@1 | 345 | log.severe("SAAJ0009.p2p.msg.send.failed"); |
duke@1 | 346 | throw new SOAPExceptionImpl("Message send failed", ex); |
duke@1 | 347 | } |
duke@1 | 348 | |
duke@1 | 349 | SOAPMessage response = null; |
duke@1 | 350 | if (responseCode == HttpURLConnection.HTTP_OK || isFailure) { |
duke@1 | 351 | try { |
duke@1 | 352 | MimeHeaders headers = new MimeHeaders(); |
duke@1 | 353 | |
duke@1 | 354 | String key, value; |
duke@1 | 355 | |
duke@1 | 356 | // Header field 0 is the status line so we skip it. |
duke@1 | 357 | |
duke@1 | 358 | int i = 1; |
duke@1 | 359 | |
duke@1 | 360 | while (true) { |
duke@1 | 361 | key = httpConnection.getHeaderFieldKey(i); |
duke@1 | 362 | value = httpConnection.getHeaderField(i); |
duke@1 | 363 | |
duke@1 | 364 | if (key == null && value == null) |
duke@1 | 365 | break; |
duke@1 | 366 | |
duke@1 | 367 | if (key != null) { |
duke@1 | 368 | StringTokenizer values = |
duke@1 | 369 | new StringTokenizer(value, ","); |
duke@1 | 370 | while (values.hasMoreTokens()) |
duke@1 | 371 | headers.addHeader(key, values.nextToken().trim()); |
duke@1 | 372 | } |
duke@1 | 373 | i++; |
duke@1 | 374 | } |
duke@1 | 375 | |
duke@1 | 376 | InputStream httpIn = |
duke@1 | 377 | (isFailure |
duke@1 | 378 | ? httpConnection.getErrorStream() |
duke@1 | 379 | : httpConnection.getInputStream()); |
duke@1 | 380 | |
duke@1 | 381 | byte[] bytes = readFully(httpIn); |
duke@1 | 382 | |
duke@1 | 383 | int length = |
duke@1 | 384 | httpConnection.getContentLength() == -1 |
duke@1 | 385 | ? bytes.length |
duke@1 | 386 | : httpConnection.getContentLength(); |
duke@1 | 387 | |
duke@1 | 388 | // If no reply message is returned, |
duke@1 | 389 | // content-Length header field value is expected to be zero. |
duke@1 | 390 | if (length == 0) { |
duke@1 | 391 | response = null; |
duke@1 | 392 | log.warning("SAAJ0014.p2p.content.zero"); |
duke@1 | 393 | } else { |
duke@1 | 394 | ByteInputStream in = new ByteInputStream(bytes, length); |
duke@1 | 395 | response = messageFactory.createMessage(headers, in); |
duke@1 | 396 | } |
duke@1 | 397 | |
duke@1 | 398 | httpIn.close(); |
duke@1 | 399 | httpConnection.disconnect(); |
duke@1 | 400 | |
duke@1 | 401 | } catch (SOAPException ex) { |
duke@1 | 402 | throw ex; |
duke@1 | 403 | } catch (Exception ex) { |
duke@1 | 404 | log.log(Level.SEVERE,"SAAJ0010.p2p.cannot.read.resp", ex); |
duke@1 | 405 | throw new SOAPExceptionImpl( |
duke@1 | 406 | "Unable to read response: " + ex.getMessage()); |
duke@1 | 407 | } |
duke@1 | 408 | } |
duke@1 | 409 | return response; |
duke@1 | 410 | } |
duke@1 | 411 | |
duke@1 | 412 | // Object identifies where the request should be sent. |
duke@1 | 413 | // It is required to support objects of type String and java.net.URL. |
duke@1 | 414 | |
duke@1 | 415 | public SOAPMessage get(Object endPoint) throws SOAPException { |
duke@1 | 416 | if (closed) { |
duke@1 | 417 | log.severe("SAAJ0011.p2p.get.already.closed.conn"); |
duke@1 | 418 | throw new SOAPExceptionImpl("Connection is closed"); |
duke@1 | 419 | } |
duke@1 | 420 | Class urlEndpointClass = null; |
duke@1 | 421 | |
duke@1 | 422 | try { |
duke@1 | 423 | urlEndpointClass = Class.forName("javax.xml.messaging.URLEndpoint"); |
duke@1 | 424 | } catch (Exception ex) { |
duke@1 | 425 | //Do nothing. URLEndpoint is available only when JAXM is there. |
duke@1 | 426 | } |
duke@1 | 427 | |
duke@1 | 428 | if (urlEndpointClass != null) { |
duke@1 | 429 | if (urlEndpointClass.isInstance(endPoint)) { |
duke@1 | 430 | String url = null; |
duke@1 | 431 | |
duke@1 | 432 | try { |
duke@1 | 433 | Method m = urlEndpointClass.getMethod("getURL", (Class[])null); |
duke@1 | 434 | url = (String) m.invoke(endPoint, (Object[])null); |
duke@1 | 435 | } catch (Exception ex) { |
duke@1 | 436 | log.severe("SAAJ0004.p2p.internal.err"); |
duke@1 | 437 | throw new SOAPExceptionImpl( |
duke@1 | 438 | "Internal error: " + ex.getMessage()); |
duke@1 | 439 | } |
duke@1 | 440 | try { |
duke@1 | 441 | endPoint = new URL(url); |
duke@1 | 442 | } catch (MalformedURLException mex) { |
duke@1 | 443 | log.severe("SAAJ0005.p2p."); |
duke@1 | 444 | throw new SOAPExceptionImpl("Bad URL: " + mex.getMessage()); |
duke@1 | 445 | } |
duke@1 | 446 | } |
duke@1 | 447 | } |
duke@1 | 448 | |
duke@1 | 449 | if (endPoint instanceof java.lang.String) { |
duke@1 | 450 | try { |
duke@1 | 451 | endPoint = new URL((String) endPoint); |
duke@1 | 452 | } catch (MalformedURLException mex) { |
duke@1 | 453 | log.severe("SAAJ0006.p2p.bad.URL"); |
duke@1 | 454 | throw new SOAPExceptionImpl("Bad URL: " + mex.getMessage()); |
duke@1 | 455 | } |
duke@1 | 456 | } |
duke@1 | 457 | |
duke@1 | 458 | if (endPoint instanceof URL) |
duke@1 | 459 | try { |
duke@1 | 460 | PriviledgedGet pg = new PriviledgedGet(this, (URL) endPoint); |
duke@1 | 461 | SOAPMessage response = |
duke@1 | 462 | (SOAPMessage) AccessController.doPrivileged(pg); |
duke@1 | 463 | |
duke@1 | 464 | return response; |
duke@1 | 465 | } catch (Exception ex) { |
duke@1 | 466 | throw new SOAPExceptionImpl(ex); |
duke@1 | 467 | } else |
duke@1 | 468 | throw new SOAPExceptionImpl("Bad endPoint type " + endPoint); |
duke@1 | 469 | } |
duke@1 | 470 | |
duke@1 | 471 | static class PriviledgedGet implements PrivilegedExceptionAction { |
duke@1 | 472 | |
duke@1 | 473 | HttpSOAPConnection c; |
duke@1 | 474 | URL endPoint; |
duke@1 | 475 | |
duke@1 | 476 | PriviledgedGet(HttpSOAPConnection c, URL endPoint) { |
duke@1 | 477 | this.c = c; |
duke@1 | 478 | this.endPoint = endPoint; |
duke@1 | 479 | } |
duke@1 | 480 | |
duke@1 | 481 | public Object run() throws Exception { |
duke@1 | 482 | return c.get(endPoint); |
duke@1 | 483 | } |
duke@1 | 484 | } |
duke@1 | 485 | |
duke@1 | 486 | SOAPMessage get(URL endPoint) throws SOAPException { |
duke@1 | 487 | boolean isFailure = false; |
duke@1 | 488 | |
duke@1 | 489 | URL url = null; |
duke@1 | 490 | HttpURLConnection httpConnection = null; |
duke@1 | 491 | |
duke@1 | 492 | int responseCode = 0; |
duke@1 | 493 | try { |
duke@1 | 494 | /// Is https GET allowed?? |
duke@1 | 495 | if (endPoint.getProtocol().equals("https")) |
duke@1 | 496 | initHttps(); |
duke@1 | 497 | // Process the URL |
duke@1 | 498 | JaxmURI uri = new JaxmURI(endPoint.toString()); |
duke@1 | 499 | String userInfo = uri.getUserinfo(); |
duke@1 | 500 | |
duke@1 | 501 | url = endPoint; |
duke@1 | 502 | |
duke@1 | 503 | if (dL > 0) |
duke@1 | 504 | d("uri: " + userInfo + " " + url + " " + uri); |
duke@1 | 505 | |
duke@1 | 506 | // TBD |
duke@1 | 507 | // Will deal with https later. |
duke@1 | 508 | if (!url.getProtocol().equalsIgnoreCase("http") |
duke@1 | 509 | && !url.getProtocol().equalsIgnoreCase("https")) { |
duke@1 | 510 | log.severe("SAAJ0052.p2p.protocol.mustbe.http.or.https"); |
duke@1 | 511 | throw new IllegalArgumentException( |
duke@1 | 512 | "Protocol " |
duke@1 | 513 | + url.getProtocol() |
duke@1 | 514 | + " not supported in URL " |
duke@1 | 515 | + url); |
duke@1 | 516 | } |
duke@1 | 517 | httpConnection = (HttpURLConnection) createConnection(url); |
duke@1 | 518 | |
duke@1 | 519 | httpConnection.setRequestMethod("GET"); |
duke@1 | 520 | |
duke@1 | 521 | httpConnection.setDoOutput(true); |
duke@1 | 522 | httpConnection.setDoInput(true); |
duke@1 | 523 | httpConnection.setUseCaches(false); |
duke@1 | 524 | HttpURLConnection.setFollowRedirects(true); |
duke@1 | 525 | |
duke@1 | 526 | httpConnection.connect(); |
duke@1 | 527 | |
duke@1 | 528 | try { |
duke@1 | 529 | |
duke@1 | 530 | responseCode = httpConnection.getResponseCode(); |
duke@1 | 531 | |
duke@1 | 532 | // let HTTP_INTERNAL_ERROR (500) through because it is used for SOAP faults |
duke@1 | 533 | if (responseCode == HttpURLConnection.HTTP_INTERNAL_ERROR) { |
duke@1 | 534 | isFailure = true; |
duke@1 | 535 | } else if ((responseCode / 100) != 2) { |
duke@1 | 536 | log.log(Level.SEVERE, |
duke@1 | 537 | "SAAJ0008.p2p.bad.response", |
duke@1 | 538 | new String[] { httpConnection.getResponseMessage()}); |
duke@1 | 539 | throw new SOAPExceptionImpl( |
duke@1 | 540 | "Bad response: (" |
duke@1 | 541 | + responseCode |
duke@1 | 542 | + httpConnection.getResponseMessage()); |
duke@1 | 543 | |
duke@1 | 544 | } |
duke@1 | 545 | } catch (IOException e) { |
duke@1 | 546 | // on JDK1.3.1_01, we end up here, but then getResponseCode() succeeds! |
duke@1 | 547 | responseCode = httpConnection.getResponseCode(); |
duke@1 | 548 | if (responseCode == HttpURLConnection.HTTP_INTERNAL_ERROR) { |
duke@1 | 549 | isFailure = true; |
duke@1 | 550 | } else { |
duke@1 | 551 | throw e; |
duke@1 | 552 | } |
duke@1 | 553 | |
duke@1 | 554 | } |
duke@1 | 555 | |
duke@1 | 556 | } catch (SOAPException ex) { |
duke@1 | 557 | throw ex; |
duke@1 | 558 | } catch (Exception ex) { |
duke@1 | 559 | log.severe("SAAJ0012.p2p.get.failed"); |
duke@1 | 560 | throw new SOAPExceptionImpl("Get failed", ex); |
duke@1 | 561 | } |
duke@1 | 562 | |
duke@1 | 563 | SOAPMessage response = null; |
duke@1 | 564 | if (responseCode == HttpURLConnection.HTTP_OK || isFailure) { |
duke@1 | 565 | try { |
duke@1 | 566 | MimeHeaders headers = new MimeHeaders(); |
duke@1 | 567 | |
duke@1 | 568 | String key, value; |
duke@1 | 569 | |
duke@1 | 570 | // Header field 0 is the status line so we skip it. |
duke@1 | 571 | |
duke@1 | 572 | int i = 1; |
duke@1 | 573 | |
duke@1 | 574 | while (true) { |
duke@1 | 575 | key = httpConnection.getHeaderFieldKey(i); |
duke@1 | 576 | value = httpConnection.getHeaderField(i); |
duke@1 | 577 | |
duke@1 | 578 | if (key == null && value == null) |
duke@1 | 579 | break; |
duke@1 | 580 | |
duke@1 | 581 | if (key != null) { |
duke@1 | 582 | StringTokenizer values = |
duke@1 | 583 | new StringTokenizer(value, ","); |
duke@1 | 584 | while (values.hasMoreTokens()) |
duke@1 | 585 | headers.addHeader(key, values.nextToken().trim()); |
duke@1 | 586 | } |
duke@1 | 587 | i++; |
duke@1 | 588 | } |
duke@1 | 589 | |
duke@1 | 590 | InputStream httpIn = |
duke@1 | 591 | (isFailure |
duke@1 | 592 | ? httpConnection.getErrorStream() |
duke@1 | 593 | : httpConnection.getInputStream()); |
duke@1 | 594 | |
duke@1 | 595 | byte[] bytes = readFully(httpIn); |
duke@1 | 596 | |
duke@1 | 597 | int length = |
duke@1 | 598 | httpConnection.getContentLength() == -1 |
duke@1 | 599 | ? bytes.length |
duke@1 | 600 | : httpConnection.getContentLength(); |
duke@1 | 601 | |
duke@1 | 602 | // If no reply message is returned, |
duke@1 | 603 | // content-Length header field value is expected to be zero. |
duke@1 | 604 | if (length == 0) { |
duke@1 | 605 | response = null; |
duke@1 | 606 | log.warning("SAAJ0014.p2p.content.zero"); |
duke@1 | 607 | } else { |
duke@1 | 608 | |
duke@1 | 609 | ByteInputStream in = new ByteInputStream(bytes, length); |
duke@1 | 610 | response = messageFactory.createMessage(headers, in); |
duke@1 | 611 | } |
duke@1 | 612 | |
duke@1 | 613 | httpIn.close(); |
duke@1 | 614 | httpConnection.disconnect(); |
duke@1 | 615 | |
duke@1 | 616 | } catch (SOAPException ex) { |
duke@1 | 617 | throw ex; |
duke@1 | 618 | } catch (Exception ex) { |
duke@1 | 619 | log.log(Level.SEVERE, |
duke@1 | 620 | "SAAJ0010.p2p.cannot.read.resp", |
duke@1 | 621 | ex); |
duke@1 | 622 | throw new SOAPExceptionImpl( |
duke@1 | 623 | "Unable to read response: " + ex.getMessage()); |
duke@1 | 624 | } |
duke@1 | 625 | } |
duke@1 | 626 | return response; |
duke@1 | 627 | } |
duke@1 | 628 | |
duke@1 | 629 | private byte[] readFully(InputStream istream) throws IOException { |
duke@1 | 630 | ByteArrayOutputStream bout = new ByteArrayOutputStream(); |
duke@1 | 631 | byte[] buf = new byte[1024]; |
duke@1 | 632 | int num = 0; |
duke@1 | 633 | |
duke@1 | 634 | while ((num = istream.read(buf)) != -1) { |
duke@1 | 635 | bout.write(buf, 0, num); |
duke@1 | 636 | } |
duke@1 | 637 | |
duke@1 | 638 | byte[] ret = bout.toByteArray(); |
duke@1 | 639 | |
duke@1 | 640 | return ret; |
duke@1 | 641 | } |
duke@1 | 642 | |
duke@1 | 643 | private static String SSL_PKG = "com.sun.net.ssl.internal.www.protocol"; |
duke@1 | 644 | private static String SSL_PROVIDER = |
duke@1 | 645 | "com.sun.net.ssl.internal.ssl.Provider"; |
duke@1 | 646 | private void initHttps() { |
duke@1 | 647 | //if(!setHttps) { |
duke@1 | 648 | String pkgs = System.getProperty("java.protocol.handler.pkgs"); |
duke@1 | 649 | log.log(Level.FINE, |
duke@1 | 650 | "SAAJ0053.p2p.providers", |
duke@1 | 651 | new String[] { pkgs }); |
duke@1 | 652 | |
duke@1 | 653 | if (pkgs == null || pkgs.indexOf(SSL_PKG) < 0) { |
duke@1 | 654 | if (pkgs == null) |
duke@1 | 655 | pkgs = SSL_PKG; |
duke@1 | 656 | else |
duke@1 | 657 | pkgs = pkgs + "|" + SSL_PKG; |
duke@1 | 658 | System.setProperty("java.protocol.handler.pkgs", pkgs); |
duke@1 | 659 | log.log(Level.FINE, |
duke@1 | 660 | "SAAJ0054.p2p.set.providers", |
duke@1 | 661 | new String[] { pkgs }); |
duke@1 | 662 | try { |
duke@1 | 663 | Class c = Class.forName(SSL_PROVIDER); |
duke@1 | 664 | Provider p = (Provider) c.newInstance(); |
duke@1 | 665 | Security.addProvider(p); |
duke@1 | 666 | log.log(Level.FINE, |
duke@1 | 667 | "SAAJ0055.p2p.added.ssl.provider", |
duke@1 | 668 | new String[] { SSL_PROVIDER }); |
duke@1 | 669 | //System.out.println("Added SSL_PROVIDER " + SSL_PROVIDER); |
duke@1 | 670 | //setHttps = true; |
duke@1 | 671 | } catch (Exception ex) { |
duke@1 | 672 | } |
duke@1 | 673 | } |
duke@1 | 674 | //} |
duke@1 | 675 | } |
duke@1 | 676 | |
duke@1 | 677 | private void initAuthUserInfo(HttpURLConnection conn, String userInfo) { |
duke@1 | 678 | String user; |
duke@1 | 679 | String password; |
duke@1 | 680 | if (userInfo != null) { // get the user and password |
duke@1 | 681 | //System.out.println("UserInfo= " + userInfo ); |
duke@1 | 682 | int delimiter = userInfo.indexOf(':'); |
duke@1 | 683 | if (delimiter == -1) { |
duke@1 | 684 | user = ParseUtil.decode(userInfo); |
duke@1 | 685 | password = null; |
duke@1 | 686 | } else { |
duke@1 | 687 | user = ParseUtil.decode(userInfo.substring(0, delimiter++)); |
duke@1 | 688 | password = ParseUtil.decode(userInfo.substring(delimiter)); |
duke@1 | 689 | } |
duke@1 | 690 | |
duke@1 | 691 | String plain = user + ":"; |
duke@1 | 692 | byte[] nameBytes = plain.getBytes(); |
duke@1 | 693 | byte[] passwdBytes = password.getBytes(); |
duke@1 | 694 | |
duke@1 | 695 | // concatenate user name and password bytes and encode them |
duke@1 | 696 | byte[] concat = new byte[nameBytes.length + passwdBytes.length]; |
duke@1 | 697 | |
duke@1 | 698 | System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length); |
duke@1 | 699 | System.arraycopy( |
duke@1 | 700 | passwdBytes, |
duke@1 | 701 | 0, |
duke@1 | 702 | concat, |
duke@1 | 703 | nameBytes.length, |
duke@1 | 704 | passwdBytes.length); |
duke@1 | 705 | String auth = "Basic " + new String(Base64.encode(concat)); |
duke@1 | 706 | conn.setRequestProperty("Authorization", auth); |
duke@1 | 707 | if (dL > 0) |
duke@1 | 708 | d("Adding auth " + auth); |
duke@1 | 709 | } |
duke@1 | 710 | } |
duke@1 | 711 | |
duke@1 | 712 | private static final int dL = 0; |
duke@1 | 713 | private void d(String s) { |
duke@1 | 714 | log.log(Level.SEVERE, |
duke@1 | 715 | "SAAJ0013.p2p.HttpSOAPConnection", |
duke@1 | 716 | new String[] { s }); |
duke@1 | 717 | System.err.println("HttpSOAPConnection: " + s); |
duke@1 | 718 | } |
duke@1 | 719 | |
duke@1 | 720 | private java.net.HttpURLConnection createConnection(URL endpoint) |
duke@1 | 721 | throws IOException { |
duke@1 | 722 | return (HttpURLConnection) endpoint.openConnection(); |
duke@1 | 723 | } |
duke@1 | 724 | |
duke@1 | 725 | } |