103928aee4356845252ac6b662d5c72c29903813eJake Slack//
203928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
303928aee4356845252ac6b662d5c72c29903813eJake Slack//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
403928aee4356845252ac6b662d5c72c29903813eJake Slack//  ------------------------------------------------------------------------
503928aee4356845252ac6b662d5c72c29903813eJake Slack//  All rights reserved. This program and the accompanying materials
603928aee4356845252ac6b662d5c72c29903813eJake Slack//  are made available under the terms of the Eclipse Public License v1.0
703928aee4356845252ac6b662d5c72c29903813eJake Slack//  and Apache License v2.0 which accompanies this distribution.
803928aee4356845252ac6b662d5c72c29903813eJake Slack//
903928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Eclipse Public License is available at
1003928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.eclipse.org/legal/epl-v10.html
1103928aee4356845252ac6b662d5c72c29903813eJake Slack//
1203928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Apache License v2.0 is available at
1303928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.opensource.org/licenses/apache2.0.php
1403928aee4356845252ac6b662d5c72c29903813eJake Slack//
1503928aee4356845252ac6b662d5c72c29903813eJake Slack//  You may elect to redistribute this code under either of these licenses.
1603928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
1703928aee4356845252ac6b662d5c72c29903813eJake Slack//
1803928aee4356845252ac6b662d5c72c29903813eJake Slack
1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.server;
2003928aee4356845252ac6b662d5c72c29903813eJake Slack
2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException;
2203928aee4356845252ac6b662d5c72c29903813eJake Slack
2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.Generator;
2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.HttpException;
2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.HttpStatus;
2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.Parser;
2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.Connection;
2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.EndPoint;
2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log;
3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger;
3103928aee4356845252ac6b662d5c72c29903813eJake Slack
3203928aee4356845252ac6b662d5c72c29903813eJake Slack
3303928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------ */
3403928aee4356845252ac6b662d5c72c29903813eJake Slack/** Blocking Server HTTP Connection
3503928aee4356845252ac6b662d5c72c29903813eJake Slack */
3603928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class BlockingHttpConnection extends AbstractHttpConnection
3703928aee4356845252ac6b662d5c72c29903813eJake Slack{
3803928aee4356845252ac6b662d5c72c29903813eJake Slack    private static final Logger LOG = Log.getLogger(BlockingHttpConnection.class);
3903928aee4356845252ac6b662d5c72c29903813eJake Slack
4003928aee4356845252ac6b662d5c72c29903813eJake Slack    public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server)
4103928aee4356845252ac6b662d5c72c29903813eJake Slack    {
4203928aee4356845252ac6b662d5c72c29903813eJake Slack        super(connector,endpoint,server);
4303928aee4356845252ac6b662d5c72c29903813eJake Slack    }
4403928aee4356845252ac6b662d5c72c29903813eJake Slack
4503928aee4356845252ac6b662d5c72c29903813eJake Slack    public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server, Parser parser, Generator generator, Request request)
4603928aee4356845252ac6b662d5c72c29903813eJake Slack    {
4703928aee4356845252ac6b662d5c72c29903813eJake Slack        super(connector,endpoint,server,parser,generator,request);
4803928aee4356845252ac6b662d5c72c29903813eJake Slack    }
4903928aee4356845252ac6b662d5c72c29903813eJake Slack
5003928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
5103928aee4356845252ac6b662d5c72c29903813eJake Slack    protected void handleRequest() throws IOException
5203928aee4356845252ac6b662d5c72c29903813eJake Slack    {
5303928aee4356845252ac6b662d5c72c29903813eJake Slack        super.handleRequest();
5403928aee4356845252ac6b662d5c72c29903813eJake Slack    }
5503928aee4356845252ac6b662d5c72c29903813eJake Slack
5603928aee4356845252ac6b662d5c72c29903813eJake Slack    public Connection handle() throws IOException
5703928aee4356845252ac6b662d5c72c29903813eJake Slack    {
5803928aee4356845252ac6b662d5c72c29903813eJake Slack        Connection connection = this;
5903928aee4356845252ac6b662d5c72c29903813eJake Slack
6003928aee4356845252ac6b662d5c72c29903813eJake Slack        try
6103928aee4356845252ac6b662d5c72c29903813eJake Slack        {
6203928aee4356845252ac6b662d5c72c29903813eJake Slack            setCurrentConnection(this);
6303928aee4356845252ac6b662d5c72c29903813eJake Slack
6403928aee4356845252ac6b662d5c72c29903813eJake Slack            // do while the endpoint is open
6503928aee4356845252ac6b662d5c72c29903813eJake Slack            // AND the connection has not changed
6603928aee4356845252ac6b662d5c72c29903813eJake Slack            while (_endp.isOpen() && connection==this)
6703928aee4356845252ac6b662d5c72c29903813eJake Slack            {
6803928aee4356845252ac6b662d5c72c29903813eJake Slack                try
6903928aee4356845252ac6b662d5c72c29903813eJake Slack                {
7003928aee4356845252ac6b662d5c72c29903813eJake Slack                    // If we are not ended then parse available
7103928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (!_parser.isComplete() && !_endp.isInputShutdown())
7203928aee4356845252ac6b662d5c72c29903813eJake Slack                        _parser.parseAvailable();
7303928aee4356845252ac6b662d5c72c29903813eJake Slack
7403928aee4356845252ac6b662d5c72c29903813eJake Slack                    // Do we have more generating to do?
7503928aee4356845252ac6b662d5c72c29903813eJake Slack                    // Loop here because some writes may take multiple steps and
7603928aee4356845252ac6b662d5c72c29903813eJake Slack                    // we need to flush them all before potentially blocking in the
7703928aee4356845252ac6b662d5c72c29903813eJake Slack                    // next loop.
7803928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (_generator.isCommitted() && !_generator.isComplete() && !_endp.isOutputShutdown())
7903928aee4356845252ac6b662d5c72c29903813eJake Slack                        _generator.flushBuffer();
8003928aee4356845252ac6b662d5c72c29903813eJake Slack
8103928aee4356845252ac6b662d5c72c29903813eJake Slack                    // Flush buffers
8203928aee4356845252ac6b662d5c72c29903813eJake Slack                    _endp.flush();
8303928aee4356845252ac6b662d5c72c29903813eJake Slack                }
8403928aee4356845252ac6b662d5c72c29903813eJake Slack                catch (HttpException e)
8503928aee4356845252ac6b662d5c72c29903813eJake Slack                {
8603928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (LOG.isDebugEnabled())
8703928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
8803928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.debug("uri="+_uri);
8903928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.debug("fields="+_requestFields);
9003928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.debug(e);
9103928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
9203928aee4356845252ac6b662d5c72c29903813eJake Slack                    _generator.sendError(e.getStatus(), e.getReason(), null, true);
9303928aee4356845252ac6b662d5c72c29903813eJake Slack                    _parser.reset();
9403928aee4356845252ac6b662d5c72c29903813eJake Slack                    _endp.shutdownOutput();
9503928aee4356845252ac6b662d5c72c29903813eJake Slack                }
9603928aee4356845252ac6b662d5c72c29903813eJake Slack                finally
9703928aee4356845252ac6b662d5c72c29903813eJake Slack                {
9803928aee4356845252ac6b662d5c72c29903813eJake Slack                    //  Is this request/response round complete and are fully flushed?
9903928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (_parser.isComplete() && _generator.isComplete())
10003928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
10103928aee4356845252ac6b662d5c72c29903813eJake Slack                        // Reset the parser/generator
10203928aee4356845252ac6b662d5c72c29903813eJake Slack                        reset();
10303928aee4356845252ac6b662d5c72c29903813eJake Slack
10403928aee4356845252ac6b662d5c72c29903813eJake Slack                        // look for a switched connection instance?
10503928aee4356845252ac6b662d5c72c29903813eJake Slack                        if (_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
10603928aee4356845252ac6b662d5c72c29903813eJake Slack                        {
10703928aee4356845252ac6b662d5c72c29903813eJake Slack                            Connection switched=(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection");
10803928aee4356845252ac6b662d5c72c29903813eJake Slack                            if (switched!=null)
10903928aee4356845252ac6b662d5c72c29903813eJake Slack                                connection=switched;
11003928aee4356845252ac6b662d5c72c29903813eJake Slack                        }
11103928aee4356845252ac6b662d5c72c29903813eJake Slack
11203928aee4356845252ac6b662d5c72c29903813eJake Slack                        // TODO Is this required?
11303928aee4356845252ac6b662d5c72c29903813eJake Slack                        if (!_generator.isPersistent() && !_endp.isOutputShutdown())
11403928aee4356845252ac6b662d5c72c29903813eJake Slack                        {
11503928aee4356845252ac6b662d5c72c29903813eJake Slack                            LOG.warn("Safety net oshut!!! Please open a bugzilla");
11603928aee4356845252ac6b662d5c72c29903813eJake Slack                            _endp.shutdownOutput();
11703928aee4356845252ac6b662d5c72c29903813eJake Slack                        }
11803928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
11903928aee4356845252ac6b662d5c72c29903813eJake Slack
12003928aee4356845252ac6b662d5c72c29903813eJake Slack                    // If we don't have a committed response and we are not suspended
12103928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (_endp.isInputShutdown() && _generator.isIdle() && !_request.getAsyncContinuation().isSuspended())
12203928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
12303928aee4356845252ac6b662d5c72c29903813eJake Slack                        // then no more can happen, so close.
12403928aee4356845252ac6b662d5c72c29903813eJake Slack                        _endp.close();
12503928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
12603928aee4356845252ac6b662d5c72c29903813eJake Slack                }
12703928aee4356845252ac6b662d5c72c29903813eJake Slack            }
12803928aee4356845252ac6b662d5c72c29903813eJake Slack
12903928aee4356845252ac6b662d5c72c29903813eJake Slack            return connection;
13003928aee4356845252ac6b662d5c72c29903813eJake Slack        }
13103928aee4356845252ac6b662d5c72c29903813eJake Slack        finally
13203928aee4356845252ac6b662d5c72c29903813eJake Slack        {
13303928aee4356845252ac6b662d5c72c29903813eJake Slack            setCurrentConnection(null);
13403928aee4356845252ac6b662d5c72c29903813eJake Slack            _parser.returnBuffers();
13503928aee4356845252ac6b662d5c72c29903813eJake Slack            _generator.returnBuffers();
13603928aee4356845252ac6b662d5c72c29903813eJake Slack        }
13703928aee4356845252ac6b662d5c72c29903813eJake Slack    }
13803928aee4356845252ac6b662d5c72c29903813eJake Slack}
139