@@ -638,6 +638,12 @@ protected boolean statusDropsConnection(int status) {
638638 status == 501 /* SC_NOT_IMPLEMENTED */ ;
639639 }
640640
641+
642+ /**
643+ * Allows the super class to set the socket wrapper being used.
644+ */
645+ protected abstract void setSocketWrapper (SocketWrapper <S > socketWrapper );
646+
641647
642648 /**
643649 * Exposes input buffer to super class to allow better code re-use.
@@ -837,6 +843,211 @@ public final void action(ActionCode actionCode, Object param) {
837843 protected abstract void setSocketTimeout (int timeout ) throws IOException ;
838844
839845
846+ /**
847+ * Process pipelined HTTP requests using the specified input and output
848+ * streams.
849+ *
850+ * @param socketWrapper Socket from which the HTTP requests will be read
851+ * and the HTTP responses will be written.
852+ *
853+ * @throws IOException error during an I/O operation
854+ */
855+ @ Override
856+ public SocketState process (SocketWrapper <S > socketWrapper )
857+ throws IOException {
858+ RequestInfo rp = request .getRequestProcessor ();
859+ rp .setStage (org .apache .coyote .Constants .STAGE_PARSE );
860+
861+ // Setting up the I/O
862+ setSocketWrapper (socketWrapper );
863+ getInputBuffer ().init (socketWrapper , endpoint );
864+ getOutputBuffer ().init (socketWrapper , endpoint );
865+
866+ // Flags
867+ error = false ;
868+ keepAlive = true ;
869+ comet = false ;
870+ openSocket = false ;
871+ sendfileInProgress = false ;
872+ readComplete = true ;
873+ if (endpoint .getUsePolling ()) {
874+ keptAlive = false ;
875+ } else {
876+ keptAlive = socketWrapper .isKeptAlive ();
877+ }
878+
879+ if (disableKeepAlive ()) {
880+ socketWrapper .setKeepAliveLeft (0 );
881+ }
882+
883+ while (!error && keepAlive && !comet && !isAsync () &&
884+ !endpoint .isPaused ()) {
885+
886+ // Parsing the request header
887+ try {
888+ setRequestLineReadTimeout ();
889+
890+ if (!getInputBuffer ().parseRequestLine (keptAlive )) {
891+ if (handleIncompleteRequestLineRead ()) {
892+ break ;
893+ }
894+ }
895+
896+ if (endpoint .isPaused ()) {
897+ // 503 - Service unavailable
898+ response .setStatus (503 );
899+ adapter .log (request , response , 0 );
900+ error = true ;
901+ } else {
902+ request .setStartTime (System .currentTimeMillis ());
903+ keptAlive = true ;
904+ // Currently only NIO will ever return false here
905+ if (!getInputBuffer ().parseHeaders ()) {
906+ // We've read part of the request, don't recycle it
907+ // instead associate it with the socket
908+ openSocket = true ;
909+ readComplete = false ;
910+ break ;
911+ }
912+ if (!disableUploadTimeout ) {
913+ setSocketTimeout (connectionUploadTimeout );
914+ }
915+ }
916+ } catch (IOException e ) {
917+ if (getLog ().isDebugEnabled ()) {
918+ getLog ().debug (
919+ sm .getString ("http11processor.header.parse" ), e );
920+ }
921+ error = true ;
922+ break ;
923+ } catch (Throwable t ) {
924+ ExceptionUtils .handleThrowable (t );
925+ if (getLog ().isDebugEnabled ()) {
926+ getLog ().debug (
927+ sm .getString ("http11processor.header.parse" ), t );
928+ }
929+ // 400 - Bad Request
930+ response .setStatus (400 );
931+ adapter .log (request , response , 0 );
932+ error = true ;
933+ }
934+
935+ if (!error ) {
936+ // Setting up filters, and parse some request headers
937+ rp .setStage (org .apache .coyote .Constants .STAGE_PREPARE );
938+ try {
939+ prepareRequest ();
940+ } catch (Throwable t ) {
941+ ExceptionUtils .handleThrowable (t );
942+ if (getLog ().isDebugEnabled ()) {
943+ getLog ().debug (sm .getString (
944+ "http11processor.request.prepare" ), t );
945+ }
946+ // 400 - Internal Server Error
947+ response .setStatus (400 );
948+ adapter .log (request , response , 0 );
949+ error = true ;
950+ }
951+ }
952+
953+ if (maxKeepAliveRequests == 1 ) {
954+ keepAlive = false ;
955+ } else if (maxKeepAliveRequests > 0 &&
956+ socketWrapper .decrementKeepAlive () <= 0 ) {
957+ keepAlive = false ;
958+ }
959+
960+ // Process the request in the adapter
961+ if (!error ) {
962+ try {
963+ rp .setStage (org .apache .coyote .Constants .STAGE_SERVICE );
964+ adapter .service (request , response );
965+ // Handle when the response was committed before a serious
966+ // error occurred. Throwing a ServletException should both
967+ // set the status to 500 and set the errorException.
968+ // If we fail here, then the response is likely already
969+ // committed, so we can't try and set headers.
970+ if (keepAlive && !error ) { // Avoid checking twice.
971+ error = response .getErrorException () != null ||
972+ (!isAsync () &&
973+ statusDropsConnection (response .getStatus ()));
974+ }
975+ setCometTimeouts (socketWrapper );
976+ } catch (InterruptedIOException e ) {
977+ error = true ;
978+ } catch (Throwable t ) {
979+ ExceptionUtils .handleThrowable (t );
980+ getLog ().error (sm .getString (
981+ "http11processor.request.process" ), t );
982+ // 500 - Internal Server Error
983+ response .setStatus (500 );
984+ adapter .log (request , response , 0 );
985+ error = true ;
986+ }
987+ }
988+
989+ // Finish the handling of the request
990+ rp .setStage (org .apache .coyote .Constants .STAGE_ENDINPUT );
991+
992+ if (!isAsync () && !comet ) {
993+ if (error ) {
994+ // If we know we are closing the connection, don't drain
995+ // input. This way uploading a 100GB file doesn't tie up the
996+ // thread if the servlet has rejected it.
997+ getInputBuffer ().setSwallowInput (false );
998+ }
999+ endRequest ();
1000+ }
1001+
1002+ rp .setStage (org .apache .coyote .Constants .STAGE_ENDOUTPUT );
1003+
1004+ // If there was an error, make sure the request is counted as
1005+ // and error, and update the statistics counter
1006+ if (error ) {
1007+ response .setStatus (500 );
1008+ }
1009+ request .updateCounters ();
1010+
1011+ if (!isAsync () && !comet || error ) {
1012+ getInputBuffer ().nextRequest ();
1013+ getOutputBuffer ().nextRequest ();
1014+ }
1015+
1016+ if (!disableUploadTimeout ) {
1017+ setSocketTimeout (endpoint .getSoTimeout ());
1018+ }
1019+
1020+ rp .setStage (org .apache .coyote .Constants .STAGE_KEEPALIVE );
1021+
1022+ if (breakKeepAliveLoop (socketWrapper )) {
1023+ break ;
1024+ }
1025+ }
1026+
1027+ rp .setStage (org .apache .coyote .Constants .STAGE_ENDED );
1028+
1029+ if (error || endpoint .isPaused ()) {
1030+ return SocketState .CLOSED ;
1031+ } else if (comet || isAsync ()) {
1032+ return SocketState .LONG ;
1033+ } else {
1034+ if (sendfileInProgress ) {
1035+ return SocketState .SENDFILE ;
1036+ } else {
1037+ if (openSocket ) {
1038+ if (readComplete ) {
1039+ return SocketState .OPEN ;
1040+ } else {
1041+ return SocketState .LONG ;
1042+ }
1043+ } else {
1044+ return SocketState .CLOSED ;
1045+ }
1046+ }
1047+ }
1048+ }
1049+
1050+
8401051 /**
8411052 * After reading the request headers, we have to setup the request filters.
8421053 */
0 commit comments