/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/ProxyClient.java,v 1.5 2004/12/20 11:39:04 olegk Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* 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
* <http://www.apache.org/>.
*
*/
package org.apache.commons.httpclient;
import java.io.IOException;
import java.net.Socket;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpParams;
/**
* A client that provides {@link java.net.Socket sockets} for communicating through HTTP proxies
* via the HTTP CONNECT method. This is primarily needed for non-HTTP protocols that wish to
* communicate via an HTTP proxy.
*
* @author <a href="mailto:[email protected]">Oleg Kalnichevski</a>
* @author Michael Becke
*
* @since 3.0
*
* @version $Revision: 480424 $
*/
public class ProxyClient {
// ----------------------------------------------------- Instance Variables
/**
* The {@link HttpState HTTP state} associated with this ProxyClient.
*/
private HttpState state = new HttpState();
/**
* The {@link HttpClientParams collection of parameters} associated with this ProxyClient.
*/
private HttpClientParams params = null;
/**
* The {@link HostConfiguration host configuration} associated with
* the ProxyClient
*/
private HostConfiguration hostConfiguration = new HostConfiguration();
/**
* Creates an instance of ProxyClient using default {@link HttpClientParams parameter set}.
*
* @see HttpClientParams
*/
public ProxyClient() {
this(new HttpClientParams());
}
/**
* Creates an instance of ProxyClient using the given
* {@link HttpClientParams parameter set}.
*
* @param params The {@link HttpClientParams parameters} to use.
*
* @see HttpClientParams
*/
public ProxyClient(HttpClientParams params) {
super();
if (params == null) {
throw new IllegalArgumentException("Params may not be null");
}
this.params = params;
}
// ------------------------------------------------------------- Properties
/**
* Returns {@link HttpState HTTP state} associated with the ProxyClient.
*
* @see #setState(HttpState)
* @return the shared client state
*/
public synchronized HttpState getState() {
return state;
}
/**
* Assigns {@link HttpState HTTP state} for the ProxyClient.
*
* @see #getState()
* @param state the new {@link HttpState HTTP state} for the client
*/
public synchronized void setState(HttpState state) {
this.state = state;
}
/**
* Returns the {@link HostConfiguration host configuration} associated with the
* ProxyClient.
*
* @return {@link HostConfiguration host configuration}
*/
public synchronized HostConfiguration getHostConfiguration() {
return hostConfiguration;
}
/**
* Assigns the {@link HostConfiguration host configuration} to use with the
* ProxyClient.
*
* @param hostConfiguration The {@link HostConfiguration host configuration} to set
*/
public synchronized void setHostConfiguration(HostConfiguration hostConfiguration) {
this.hostConfiguration = hostConfiguration;
}
/**
* Returns {@link HttpClientParams HTTP protocol parameters} associated with this ProxyClient.
*
* @see HttpClientParams
*/
public synchronized HttpClientParams getParams() {
return this.params;
}
/**
* Assigns {@link HttpClientParams HTTP protocol parameters} for this ProxyClient.
*
* @see HttpClientParams
*/
public synchronized void setParams(final HttpClientParams params) {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
this.params = params;
}
/**
* Creates a socket that is connected, via the HTTP CONNECT method, to a proxy.
*
* <p>
* Even though HTTP CONNECT proxying is generally used for HTTPS tunneling, the returned
* socket will not have been wrapped in an SSL socket.
* </p>
*
* <p>
* Both the proxy and destination hosts must be set via the
* {@link #getHostConfiguration() host configuration} prior to calling this method.
* </p>
*
* @return the connect response
*
* @throws IOException
* @throws HttpException
*
* @see #getHostConfiguration()
*/
public ConnectResponse connect() throws IOException, HttpException {
HostConfiguration hostconf = getHostConfiguration();
if (hostconf.getProxyHost() == null) {
throw new IllegalStateException("proxy host must be configured");
}
if (hostconf.getHost() == null) {
throw new IllegalStateException("destination host must be configured");
}
if (hostconf.getProtocol().isSecure()) {
throw new IllegalStateException("secure protocol socket factory may not be used");
}
ConnectMethod method = new ConnectMethod(getHostConfiguration());
method.getParams().setDefaults(getParams());
DummyConnectionManager connectionManager = new DummyConnectionManager();
connectionManager.setConnectionParams(getParams());
HttpMethodDirector director = new HttpMethodDirector(
connectionManager,
hostconf,
getParams(),
getState()
);
director.executeMethod(method);
ConnectResponse response = new ConnectResponse();
response.setConnectMethod(method);
// only set the socket if the connect was successful
if (method.getStatusCode() == HttpStatus.SC_OK) {
response.setSocket(connectionManager.getConnection().getSocket());
} else {
connectionManager.getConnection().close();
}
return response;
}
/**
* Contains the method used to execute the connect along with the created socket.
*/
public static class ConnectResponse {
private ConnectMethod connectMethod;
private Socket socket;
private ConnectResponse() {}
/**
* Gets the method that was used to execute the connect. This method is useful for
* analyzing the proxy's response when a connect fails.
*
* @return the connectMethod.
*/
public ConnectMethod getConnectMethod() {
return connectMethod;
}
/**
* @param connectMethod The connectMethod to set.
*/
private void setConnectMethod(ConnectMethod connectMethod) {
this.connectMethod = connectMethod;
}
/**
* Gets the socket connected and authenticated (if appropriate) to the configured
* HTTP proxy, or <code>null</code> if a connection could not be made. It is the
* responsibility of the user to close this socket when it is no longer needed.
*
* @return the socket.
*/
public Socket getSocket() {
return socket;
}
/**
* @param socket The socket to set.
*/
private void setSocket(Socket socket) {
this.socket = socket;
}
}
/**
* A connection manager that creates a single connection. Meant to be used only once.
*/
static class DummyConnectionManager implements HttpConnectionManager {
private HttpConnection httpConnection;
private HttpParams connectionParams;
public void closeIdleConnections(long idleTimeout) {
}
public HttpConnection getConnection() {
return httpConnection;
}
public void setConnectionParams(HttpParams httpParams) {
this.connectionParams = httpParams;
}
public HttpConnection getConnectionWithTimeout(
HostConfiguration hostConfiguration, long timeout) {
httpConnection = new HttpConnection(hostConfiguration);
httpConnection.setHttpConnectionManager(this);
httpConnection.getParams().setDefaults(connectionParams);
return httpConnection;
}
/**
* @deprecated
*/
public HttpConnection getConnection(HostConfiguration hostConfiguration, long timeout)
throws HttpException {
return getConnectionWithTimeout(hostConfiguration, timeout);
}
public HttpConnection getConnection(HostConfiguration hostConfiguration) {
return getConnectionWithTimeout(hostConfiguration, -1);
}
public void releaseConnection(HttpConnection conn) {
}
public HttpConnectionManagerParams getParams() {
return null;
}
public void setParams(HttpConnectionManagerParams params) {
}
}
}
|