You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by mb...@apache.org on 2004/04/13 04:08:30 UTC
cvs commit: jakarta-commons/httpclient/src/examples ProxyTunnelDemo.java
mbecke 2004/04/12 19:08:30
Modified: httpclient/src/java/org/apache/commons/httpclient
HttpConnection.java
Added: httpclient/src/java/org/apache/commons/httpclient
ProxyClient.java
httpclient/src/examples ProxyTunnelDemo.java
Log:
Adds stand-alone support for tunneled HTTP proxies via the ProxyClient.
PR: 28151
Submitted by: Michael Becke
Reviewed by: Oleg Kalnichevski
Revision Changes Path
1.86 +14 -5 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java
Index: HttpConnection.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -r1.85 -r1.86
--- HttpConnection.java 22 Feb 2004 18:08:45 -0000 1.85
+++ HttpConnection.java 13 Apr 2004 02:08:30 -0000 1.86
@@ -82,7 +82,7 @@
*
* @author Rod Waldhoff
* @author Sean C. Sullivan
- * @author Ortwin Glück
+ * @author Ortwin Gl??ck
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
@@ -199,6 +199,15 @@
}
// ------------------------------------------ Attribute Setters and Getters
+
+ /**
+ * Returns the connection socket.
+ *
+ * @return the socket.
+ */
+ protected Socket getSocket() {
+ return this.socket;
+ }
/**
* Returns the host.
1.1 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ProxyClient.java
Index: ProxyClient.java
===================================================================
/*
* $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ProxyClient.java,v 1.1 2004/04/13 02:08:30 mbecke Exp $
* $Revision: 1.1 $
* $Date: 2004/04/13 02:08:30 $
*
* ====================================================================
*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed 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/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
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:oleg@ural.ru">Oleg Kalnichevski</a>
* @author Michael Becke
*
* @since 3.0
*
* @version $Revision: 1.1 $
*/
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 {
if (!getHostConfiguration().isProxySet()) {
throw new IllegalStateException("proxy host must be configured");
}
if (!getHostConfiguration().isHostSet()) {
throw new IllegalStateException("destination host must be configured");
}
ConnectMethod method = new ConnectMethod();
method.getParams().setDefaults(getParams());
DummyConnectionManager connectionManager = new DummyConnectionManager();
connectionManager.setConnectionParams(getParams());
HttpMethodDirector director = new HttpMethodDirector(
connectionManager,
getHostConfiguration(),
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.
*/
class DummyConnectionManager implements HttpConnectionManager {
private HttpConnection httpConnection;
private HttpParams connectionParams;
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;
}
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) {
}
}
}
1.1 jakarta-commons/httpclient/src/examples/ProxyTunnelDemo.java
Index: ProxyTunnelDemo.java
===================================================================
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
import org.apache.commons.httpclient.ProxyClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.HttpAuthRealm;
/*
* $Header: /home/cvs/jakarta-commons/httpclient/src/examples/ProxyTunnelDemo.java,v 1.1 2004/04/13 02:08:30 mbecke Exp $
* $Revision: 1.1 $
* $Date: 2004/04/13 02:08:30 $
* ====================================================================
*
* Copyright 2002-2004 The Apache Software Foundation
*
* Licensed 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/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
/**
* Example code for using {@link org.apache.commons.httpclient.ProxyClient}.
*
* @author Oleg Kalnichevski
* @author Michael Becke
*/
public class ProxyTunnelDemo {
public static void main(String[] args) throws Exception {
ProxyClient proxyclient = new ProxyClient();
// set the host the proxy should create a connection to
//
// Note: By default port 80 will be used. Some proxies only allow conections
// to ports 443 and 8443. This is because the HTTP CONNECT method was intented
// to be used for tunneling HTTPS.
proxyclient.getHostConfiguration().setHost("www.yahoo.com");
// set the proxy host and port
proxyclient.getHostConfiguration().setProxy("10.0.1.1", 3128);
// set the proxy credentials, only necessary for authenticating proxies
proxyclient.getState().setProxyCredentials(
new HttpAuthRealm("10.0.1.1", 3128, null),
new UsernamePasswordCredentials("proxy", "proxy"));
// create the socket
ProxyClient.ConnectResponse response = proxyclient.connect();
if (response.getSocket() != null) {
Socket socket = response.getSocket();
try {
// go ahead and do an HTTP GET using the socket
Writer out = new OutputStreamWriter(
socket.getOutputStream(), "ISO-8859-1");
out.write("GET http://www.yahoo.com/ HTTP/1.1\r\n");
out.write("Host: www.yahoo.com\r\n");
out.write("Agent: whatever\r\n");
out.write("\r\n");
out.flush();
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream(), "ISO-8859-1"));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} finally {
// be sure to close the socket when we're done
socket.close();
}
} else {
// the proxy connect was not successful, check connect method for reasons why
System.out.println("Connect failed: " + response.getConnectMethod().getStatusLine());
System.out.println(response.getConnectMethod().getResponseBodyAsString());
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org