Search in sources :

Example 16 with Connection

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();
    }
}
Also used : AbstractConnection(org.eclipse.jetty.io.AbstractConnection) Connection(org.eclipse.jetty.io.Connection) IOException(java.io.IOException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException)

Example 17 with Connection

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();
    }
}
Also used : Connection(org.eclipse.jetty.io.Connection) AbstractConnection(org.eclipse.jetty.io.AbstractConnection) EndPoint(org.eclipse.jetty.io.EndPoint) EndPoint(org.eclipse.jetty.io.EndPoint)

Example 18 with Connection

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;
}
Also used : BadMessageException(org.eclipse.jetty.http.BadMessageException) HttpFields(org.eclipse.jetty.http.HttpFields) Connection(org.eclipse.jetty.io.Connection) IOException(java.io.IOException)

Aggregations

Connection (org.eclipse.jetty.io.Connection)18 Test (org.junit.Test)9 CountDownLatch (java.util.concurrent.CountDownLatch)8 IOException (java.io.IOException)7 Socket (java.net.Socket)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 ServletException (javax.servlet.ServletException)5 HttpServletRequest (javax.servlet.http.HttpServletRequest)5 HttpServletResponse (javax.servlet.http.HttpServletResponse)5 AbstractConnection (org.eclipse.jetty.io.AbstractConnection)4 EndPoint (org.eclipse.jetty.io.EndPoint)3 AbstractHandler (org.eclipse.jetty.server.handler.AbstractHandler)3 Slow (org.eclipse.jetty.toolchain.test.annotation.Slow)3 Timer (com.codahale.metrics.Timer)2 InputStream (java.io.InputStream)2 InterruptedIOException (java.io.InterruptedIOException)2 OutputStream (java.io.OutputStream)2 UncheckedIOException (java.io.UncheckedIOException)2 AsyncContext (javax.servlet.AsyncContext)2 ReadListener (javax.servlet.ReadListener)2