1 21 package org.jacorb.orb.http.httpserver; 22 23 import java.io.*; 24 import java.net.*; 25 import java.util.*; 26 import java.text.*; 27 28 public class ServeConnection 29 { 30 31 private Socket socket; 32 33 private ServeInputStream in; 34 private ServeOutputStream out; 35 36 private Vector cookies = new Vector(); 38 39 public static final int SC_CONTINUE = 100; 40 public static final int SC_SWITCHING_PROTOCOLS = 101; 41 public static final int SC_OK = 200; 42 public static final int SC_CREATED = 201; 43 public static final int SC_ACCEPTED = 202; 44 public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203; 45 public static final int SC_NO_CONTENT = 204; 46 public static final int SC_RESET_CONTENT = 205; 47 public static final int SC_PARTIAL_CONTENT = 206; 48 public static final int SC_MULTIPLE_CHOICES = 300; 49 public static final int SC_MOVED_PERMANENTLY = 301; 50 public static final int SC_MOVED_TEMPORARILY = 302; 51 public static final int SC_SEE_OTHER = 303; 52 public static final int SC_NOT_MODIFIED = 304; 53 public static final int SC_USE_PROXY = 305; 54 public static final int SC_BAD_REQUEST = 400; 55 public static final int SC_UNAUTHORIZED = 401; 56 public static final int SC_PAYMENT_REQUIRED = 402; 57 public static final int SC_FORBIDDEN = 403; 58 public static final int SC_NOT_FOUND = 404; 59 public static final int SC_METHOD_NOT_ALLOWED = 405; 60 public static final int SC_NOT_ACCEPTABLE = 406; 61 public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407; 62 public static final int SC_REQUEST_TIMEOUT = 408; 63 public static final int SC_CONFLICT = 409; 64 public static final int SC_GONE = 410; 65 public static final int SC_LENGTH_REQUIRED = 411; 66 public static final int SC_PRECONDITION_FAILED = 412; 67 public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413; 68 public static final int SC_REQUEST_URI_TOO_LONG = 414; 69 public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415; 70 public static final int SC_INTERNAL_SERVER_ERROR = 500; 71 public static final int SC_NOT_IMPLEMENTED = 501; 72 public static final int SC_BAD_GATEWAY = 502; 73 public static final int SC_SERVICE_UNAVAILABLE = 503; 74 public static final int SC_GATEWAY_TIMEOUT = 504; 75 public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505; 76 77 78 79 public ServeConnection( Socket socket,java.io.InputStream _in) 81 { 82 this.socket = socket; 84 try 85 { 86 in = new ServeInputStream(_in); 88 out = new ServeOutputStream( socket.getOutputStream(), this ); 89 } 90 catch ( IOException e ) 91 { 92 problem( "Getting streams: " + e.getMessage(), SC_BAD_REQUEST ); 93 } 94 95 parseRequest(); 96 97 98 105 } 106 107 108 110 private String reqMethod = null; 111 private String reqUriPath = null; 112 private String reqProtocol = null; 113 private boolean oneOne; private boolean reqMime; 115 String reqQuery = null; 116 private Vector reqHeaderNames = new Vector(); 117 private Vector reqHeaderValues = new Vector(); 118 119 120 public void close(){ 121 122 try 123 { 124 socket.close(); 125 } 126 catch ( IOException e ) { } 127 } 128 129 private void parseRequest() 130 { 131 byte[] lineBytes = new byte[4096]; 132 int len; 133 String line; 134 135 try 136 { 137 len = in.readLine( lineBytes, 0, lineBytes.length ); 139 if ( len == -1 || len == 0 ) 140 { 141 problem( "Empty request", SC_BAD_REQUEST ); 142 return; 143 } 144 line = new String ( lineBytes, 0, len ); 145 String [] tokens = splitStr( line ); 146 switch ( tokens.length ) 147 { 148 case 2: 149 reqProtocol = "HTTP/0.9"; 151 oneOne = false; 152 reqMime = false; 153 break; 154 case 3: 155 reqProtocol = tokens[2]; 156 oneOne = ! reqProtocol.toUpperCase().equals( "HTTP/1.0" ); 157 reqMime = true; 158 while ( true ) 160 { 161 len = in.readLine( lineBytes, 0, lineBytes.length ); 162 if ( len == -1 || len == 0 ) 163 break; 164 line = new String ( lineBytes, 0, len ); 165 int colonBlank = line.indexOf( ": " ); 166 if ( colonBlank != -1 ) 167 { 168 String name = line.substring( 0, colonBlank ); 169 String value = line.substring( colonBlank + 2 ); 170 reqHeaderNames.addElement( name.toLowerCase() ); 171 reqHeaderValues.addElement( value ); 172 } 173 } 174 break; 175 default: 176 problem( "Malformed request line", SC_BAD_REQUEST ); 177 return; 178 } 179 reqMethod = tokens[0]; 180 reqUriPath = tokens[1]; 181 182 if ( oneOne ) 184 { 185 String host = getHeader( "host" ); 186 if ( host == null ) 187 { 188 problem( 189 "Host header missing on HTTP/1.1 request", 190 SC_BAD_REQUEST ); 191 return; 192 } 193 } 195 196 int qmark = reqUriPath.indexOf( '?' ); 198 if ( qmark != -1 ) 199 { 200 reqQuery = reqUriPath.substring( qmark + 1 ); 201 reqUriPath = reqUriPath.substring( 0, qmark ); 202 } 203 204 reqUriPath = decode( reqUriPath ); 206 207 }catch ( Exception e ) 209 { 210 problem( "Reading request: " + e.getMessage(), SC_BAD_REQUEST ); 211 } 212 } 213 214 public void answerRequest(byte[] answer) 215 { 216 setStatus( SC_OK ); 218 setDateHeader( "Date", System.currentTimeMillis() ); 219 setHeader( "Server", "JacORB builtin HTTPServer"); 220 setHeader( "Connection", "close" ); 221 try 222 { 223 out.write(answer,0,answer.length); 224 out.flush(); 225 out.close(); 226 } 227 catch ( Exception e ) 228 { 229 problem( 230 "unexpected problem running servlet: " + e.toString(), 231 SC_INTERNAL_SERVER_ERROR ); 232 } 233 } 234 235 private void problem( String logMessage, int resCode ) 236 { 237 try 238 { 239 sendError( resCode ); 240 } 241 catch ( IOException e ) { } 242 } 243 244 private String decode( String str ) 245 { 246 StringBuffer result = new StringBuffer (); 247 int l = str.length(); 248 for ( int i = 0; i < l; ++i ) 249 { 250 char c = str.charAt( i ); 251 if ( c == '%' && i + 2 < l ) 252 { 253 char c1 = str.charAt( i + 1 ); 254 char c2 = str.charAt( i + 2 ); 255 if ( isHexit( c1 ) && isHexit( c2 ) ) 256 { 257 result.append( (char) ( hexit( c1 ) * 16 + hexit( c2 ) ) ); 258 i += 2; 259 } 260 else 261 result.append( c ); 262 } 263 else 264 result.append( c ); 265 } 266 return result.toString(); 267 } 268 269 private boolean isHexit( char c ) 270 { 271 String legalChars = "0123456789abcdefABCDEF"; 272 return ( legalChars.indexOf( c ) != -1 ); 273 } 274 275 private int hexit( char c ) 276 { 277 if ( c >= '0' && c <= '9' ) 278 return c - '0'; 279 if ( c >= 'a' && c <= 'f' ) 280 return c - 'a' + 10; 281 if ( c >= 'A' && c <= 'F' ) 282 return c - 'A' + 10; 283 return 0; } 285 286 287 289 public int getContentLength() 292 { 293 return getIntHeader( "content-length", -1 ); 294 } 295 296 public String getContentType() 300 { 301 return getHeader( "content-type" ); 302 } 303 304 public String getProtocol() 308 { 309 return reqProtocol; 310 } 311 312 public String getScheme() 318 { 319 return "http"; 320 } 321 322 public String getServerName() 326 { 327 try 328 { 329 return InetAddress.getLocalHost().getHostName(); 330 } 331 catch ( UnknownHostException e ) 332 { 333 return null; 334 } 335 } 336 337 public int getServerPort() 341 { 342 return socket.getLocalPort(); 343 } 344 345 public String getRemoteAddr() 348 { 349 return socket.getInetAddress().toString(); 350 } 351 352 public String getRemoteHost() 356 { 357 return socket.getInetAddress().getHostName(); 358 } 359 360 public String getRealPath( String path ) 367 { 368 return "/"; } 370 371 public ServeInputStream getInputStream() throws IOException 375 { 376 return in; 377 } 378 379 public BufferedReader getReader() 384 { 385 return null; 387 } 388 389 Vector queryNames = null; 390 Vector queryValues = null; 391 392 public Enumeration getParameterNames() 394 { 395 if ( queryNames == null ) 396 { 397 queryNames = new Vector(); 398 queryValues = new Vector(); 399 String qs = getQueryString(); 400 if ( qs != null ) 401 { 402 Enumeration en = new StringTokenizer( qs, "&" ); 403 while ( en.hasMoreElements() ) 404 { 405 String nv = (String ) en.nextElement(); 406 int eq = nv.indexOf( '=' ); 407 String name, value; 408 if ( eq == -1 ) 409 { 410 name = nv; 411 value = ""; 412 } 413 else 414 { 415 name = nv.substring( 0, eq ); 416 value = nv.substring( eq + 1 ); 417 } 418 queryNames.addElement( name ); 419 queryValues.addElement( value ); 420 } 421 } 422 } 423 return queryNames.elements(); 424 } 425 426 public String getParameter( String name ) 430 { 431 Enumeration en = getParameterNames(); 432 int i = queryNames.indexOf( name ); 433 if ( i == -1 ) 434 return null; 435 else 436 return (String ) queryValues.elementAt( i ); 437 } 438 439 public String [] getParameterValues( String name ) 442 { 443 Vector v = new Vector(); 444 Enumeration en = getParameterNames(); 445 for ( int i = 0; i < queryNames.size(); ++i ) 446 { 447 String n = (String ) queryNames.elementAt( i ); 448 if ( name.equals( n ) ) 449 v.addElement( queryValues.elementAt( i ) ); 450 } 451 if ( v.size() == 0 ) 452 return null; 453 String [] vArray = new String [v.size()]; 454 v.copyInto( vArray ); 455 return vArray; 456 } 457 458 public Object getAttribute( String name ) 462 { 463 return null; 465 } 466 467 468 470 478 public String getMethod() 482 { 483 return reqMethod; 484 } 485 486 public String getRequestURI() 488 { 489 String portPart = ""; 490 int port = getServerPort(); 491 if ( port != 80 ) 492 portPart = ":" + port; 493 String queryPart = ""; 494 String queryString = getQueryString(); 495 if ( queryString != null && queryString.length() > 0 ) 496 queryPart = "?" + queryString; 497 return "http://" + getServerName() + portPart + reqUriPath + queryPart; 498 } 499 500 public String getServletPath() 504 { 505 return reqUriPath; 509 } 510 511 public String getPathInfo() 515 { 516 return null; 520 } 521 522 public String getPathTranslated() 526 { 527 return null; 531 } 532 533 public String getQueryString() 536 { 537 return reqQuery; 538 } 539 540 public String getRemoteUser() 543 { 544 return null; 547 } 548 549 public String getAuthType() 552 { 553 return null; 555 } 556 557 public String getHeader( String name ) 561 { 562 int i = reqHeaderNames.indexOf( name.toLowerCase() ); 563 if ( i == -1 ) 564 return null; 565 return (String ) reqHeaderValues.elementAt( i ); 566 } 567 568 public int getIntHeader( String name, int def ) 572 { 573 String val = getHeader( name ); 574 if ( val == null ) 575 return def; 576 try 577 { 578 return Integer.parseInt( val ); 579 } 580 catch ( Exception e ) 581 { 582 return def; 583 } 584 } 585 586 public long getLongHeader( String name, long def ) 590 { 591 String val = getHeader( name ); 592 if ( val == null ) 593 return def; 594 try 595 { 596 return Long.parseLong( val ); 597 } 598 catch ( Exception e ) 599 { 600 return def; 601 } 602 } 603 604 public long getDateHeader( String name, long def ) 608 { 609 String val = getHeader( name ); 610 if ( val == null ) 611 return def; 612 try 613 { 614 return DateFormat.getDateInstance().parse( val ).getTime(); 615 } 616 catch ( Exception e ) 617 { 618 return def; 619 } 620 } 621 622 public Enumeration getHeaderNames() 624 { 625 return reqHeaderNames.elements(); 626 } 627 628 630 646 public String getRequestedSessionId() 651 { 652 return null; 653 } 654 655 public boolean isRequestedSessionIdValid() 660 { 661 return false; 662 } 663 664 public boolean isRequestedSessionIdFromCookie() 668 { 669 return false; 670 } 671 672 public boolean isRequestedSessionIdFromUrl() 676 { 677 return false; 678 } 679 680 681 683 public void setContentLength( int length ) 686 { 687 setIntHeader( "Content-length", length ); 688 } 689 690 public void setContentType( String type ) 693 { 694 setHeader( "Content-type", type ); 695 } 696 697 public ServeOutputStream getOutputStream() 699 { 700 return out; 701 } 702 703 public PrintWriter getWriter() throws IOException 711 { 712 return null; 714 } 715 716 public String getCharacterEncoding() 721 { 722 return null; 724 } 725 726 727 729 736 public boolean containsHeader( String name ) 739 { 740 return resHeaderNames.contains( name ); 741 } 742 743 private int resCode = -1; 744 private String resMessage = null; 745 private Vector resHeaderNames = new Vector(); 746 private Vector resHeaderValues = new Vector(); 747 748 public void setStatus( int resCode, String resMessage ) 752 { 753 this.resCode = resCode; 754 this.resMessage = resMessage; 755 } 756 757 public void setStatus( int resCode ) 760 { 761 switch ( resCode ) 762 { 763 case SC_CONTINUE: setStatus( resCode, "Continue" ); break; 764 case SC_SWITCHING_PROTOCOLS: 765 setStatus( resCode, "Switching protocols" ); break; 766 case SC_OK: setStatus( resCode, "Ok" ); break; 767 case SC_CREATED: setStatus( resCode, "Created" ); break; 768 case SC_ACCEPTED: setStatus( resCode, "Accepted" ); break; 769 case SC_NON_AUTHORITATIVE_INFORMATION: 770 setStatus( resCode, "Non-authoritative" ); break; 771 case SC_NO_CONTENT: setStatus( resCode, "No content" ); break; 772 case SC_RESET_CONTENT: setStatus( resCode, "Reset content" ); break; 773 case SC_PARTIAL_CONTENT: 774 setStatus( resCode, "Partial content" ); break; 775 case SC_MULTIPLE_CHOICES: 776 setStatus( resCode, "Multiple choices" ); break; 777 case SC_MOVED_PERMANENTLY: 778 setStatus( resCode, "Moved permanentently" ); break; 779 case SC_MOVED_TEMPORARILY: 780 setStatus( resCode, "Moved temporarily" ); break; 781 case SC_SEE_OTHER: setStatus( resCode, "See other" ); break; 782 case SC_NOT_MODIFIED: setStatus( resCode, "Not modified" ); break; 783 case SC_USE_PROXY: setStatus( resCode, "Use proxy" ); break; 784 case SC_BAD_REQUEST: setStatus( resCode, "Bad request" ); break; 785 case SC_UNAUTHORIZED: setStatus( resCode, "Unauthorized" ); break; 786 case SC_PAYMENT_REQUIRED: 787 setStatus( resCode, "Payment required" ); break; 788 case SC_FORBIDDEN: setStatus( resCode, "Forbidden" ); break; 789 case SC_NOT_FOUND: setStatus( resCode, "Not found" ); break; 790 case SC_METHOD_NOT_ALLOWED: 791 setStatus( resCode, "Method not allowed" ); break; 792 case SC_NOT_ACCEPTABLE: 793 setStatus( resCode, "Not acceptable" ); break; 794 case SC_PROXY_AUTHENTICATION_REQUIRED: 795 setStatus( resCode, "Proxy auth required" ); break; 796 case SC_REQUEST_TIMEOUT: 797 setStatus( resCode, "Request timeout" ); break; 798 case SC_CONFLICT: setStatus( resCode, "Conflict" ); break; 799 case SC_GONE: setStatus( resCode, "Gone" ); break; 800 case SC_LENGTH_REQUIRED: 801 setStatus( resCode, "Length required" ); break; 802 case SC_PRECONDITION_FAILED: 803 setStatus( resCode, "Precondition failed" ); break; 804 case SC_REQUEST_ENTITY_TOO_LARGE: 805 setStatus( resCode, "Request entity too large" ); break; 806 case SC_REQUEST_URI_TOO_LONG: 807 setStatus( resCode, "Request URI too large" ); break; 808 case SC_UNSUPPORTED_MEDIA_TYPE: 809 setStatus( resCode, "Unsupported media type" ); break; 810 case SC_INTERNAL_SERVER_ERROR: 811 setStatus( resCode, "Internal server error" ); break; 812 case SC_NOT_IMPLEMENTED: 813 setStatus( resCode, "Not implemented" ); break; 814 case SC_BAD_GATEWAY: setStatus( resCode, "Bad gateway" ); break; 815 case SC_SERVICE_UNAVAILABLE: 816 setStatus( resCode, "Service unavailable" ); break; 817 case SC_GATEWAY_TIMEOUT: 818 setStatus( resCode, "Gateway timeout" ); break; 819 case SC_HTTP_VERSION_NOT_SUPPORTED: 820 setStatus( resCode, "HTTP version not supported" ); break; 821 default: setStatus( resCode, "" ); break; 822 } 823 } 824 825 public void setHeader( String name, String value ) 829 { 830 resHeaderNames.addElement( name ); 831 resHeaderValues.addElement( value ); 832 } 833 834 public void setIntHeader( String name, int value ) 838 { 839 setHeader( name, Integer.toString( value ) ); 840 } 841 842 public void setLongHeader( String name, long value ) 846 { 847 setHeader( name, Long.toString( value ) ); 848 } 849 850 public void setDateHeader( String name, long value ) 854 { 855 setHeader( name, to1123String( new Date( value ) ) ); 856 } 857 858 private static final String [] weekdays = 859 { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; 860 861 private static String to1123String( Date date ) 863 { 864 int localDay = date.getDay(); 874 int localDate = date.getDate(); 875 String gmtStr = date.toGMTString(); 876 int blank = gmtStr.indexOf( ' ' ); 877 int gmtDate = Integer.parseInt( gmtStr.substring( 0, blank ) ); 878 int gmtDay; 879 if ( gmtDate > localDate || ( gmtDate < localDate && gmtDate == 1 ) ) 880 gmtDay = ( localDay + 1 ) % 7; 881 else if ( localDate > gmtDate || ( localDate < gmtDate && localDate == 1 ) ) 882 gmtDay = ( localDay + 6 ) % 7; 883 else 884 gmtDay = localDay; 885 return weekdays[gmtDay] + ( gmtDate < 10 ? ", 0" : ", " ) + gmtStr; 886 } 887 888 private boolean headersWritten = false; 889 890 void writeHeaders() throws IOException 894 { 895 if ( headersWritten ) 896 return; 897 headersWritten = true; 898 if ( reqMime ) 899 { 900 out.println( reqProtocol + " " + resCode + " " + resMessage ); 901 for ( int i = 0; i < resHeaderNames.size(); ++i ) 902 { 903 String name = (String ) resHeaderNames.elementAt( i ); 904 String value = (String ) resHeaderValues.elementAt( i ); 905 if ( value != null ) out.println( name + ": " + value ); 907 } 908 out.println( "" ); 909 out.flush(); 910 } 911 } 912 913 public void sendError( int resCode, String resMessage ) throws IOException 918 { 919 setStatus( resCode, resMessage ); 920 realSendError(); 921 } 922 923 public void sendError( int resCode ) throws IOException 928 { 929 setStatus( resCode ); 930 realSendError(); 931 } 932 933 private void realSendError() throws IOException 934 { 935 setContentType( "text/html" ); 936 out.println( "<HTML><HEAD>" ); 937 out.println( "<TITLE>" + resCode + " " + resMessage + "</TITLE>" ); 938 out.println( "</HEAD><BODY BGCOLOR=\"#99cc99\">" ); 939 out.println( "<H2>" + resCode + " " + resMessage + "</H2>" ); 940 out.println( "<HR>" ); 941 out.println( "</BODY></HTML>" ); 942 out.flush(); 943 } 944 945 public void sendRedirect( String location ) throws IOException 950 { 951 setHeader( "Location", location ); 952 sendError( SC_MOVED_TEMPORARILY ); 953 } 954 955 958 public String encodeUrl( String url ) 969 { 970 return url; 971 } 972 973 public String encodeRedirectUrl( String url ) 985 { 986 return url; 987 } 988 989 public static String [] splitStr( String str ) 993 { 994 StringTokenizer st = new StringTokenizer( str ); 995 int n = st.countTokens(); 996 String [] strs = new String [n]; 997 for ( int i = 0; i < n; ++i ) 998 strs[i] = st.nextToken(); 999 return strs; 1000 } 1001 } 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 | Popular Tags |