1 55 package org.jboss.axis.transport.http; 56 57 import java.io.BufferedInputStream ; 58 import java.io.BufferedOutputStream ; 59 import java.io.ByteArrayOutputStream ; 60 import java.io.IOException ; 61 import java.io.InputStream ; 62 import java.io.OutputStream ; 63 import java.net.Socket ; 64 import java.net.URL ; 65 import java.util.HashMap ; 66 import java.util.Iterator ; 67 68 import javax.xml.soap.MimeHeader ; 69 import javax.xml.soap.MimeHeaders ; 70 import javax.xml.soap.SOAPException ; 71 72 import org.jboss.axis.AxisFault; 73 import org.jboss.axis.Message; 74 import org.jboss.axis.MessageContext; 75 import org.jboss.axis.MessagePart; 76 import org.jboss.axis.components.net.BooleanHolder; 77 import org.jboss.axis.components.net.SocketFactory; 78 import org.jboss.axis.components.net.SocketFactoryFactory; 79 import org.jboss.axis.encoding.Base64; 80 import org.jboss.axis.handlers.BasicHandler; 81 import org.jboss.axis.soap.SOAP12Constants; 82 import org.jboss.axis.soap.SOAPConstants; 83 import org.jboss.axis.utils.Messages; 84 import org.jboss.logging.Logger; 85 86 92 public class HTTPSender extends BasicHandler 93 { 94 95 private static Logger log = Logger.getLogger(HTTPSender.class.getName()); 96 97 104 public void invoke(MessageContext msgContext) throws AxisFault 105 { 106 107 if (log.isDebugEnabled()) 108 { 109 log.debug(Messages.getMessage("enter00", "HTTPSender::invoke")); 110 } 111 try 112 { 113 BooleanHolder useFullURL = new BooleanHolder(false); 114 StringBuffer otherHeaders = new StringBuffer (); 115 URL targetURL = new URL (msgContext.getStrProp(MessageContext.TRANS_URL)); 116 String host = targetURL.getHost(); 117 int port = targetURL.getPort(); 118 Socket sock = null; 119 120 log.debug("TargetURL: " + targetURL); 121 122 sock = getSocket(targetURL.getProtocol(), host, port, otherHeaders, useFullURL, msgContext.getTransportOptions()); 123 124 if (msgContext.getTimeout() != 0) 126 { 127 sock.setSoTimeout(msgContext.getTimeout()); 128 } 129 130 InputStream inp = writeToSocket(sock, msgContext, targetURL, otherHeaders, host, port, useFullURL); 132 133 MimeHeaders headers = new MimeHeaders (); 135 inp = readHeadersFromSocket(sock, msgContext, inp, headers); 136 readFromSocket(sock, msgContext, inp, headers); 137 } 138 catch (Exception e) 139 { 140 log.debug(e.getMessage(), e); 141 throw AxisFault.makeFault(e); 142 } 143 if (log.isDebugEnabled()) 144 { 145 log.debug(Messages.getMessage("exit00", 146 "HTTPDispatchHandler::invoke")); 147 } 148 } 149 150 161 private Socket getSocket(String protocol, 162 String host, int port, StringBuffer otherHeaders, BooleanHolder useFullURL, HashMap options) 163 throws Exception 164 { 165 SocketFactory factory = SocketFactoryFactory.getFactory(protocol, options); 166 return factory.create(host, port, otherHeaders, useFullURL); 167 } 168 169 181 private InputStream writeToSocket(Socket sock, MessageContext msgContext, URL tmpURL, 182 StringBuffer otherHeaders, String host, int port, 183 BooleanHolder useFullURL) 184 throws IOException 185 { 186 187 String userID = null; 188 String passwd = null; 189 190 userID = msgContext.getUsername(); 191 passwd = msgContext.getPassword(); 192 193 String action = msgContext.useSOAPAction() 195 ? msgContext.getSOAPActionURI() 196 : ""; 197 198 if (action == null) 199 { 200 action = ""; 201 } 202 203 if ((userID == null) && (tmpURL.getUserInfo() != null)) 206 { 207 String info = tmpURL.getUserInfo(); 208 int sep = info.indexOf(':'); 209 210 if ((sep >= 0) && (sep + 1 < info.length())) 211 { 212 userID = info.substring(0, sep); 213 passwd = info.substring(sep + 1); 214 } 215 else 216 { 217 userID = info; 218 } 219 } 220 if (userID != null) 221 { 222 StringBuffer tmpBuf = new StringBuffer (); 223 224 tmpBuf.append(userID).append(":").append((passwd == null) 225 ? "" 226 : passwd); 227 otherHeaders.append(HTTPConstants.HEADER_AUTHORIZATION) 228 .append(": Basic ") 229 .append(Base64.encode(tmpBuf.toString().getBytes())) 230 .append("\r\n"); 231 } 232 233 if (msgContext.getMaintainSession()) 236 { 237 String cookie = msgContext.getStrProp(HTTPConstants.HEADER_COOKIE); 238 String cookie2 = msgContext.getStrProp(HTTPConstants.HEADER_COOKIE2); 239 240 if (cookie != null) 241 { 242 otherHeaders.append(HTTPConstants.HEADER_COOKIE).append(": ") 243 .append(cookie).append("\r\n"); 244 } 245 if (cookie2 != null) 246 { 247 otherHeaders.append(HTTPConstants.HEADER_COOKIE2).append(": ") 248 .append(cookie2).append("\r\n"); 249 } 250 } 251 252 StringBuffer header = new StringBuffer (); 253 254 String webMethod = null; 255 boolean posting = true; 256 257 if (msgContext.getSOAPConstants() == SOAPConstants.SOAP12_CONSTANTS) 260 webMethod = msgContext.getStrProp(SOAP12Constants.PROP_WEBMETHOD); 261 if (webMethod == null) 262 { 263 webMethod = HTTPConstants.HEADER_POST; 264 } 265 else 266 { 267 posting = webMethod.equals(HTTPConstants.HEADER_POST); 268 } 269 270 header.append(webMethod).append(" "); 271 if (useFullURL.value) 272 { 273 header.append(tmpURL.toExternalForm()); 274 } 275 else 276 { 277 header.append((((tmpURL.getFile() == null) 278 || tmpURL.getFile().equals("")) 279 ? "/" 280 : tmpURL.getFile())); 281 } 282 283 Message requestMsg = msgContext.getRequestMessage(); 284 285 boolean http10 = true; boolean httpChunkStream = false; boolean httpContinueExpected = false; String httpConnection = null; 290 291 String httpver = msgContext.getStrProp(MessageContext.HTTP_TRANSPORT_VERSION); 292 if (null == httpver) httpver = HTTPConstants.HEADER_PROTOCOL_V10; 293 httpver = httpver.trim(); 294 if (httpver.equals(HTTPConstants.HEADER_PROTOCOL_V11)) 295 { 296 http10 = false; 297 } 298 299 MimeHeaders mimeHeaders = requestMsg.getMimeHeaders(); 301 if (mimeHeaders != null) 302 { 303 Iterator i = mimeHeaders.getAllHeaders(); 304 while (i.hasNext()) 305 { 306 MimeHeader mimeHeader = (MimeHeader ) i.next(); 307 String name = mimeHeader.getName(); 308 String value = mimeHeader.getValue(); 309 if (name.equalsIgnoreCase(HTTPConstants.HEADER_TRANSFER_ENCODING)) 310 { 311 if (!http10) 312 { 313 if (null != value && value.trim().equalsIgnoreCase(HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED)) 314 httpChunkStream = true; 315 } 316 } 317 else if (name.equalsIgnoreCase(HTTPConstants.HEADER_HOST)) 318 { 319 } 321 else if (name.equalsIgnoreCase(HTTPConstants.HEADER_CONTENT_TYPE)) 322 { 323 } 325 else if (name.equalsIgnoreCase(HTTPConstants.HEADER_SOAP_ACTION)) 326 { 327 action = value; 329 } 330 else if (name.equalsIgnoreCase(HTTPConstants.HEADER_CONTENT_LENGTH)) 331 { 332 } 334 else if (name.equalsIgnoreCase(HTTPConstants.HEADER_COOKIE)) 335 { 336 } 338 else if (name.equalsIgnoreCase(HTTPConstants.HEADER_COOKIE2)) 339 { 340 } 342 else if (name.equalsIgnoreCase(HTTPConstants.HEADER_AUTHORIZATION)) 343 { 344 } 346 else if (name.equalsIgnoreCase(HTTPConstants.HEADER_PROXY_AUTHORIZATION)) 347 { 348 } 350 else if (name.equalsIgnoreCase(HTTPConstants.HEADER_CONNECTION)) 351 { 352 if (!http10) 353 { 354 if (value.trim().equalsIgnoreCase(HTTPConstants.HEADER_CONNECTION_CLOSE)) 355 httpConnection = HTTPConstants.HEADER_CONNECTION_CLOSE; 356 } 357 } 360 else if (!http10 && name.equalsIgnoreCase(HTTPConstants.HEADER_EXPECT)) 361 { 362 if (null != value && value.trim().equalsIgnoreCase(HTTPConstants.HEADER_EXPECT_100_Continue)) 363 httpContinueExpected = true; 364 } 365 else 366 { 367 otherHeaders.append(name).append(": ").append(value + "\r\n"); 368 } 369 } 370 } 371 372 if (!http10) 373 httpConnection = HTTPConstants.HEADER_CONNECTION_CLOSE; 375 header.append(" "); 376 header.append(http10 ? HTTPConstants.HEADER_PROTOCOL_10 : 377 HTTPConstants.HEADER_PROTOCOL_11) 378 .append("\r\n"); 379 if (posting) 380 { 381 header.append(HTTPConstants.HEADER_CONTENT_TYPE) 382 .append(": ") 383 .append(requestMsg.getContentType(msgContext.getSOAPConstants())) 384 .append("\r\n"); 385 } 386 header.append(HTTPConstants.HEADER_ACCEPT) .append(": ") 388 .append(HTTPConstants.HEADER_ACCEPT_APPL_SOAP) 389 .append(", ") 390 .append(HTTPConstants.HEADER_ACCEPT_APPLICATION_DIME) 391 .append(", ") 392 .append(HTTPConstants.HEADER_ACCEPT_MULTIPART_RELATED) 393 .append(", ") 394 .append(HTTPConstants.HEADER_ACCEPT_TEXT_ALL) 395 .append("\r\n") 396 .append(HTTPConstants.HEADER_USER_AGENT) .append(": ") 398 .append(Messages.getMessage("axisUserAgent")) 399 .append("\r\n") 400 .append(HTTPConstants.HEADER_HOST) .append(": ") 402 .append(host) 403 .append((port == -1) ? ("") : (":" + port)) 404 .append("\r\n") 405 .append(HTTPConstants.HEADER_CACHE_CONTROL) .append(": ") 407 .append(HTTPConstants.HEADER_CACHE_CONTROL_NOCACHE) 408 .append("\r\n") 409 .append(HTTPConstants.HEADER_PRAGMA) 410 .append(": ") 411 .append(HTTPConstants.HEADER_CACHE_CONTROL_NOCACHE) 412 .append("\r\n") 413 .append(HTTPConstants.HEADER_SOAP_ACTION) .append(": \"") 415 .append(action) 416 .append("\"\r\n"); 417 418 if (posting) 419 { 420 if (!httpChunkStream) 421 { 422 header.append(HTTPConstants.HEADER_CONTENT_LENGTH) 424 .append(": ") 425 .append(requestMsg.getContentLength()) 426 .append("\r\n"); 427 } 428 else 429 { 430 header.append(HTTPConstants.HEADER_TRANSFER_ENCODING) 432 .append(": ") 433 .append(HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED) 434 .append("\r\n"); 435 } 436 } 437 438 if (null != httpConnection) 439 { 440 header.append(HTTPConstants.HEADER_CONNECTION); 441 header.append(": "); 442 header.append(httpConnection); 443 header.append("\r\n"); 444 } 445 446 if (null != otherHeaders) 447 { 448 header.append(otherHeaders.toString()); 452 } 453 454 455 header.append("\r\n"); 457 OutputStream out = sock.getOutputStream(); 458 459 if (!posting) 460 { 461 out.write(header.toString() 462 .getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING)); 463 out.flush(); 464 return null; 465 } 466 467 InputStream inp = null; 468 469 if (httpChunkStream) 470 { 471 out.write(header.toString() 472 .getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING)); 473 } 474 475 if (httpContinueExpected) 476 { 477 out.flush(); 480 MimeHeaders cheaders = new MimeHeaders (); 481 inp = readHeadersFromSocket(sock, msgContext, null, cheaders); 482 int returnCode = -1; 483 Integer Irc = (Integer )msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE); 484 if (null != Irc) returnCode = Irc.intValue(); 485 if (100 == returnCode) 486 { 487 msgContext.removeProperty(HTTPConstants.MC_HTTP_STATUS_CODE); 489 msgContext.removeProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE); 490 } 491 else 492 { 493 String statusMessage = (String ) 495 msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE); 496 497 AxisFault fault = new AxisFault("HTTP", "(" + returnCode + ")" + statusMessage, null, null); 498 499 fault.setFaultDetailString(Messages.getMessage("return01", 500 "" + returnCode, "")); 501 throw fault; 502 } 503 } 504 505 try 506 { 507 if (httpChunkStream == false) 508 { 509 out = new BufferedOutputStream (out, 8 * 1024); 510 out.write(header.toString().getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING)); 511 requestMsg.writeTo(out); 512 out.flush(); 514 } 515 else 516 { 517 ChunkedOutputStream chunkedOutputStream = new ChunkedOutputStream(out); 518 out = new BufferedOutputStream (chunkedOutputStream, 8 * 1024); 519 requestMsg.writeTo(out); 520 out.flush(); 521 chunkedOutputStream.eos(); 522 } 523 } 524 catch (SOAPException e) 525 { 526 log.debug("Cannot serialize request message", e); 527 } 528 529 if (log.isDebugEnabled()) 530 { 531 log.debug("XML request sent"); 532 log.debug("----------------------------------------------"); 533 MessagePart msgPart = (MessagePart)requestMsg.getSOAPPart(); 534 String xmlMessage = msgPart.getAsString(); 535 log.debug("----------------------------------------------"); 536 log.debug(xmlMessage); 537 log.debug("----------------------------------------------"); 538 } 539 540 return inp; 541 } 542 543 private InputStream readHeadersFromSocket(Socket sock, MessageContext msgContext, InputStream inp, MimeHeaders headers) 544 throws IOException 545 { 546 byte b = 0; 547 int len = 0; 548 int colonIndex = -1; 549 String name, value; 550 int returnCode = 0; 551 if (null == inp) inp = new BufferedInputStream (sock.getInputStream()); 552 553 if (headers == null) 554 headers = new MimeHeaders (); 555 556 560 561 boolean readTooMuch = false; 562 563 for (ByteArrayOutputStream buf = new ByteArrayOutputStream (4097); ;) 564 { 565 if (!readTooMuch) 566 { 567 b = (byte)inp.read(); 568 } 569 if (b == -1) 570 { 571 break; 572 } 573 readTooMuch = false; 574 if ((b != '\r') && (b != '\n')) 575 { 576 if ((b == ':') && (colonIndex == -1)) 577 { 578 colonIndex = len; 579 } 580 len++; 581 buf.write(b); 582 } 583 else if (b == '\r') 584 { 585 continue; 586 } 587 else 588 { if (len == 0) 590 { 591 break; 592 } 593 b = (byte)inp.read(); 594 readTooMuch = true; 595 596 if ((b == ' ') || (b == '\t')) 598 { 599 continue; 600 } 601 buf.close(); 602 byte[] hdata = buf.toByteArray(); 603 buf.reset(); 604 if (colonIndex != -1) 605 { 606 name = 607 new String (hdata, 0, colonIndex, 608 HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING); 609 value = 610 new String (hdata, colonIndex + 1, len - 1 - colonIndex, 611 HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING); 612 colonIndex = -1; 613 } 614 else 615 { 616 617 name = 618 new String (hdata, 0, len, 619 HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING); 620 value = ""; 621 } 622 if (log.isDebugEnabled()) 623 { 624 log.debug(name + value); 625 } 626 if (msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE) 627 == null) 628 { 629 630 int start = name.indexOf(' ') + 1; 632 String tmp = name.substring(start).trim(); 633 int end = tmp.indexOf(' '); 634 635 if (end != -1) 636 { 637 tmp = tmp.substring(0, end); 638 } 639 returnCode = Integer.parseInt(tmp); 640 msgContext.setProperty(HTTPConstants.MC_HTTP_STATUS_CODE, 641 new Integer (returnCode)); 642 msgContext.setProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE, 643 name.substring(start + end + 1)); 644 } 645 else 646 { 647 headers.addHeader(name, value.trim()); 649 } 650 len = 0; 651 } 652 } 653 654 return inp; 655 } 656 657 664 private void readFromSocket(Socket sock, 665 MessageContext msgContext, 666 InputStream inp, 667 MimeHeaders headers) 668 throws IOException 669 { 670 Message responseMsg = null; 671 byte b; 672 673 Integer rc = (Integer )msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE); 674 int returnCode = 0; 675 if (rc != null) 676 { 677 returnCode = rc.intValue(); 678 } 679 else 680 { 681 } 683 684 685 String contentType = getFirstTrimmedHeader(headers, HTTPConstants.HEADER_CONTENT_TYPE); 686 687 if ((returnCode > 199) && (returnCode < 300)) 688 { 689 } 691 else if (msgContext.getSOAPConstants() == 692 SOAPConstants.SOAP12_CONSTANTS) 693 { 694 } 697 else if ((contentType != null) && !contentType.startsWith("text/html") 698 && ((returnCode > 499) && (returnCode < 600))) 699 { 700 } 702 else 703 { 704 ByteArrayOutputStream buf = new ByteArrayOutputStream (4097); 707 708 while (-1 != (b = (byte)inp.read())) 709 { 710 buf.write(b); 711 } 712 String statusMessage = msgContext.getStrProp(HTTPConstants.MC_HTTP_STATUS_MESSAGE); 713 AxisFault fault = new AxisFault("HTTP", "(" + returnCode + ")" + 714 statusMessage, null, null); 715 716 fault.setFaultDetailString(Messages.getMessage("return01", 717 "" + returnCode, buf.toString())); 718 throw fault; 719 } 720 721 String transferEncoding = getFirstTrimmedHeader(headers, HTTPConstants.HEADER_TRANSFER_ENCODING); 722 723 if (HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED.equals(transferEncoding)) 724 inp = new ChunkedInputStream(inp); 725 726 InputStream inputStream = new SocketInputStream(inp, sock); 727 728 responseMsg = new Message(inputStream, false, headers); 729 responseMsg.setMessageType(Message.RESPONSE); 730 731 msgContext.setResponseMessage(responseMsg); 732 733 if (msgContext.getMaintainSession()) 736 { 737 handleCookie(HTTPConstants.HEADER_COOKIE, 738 HTTPConstants.HEADER_SET_COOKIE, headers, msgContext); 739 handleCookie(HTTPConstants.HEADER_COOKIE2, 740 HTTPConstants.HEADER_SET_COOKIE2, headers, msgContext); 741 } 742 743 if (log.isDebugEnabled()) 744 { 745 log.debug("XML response received"); 746 log.debug("----------------------------------------------"); 747 MessagePart msgPart = (MessagePart)responseMsg.getSOAPPart(); 748 String xmlMessage = new String (msgPart.getAsBytes()); 749 log.debug("----------------------------------------------"); 750 log.debug(xmlMessage); 751 log.debug("----------------------------------------------"); 752 } 753 } 754 755 763 public void handleCookie(String cookieName, String setCookieName, MimeHeaders headers, MessageContext msgContext) 764 { 765 766 String cookie = getFirstTrimmedHeader(headers, setCookieName); 767 if (cookie == null) 768 return; 769 770 int index = cookie.indexOf(';'); 772 773 if (index != -1) 774 { 775 cookie = cookie.substring(0, index); 776 } 777 msgContext.setProperty(cookieName, cookie); 778 } 779 780 private static String getFirstTrimmedHeader(MimeHeaders headers, String name) 781 { 782 if (headers == null) 783 return null; 784 785 String [] values = headers.getHeader(name); 786 if (values == null) 787 return null; 788 789 return (values[0] == null) ? null : values[0].trim(); 790 } 791 } 792 | Popular Tags |