From ceb4ed1d39cbf95a7e40f86f90442d43dec641c1 Mon Sep 17 00:00:00 2001 From: Roland Weber Date: Wed, 3 Jan 2007 20:58:12 +0000 Subject: [PATCH] new connection interfaces, step 2 - return of the Operator git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@492299 13f79535-47bb-0310-9956-ffa450edef68 --- .../http/conn/SocketConnectionOperator.java | 106 +++++++++ .../conn/impl/DefaultClientConnection.java | 2 +- .../impl/DefaultSocketConnectionOperator.java | 204 ++++++++++++++++++ 3 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 src/java/org/apache/http/conn/SocketConnectionOperator.java create mode 100644 src/java/org/apache/http/conn/impl/DefaultSocketConnectionOperator.java diff --git a/src/java/org/apache/http/conn/SocketConnectionOperator.java b/src/java/org/apache/http/conn/SocketConnectionOperator.java new file mode 100644 index 000000000..81101d2b9 --- /dev/null +++ b/src/java/org/apache/http/conn/SocketConnectionOperator.java @@ -0,0 +1,106 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.io.IOException; +import java.net.Socket; + +import org.apache.http.HttpHost; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; + + + +/** + * Interface for opening {@link UnmanagedClientConnection connections}. + * This interface encapsulates the logic to create sockets and to + * open or update the connection with the new socket. + * Implementations will most likely make use of + * {@link SocketFactory socket factories}. + *
+ * The methods in this interface allow the creation of plain and layered + * sockets. Creating a tunnelled connection through a proxy, however, + * is not within the scope of the operator. + * + * @author Roland Weber + * + * + * + * @version $Revision$ $Date$ + * + */ +public interface SocketConnectionOperator { + + + /** + * Opens a connection to the given target host. + * + * @param conn the connection to open + * @param target the target host to connect to + * @param context the context for the connection + * @param params the parameters for the connection + * + * @throws IOException in case of a problem + */ + void openConnection(UnmanagedClientConnection conn, + HttpHost target, + HttpContext context, + HttpParams params) + throws IOException + ; + + + /** + * Updates a connection with a layered secure connection. + * The typical use of this method is to update a tunnelled plain + * connection (HTTP) to a secure TLS/SSL connection (HTTPS). + * + * @param conn the open connection to update + * @param target the target host for the updated connection. + * The connection must already be open to the + * host and port, but the scheme of the target + * will be used to create a layered connection. + * @param context the context for the connection + * @param params the parameters for the updated connection + * + * @throws IOException in case of a problem + */ + void updateSecureConnection(UnmanagedClientConnection conn, + HttpHost target, + HttpContext context, + HttpParams params) + throws IOException + ; + + +} // interface SocketConnectionOperator + diff --git a/src/java/org/apache/http/conn/impl/DefaultClientConnection.java b/src/java/org/apache/http/conn/impl/DefaultClientConnection.java index 7e4f376cc..dc9be95a6 100644 --- a/src/java/org/apache/http/conn/impl/DefaultClientConnection.java +++ b/src/java/org/apache/http/conn/impl/DefaultClientConnection.java @@ -45,7 +45,7 @@ import org.apache.http.conn.UnmanagedClientConnection; /** * Default implementation of a managed client connection. * - * @author Roland Weber (rolandw@apache.org) + * @author Roland Weber * * * diff --git a/src/java/org/apache/http/conn/impl/DefaultSocketConnectionOperator.java b/src/java/org/apache/http/conn/impl/DefaultSocketConnectionOperator.java new file mode 100644 index 000000000..c93e51ab3 --- /dev/null +++ b/src/java/org/apache/http/conn/impl/DefaultSocketConnectionOperator.java @@ -0,0 +1,204 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.impl; + +import java.io.IOException; +import java.net.Socket; +import java.net.InetAddress; + +import org.apache.http.HttpHost; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.protocol.HttpContext; + +import org.apache.http.conn.Scheme; +import org.apache.http.conn.SocketFactory; +import org.apache.http.conn.SecureSocketFactory; +import org.apache.http.conn.UnmanagedClientConnection; +import org.apache.http.conn.SocketConnectionOperator; + + +/** + * Default implementation of a + * {@link SocketConnectionOperator SocketConnectionOperator}. + * It uses the {@link Scheme Scheme} class to look up + * {@link SocketFactory SocketFactory} objects. + * + * @author Roland Weber + * + * + * + * @version $Revision$ $Date$ + * + */ +public class DefaultSocketConnectionOperator + implements SocketConnectionOperator { + + + + // public default constructor + + + + // non-javadoc, see interface SocketConnectionOperator + public void openConnection(UnmanagedClientConnection conn, + HttpHost target, + HttpContext context, + HttpParams params) + throws IOException { + + if (conn == null) { + throw new IllegalArgumentException + ("Connection must not be null."); + } + if (target == null) { + throw new IllegalArgumentException + ("Target host must not be null."); + } + //@@@ is context allowed to be null? + if (params == null) { + throw new IllegalArgumentException + ("Parameters must not be null."); + } + if (conn.isOpen()) { + throw new IllegalArgumentException + ("Connection must not be open."); + } + + InetAddress local = null; + //@@@ TODO: deal with local address stuff from context + + final Scheme schm = Scheme.getScheme(target.getSchemeName()); + if (schm == null) { + throw new IllegalArgumentException + ("Unknown scheme '" + target.getSchemeName() + + "' in target host."); + } + final SocketFactory sf = schm.getSocketFactory(); + //@@@ create socket, register in connection, connect? (HTTPCLIENT-475) + //@@@ Requires registration method, since conn.open(...) fails if + //@@@ the socket is not open. Dependent objects need the streams! + final Socket sock = sf.connectSocket + (null, target.getHostName(), target.getPort(), local, 0, params); + prepareSocket(sock, context, params); + + //@@@ ask the factory whether the new socket is secure? + boolean secure = (sf instanceof SecureSocketFactory); + + conn.open(sock, target, secure, params); + //@@@ error handling: close the created socket in case of exception? + + } // openConnection + + + // non-javadoc, see interface SocketConnectionOperator + public void updateSecureConnection(UnmanagedClientConnection conn, + HttpHost target, + HttpContext context, + HttpParams params) + throws IOException { + + + if (conn == null) { + throw new IllegalArgumentException + ("Connection must not be null."); + } + if (target == null) { + throw new IllegalArgumentException + ("Target host must not be null."); + } + //@@@ is context allowed to be null? + if (params == null) { + throw new IllegalArgumentException + ("Parameters must not be null."); + } + if (!conn.isOpen()) { + throw new IllegalArgumentException + ("Connection must be open."); + } + + final Scheme schm = Scheme.getScheme(target.getSchemeName()); + if (schm == null) { + throw new IllegalArgumentException + ("Unknown scheme '" + target.getSchemeName() + + "' in target host."); + } + if (!(schm.getSocketFactory() instanceof SecureSocketFactory)) { + throw new IllegalArgumentException + ("Target scheme (" + schm.getName() + + ") must have secure socket factory."); + } + + final SecureSocketFactory ssf = + (SecureSocketFactory)schm.getSocketFactory(); + final Socket sock = ssf.createSocket + (conn.getSocket(), target.getHostName(), target.getPort(), true); + prepareSocket(sock, context, params); + + //@@@ ask the factory whether the new socket is secure? + boolean secure = true; + + conn.update(sock, target, secure, params); + //@@@ error handling: close the layered socket in case of exception? + + } // updateSecureConnection + + + /** + * Performs standard initializations on a newly created socket. + * + * @param sock the socket to prepare + * @param context the context for the connection + * @param params the parameters from which to prepare the socket + * + * @throws IOException in case of an IO problem + */ + protected void prepareSocket(Socket sock, HttpContext context, + HttpParams params) + throws IOException { + + // context currently not used, but derived classes may need it + //@@@ is context allowed to be null? + + sock.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params)); + sock.setSoTimeout(HttpConnectionParams.getSoTimeout(params)); + + int linger = HttpConnectionParams.getLinger(params); + if (linger >= 0) { + sock.setSoLinger(linger > 0, linger); + } + + } // prepareSocket + + +} // interface SocketConnectionOperator +