1 23 24 39 package com.sun.enterprise.web.connector.grizzly; 40 41 import com.sun.enterprise.web.connector.grizzly.async.DefaultAsyncHandler; 42 import com.sun.enterprise.web.connector.grizzly.async.DefaultAsyncExecutor; 43 import java.io.EOFException ; 44 import java.io.IOException ; 45 import java.io.InputStream ; 46 import java.io.InterruptedIOException ; 47 import java.io.OutputStream ; 48 49 import java.net.InetAddress ; 50 import java.net.Socket ; 51 import java.nio.ByteBuffer ; 52 import java.nio.channels.SocketChannel ; 53 import java.util.logging.Logger ; 54 import java.util.logging.Level ; 55 56 import org.apache.catalina.util.ServerInfo; 57 58 import org.apache.coyote.ActionCode; 59 import org.apache.coyote.ActionHook; 60 import org.apache.coyote.Adapter; 61 import org.apache.coyote.Processor; 62 import org.apache.coyote.Request; 63 import org.apache.coyote.RequestInfo; 64 import org.apache.coyote.Response; 65 import org.apache.coyote.http11.InternalInputBuffer; 66 import org.apache.coyote.http11.InternalOutputBuffer; 67 import org.apache.coyote.http11.InputFilter; 68 import org.apache.coyote.http11.OutputFilter; 69 import org.apache.coyote.http11.filters.ChunkedInputFilter; 70 import org.apache.coyote.http11.filters.ChunkedOutputFilter; 71 import org.apache.coyote.http11.filters.GzipOutputFilter; 72 import org.apache.coyote.http11.filters.IdentityInputFilter; 73 import org.apache.coyote.http11.filters.IdentityOutputFilter; 74 import org.apache.coyote.http11.filters.VoidInputFilter; 75 import org.apache.coyote.http11.filters.VoidOutputFilter; 76 import org.apache.coyote.http11.filters.BufferedInputFilter; 77 import org.apache.coyote.tomcat5.CoyoteAdapter; 78 import org.apache.coyote.tomcat5.CoyoteRequest; 79 80 import org.apache.tomcat.util.buf.Ascii; 81 import org.apache.tomcat.util.buf.ByteChunk; 82 import org.apache.tomcat.util.buf.HexUtils; 83 import org.apache.tomcat.util.buf.MessageBytes; 84 import org.apache.tomcat.util.http.FastHttpDateFormat; 85 import org.apache.tomcat.util.http.MimeHeaders; 86 import org.apache.tomcat.util.net.SSLImplementation; 87 import org.apache.tomcat.util.net.SSLSupport; 88 import com.sun.enterprise.web.connector.grizzly.handlers.NoParsingHandler; 89 90 import com.sun.org.apache.commons.modeler.Registry; 91 92 import javax.management.ObjectName ; 93 94 import java.nio.channels.Selector ; 95 96 102 public class ProcessorTask extends TaskBase implements Processor, ActionHook { 103 104 107 protected Adapter adapter = null; 108 109 110 113 protected Request request = null; 114 115 116 119 protected Response response = null; 120 121 122 125 protected InternalInputBuffer inputBuffer = null; 126 127 128 131 protected InternalOutputBuffer outputBuffer = null; 132 133 134 137 protected boolean started = false; 138 139 140 143 protected boolean error = false; 144 145 146 149 protected boolean keepAlive = true; 150 151 152 155 protected boolean connectionHeaderValue = true; 156 157 160 protected boolean http11 = true; 161 162 163 166 protected boolean http09 = false; 167 168 169 173 protected boolean contentDelimitation = true; 174 175 176 179 protected SSLSupport sslSupport; 180 181 182 185 protected Socket socket; 186 187 188 191 protected String remoteAddr = null; 192 193 194 197 protected String remoteHost = null; 198 199 200 203 protected String localName = null; 204 205 206 209 protected int localPort = -1; 210 211 212 215 protected int remotePort = -1; 216 217 218 221 protected String localAddr = null; 222 223 224 227 protected int timeout = 300000; 228 229 230 233 protected int maxPostSize = 2 * 1024 * 1024; 234 235 236 239 protected char[] hostNameC = new char[0]; 240 241 242 247 protected TaskContext taskContext; 248 249 250 253 protected TaskEvent<TaskContext> taskEvent; 254 255 256 259 protected SSLImplementation sslImplementation = null; 260 261 262 265 protected boolean usingNioNonBlocking = true; 266 267 268 272 private boolean hasRequestInfoRegistered = false; 273 274 275 278 protected int maxHttpHeaderSize = Constants.DEFAULT_HEADER_SIZE; 279 280 281 284 protected static int requestCount; 285 286 287 290 private int requestBufferSize = Constants.DEFAULT_REQUEST_BUFFER_SIZE; 291 292 293 297 private ObjectName oname; 298 299 300 303 protected boolean useAlternateKeepAlive = false; 304 305 306 309 protected boolean dropConnection = false; 310 311 312 316 protected int maxKeepAliveRequests = Constants.DEFAULT_MAX_KEEP_ALIVE; 317 318 319 322 protected int keepAliveLeft; 323 324 325 328 protected Handler handler; 329 330 331 334 private String defaultResponseType = 335 org.apache.coyote.tomcat5.Constants.DEFAULT_RESPONSE_TYPE; 336 337 338 341 private String forcedResponseType = 342 org.apache.coyote.tomcat5.Constants.FORCED_RESPONSE_TYPE; 343 344 345 348 private boolean asyncExecution = false; 349 350 351 354 private RequestInfo requestInfo; 355 356 357 360 private SocketChannelOutputBuffer channelOutputBuffer; 361 362 363 367 private AsyncHandler asyncHandler; 368 369 370 373 private boolean sslEnabled = sslImplementation == null ? false: true; 374 375 376 378 public ProcessorTask(){ 379 this(true, true); 380 } 381 382 public ProcessorTask(boolean useNio, boolean init){ 383 384 usingNioNonBlocking = useNio; 385 type = PROCESSOR_TASK; 386 if (init) { 387 initialize(); 388 } 389 } 390 391 392 395 protected void initialize(){ 396 started = true; 397 request = new Request(); 398 399 response = new Response(); 400 response.setHook(this); 401 402 inputBuffer = new InternalInputBuffer(request,requestBufferSize); 403 404 if ( usingNioNonBlocking ){ 405 outputBuffer = new SocketChannelOutputBuffer(response, 406 maxHttpHeaderSize); 407 } else { 408 outputBuffer = new InternalOutputBuffer(response, 409 maxHttpHeaderSize); 410 } 411 request.setInputBuffer(inputBuffer); 412 413 response.setOutputBuffer(outputBuffer); 414 request.setResponse(response); 415 416 initializeFilters(); 417 418 } 419 420 421 423 424 428 public void doTask() throws IOException { 429 boolean sslEnabled = sslImplementation == null ? false: true; 430 usingNioNonBlocking = usingNioNonBlocking && !sslEnabled; 431 try { 432 if ( usingNioNonBlocking ) { 433 process(taskContext.getInputStream(), 434 taskContext.getOutputStream()); 435 } else { 436 process(socket.getInputStream(),socket.getOutputStream()); 437 } 438 } catch(Throwable ex){ 439 SelectorThread.logger().log(Level.FINE, 440 "processorTask.errorProcessingRequest", ex); 441 } finally { 442 terminateProcess(); 443 } 444 } 445 446 447 449 450 public void taskEvent(TaskEvent event){ 451 if ( event.getStatus() == TaskEvent.START) { 452 taskContext = (TaskContext)event.attachement(); 453 if ( taskEvent == null ) { 454 taskEvent = new TaskEvent<TaskContext>(); 455 } 456 457 taskEvent.attach(taskContext); 458 459 if ( !asyncExecution ) { 460 execute(); 461 } else { 462 asyncHandler.handle(this); 463 } 464 } 465 } 466 467 469 470 473 public void preProcess() throws Exception { 474 if ( usingNioNonBlocking && !sslEnabled ) { 475 preProcess(taskContext.getInputStream(), 476 taskContext.getOutputStream()); 477 } else { 478 preProcess(socket.getInputStream(), 479 socket.getOutputStream()); 480 } 481 } 482 483 484 489 public void preProcess(InputStream input, OutputStream output) 490 throws Exception { 491 492 if ( !started ){ 494 initialize(); 495 } 496 497 if (isMonitoringEnabled()){ 498 adapter. 499 fireAdapterEvent(Adapter.CONNECTION_PROCESSING_STARTED, 500 request.getRequestProcessor()); 501 } 502 503 504 if (sslImplementation != null) { 505 sslSupport = sslImplementation.getSSLSupport(socket); 506 } 507 508 if( selectorThread.getDomain() != null 509 && isMonitoringEnabled() 510 && !hasRequestInfoRegistered ) { 511 registerMonitoring(); 512 } else if (!isMonitoringEnabled() && hasRequestInfoRegistered) { 513 unregisterMonitoring(); 514 } 515 516 if (isMonitoringEnabled()) { 517 requestInfo = request.getRequestProcessor(); 518 requestInfo.setWorkerThreadID(Thread.currentThread().getId()); 519 } 520 521 inputBuffer.setInputStream(input); 523 if ( usingNioNonBlocking ) { 524 channelOutputBuffer = ((SocketChannelOutputBuffer)outputBuffer); 525 channelOutputBuffer.setChannel((SocketChannel )key.channel()); 526 } else { 527 outputBuffer.setOutputStream(output); 528 } 529 530 remoteAddr = null; 532 remoteHost = null; 533 localName = null; 534 localAddr = null; 535 remotePort = -1; 536 localPort = -1; 537 connectionHeaderValue = true; 538 539 error = false; 541 keepAlive = true; 542 543 keepAliveLeft = maxKeepAliveRequests; 544 int soTimeout = socket.getSoTimeout(); 545 if (request.getServerPort() == 0) { 546 request.setServerPort(selectorThread.getPort()); 547 } 548 } 549 550 551 554 public boolean processNonBlocked() throws Exception { 555 if ( usingNioNonBlocking && !sslEnabled ) { 556 return processNonBlocked(taskContext.getInputStream(), 557 taskContext.getOutputStream()); 558 } else { 559 return processNonBlocked(socket.getInputStream(), 560 socket.getOutputStream()); 561 } 562 } 563 564 565 570 public boolean processNonBlocked(InputStream input, OutputStream output) 571 throws Exception { 572 boolean exitWhile = parseRequest(input,output,false); 573 if ( exitWhile ) return exitWhile; 574 invokeAdapter(); 575 postResponse(); 576 return error; 577 } 578 579 580 583 public void processBlocked() throws Exception { 584 if ( usingNioNonBlocking && !sslEnabled ) { 585 processBlocked(taskContext.getInputStream(), 586 taskContext.getOutputStream()); 587 } else { 588 processBlocked(socket.getInputStream(), 589 socket.getOutputStream()); 590 } 591 } 592 593 594 599 public void processBlocked(InputStream input, OutputStream output) 600 throws Exception { 601 boolean keptAlive = false; 602 while (started && !error && keepAlive) { 603 604 boolean exitWhile = parseRequest(input,output,keptAlive); 605 if ( exitWhile ) break; 606 607 invokeAdapter(); 608 postResponse(); 609 } 610 } 611 612 613 618 public void postResponse() throws Exception { 619 try { 621 inputBuffer.endRequest(); 622 } catch (IOException e) { 623 error = true; 624 } catch (Throwable t) { 625 SelectorThread.logger().log(Level.SEVERE, 626 "processorTask.errorFinishingRequest", t); 627 response.setStatus(500); 629 error = true; 630 } 631 try { 632 outputBuffer.endRequest(); 633 } catch (IOException e) { 634 error = true; 635 } catch (Throwable t) { 636 SelectorThread.logger().log(Level.SEVERE, 637 "processorTask.errorFinishingResponse", t); 638 error = true; 639 } 640 641 if (error) { 644 response.setStatus(500); 645 } 646 647 if (isMonitoringEnabled()) { 648 request.updateCounters(); 649 adapter.fireAdapterEvent(Adapter.REQUEST_PROCESSING_COMPLETED, 650 request.getRequestProcessor()); 651 } 652 653 inputBuffer.nextRequest(); 655 outputBuffer.nextRequest(); 656 } 657 658 659 663 public void invokeAdapter(){ 664 if (!error) { 666 try { 667 adapter.service(request, response); 668 if(keepAlive && !error) { error = response.getErrorException() != null || 675 statusDropsConnection(response.getStatus()); 676 } 677 678 } catch (InterruptedIOException e) { 679 error = true; 680 } catch (Throwable t) { 681 SelectorThread.logger().log(Level.SEVERE, 682 "processorTask.serviceError", t); 683 response.setStatus(500); 685 error = true; 686 } 687 } 688 } 689 690 691 694 public void parseRequest() throws Exception { 695 if ( usingNioNonBlocking && !sslEnabled ) { 696 parseRequest(taskContext.getInputStream(), 697 taskContext.getOutputStream(), true); 698 } else { 699 parseRequest(socket.getInputStream(),socket.getOutputStream(),true); 700 } 701 } 702 703 704 709 public boolean parseRequest(InputStream input, OutputStream output, 710 boolean keptAlive) throws Exception { 711 712 try { 714 if (isMonitoringEnabled()){ 715 adapter.fireAdapterEvent(Adapter.REQUEST_PROCESSING_STARTED, 716 request.getRequestProcessor()); 717 } 718 719 inputBuffer.parseRequestLine(); 720 if (isMonitoringEnabled()) { 721 request.getRequestProcessor().setRequestCompletionTime(0); 722 } 723 724 request.setStartTime(System.currentTimeMillis()); 725 if ( handler.handle(request,Handler.REQUEST_LINE_PARSED) 726 == Handler.BREAK){ 727 return true; 728 } 729 730 keptAlive = true; 731 inputBuffer.parseHeaders(); 732 } catch (IOException e) { 733 SelectorThread.logger().log(Level.FINEST, 734 "processorTask.nonBlockingError", e); 735 error = true; 736 keepAlive = false; 737 return true; 738 } catch (Throwable t) { 739 SelectorThread.logger().log(Level.SEVERE, 740 "processorTask.nonBlockingError", t); 741 response.setStatus(400); 743 error = true; 744 } 745 746 try { 748 prepareRequest(); 749 } catch (Throwable t) { 750 SelectorThread.logger().log(Level.FINE, 751 "processorTask.createRequestError", t); 752 response.setStatus(400); 754 error = true; 755 } 756 757 if (!usingNioNonBlocking){ 758 if (maxKeepAliveRequests > 0 && --keepAliveLeft == 0) 759 keepAlive = false; 760 } 761 return false; 762 } 763 764 765 769 public void postProcess() throws Exception { 770 if ( usingNioNonBlocking && !sslEnabled ) { 771 postProcess(taskContext.getInputStream(), 772 taskContext.getOutputStream()); 773 } else { 774 postProcess(socket.getInputStream(),socket.getOutputStream()); 775 } 776 } 777 778 779 783 public void postProcess(InputStream input, OutputStream output) 784 throws Exception { 785 if (!recycle){ 786 started = false; 787 inputBuffer = null; 788 outputBuffer = null; 789 response = null; 790 if (isMonitoringEnabled()) { 791 request.getRequestProcessor().setWorkerThreadID(0); 792 adapter.fireAdapterEvent(Adapter.CONNECTION_PROCESSING_COMPLETED, 793 request.getRequestProcessor()); 794 } 795 request = null; 796 } else { 797 inputBuffer.recycle(); 798 outputBuffer.recycle(); 799 } 800 801 sslSupport = null; 803 804 if (error){ 805 keepAlive = false; 806 connectionHeaderValue = false; 807 } 808 } 809 810 811 815 public void terminateProcess(){ 816 if ( error && usingNioNonBlocking) { 817 taskEvent.setStatus(TaskEvent.ERROR); 818 } else { 819 taskEvent.setStatus(TaskEvent.COMPLETED); 820 } 821 fireTaskEvent(taskEvent); 822 } 823 824 825 827 828 838 public boolean process(InputStream input, OutputStream output) 839 throws Exception { 840 preProcess(input,output); 841 if ( !usingNioNonBlocking ) { 842 processBlocked(input,output); 843 } else { 844 processNonBlocked(input,output); 845 } 846 postProcess(input,output); 847 return keepAlive; 848 } 849 850 851 854 public Request getRequest() { 855 return request; 856 } 857 858 859 861 862 868 public void action(ActionCode actionCode, Object param) { 869 870 if (actionCode == ActionCode.ACTION_COMMIT) { 871 873 if (response.isCommitted()) 874 return; 875 876 prepareResponse(); 878 try { 879 outputBuffer.commit(); 880 } catch (IOException ex) { 881 SelectorThread.logger().log(Level.FINEST, 882 "processorTask.nonBlockingError", ex); 883 error = true; 885 } 886 887 } else if (actionCode == ActionCode.ACTION_ACK) { 888 889 891 894 if ((response.isCommitted()) || (!http11)) 895 return; 896 897 MessageBytes expectMB = request.getMimeHeaders().getValue("expect"); 898 if ((expectMB != null) 899 && (expectMB.indexOfIgnoreCase("100-continue", 0) != -1)) { 900 try { 901 outputBuffer.sendAck(); 902 } catch (IOException e) { 903 error = true; 905 } 906 } 907 908 } else if (actionCode == ActionCode.ACTION_CLOSE) { 909 911 914 try { 915 outputBuffer.endRequest(); 916 } catch (IOException e) { 917 SelectorThread.logger().log(Level.FINEST, 918 "processorTask.nonBlockingError", e); 919 error = true; 921 } 922 923 } else if (actionCode == ActionCode.ACTION_RESET) { 924 925 927 929 outputBuffer.reset(); 930 931 } else if (actionCode == ActionCode.ACTION_CUSTOM) { 932 933 935 } else if (actionCode == ActionCode.ACTION_START) { 936 937 started = true; 938 939 } else if (actionCode == ActionCode.ACTION_STOP) { 940 941 started = false; 942 943 } else if (actionCode == ActionCode.ACTION_REQ_SSL_ATTRIBUTE ) { 944 945 try { 946 if (sslSupport != null) { 947 Object sslO = sslSupport.getCipherSuite(); 948 if (sslO != null) 949 request.setAttribute 950 (SSLSupport.CIPHER_SUITE_KEY, sslO); 951 sslO = sslSupport.getPeerCertificateChain(false); 952 if (sslO != null) 953 request.setAttribute 954 (SSLSupport.CERTIFICATE_KEY, sslO); 955 sslO = sslSupport.getKeySize(); 956 if (sslO != null) 957 request.setAttribute 958 (SSLSupport.KEY_SIZE_KEY, sslO); 959 sslO = sslSupport.getSessionId(); 960 if (sslO != null) 961 request.setAttribute 962 (SSLSupport.SESSION_ID_KEY, sslO); 963 } 964 } catch (Exception e) { 965 SelectorThread.logger().log(Level.WARNING, 966 "processorTask.errorSSL" ,e); 967 } 968 969 } else if (actionCode == ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE) { 970 971 if ((remoteAddr == null) && (socket != null)) { 972 InetAddress inetAddr = socket.getInetAddress(); 973 if (inetAddr != null) { 974 remoteAddr = inetAddr.getHostAddress(); 975 } 976 } 977 request.remoteAddr().setString(remoteAddr); 978 979 } else if (actionCode == ActionCode.ACTION_REQ_LOCAL_NAME_ATTRIBUTE) { 980 981 if ((localName == null) && (socket != null)) { 982 InetAddress inetAddr = socket.getLocalAddress(); 983 if (inetAddr != null) { 984 localName = inetAddr.getHostName(); 985 } 986 } 987 request.localName().setString(localName); 988 989 } else if (actionCode == ActionCode.ACTION_REQ_HOST_ATTRIBUTE) { 990 991 if ((remoteHost == null) && (socket != null)) { 992 InetAddress inetAddr = socket.getInetAddress(); 993 if (inetAddr != null) { 994 remoteHost = inetAddr.getHostName(); 995 } 996 997 if(remoteHost == null) { 998 if(remoteAddr != null) { 999 remoteHost = remoteAddr; 1000 } else { request.remoteHost().recycle(); 1002 } 1003 } 1004 } 1005 request.remoteHost().setString(remoteHost); 1006 1007 } else if (actionCode == ActionCode.ACTION_REQ_LOCAL_ADDR_ATTRIBUTE) { 1008 1009 if (localAddr == null) 1010 localAddr = socket.getLocalAddress().getHostAddress(); 1011 1012 request.localAddr().setString(localAddr); 1013 1014 } else if (actionCode == ActionCode.ACTION_REQ_REMOTEPORT_ATTRIBUTE) { 1015 1016 if ((remotePort == -1 ) && (socket !=null)) { 1017 remotePort = socket.getPort(); 1018 } 1019 request.setRemotePort(remotePort); 1020 1021 } else if (actionCode == ActionCode.ACTION_REQ_LOCALPORT_ATTRIBUTE) { 1022 1023 if ((localPort == -1 ) && (socket !=null)) { 1024 localPort = socket.getLocalPort(); 1025 } 1026 request.setLocalPort(localPort); 1027 1028 } else if (actionCode == ActionCode.ACTION_REQ_SSL_CERTIFICATE) { 1029 if( sslSupport != null) { 1030 1034 InputFilter[] inputFilters = inputBuffer.getFilters(); 1035 ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]) 1036 .setLimit(maxPostSize); 1037 inputBuffer.addActiveFilter 1038 (inputFilters[Constants.BUFFERED_FILTER]); 1039 try { 1040 Object sslO = sslSupport.getPeerCertificateChain(true); 1041 if( sslO != null) { 1042 request.setAttribute 1043 (SSLSupport.CERTIFICATE_KEY, sslO); 1044 } 1045 } catch (Exception e) { 1046 SelectorThread.logger().log(Level.WARNING, 1047 "processorTask.exceptionSSLcert",e); 1048 } 1049 } 1050 } else if ( actionCode == ActionCode.ACTION_POST_REQUEST ) { 1051 if (response.getStatus() == 200){ 1052 try{ 1053 handler.handle(request,Handler.RESPONSE_PROCEEDED); 1054 } catch(IOException ex){ 1055 ; } 1057 } 1058 } 1059 } 1060 1061 1063 1064 1069 public void setAdapter(Adapter adapter) { 1070 this.adapter = adapter; 1071 } 1072 1073 1074 1079 public Adapter getAdapter() { 1080 return adapter; 1081 } 1082 1083 1084 1086 1087 1090 protected void prepareRequest() { 1091 1092 http11 = true; 1093 http09 = false; 1094 contentDelimitation = false; 1095 if (sslSupport != null) { 1096 request.scheme().setString("https"); 1097 } 1098 MessageBytes protocolMB = request.protocol(); 1099 if (protocolMB.equals(Constants.HTTP_11)) { 1100 http11 = true; 1101 protocolMB.setString(Constants.HTTP_11); 1102 } else if (protocolMB.equals(Constants.HTTP_10)) { 1103 http11 = false; 1104 keepAlive = false; 1105 protocolMB.setString(Constants.HTTP_10); 1106 } else if (protocolMB.equals("")) { 1107 http09 = true; 1109 http11 = false; 1110 keepAlive = false; 1111 } else { 1112 http11 = false; 1114 error = true; 1115 response.setStatus(505); 1117 } 1118 1119 MessageBytes methodMB = request.method(); 1120 if (methodMB.equals(Constants.GET)) { 1121 methodMB.setString(Constants.GET); 1122 } else if (methodMB.equals(Constants.POST)) { 1123 methodMB.setString(Constants.POST); 1124 } 1125 1126 MimeHeaders headers = request.getMimeHeaders(); 1127 1128 MessageBytes connectionValueMB = headers.getValue("connection"); 1130 if (connectionValueMB != null) { 1131 ByteChunk connectionValueBC = connectionValueMB.getByteChunk(); 1132 if (findBytes(connectionValueBC, Constants.CLOSE_BYTES) != -1) { 1133 keepAlive = false; 1134 connectionHeaderValue = false; 1135 } else if (findBytes(connectionValueBC, 1136 Constants.KEEPALIVE_BYTES) != -1) { 1137 keepAlive = true; 1138 connectionHeaderValue = true; 1139 } 1140 } 1141 1142 1143 ByteChunk uriBC = request.requestURI().getByteChunk(); 1145 if (uriBC.startsWithIgnoreCase("http", 0)) { 1146 1147 int pos = uriBC.indexOf("://", 0, 3, 4); 1148 int uriBCStart = uriBC.getStart(); 1149 int slashPos = -1; 1150 if (pos != -1) { 1151 byte[] uriB = uriBC.getBytes(); 1152 slashPos = uriBC.indexOf('/', pos + 3); 1153 if (slashPos == -1) { 1154 slashPos = uriBC.getLength(); 1155 request.requestURI().setBytes 1157 (uriB, uriBCStart + pos + 1, 1); 1158 } else { 1159 request.requestURI().setBytes 1160 (uriB, uriBCStart + slashPos, 1161 uriBC.getLength() - slashPos); 1162 } 1163 MessageBytes hostMB = headers.setValue("host"); 1164 hostMB.setBytes(uriB, uriBCStart + pos + 3, 1165 slashPos - pos - 3); 1166 } 1167 1168 } 1169 1170 InputFilter[] inputFilters = inputBuffer.getFilters(); 1172 1173 long contentLength = request.getContentLengthLong(); 1175 if (contentLength >= 0) { 1176 1177 inputBuffer.addActiveFilter 1178 (inputFilters[Constants.IDENTITY_FILTER]); 1179 contentDelimitation = true; 1180 } 1181 1182 MessageBytes transferEncodingValueMB = null; 1184 if (http11) 1185 transferEncodingValueMB = headers.getValue("transfer-encoding"); 1186 if (transferEncodingValueMB != null) { 1187 String transferEncodingValue = transferEncodingValueMB.toString(); 1188 int startPos = 0; 1190 int commaPos = transferEncodingValue.indexOf(','); 1191 String encodingName = null; 1192 while (commaPos != -1) { 1193 encodingName = transferEncodingValue.substring 1194 (startPos, commaPos).toLowerCase().trim(); 1195 if (!addInputFilter(inputFilters, encodingName)) { 1196 error = true; 1198 response.setStatus(501); 1200 } 1201 startPos = commaPos + 1; 1202 commaPos = transferEncodingValue.indexOf(',', startPos); 1203 } 1204 encodingName = transferEncodingValue.substring(startPos) 1205 .toLowerCase().trim(); 1206 if (!addInputFilter(inputFilters, encodingName)) { 1207 error = true; 1209 response.setStatus(501); 1211 } 1212 } 1213 1214 MessageBytes valueMB = headers.getValue("host"); 1215 1216 if (http11 && (valueMB == null)) { 1218 error = true; 1219 response.setStatus(400); 1221 } 1222 1223 parseHost(valueMB); 1224 1225 if (!contentDelimitation) { 1226 inputBuffer.addActiveFilter 1230 (inputFilters[Constants.VOID_FILTER]); 1231 contentDelimitation = true; 1232 } 1233 } 1234 1235 1236 1239 public void parseHost(MessageBytes valueMB) { 1240 1241 if (valueMB == null || valueMB.isNull()) { 1242 request.setServerPort(socket.getLocalPort()); 1246 InetAddress localAddress = socket.getLocalAddress(); 1247 request.setLocalHost(localAddress.getHostName()); 1250 request.serverName().setString(localAddress.getHostName()); 1251 return; 1252 } 1253 1254 ByteChunk valueBC = valueMB.getByteChunk(); 1255 byte[] valueB = valueBC.getBytes(); 1256 int valueL = valueBC.getLength(); 1257 int valueS = valueBC.getStart(); 1258 int colonPos = -1; 1259 if (hostNameC.length < valueL) { 1260 hostNameC = new char[valueL]; 1261 } 1262 1263 boolean ipv6 = (valueB[valueS] == '['); 1264 boolean bracketClosed = false; 1265 for (int i = 0; i < valueL; i++) { 1266 char b = (char) valueB[i + valueS]; 1267 hostNameC[i] = b; 1268 if (b == ']') { 1269 bracketClosed = true; 1270 } else if (b == ':') { 1271 if (!ipv6 || bracketClosed) { 1272 colonPos = i; 1273 break; 1274 } 1275 } 1276 } 1277 1278 if (colonPos < 0) { 1279 if (sslSupport == null) { 1280 request.setServerPort(80); 1282 } else { 1283 request.setServerPort(443); 1285 } 1286 request.serverName().setChars(hostNameC, 0, valueL); 1287 } else { 1288 1289 request.serverName().setChars(hostNameC, 0, colonPos); 1290 1291 int port = 0; 1292 int mult = 1; 1293 for (int i = valueL - 1; i > colonPos; i--) { 1294 int charValue = HexUtils.DEC[(int) valueB[i + valueS]]; 1295 if (charValue == -1) { 1296 error = true; 1298 response.setStatus(400); 1300 break; 1301 } 1302 port = port + (charValue * mult); 1303 mult = 10 * mult; 1304 } 1305 request.setServerPort(port); 1306 1307 } 1308 1309 } 1310 1311 1312 1316 protected void prepareResponse() { 1317 1318 boolean entityBody = true; 1319 contentDelimitation = false; 1320 1321 OutputFilter[] outputFilters = outputBuffer.getFilters(); 1322 1323 if (http09 == true) { 1324 outputBuffer.addActiveFilter 1326 (outputFilters[Constants.IDENTITY_FILTER]); 1327 return; 1328 } 1329 1330 int statusCode = response.getStatus(); 1331 if ((statusCode == 204) || (statusCode == 205) 1332 || (statusCode == 304)) { 1333 outputBuffer.addActiveFilter 1335 (outputFilters[Constants.VOID_FILTER]); 1336 entityBody = false; 1337 contentDelimitation = true; 1338 } 1339 1340 MessageBytes methodMB = request.method(); 1341 if (methodMB.equals("HEAD")) { 1342 outputBuffer.addActiveFilter 1344 (outputFilters[Constants.VOID_FILTER]); 1345 contentDelimitation = true; 1346 } 1347 1348 MimeHeaders headers = response.getMimeHeaders(); 1349 if (!entityBody) { 1350 response.setContentLength(-1); 1351 } else { 1352 if ( forcedResponseType.equalsIgnoreCase( 1353 org.apache.coyote.tomcat5.Constants.FORCED_RESPONSE_TYPE) ) { 1354 String contentType = response.getContentType(); 1355 if (contentType != null) { 1356 headers.setValue("Content-Type").setString(contentType); 1357 } else { 1358 headers.setValue("Content-Type") 1359 .setString(defaultResponseType); 1360 } 1361 } else { 1362 headers.setValue("Content-Type").setString(forcedResponseType); 1363 } 1364 1365 String contentLanguage = response.getContentLanguage(); 1366 if (contentLanguage != null) { 1367 headers.setValue("Content-Language") 1368 .setString(contentLanguage); 1369 } 1370 } 1371 1372 int contentLength = response.getContentLength(); 1373 if (contentLength != -1) { 1374 headers.setValue("Content-Length").setInt(contentLength); 1375 outputBuffer.addActiveFilter 1376 (outputFilters[Constants.IDENTITY_FILTER]); 1377 contentDelimitation = true; 1378 } else { 1379 if (entityBody && http11 && keepAlive) { 1380 outputBuffer.addActiveFilter 1381 (outputFilters[Constants.CHUNKED_FILTER]); 1382 contentDelimitation = true; 1383 response.addHeader("Transfer-Encoding", "chunked"); 1384 } else { 1385 outputBuffer.addActiveFilter 1386 (outputFilters[Constants.IDENTITY_FILTER]); 1387 } 1388 } 1389 1390 if (! response.containsHeader("Date")){ 1392 String date = FastHttpDateFormat.getCurrentDate(); 1393 response.addHeader("Date", date); 1394 } 1395 1396 headers.setValue("Server").setString(ServerInfo.getServerInfo()); 1398 1399 1402 if ((entityBody) && (!contentDelimitation)) { 1403 keepAlive = false; 1406 } 1407 1408 keepAlive = keepAlive && !statusDropsConnection(statusCode) 1411 && !dropConnection; 1412 if (!keepAlive ) { 1413 headers.setValue("Connection").setString("close"); 1414 connectionHeaderValue = false; 1415 } else if (!http11 && !error) { 1416 headers.setValue("Connection").setString("Keep-Alive"); 1417 } 1418 1419 outputBuffer.sendStatus(); 1421 1422 int size = headers.size(); 1423 for (int i = 0; i < size; i++) { 1424 outputBuffer.sendHeader(headers.getName(i), headers.getValue(i)); 1425 } 1426 outputBuffer.endHeaders(); 1427 1428 } 1429 1430 1431 1434 protected void initializeFilters() { 1435 1436 inputBuffer.addFilter(new IdentityInputFilter()); 1438 outputBuffer.addFilter(new IdentityOutputFilter()); 1439 1440 inputBuffer.addFilter(new ChunkedInputFilter()); 1442 outputBuffer.addFilter(new ChunkedOutputFilter()); 1443 1444 inputBuffer.addFilter(new VoidInputFilter()); 1446 outputBuffer.addFilter(new VoidOutputFilter()); 1447 1448 inputBuffer.addFilter(new BufferedInputFilter()); 1450 1451 outputBuffer.addFilter(new GzipOutputFilter()); 1454 1455 } 1456 1457 1458 1464 protected boolean addInputFilter(InputFilter[] inputFilters, 1465 String encodingName) { 1466 if (encodingName.equals("identity")) { 1467 } else if (encodingName.equals("chunked")) { 1469 inputBuffer.addActiveFilter 1470 (inputFilters[Constants.CHUNKED_FILTER]); 1471 contentDelimitation = true; 1472 } else { 1473 for (int i = 2; i < inputFilters.length; i++) { 1474 if (inputFilters[i].getEncodingName() 1475 .toString().equals(encodingName)) { 1476 inputBuffer.addActiveFilter(inputFilters[i]); 1477 return true; 1478 } 1479 } 1480 return false; 1481 } 1482 return true; 1483 } 1484 1485 1486 1490 protected int findBytes(ByteChunk bc, byte[] b) { 1491 1492 byte first = b[0]; 1493 byte[] buff = bc.getBuffer(); 1494 int start = bc.getStart(); 1495 int end = bc.getEnd(); 1496 1497 int srcEnd = b.length; 1499 1500 for (int i = start; i <= (end - srcEnd); i++) { 1501 if (Ascii.toLower(buff[i]) != first) continue; 1502 int myPos = i+1; 1504 for (int srcPos = 1; srcPos < srcEnd; ) { 1505 if (Ascii.toLower(buff[myPos++]) != b[srcPos++]) 1506 break; 1507 if (srcPos == srcEnd) return i - start; } 1509 } 1510 return -1; 1511 1512 } 1513 1514 1518 protected boolean statusDropsConnection(int status) { 1519 return status == 400 || 1520 status == 408 || 1521 status == 411 || 1522 status == 413 || 1523 status == 414 || 1524 status == 500 || 1525 status == 503 || 1526 status == 501 ; 1527 } 1528 1529 1534 protected void addFilter(String className) { 1535 try { 1536 Class clazz = Class.forName(className); 1537 Object obj = clazz.newInstance(); 1538 if (obj instanceof InputFilter) { 1539 inputBuffer.addFilter((InputFilter) obj); 1540 } else if (obj instanceof OutputFilter) { 1541 outputBuffer.addFilter((OutputFilter) obj); 1542 } else { 1543 SelectorThread.logger().log(Level.WARNING, 1544 "processorTask.unknownFilter" ,className); 1545 } 1546 } catch (Exception e) { 1547 SelectorThread.logger().log(Level.SEVERE,"processorTask.errorFilter", 1548 new Object []{className, e}); 1549 } 1550 } 1551 1552 1553 1556 public void setMaxPostSize(int mps) { 1557 maxPostSize = mps; 1558 } 1559 1560 1561 1564 public int getMaxPostSize() { 1565 return maxPostSize; 1566 } 1567 1568 1569 1572 public void setSocket(Socket socket){ 1573 this.socket = socket; 1574 } 1575 1576 1577 1580 public void setTimeout( int timeouts ) { 1581 timeout = timeouts ; 1582 } 1583 1584 1587 public int getTimeout() { 1588 return timeout; 1589 } 1590 1591 1595 public void setSSLImplementation( SSLImplementation sslImplementation){ 1596 this.sslImplementation = sslImplementation; 1597 } 1598 1599 1600 1603 private void registerMonitoring(){ 1604 1605 RequestInfo requestInfo = request.getRequestProcessor(); 1606 requestInfo.setGlobalProcessor(getRequestGroupInfo()); 1608 1609 try { 1610 oname = new ObjectName (selectorThread.getDomain() 1611 + ":type=RequestProcessor,worker=http" 1612 + selectorThread.getPort() 1613 + ",name=HttpRequest" 1614 + requestCount++ ); 1615 Registry.getRegistry().registerComponent(requestInfo, oname, 1616 null); 1617 } catch( Exception ex ) { 1618 SelectorThread.logger().log(Level.WARNING, 1619 "processorTask.errorRegisteringRequest", 1620 ex); 1621 } 1622 1623 hasRequestInfoRegistered = true; 1624 } 1625 1626 1627 1631 private void unregisterMonitoring() { 1632 1633 RequestInfo requestInfo = request.getRequestProcessor(); 1634 1641 requestInfo.setGlobalProcessor(null); 1642 requestInfo.reset(); 1643 1644 if (oname != null) { 1645 try { 1646 Registry.getRegistry().unregisterComponent(oname); 1647 } catch (Exception ex) { 1648 SelectorThread.logger().log(Level.WARNING, 1649 "processorTask.errorUnregisteringRequest", 1650 ex); 1651 } 1652 } 1653 1654 hasRequestInfoRegistered = false; 1655 } 1656 1657 1658 public int getMaxHttpHeaderSize() { 1659 return maxHttpHeaderSize; 1660 } 1661 1662 public void setMaxHttpHeaderSize(int maxHttpHeaderSize) { 1663 this.maxHttpHeaderSize = maxHttpHeaderSize; 1664 } 1665 1666 1667 1670 public void setBufferSize(int requestBufferSize){ 1671 this.requestBufferSize = requestBufferSize; 1672 } 1673 1674 1675 1678 public int getBufferSize(){ 1679 return requestBufferSize; 1680 } 1681 1682 1683 1687 public void useAlternateKeepAlive(boolean useAlternateKeepAlive){ 1688 this.useAlternateKeepAlive = useAlternateKeepAlive; 1689 } 1690 1691 1692 1696 protected Socket getSocket(){ 1697 return socket; 1698 } 1699 1700 1701 1706 public void setDropConnection(boolean dropConnection){ 1707 this.dropConnection = dropConnection; 1708 } 1709 1710 1711 1714 public boolean getDropConnection(){ 1715 return dropConnection; 1716 } 1717 1718 1719 1724 public void setMaxKeepAliveRequests(int maxKeepAliveRequests) { 1725 this.maxKeepAliveRequests = maxKeepAliveRequests; 1726 } 1727 1728 1729 1732 public int getMaxKeepAliveRequests() { 1733 return maxKeepAliveRequests; 1734 } 1735 1736 1737 1740 public int countBlockingKeepAlive(){ 1741 if (maxKeepAliveRequests == -1) return -1; 1742 1743 return maxKeepAliveRequests - keepAliveLeft; 1744 } 1745 1746 1747 1750 public void setHandler(Handler handler){ 1751 this.handler = handler; 1752 } 1753 1754 1755 1760 public void setDefaultResponseType(String defaultResponseType){ 1761 this.defaultResponseType = defaultResponseType; 1762 } 1763 1764 1765 1768 public String getDefaultResponseType(){ 1769 return defaultResponseType; 1770 } 1771 1772 1773 1779 public void setForcedResponseType(String forcedResponseType){ 1780 this.forcedResponseType = forcedResponseType; 1781 } 1782 1783 1784 1787 public String getForcedResponseType(){ 1788 return forcedResponseType; 1789 } 1790 1791 1792 1794 1797 public void setEnableAsyncExecution(boolean asyncExecution){ 1798 this.asyncExecution = asyncExecution; 1799 } 1800 1801 1802 1805 public boolean isAsyncExecutionEnabled(){ 1806 return asyncExecution; 1807 } 1808 1809 1810 1814 public void setAsyncHandler(AsyncHandler asyncHandler){ 1815 this.asyncHandler = asyncHandler; 1816 } 1817 1818 1819 1823 public AsyncHandler getAsyncHandler(){ 1824 return asyncHandler; 1825 } 1826 1827 1828 1831 public void recycle(){ 1832 clearTaskListeners(); 1833 socket = null; 1834 dropConnection = false; 1835 key = null; 1836 channelOutputBuffer.setChannel(null); 1837 } 1838} 1839 1840 | Popular Tags |