Class Name | org.apache.coyote.http11.Http11ConnectionHandler |
Inheritance | Handler |
Related Classes | Http11Protocol RequestGroupInfo Http11Processor |
Functionality | Maitainance processor list,assign cooresponding processor to input requests. |
Analysis
Http11ConnectionHandler is a static class been defined in Http11Protocal.java file, it's very strange design that it actually inherited from Handler interface which was defined in JIoEndpoint. Not sure why Tomcat design the connector this way, but there must be a reason.
Recalling to blog about JIoEndpoint, Http11ConnectionHandler will be used by cocurrent threads in SocketProcessor.run() method, which means, Http11ConnectionHandler need to be working file in multiple thread. That's why thread safe was considered highest priority when desin this class.
Fields
There are five instance fields defined in this class:
The key method of Http11ConnectionHandler is the "process" method:
public SocketState process(SocketWrapper<Socket> socket, SocketStatus status) { Http11Processor processor = connections.remove(socket); try { if (processor == null) { processor = recycledProcessors.poll(); } if (processor == null) { processor = createProcessor(); } if (proto.isSSLEnabled() && (proto.sslImplementation != null)) { processor.setSSLSupport( proto.sslImplementation.getSSLSupport( socket.getSocket())); } else { processor.setSSLSupport(null); } SocketState state = socket.isAsync()?processor.asyncDispatch(status):processor.process(socket); if (state == SocketState.LONG) { connections.put(socket, processor); socket.setAsync(true); // longPoll may change socket state (e.g. to trigger a // complete or dispatch) return processor.asyncPostProcess(); } else { socket.setAsync(false); recycledProcessors.offer(processor); } return state; } catch(java.net.SocketException e) { // SocketExceptions are normal log.debug(sm.getString( "http11protocol.proto.socketexception.debug"), e); } catch (java.io.IOException e) { // IOExceptions are normal log.debug(sm.getString( "http11protocol.proto.ioexception.debug"), e); } // Future developers: if you discover any other // rare-but-nonfatal exceptions, catch them here, and log as // above. catch (Throwable e) { ExceptionUtils.handleThrowable(e); // any other exception or error is odd. Here we log it // with "ERROR" level, so it will show up even on // less-than-verbose logs. log.error(sm.getString("http11protocol.proto.error"), e); } recycledProcessors.offer(processor); return SocketState.CLOSED; }
The method will first check if an existing processor been assign to current socket, use the existing processor if has, otherwise a new one will be created.
Processor will set it's SSL support based on the setting in ProtocalHandler, we will leave this part in future discussion.
After that, the socket will be processed by the processor differently according to if the socket is an asynchronized.
The processor will be recyled once finished process, and the socket status will be set to CLOSED.