protected HttpChannelOverHttp newHttpChannel() { HttpChannelOverHttp httpChannel = new HttpChannelOverHttp(this, _connector, _config, getEndPoint(), this); return httpChannel; }
@Override public int getHeaderCacheSize() { return getHttpConfiguration().getHeaderCacheSize(); }
@Override public void onComplianceViolation(HttpCompliance compliance,HttpCompliance required, String reason) { if (_httpConnection.isRecordHttpComplianceViolations()) { if (_complianceViolations == null) { _complianceViolations = new ArrayList<>(); } String violation = String.format("%s<%s: %s for %s", compliance, required, reason, getHttpTransport()); _complianceViolations.add(violation); if (LOG.isDebugEnabled()) LOG.debug(violation); } } }
/** * If the associated response has the Expect header set to 100 Continue, * then accessing the input stream indicates that the handler/servlet * is ready for the request body and thus a 100 Continue response is sent. * * @throws IOException if the InputStream cannot be created */ @Override public void continue100(int available) throws IOException { // If the client is expecting 100 CONTINUE, then send it now. // TODO: consider using an AtomicBoolean ? if (isExpecting100Continue()) { _expect100Continue = false; // is content missing? if (available == 0) { if (getResponse().isCommitted()) throw new IOException("Committed before 100 Continues"); boolean committed = sendResponse(HttpGenerator.CONTINUE_100_INFO, null, false); if (!committed) throw new IOException("Concurrent commit while trying to send 100-Continue"); } } }
boolean onIdleTimeout(Throwable timeout) { if (_delayedForContent) { _delayedForContent = false; getRequest().getHttpInput().onIdleTimeout(timeout); execute(this); return false; } return true; }
this.getRequest().setAttribute(ATTR_COMPLIANCE_VIOLATIONS, _complianceViolations); if (getHttpConfiguration().isPersistentConnectionsEnabled()) persistent = HttpMethod.CONNECT.is(_metadata.getMethod()); if (persistent) getResponse().getHttpFields().add(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE); badMessage(HttpStatus.EXPECTATION_FAILED_417,null); return false; if (getHttpConfiguration().isPersistentConnectionsEnabled()) persistent = HttpMethod.CONNECT.is(_metadata.getMethod()); if (!persistent) getResponse().getHttpFields().add(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE); if (_upgrade!=null && upgrade()) return true; "*".equals(_metadata.getURI().toString()) && _fields.size()==0 && upgrade()) return true; badMessage(HttpStatus.UPGRADE_REQUIRED_426,null); _httpConnection.getParser().close(); return false;
for (ConnectionFactory f : getConnector().getConnectionFactories()) LOG.debug("No factory for {} in {}",_upgrade,getConnector()); return false; Connection upgrade_connection = factory.upgradeConnection(getConnector(),getEndPoint(),_metadata,response101); if (upgrade_connection==null) sendResponse(new MetaData.Response(HttpVersion.HTTP_1_1,HttpStatus.SWITCHING_PROTOCOLS_101,response101,0),null,true); LOG.debug("Upgrade from {} to {}", getEndPoint().getConnection(),upgrade_connection); getRequest().setAttribute(HttpConnection.UPGRADE_CONNECTION_ATTRIBUTE,upgrade_connection); getResponse().setStatus(101); getHttpTransport().onCompleted(); return true;
if (_channel.getResponse().getStatus() == HttpStatus.SWITCHING_PROTOCOLS_101) Connection connection = (Connection)_channel.getRequest().getAttribute(UPGRADE_CONNECTION_ATTRIBUTE); if (connection != null) _channel.getState().upgrade(); getEndPoint().upgrade(connection); _channel.recycle(); _parser.reset(); _generator.reset(); if (_channel.isExpecting100Continue()) if (_channel.getRequest().getHttpInput().isAsync()) _channel.abort(new IOException("unconsumed input")); LOG.debug("unconsumed input {}", this); if (!_channel.getRequest().getHttpInput().consumeAll()) _channel.abort(new IOException("unconsumed input")); _channel.recycle(); if (_generator.isPersistent() && !_parser.isClosed()) _parser.reset();
@Override public void badMessage(int status, String reason) { _httpConnection.getGenerator().setPersistent(false); try { // Need to call onRequest, so RequestLog can reports as much as possible onRequest(_metadata); getRequest().getHttpInput().earlyEOF(); } catch (Exception e) { LOG.ignore(e); } onBadMessage(status,reason); }
/** Fill and parse data looking for content * @return true if an {@link RequestHandler} method was called and it returned true; */ protected boolean fillAndParseForContent() { boolean handled=false; while (_parser.inContentState()) { int filled = fillRequestBuffer(); boolean handle = parseRequestBuffer(); handled|=handle; if (handle || filled<=0 || _channel.getRequest().getHttpInput().hasContent()) break; } return handled; }
@Override public void onFlushed(long bytes) throws IOException { // Unfortunately cannot distinguish between header and content // bytes, and for content bytes whether they are chunked or not. _channel.getResponse().getHttpOutput().onFlushed(bytes); }
this.getRequest().setAttribute(HttpCompliance.VIOLATIONS_ATTR, _complianceViolations); _complianceViolations=null; if (getHttpConfiguration().isPersistentConnectionsEnabled()) persistent = HttpMethod.CONNECT.is(_metadata.getMethod()); if (persistent) getResponse().getHttpFields().add(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE); badMessage(new BadMessageException(HttpStatus.EXPECTATION_FAILED_417)); return false; if (getHttpConfiguration().isPersistentConnectionsEnabled()) persistent = HttpMethod.CONNECT.is(_metadata.getMethod()); if (!persistent) getResponse().getHttpFields().add(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE); if (_upgrade != null && upgrade()) return true; "*".equals(_metadata.getURI().toString()) && _fields.size() == 0 && upgrade()) return true; badMessage(new BadMessageException(HttpStatus.UPGRADE_REQUIRED_426)); _httpConnection.getParser().close(); return false;
for (ConnectionFactory f : getConnector().getConnectionFactories()) LOG.debug("No factory for {} in {}", _upgrade, getConnector()); return false; Connection upgrade_connection = factory.upgradeConnection(getConnector(), getEndPoint(), _metadata, response101); if (upgrade_connection == null) sendResponse(new MetaData.Response(HttpVersion.HTTP_1_1, HttpStatus.SWITCHING_PROTOCOLS_101, response101, 0), null, true); LOG.debug("Upgrade from {} to {}", getEndPoint().getConnection(), upgrade_connection); getRequest().setAttribute(HttpConnection.UPGRADE_CONNECTION_ATTRIBUTE, upgrade_connection); getResponse().setStatus(101); getHttpTransport().onCompleted(); return true;
if (_channel.getResponse().getStatus() == HttpStatus.SWITCHING_PROTOCOLS_101) Connection connection = (Connection)_channel.getRequest().getAttribute(UPGRADE_CONNECTION_ATTRIBUTE); if (connection != null) _channel.getState().upgrade(); getEndPoint().upgrade(connection); _channel.recycle(); _parser.reset(); _generator.reset(); if (_channel.isExpecting100Continue()) _channel.abort(new IOException("unconsumed input")); _channel.abort(new IOException("unconsumed input")); _channel.recycle(); if (!_parser.isClosed())
@Override public void badMessage(BadMessageException failure) { _httpConnection.getGenerator().setPersistent(false); try { // Need to call onRequest, so RequestLog can reports as much as possible onRequest(_metadata); getRequest().getHttpInput().earlyEOF(); } catch (Exception e) { LOG.ignore(e); } onBadMessage(failure); }
/** * If the associated response has the Expect header set to 100 Continue, * then accessing the input stream indicates that the handler/servlet * is ready for the request body and thus a 100 Continue response is sent. * * @throws IOException if the InputStream cannot be created */ @Override public void continue100(int available) throws IOException { // If the client is expecting 100 CONTINUE, then send it now. // TODO: consider using an AtomicBoolean ? if (isExpecting100Continue()) { _expect100Continue = false; // is content missing? if (available == 0) { if (getResponse().isCommitted()) throw new IOException("Committed before 100 Continues"); boolean committed = sendResponse(HttpGenerator.CONTINUE_100_INFO, null, false); if (!committed) throw new IOException("Concurrent commit while trying to send 100-Continue"); } } }
public HttpConnection(HttpConfiguration config, Connector connector, EndPoint endPoint, HttpCompliance compliance, boolean recordComplianceViolations) { super(endPoint, connector.getExecutor()); _config = config; _connector = connector; _bufferPool = _connector.getByteBufferPool(); _generator = newHttpGenerator(); _channel = newHttpChannel(); _input = _channel.getRequest().getHttpInput(); _parser = newHttpParser(compliance); _recordHttpComplianceViolations = recordComplianceViolations; if (LOG.isDebugEnabled()) LOG.debug("New HTTP Connection {}", this); }