1// 2// ======================================================================== 3// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 4// ------------------------------------------------------------------------ 5// All rights reserved. This program and the accompanying materials 6// are made available under the terms of the Eclipse Public License v1.0 7// and Apache License v2.0 which accompanies this distribution. 8// 9// The Eclipse Public License is available at 10// http://www.eclipse.org/legal/epl-v10.html 11// 12// The Apache License v2.0 is available at 13// http://www.opensource.org/licenses/apache2.0.php 14// 15// You may elect to redistribute this code under either of these licenses. 16// ======================================================================== 17// 18 19package org.eclipse.jetty.server; 20 21import java.io.IOException; 22 23import org.eclipse.jetty.http.Generator; 24import org.eclipse.jetty.http.HttpException; 25import org.eclipse.jetty.http.HttpStatus; 26import org.eclipse.jetty.http.Parser; 27import org.eclipse.jetty.io.Connection; 28import org.eclipse.jetty.io.EndPoint; 29import org.eclipse.jetty.util.log.Log; 30import org.eclipse.jetty.util.log.Logger; 31 32 33/* ------------------------------------------------------------ */ 34/** Blocking Server HTTP Connection 35 */ 36public class BlockingHttpConnection extends AbstractHttpConnection 37{ 38 private static final Logger LOG = Log.getLogger(BlockingHttpConnection.class); 39 40 public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server) 41 { 42 super(connector,endpoint,server); 43 } 44 45 public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server, Parser parser, Generator generator, Request request) 46 { 47 super(connector,endpoint,server,parser,generator,request); 48 } 49 50 @Override 51 protected void handleRequest() throws IOException 52 { 53 super.handleRequest(); 54 } 55 56 public Connection handle() throws IOException 57 { 58 Connection connection = this; 59 60 try 61 { 62 setCurrentConnection(this); 63 64 // do while the endpoint is open 65 // AND the connection has not changed 66 while (_endp.isOpen() && connection==this) 67 { 68 try 69 { 70 // If we are not ended then parse available 71 if (!_parser.isComplete() && !_endp.isInputShutdown()) 72 _parser.parseAvailable(); 73 74 // Do we have more generating to do? 75 // Loop here because some writes may take multiple steps and 76 // we need to flush them all before potentially blocking in the 77 // next loop. 78 if (_generator.isCommitted() && !_generator.isComplete() && !_endp.isOutputShutdown()) 79 _generator.flushBuffer(); 80 81 // Flush buffers 82 _endp.flush(); 83 } 84 catch (HttpException e) 85 { 86 if (LOG.isDebugEnabled()) 87 { 88 LOG.debug("uri="+_uri); 89 LOG.debug("fields="+_requestFields); 90 LOG.debug(e); 91 } 92 _generator.sendError(e.getStatus(), e.getReason(), null, true); 93 _parser.reset(); 94 _endp.shutdownOutput(); 95 } 96 finally 97 { 98 // Is this request/response round complete and are fully flushed? 99 if (_parser.isComplete() && _generator.isComplete()) 100 { 101 // Reset the parser/generator 102 reset(); 103 104 // look for a switched connection instance? 105 if (_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101) 106 { 107 Connection switched=(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection"); 108 if (switched!=null) 109 connection=switched; 110 } 111 112 // TODO Is this required? 113 if (!_generator.isPersistent() && !_endp.isOutputShutdown()) 114 { 115 LOG.warn("Safety net oshut!!! Please open a bugzilla"); 116 _endp.shutdownOutput(); 117 } 118 } 119 120 // If we don't have a committed response and we are not suspended 121 if (_endp.isInputShutdown() && _generator.isIdle() && !_request.getAsyncContinuation().isSuspended()) 122 { 123 // then no more can happen, so close. 124 _endp.close(); 125 } 126 } 127 } 128 129 return connection; 130 } 131 finally 132 { 133 setCurrentConnection(null); 134 _parser.returnBuffers(); 135 _generator.returnBuffers(); 136 } 137 } 138} 139