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.client;
2003928aee4356845252ac6b662d5c72c29903813eJake Slack
2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException;
2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.InterruptedIOException;
2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.Socket;
2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.net.SocketFactory;
2503928aee4356845252ac6b662d5c72c29903813eJake Slack
2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.Connection;
2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.EndPoint;
2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.bio.SocketEndPoint;
2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.component.AbstractLifeCycle;
3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log;
3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger;
3203928aee4356845252ac6b662d5c72c29903813eJake Slack
3303928aee4356845252ac6b662d5c72c29903813eJake Slackclass SocketConnector extends AbstractLifeCycle implements HttpClient.Connector
3403928aee4356845252ac6b662d5c72c29903813eJake Slack{
3503928aee4356845252ac6b662d5c72c29903813eJake Slack    private static final Logger LOG = Log.getLogger(SocketConnector.class);
3603928aee4356845252ac6b662d5c72c29903813eJake Slack
3703928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
3803928aee4356845252ac6b662d5c72c29903813eJake Slack     *
3903928aee4356845252ac6b662d5c72c29903813eJake Slack     */
4003928aee4356845252ac6b662d5c72c29903813eJake Slack    private final HttpClient _httpClient;
4103928aee4356845252ac6b662d5c72c29903813eJake Slack
4203928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
4303928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param httpClient
4403928aee4356845252ac6b662d5c72c29903813eJake Slack     */
4503928aee4356845252ac6b662d5c72c29903813eJake Slack    SocketConnector(HttpClient httpClient)
4603928aee4356845252ac6b662d5c72c29903813eJake Slack    {
4703928aee4356845252ac6b662d5c72c29903813eJake Slack        _httpClient = httpClient;
4803928aee4356845252ac6b662d5c72c29903813eJake Slack    }
4903928aee4356845252ac6b662d5c72c29903813eJake Slack
5003928aee4356845252ac6b662d5c72c29903813eJake Slack    public void startConnection(final HttpDestination destination) throws IOException
5103928aee4356845252ac6b662d5c72c29903813eJake Slack    {
5203928aee4356845252ac6b662d5c72c29903813eJake Slack        Socket socket= destination.isSecure()
5303928aee4356845252ac6b662d5c72c29903813eJake Slack            ? destination.getSslContextFactory().newSslSocket()
5403928aee4356845252ac6b662d5c72c29903813eJake Slack            : SocketFactory.getDefault().createSocket();
5503928aee4356845252ac6b662d5c72c29903813eJake Slack
5603928aee4356845252ac6b662d5c72c29903813eJake Slack        socket.setSoTimeout(0);
5703928aee4356845252ac6b662d5c72c29903813eJake Slack        socket.setTcpNoDelay(true);
5803928aee4356845252ac6b662d5c72c29903813eJake Slack
5903928aee4356845252ac6b662d5c72c29903813eJake Slack        Address address = destination.isProxied() ? destination.getProxy() : destination.getAddress();
6003928aee4356845252ac6b662d5c72c29903813eJake Slack        socket.connect(address.toSocketAddress(), _httpClient.getConnectTimeout());
6103928aee4356845252ac6b662d5c72c29903813eJake Slack
6203928aee4356845252ac6b662d5c72c29903813eJake Slack        final EndPoint endpoint=new SocketEndPoint(socket);
6303928aee4356845252ac6b662d5c72c29903813eJake Slack
6403928aee4356845252ac6b662d5c72c29903813eJake Slack        final AbstractHttpConnection connection=new BlockingHttpConnection(_httpClient.getRequestBuffers(),_httpClient.getResponseBuffers(),endpoint);
6503928aee4356845252ac6b662d5c72c29903813eJake Slack        connection.setDestination(destination);
6603928aee4356845252ac6b662d5c72c29903813eJake Slack        destination.onNewConnection(connection);
6703928aee4356845252ac6b662d5c72c29903813eJake Slack        _httpClient.getThreadPool().dispatch(new Runnable()
6803928aee4356845252ac6b662d5c72c29903813eJake Slack        {
6903928aee4356845252ac6b662d5c72c29903813eJake Slack            public void run()
7003928aee4356845252ac6b662d5c72c29903813eJake Slack            {
7103928aee4356845252ac6b662d5c72c29903813eJake Slack                try
7203928aee4356845252ac6b662d5c72c29903813eJake Slack                {
7303928aee4356845252ac6b662d5c72c29903813eJake Slack                    Connection con = connection;
7403928aee4356845252ac6b662d5c72c29903813eJake Slack                    while(true)
7503928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
7603928aee4356845252ac6b662d5c72c29903813eJake Slack                        final Connection next = con.handle();
7703928aee4356845252ac6b662d5c72c29903813eJake Slack                        if (next!=con)
7803928aee4356845252ac6b662d5c72c29903813eJake Slack                        {
7903928aee4356845252ac6b662d5c72c29903813eJake Slack                            con=next;
8003928aee4356845252ac6b662d5c72c29903813eJake Slack                            continue;
8103928aee4356845252ac6b662d5c72c29903813eJake Slack                        }
8203928aee4356845252ac6b662d5c72c29903813eJake Slack                        break;
8303928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
8403928aee4356845252ac6b662d5c72c29903813eJake Slack                }
8503928aee4356845252ac6b662d5c72c29903813eJake Slack                catch (IOException e)
8603928aee4356845252ac6b662d5c72c29903813eJake Slack                {
8703928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (e instanceof InterruptedIOException)
8803928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.ignore(e);
8903928aee4356845252ac6b662d5c72c29903813eJake Slack                    else
9003928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
9103928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.debug(e);
9203928aee4356845252ac6b662d5c72c29903813eJake Slack                        destination.onException(e);
9303928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
9403928aee4356845252ac6b662d5c72c29903813eJake Slack                }
9503928aee4356845252ac6b662d5c72c29903813eJake Slack                finally
9603928aee4356845252ac6b662d5c72c29903813eJake Slack                {
9703928aee4356845252ac6b662d5c72c29903813eJake Slack                    try
9803928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
9903928aee4356845252ac6b662d5c72c29903813eJake Slack                        destination.returnConnection(connection,true);
10003928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
10103928aee4356845252ac6b662d5c72c29903813eJake Slack                    catch (IOException e)
10203928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
10303928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.debug(e);
10403928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
10503928aee4356845252ac6b662d5c72c29903813eJake Slack                }
10603928aee4356845252ac6b662d5c72c29903813eJake Slack            }
10703928aee4356845252ac6b662d5c72c29903813eJake Slack        });
10803928aee4356845252ac6b662d5c72c29903813eJake Slack
10903928aee4356845252ac6b662d5c72c29903813eJake Slack    }
11003928aee4356845252ac6b662d5c72c29903813eJake Slack}
111