1 55 56 package org.jboss.axis.transport.http; 57 58 import org.jboss.axis.AxisFault; 59 import org.jboss.axis.Constants; 60 import org.jboss.axis.Message; 61 import org.jboss.axis.MessageContext; 62 import org.jboss.axis.description.OperationDesc; 63 import org.jboss.axis.description.ServiceDesc; 64 import org.jboss.axis.encoding.Base64; 65 import org.jboss.axis.message.SOAPEnvelopeAxisImpl; 66 import org.jboss.axis.message.SOAPFaultImpl; 67 import org.jboss.axis.server.AxisServer; 68 import org.jboss.axis.utils.Messages; 69 import org.jboss.axis.utils.XMLUtils; 70 import org.jboss.logging.Logger; 71 import org.w3c.dom.Document ; 72 73 import javax.xml.namespace.QName ; 74 import java.io.ByteArrayInputStream ; 75 import java.io.OutputStream ; 76 import java.net.InetAddress ; 77 import java.net.Socket ; 78 import java.net.UnknownHostException ; 79 import java.util.ArrayList ; 80 import java.util.Iterator ; 81 82 83 public class SimpleAxisWorker implements Runnable 84 { 85 private static Logger log = Logger.getLogger(SimpleAxisWorker.class.getName()); 86 87 private SimpleAxisServer server; 88 private Socket socket; 89 90 private static String transportName = "SimpleHTTP"; 92 93 private static byte OK[] = ("200 " + Messages.getMessage("ok00")).getBytes(); 95 private static byte UNAUTH[] = ("401 " + Messages.getMessage("unauth00")).getBytes(); 96 private static byte SENDER[] = "400".getBytes(); 97 private static byte ISE[] = ("500 " + Messages.getMessage("internalError01")).getBytes(); 98 99 private static byte HTTP[] = "HTTP/1.0 ".getBytes(); 101 102 private static byte XML_MIME_STUFF[] = 104 ("\r\nContent-Type: text/xml; charset=utf-8\r\n" + 105 "Content-Length: ").getBytes(); 106 107 private static byte HTML_MIME_STUFF[] = 109 ("\r\nContent-Type: text/html; charset=utf-8\r\n" + 110 "Content-Length: ").getBytes(); 111 112 private static byte SEPARATOR[] = "\r\n\r\n".getBytes(); 114 115 123 private static final byte[] toLower = new byte[256]; 125 126 static 127 { 128 for (int i = 0; i < 256; i++) 129 { 130 toLower[i] = (byte)i; 131 } 132 133 for (int lc = 'a'; lc <= 'z'; lc++) 134 { 135 toLower[lc + 'A' - 'a'] = (byte)lc; 136 } 137 } 138 139 private static final int BUFSIZ = 4096; 141 142 private static final byte lenHeader[] = "content-length: ".getBytes(); 144 private static final int lenLen = lenHeader.length; 145 146 private static final byte typeHeader[] = (HTTPConstants.HEADER_CONTENT_TYPE.toLowerCase() + ": ").getBytes(); 148 private static final int typeLen = typeHeader.length; 149 150 private static final byte locationHeader[] = (HTTPConstants.HEADER_CONTENT_LOCATION.toLowerCase() + ": ").getBytes(); 152 private static final int locationLen = locationHeader.length; 153 154 private static final byte actionHeader[] = "soapaction: ".getBytes(); 156 private static final int actionLen = actionHeader.length; 157 158 private static final byte cookieHeader[] = "cookie: ".getBytes(); 160 private static final int cookieLen = cookieHeader.length; 161 162 private static final byte cookie2Header[] = "cookie2: ".getBytes(); 164 private static final int cookie2Len = cookie2Header.length; 165 166 private static final byte authHeader[] = "authorization: ".getBytes(); 168 private static final int authLen = authHeader.length; 169 170 private static final byte getHeader[] = "GET".getBytes(); 172 173 private static final byte postHeader[] = "POST".getBytes(); 175 176 private static final byte headerEnder[] = ": ".getBytes(); 178 179 private static final byte basicAuth[] = "basic ".getBytes(); 181 182 public SimpleAxisWorker(SimpleAxisServer server, Socket socket) 183 { 184 this.server = server; 185 this.socket = socket; 186 } 187 188 191 public void run() 192 { 193 byte buf[] = new byte[BUFSIZ]; 194 AxisServer engine = server.getAxisServer(); 196 197 MessageContext msgContext = new MessageContext(engine); 199 Message requestMsg = null; 200 201 NonBlockingBufferedInputStream is = 203 new NonBlockingBufferedInputStream(); 204 205 StringBuffer soapAction = new StringBuffer (); 207 StringBuffer httpRequest = new StringBuffer (); 208 StringBuffer fileName = new StringBuffer (); 209 StringBuffer cookie = new StringBuffer (); 210 StringBuffer cookie2 = new StringBuffer (); 211 StringBuffer authInfo = new StringBuffer (); 212 StringBuffer contentType = new StringBuffer (); 213 StringBuffer contentLocation = new StringBuffer (); 214 215 Message responseMsg = null; 216 217 msgContext.setTransportName(transportName); 225 226 responseMsg = null; 227 228 try 229 { 230 byte[] status = OK; 232 233 boolean doWsdl = false; 235 236 String cooky = null; 238 239 String methodName = null; 240 241 try 242 { 243 if (server.isSessionUsed()) 245 { 246 cookie.delete(0, cookie.length()); 247 cookie2.delete(0, cookie2.length()); 248 } 249 authInfo.delete(0, authInfo.length()); 250 251 is.setInputStream(socket.getInputStream()); 253 int contentLength = parseHeaders(is, buf, contentType, 255 contentLocation, soapAction, 256 httpRequest, fileName, 257 cookie, cookie2, authInfo); 258 is.setContentLength(contentLength); 259 260 int paramIdx = fileName.toString().indexOf('?'); 261 if (paramIdx != -1) 262 { 263 String params = fileName.substring(paramIdx + 1); 265 fileName.setLength(paramIdx); 266 267 log.debug(Messages.getMessage("filename00", 268 fileName.toString())); 269 log.debug(Messages.getMessage("params00", 270 params)); 271 272 if ("wsdl".equalsIgnoreCase(params)) 273 doWsdl = true; 274 275 if (params.startsWith("method=")) 276 { 277 methodName = params.substring(7); 278 } 279 } 280 281 msgContext.setProperty(Constants.MC_REALPATH, 284 fileName.toString()); 285 msgContext.setProperty(Constants.MC_RELATIVE_PATH, 286 fileName.toString()); 287 msgContext.setProperty(Constants.MC_JWS_CLASSDIR, 288 "jwsClasses"); 289 290 String url = "http://" + getLocalHost() + ":" + 292 server.getServerSocket().getLocalPort() + "/" + 293 fileName.toString(); 294 msgContext.setProperty(MessageContext.TRANS_URL, url); 295 296 String filePart = fileName.toString(); 297 if (filePart.startsWith("axis/services/")) 298 { 299 msgContext.setTargetService(filePart.substring(14)); 300 } 301 302 if (authInfo.length() > 0) 303 { 304 byte[] decoded = Base64.decode(authInfo.toString()); 307 StringBuffer userBuf = new StringBuffer (); 308 StringBuffer pwBuf = new StringBuffer (); 309 StringBuffer authBuf = userBuf; 310 for (int i = 0; i < decoded.length; i++) 311 { 312 if ((char)(decoded[i] & 0x7f) == ':') 313 { 314 authBuf = pwBuf; 315 continue; 316 } 317 authBuf.append((char)(decoded[i] & 0x7f)); 318 } 319 320 if (log.isDebugEnabled()) 321 { 322 log.debug(Messages.getMessage("user00", 323 userBuf.toString())); 324 } 325 326 msgContext.setUsername(userBuf.toString()); 327 msgContext.setPassword(pwBuf.toString()); 328 } 329 330 if (httpRequest.toString().equals("GET")) 332 { 333 OutputStream out = socket.getOutputStream(); 334 out.write(HTTP); 335 out.write(status); 336 337 if (methodName != null) 338 { 339 String body = 340 "<" + methodName + ">" + 341 "</" + methodName + ">"; 343 String msgtxt = 344 "<SOAP-ENV:Envelope" + 345 " xmlns:SOAP-ENV=\"" + Constants.URI_SOAP12_ENV + "\">" + 346 "<SOAP-ENV:Body>" + body + "</SOAP-ENV:Body>" + 347 "</SOAP-ENV:Envelope>"; 348 349 ByteArrayInputStream istream = 350 new ByteArrayInputStream (msgtxt.getBytes()); 351 requestMsg = new Message(istream); 352 } 353 else if (doWsdl) 354 { 355 engine.generateWSDL(msgContext); 356 357 Document doc = (Document )msgContext.getProperty("WSDL"); 358 if (doc != null) 359 { 360 String response = XMLUtils.DocumentToString(doc); 361 byte[] respBytes = response.getBytes(); 362 363 out.write(XML_MIME_STUFF); 364 putInt(buf, out, respBytes.length); 365 out.write(SEPARATOR); 366 out.write(respBytes); 367 out.flush(); 368 return; 369 } 370 } 371 else 372 { 373 StringBuffer sb = new StringBuffer (); 374 sb.append("<h2>And now... Some Services</h2>\n"); 375 Iterator i = engine.getConfig().getDeployedServices(); 376 out.write("<ul>\n".getBytes()); 377 while (i.hasNext()) 378 { 379 ServiceDesc sd = (ServiceDesc)i.next(); 380 sb.append("<li>\n"); 381 sb.append(sd.getName()); 382 sb.append(" <a HREF=\"../services/"); 383 sb.append(sd.getName()); 384 sb.append("?wsdl\"><i>(wsdl)</i></a></li>\n"); 385 ArrayList operations = sd.getOperations(); 386 if (!operations.isEmpty()) 387 { 388 sb.append("<ul>\n"); 389 for (Iterator it = operations.iterator(); it.hasNext();) 390 { 391 OperationDesc desc = (OperationDesc)it.next(); 392 sb.append("<li>" + desc.getName()); 393 } 394 sb.append("</ul>\n"); 395 } 396 } 397 sb.append("</ul>\n"); 398 399 byte[] bytes = sb.toString().getBytes(); 400 401 out.write(HTML_MIME_STUFF); 402 putInt(buf, out, bytes.length); 403 out.write(SEPARATOR); 404 out.write(bytes); 405 out.flush(); 406 return; 407 } 408 } 409 else 410 { 411 412 String soapActionString = soapAction.toString(); 415 if (soapActionString != null) 416 { 417 msgContext.setUseSOAPAction(true); 418 msgContext.setSOAPActionURI(soapActionString); 419 } 420 requestMsg = new Message(is, 421 false, 422 contentType.toString(), 423 contentLocation.toString()); 424 } 425 426 msgContext.setRequestMessage(requestMsg); 427 428 if (server.isSessionUsed()) 430 { 431 if (cookie.length() > 0) 433 { 434 cooky = cookie.toString().trim(); 435 } 436 else if (cookie2.length() > 0) 437 { 438 cooky = cookie2.toString().trim(); 439 } 440 441 if (cooky == null) 443 { 444 int i = server.sessionIndex++; 448 cooky = "" + i; 449 } 450 451 msgContext.setSession(server.createSession(cooky)); 452 } 453 454 engine.invoke(msgContext); 456 457 responseMsg = msgContext.getResponseMessage(); 459 if (responseMsg == null) 460 { 461 throw new AxisFault(Messages.getMessage("nullResponse00")); 462 } 463 464 } 465 catch (Exception e) 466 { 467 AxisFault af; 468 if (e instanceof AxisFault) 469 { 470 af = (AxisFault)e; 471 log.debug(Messages.getMessage("serverFault00"), af); 472 QName faultCode = af.getFaultCode(); 473 if (Constants.FAULT_SOAP12_SENDER.equals(faultCode)) 474 { 475 status = SENDER; 476 } 477 else if ("Server.Unauthorized".equals(af.getFaultCode().getLocalPart())) 478 { 479 status = UNAUTH; } 481 else 482 { 483 status = ISE; } 485 } 486 else 487 { 488 status = ISE; af = AxisFault.makeFault(e); 490 } 491 492 responseMsg = msgContext.getResponseMessage(); 496 if (responseMsg == null) 497 { 498 responseMsg = new Message(af); 499 responseMsg.setMessageContext(msgContext); 500 } 501 else 502 { 503 try 504 { 505 SOAPEnvelopeAxisImpl env = responseMsg.getSOAPEnvelope(); 506 env.clearBody(); 507 env.addBodyElement(new SOAPFaultImpl((AxisFault)e)); 508 } 509 catch (AxisFault fault) 510 { 511 } 513 } 514 } 515 516 OutputStream out = socket.getOutputStream(); 518 out.write(HTTP); 519 out.write(status); 520 out.write(("\r\n" + HTTPConstants.HEADER_CONTENT_TYPE + ": " + responseMsg.getContentType(msgContext.getSOAPConstants())).getBytes()); 522 526 if (server.isSessionUsed() && null != cooky && 0 != cooky.trim().length()) 527 { 528 StringBuffer cookieOut = new StringBuffer (); 532 cookieOut.append("\r\nSet-Cookie: ") 533 .append(cooky) 534 .append("\r\nSet-Cookie2: ") 535 .append(cooky); 536 out.write(cookieOut.toString().getBytes()); 538 } 539 540 out.write(SEPARATOR); 541 responseMsg.writeTo(out); 542 out.flush(); 544 } 545 catch (Exception e) 546 { 547 log.debug(Messages.getMessage("exception00"), e); 548 } 549 finally 550 { 551 try 552 { 553 if (socket != null) socket.close(); 554 } 555 catch (Exception e) 556 { 557 } 558 } 559 if (msgContext.getProperty(msgContext.QUIT_REQUESTED) != null) 560 { 561 try 563 { 564 server.stop(); 565 } 566 catch (Exception e) 567 { 568 } 569 } 570 571 } 572 573 protected void invokeMethodFromGet(String methodName, String args) throws Exception 574 { 575 576 } 577 578 591 private int parseHeaders(NonBlockingBufferedInputStream is, 592 byte buf[], 593 StringBuffer contentType, 594 StringBuffer contentLocation, 595 StringBuffer soapAction, 596 StringBuffer httpRequest, 597 StringBuffer fileName, 598 StringBuffer cookie, 599 StringBuffer cookie2, 600 StringBuffer authInfo) 601 throws java.io.IOException 602 { 603 int n; 604 int len = 0; 605 606 n = this.readLine(is, buf, 0, buf.length); 608 if (n < 0) 609 { 610 throw new java.io.IOException (Messages.getMessage("unexpectedEOS00")); 612 } 613 614 httpRequest.delete(0, httpRequest.length()); 616 fileName.delete(0, fileName.length()); 617 contentType.delete(0, contentType.length()); 618 contentLocation.delete(0, contentLocation.length()); 619 620 if (buf[0] == getHeader[0]) 621 { 622 httpRequest.append("GET"); 623 for (int i = 0; i < n - 5; i++) 624 { 625 char c = (char)(buf[i + 5] & 0x7f); 626 if (c == ' ') 627 break; 628 fileName.append(c); 629 } 630 log.debug(Messages.getMessage("filename01", "SimpleAxisServer", fileName.toString())); 631 return 0; 632 } 633 else if (buf[0] == postHeader[0]) 634 { 635 httpRequest.append("POST"); 636 for (int i = 0; i < n - 6; i++) 637 { 638 char c = (char)(buf[i + 6] & 0x7f); 639 if (c == ' ') 640 break; 641 fileName.append(c); 642 } 643 log.debug(Messages.getMessage("filename01", "SimpleAxisServer", fileName.toString())); 644 } 645 else 646 { 647 throw new java.io.IOException (Messages.getMessage("badRequest00")); 648 } 649 650 while ((n = readLine(is, buf, 0, buf.length)) > 0) 651 { 652 653 if ((n <= 2) && (buf[0] == '\n' || buf[0] == '\r') && (len > 0)) break; 654 655 660 int endHeaderIndex = 0; 662 while (endHeaderIndex < n && toLower[buf[endHeaderIndex]] != headerEnder[0]) 663 { 664 endHeaderIndex++; 665 } 666 endHeaderIndex += 2; 667 670 int i = endHeaderIndex - 1; 672 673 if (endHeaderIndex == lenLen && matches(buf, lenHeader)) 675 { 676 678 while ((++i < n) && (buf[i] >= '0') && (buf[i] <= '9')) 679 { 680 len = (len * 10) + (buf[i] - '0'); 681 } 682 683 } 684 else if (endHeaderIndex == actionLen 685 && matches(buf, actionHeader)) 686 { 687 688 soapAction.delete(0, soapAction.length()); 689 i++; 691 while ((++i < n) && (buf[i] != '"')) 692 { 693 soapAction.append((char)(buf[i] & 0x7f)); 694 } 695 696 } 697 else if (server.isSessionUsed() && endHeaderIndex == cookieLen 698 && matches(buf, cookieHeader)) 699 { 700 701 while ((++i < n) && (buf[i] != ';') && (buf[i] != '\r') && (buf[i] != '\n')) 703 { 704 cookie.append((char)(buf[i] & 0x7f)); 705 } 706 707 } 708 else if (server.isSessionUsed() && endHeaderIndex == cookie2Len 709 && matches(buf, cookie2Header)) 710 { 711 712 while ((++i < n) && (buf[i] != ';') && (buf[i] != '\r') && (buf[i] != '\n')) 714 { 715 cookie2.append((char)(buf[i] & 0x7f)); 716 } 717 718 } 719 else if (endHeaderIndex == authLen && matches(buf, authHeader)) 720 { 721 if (matches(buf, endHeaderIndex, basicAuth)) 722 { 723 i += basicAuth.length; 724 while (++i < n && (buf[i] != '\r') && (buf[i] != '\n')) 725 { 726 if (buf[i] == ' ') continue; 727 authInfo.append((char)(buf[i] & 0x7f)); 728 } 729 } 730 else 731 { 732 throw new java.io.IOException (Messages.getMessage("badAuth00")); 733 } 734 } 735 else if (endHeaderIndex == locationLen && matches(buf, locationHeader)) 736 { 737 while (++i < n && (buf[i] != '\r') && (buf[i] != '\n')) 738 { 739 if (buf[i] == ' ') continue; 740 contentLocation.append((char)(buf[i] & 0x7f)); 741 } 742 } 743 else if (endHeaderIndex == typeLen && matches(buf, typeHeader)) 744 { 745 while (++i < n && (buf[i] != '\r') && (buf[i] != '\n')) 746 { 747 if (buf[i] == ' ') continue; 748 contentType.append((char)(buf[i] & 0x7f)); 749 } 750 } 751 752 } 753 return len; 754 } 755 756 759 public boolean matches(byte[] buf, byte[] target) 760 { 761 for (int i = 0; i < target.length; i++) 762 { 763 if (toLower[buf[i]] != target[i]) 764 { 765 return false; 766 } 767 } 768 return true; 769 } 770 771 775 public boolean matches(byte[] buf, int bufIdx, byte[] target) 776 { 777 for (int i = 0; i < target.length; i++) 778 { 779 if (toLower[buf[bufIdx + i]] != target[i]) 780 { 781 return false; 782 } 783 } 784 return true; 785 } 786 787 793 private void putInt(byte buf[], OutputStream out, int value) 794 throws java.io.IOException 795 { 796 int len = 0; 797 int offset = buf.length; 798 799 if (value < 0) 801 { 802 buf[--offset] = (byte)'-'; 803 value = -value; 804 len++; 805 } 806 807 if (value == 0) 809 { 810 buf[--offset] = (byte)'0'; 811 len++; 812 } 813 814 while (value > 0) 816 { 817 buf[--offset] = (byte)(value % 10 + '0'); 818 value = value / 10; 819 len++; 820 } 821 822 out.write(buf, offset, len); 824 } 825 826 834 private int readLine(NonBlockingBufferedInputStream is, byte[] b, int off, int len) 835 throws java.io.IOException 836 { 837 int count = 0, c; 838 839 while ((c = is.read()) != -1) 840 { 841 if (c != '\n' && c != '\r') 842 { 843 b[off++] = (byte)c; 844 count++; 845 } 846 if (count == len) break; 847 if ('\n' == c) 848 { 849 int peek = is.peek(); if (peek != ' ' && peek != '\t') break; 851 } 852 } 853 return count > 0 ? count : -1; 854 } 855 856 859 public static String getLocalHost() 860 { 861 try 870 { 871 return InetAddress.getLocalHost().getHostAddress(); 872 } 873 catch (UnknownHostException uhe) 874 { 875 return "localhost"; 876 } 877 } 878 } 879 | Popular Tags |