use of org.eclipse.jetty.io.Connection in project jetty.project by eclipse.
the class HttpConnection method onCompleted.
/* ------------------------------------------------------------ */
@Override
public void onCompleted() {
// Handle connection upgrades
if (_channel.getResponse().getStatus() == HttpStatus.SWITCHING_PROTOCOLS_101) {
Connection connection = (Connection) _channel.getRequest().getAttribute(UPGRADE_CONNECTION_ATTRIBUTE);
if (connection != null) {
if (LOG.isDebugEnabled())
LOG.debug("Upgrade from {} to {}", this, connection);
_channel.getState().upgrade();
getEndPoint().upgrade(connection);
_channel.recycle();
_parser.reset();
_generator.reset();
if (_contentBufferReferences.get() == 0)
releaseRequestBuffer();
else {
LOG.warn("{} lingering content references?!?!", this);
// Not returned to pool!
_requestBuffer = null;
_contentBufferReferences.set(0);
}
return;
}
}
// If we are still expecting
if (_channel.isExpecting100Continue()) {
// close to seek EOF
_parser.close();
} else if (_parser.inContentState() && _generator.isPersistent()) {
// If we are async, then we have problems to complete neatly
if (_input.isAsync()) {
if (LOG.isDebugEnabled())
LOG.debug("unconsumed async input {}", this);
_channel.abort(new IOException("unconsumed input"));
} else {
if (LOG.isDebugEnabled())
LOG.debug("unconsumed input {}", this);
// Complete reading the request
if (!_input.consumeAll())
_channel.abort(new IOException("unconsumed input"));
}
}
// Reset the channel, parsers and generator
_channel.recycle();
if (!_parser.isClosed()) {
if (_generator.isPersistent())
_parser.reset();
else
_parser.close();
}
// in a slight race with #completed, but not sure what to do with that anyway.
if (_chunk != null)
_bufferPool.release(_chunk);
_chunk = null;
_generator.reset();
// if we are not called from the onfillable thread, schedule completion
if (getCurrentConnection() != this) {
// If we are looking for the next request
if (_parser.isStart()) {
// if the buffer is empty
if (BufferUtil.isEmpty(_requestBuffer)) {
// look for more data
fillInterested();
} else // else if we are still running
if (getConnector().isRunning()) {
// Dispatched to handle a pipelined request
try {
getExecutor().execute(this);
} catch (RejectedExecutionException e) {
if (getConnector().isRunning())
LOG.warn(e);
else
LOG.ignore(e);
getEndPoint().close();
}
} else {
getEndPoint().close();
}
} else // else the parser must be closed, so seek the EOF if we are still open
if (getEndPoint().isOpen())
fillInterested();
}
}
use of org.eclipse.jetty.io.Connection in project jetty.project by eclipse.
the class NegotiatingServerConnection method onFillable.
@Override
public void onFillable() {
int filled = fill();
if (filled == 0) {
if (protocol == null) {
if (engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
// Here the SSL handshake is finished, but the protocol has not been negotiated.
if (LOG.isDebugEnabled())
LOG.debug("{} could not negotiate protocol, SSLEngine: {}", this, engine);
close();
} else {
// Here the SSL handshake is not finished yet but we filled 0 bytes,
// so we need to read more.
fillInterested();
}
} else {
ConnectionFactory connectionFactory = connector.getConnectionFactory(protocol);
if (connectionFactory == null) {
LOG.info("{} application selected protocol '{}', but no correspondent {} has been configured", this, protocol, ConnectionFactory.class.getName());
close();
} else {
EndPoint endPoint = getEndPoint();
Connection newConnection = connectionFactory.newConnection(connector, endPoint);
endPoint.upgrade(newConnection);
}
}
} else if (filled < 0) {
// Something went bad, we need to close.
if (LOG.isDebugEnabled())
LOG.debug("{} detected close on client side", this);
close();
} else {
// Must never happen, since we fill using an empty buffer
throw new IllegalStateException();
}
}
use of org.eclipse.jetty.io.Connection in project jetty.project by eclipse.
the class HttpChannelOverHttp method upgrade.
/**
* <p>Attempts to perform a HTTP/1.1 upgrade.</p>
* <p>The upgrade looks up a {@link ConnectionFactory.Upgrading} from the connector
* matching the protocol specified in the {@code Upgrade} header.</p>
* <p>The upgrade may succeed, be ignored (which can allow a later handler to implement)
* or fail with a {@link BadMessageException}.</p>
*
* @return true if the upgrade was performed, false if it was ignored
* @throws BadMessageException if the upgrade failed
*/
private boolean upgrade() throws BadMessageException {
if (LOG.isDebugEnabled())
LOG.debug("upgrade {} {}", this, _upgrade);
if (_upgrade != PREAMBLE_UPGRADE_H2C && (_connection == null || !_connection.contains("upgrade")))
throw new BadMessageException(HttpStatus.BAD_REQUEST_400);
// Find the upgrade factory
ConnectionFactory.Upgrading factory = null;
for (ConnectionFactory f : getConnector().getConnectionFactories()) {
if (f instanceof ConnectionFactory.Upgrading) {
if (f.getProtocols().contains(_upgrade.getValue())) {
factory = (ConnectionFactory.Upgrading) f;
break;
}
}
}
if (factory == null) {
if (LOG.isDebugEnabled())
LOG.debug("No factory for {} in {}", _upgrade, getConnector());
return false;
}
// Create new connection
HttpFields response101 = new HttpFields();
Connection upgrade_connection = factory.upgradeConnection(getConnector(), getEndPoint(), _metadata, response101);
if (upgrade_connection == null) {
if (LOG.isDebugEnabled())
LOG.debug("Upgrade ignored for {} by {}", _upgrade, factory);
return false;
}
// Send 101 if needed
try {
if (_upgrade != PREAMBLE_UPGRADE_H2C)
sendResponse(new MetaData.Response(HttpVersion.HTTP_1_1, HttpStatus.SWITCHING_PROTOCOLS_101, response101, 0), null, true);
} catch (IOException e) {
throw new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, e);
}
if (LOG.isDebugEnabled())
LOG.debug("Upgrade from {} to {}", getEndPoint().getConnection(), upgrade_connection);
getRequest().setAttribute(HttpConnection.UPGRADE_CONNECTION_ATTRIBUTE, upgrade_connection);
getResponse().setStatus(101);
getHttpTransport().onCompleted();
return true;
}
Aggregations