You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ri...@apache.org on 2008/01/14 18:30:54 UTC
svn commit: r611863 - in
/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc:
AsyncHttpClient.java auth/AuthChallengeParser.java
codec/HttpRequestMessage.java codec/SessionCache.java
proxy/ProxyConfiguration.java proxy/ProxyFilter.java
Author: rickmcguire
Date: Mon Jan 14 09:30:43 2008
New Revision: 611863
URL: http://svn.apache.org/viewvc?rev=611863&view=rev
Log:
Add more javadoc to code
Modified:
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/auth/AuthChallengeParser.java
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestMessage.java
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/SessionCache.java
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyConfiguration.java
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyFilter.java
Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java?rev=611863&r1=611862&r2=611863&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java Mon Jan 14 09:30:43 2008
@@ -386,15 +386,21 @@
threadPool = executor;
- if (scheduler == null)
+ if (scheduler == null) {
handler = new HttpIoHandler();
- else
+ }
+ else {
handler = new HttpIoHandler(scheduler);
+ }
+
- if (threadPool == null)
+ if (threadPool == null) {
connector = new SocketConnector();
- else
+ }
+ else {
connector = new SocketConnector(Runtime.getRuntime().availableProcessors(), threadPool);
+ }
+
// disable the default thread model per recommendation from the mina folks
// http://mina.apache.org/configuring-thread-model.html
@@ -492,6 +498,16 @@
future.addListener(listener);
}
+ /**
+ * Open the appropriate connection for this message.
+ * This will either open a direct connection or connect
+ * to the configured proxy server.
+ *
+ * @param message The message getting sent. This defines the target
+ * location and also holds the proxy configuration.
+ *
+ * @return A ConnectFuture instance for managing the connection.
+ */
private ConnectFuture openConnection(HttpRequestMessage message) {
InetSocketAddress remote =
message.isProxyEnabled() ?
@@ -500,6 +516,14 @@
return connector.connect(remote, handler);
}
+ /**
+ * Attempt to get a connection from the session cache.
+ *
+ * @param message The message we're sending.
+ *
+ * @return A cached connection. This returns null if there's
+ * no available connection for the target location.
+ */
private ConnectFuture getCachedConnection(HttpRequestMessage message) {
IoSession cached = SessionCache.getInstance().getActiveSession(message);
if (cached == null) {
@@ -601,11 +625,12 @@
// (optional) add the executor filter for the event thread pool
// (if it's not there already like in a reused session)
addEventThreadPoolFilter(sess);
-
+ // now that we're connection, configure the session appropriately.
configureSession(sess);
-
+ // and finally start the request process rolling.
sess.write(request);
- } else {
+ }
+ else {
if (retries-- > 0) {
// go retry this connection
retryConnection(request, response, this);
@@ -622,6 +647,13 @@
}
}
+ /**
+ * Configure the IoSession with the client connection
+ * parameters.
+ *
+ * @param sess The session to which the configuration values are to
+ * be applied.
+ */
protected void configureSession(IoSession sess) {
sess.setAttribute(HttpIoHandler.CURRENT_REQUEST, request);
@@ -639,6 +671,14 @@
config.setTrafficClass(trafficClass);
}
+ /**
+ * Add the ExecutorFilter to the session filter chain.
+ * The ExecutorFilter allows session callbacks to be
+ * dispatched using a different thread pool than the one
+ * used for the I/O threads.
+ *
+ * @param sess The session to configure.
+ */
protected void addEventThreadPoolFilter(IoSession sess) {
if (eventThreadPool != null &&
!sess.getFilterChain().contains(EVENT_THREAD_POOL_FILTER)) {
@@ -647,6 +687,13 @@
}
}
+ /**
+ * Add the HttpProtocol filter to the session processing
+ * chain. The protocol filter handles the returned
+ * response information.
+ *
+ * @param sess The target session.
+ */
protected void addProtocolCodecFilter(IoSession sess) {
if (!sess.getFilterChain().contains(PROTOCOL_FILTER)) {
sess.getFilterChain().addLast(PROTOCOL_FILTER, new ProtocolCodecFilter(
@@ -654,6 +701,12 @@
}
}
+ /**
+ * Add an SSL filter to the io session when the
+ * connection type is "https".
+ *
+ * @param sess The session to configure.
+ */
private void addSSLFilter(IoSession sess) {
String scheme = request.getUrl().getProtocol();
@@ -676,6 +729,15 @@
}
}
+ /**
+ * Create an SSLFilter instance for this client. The
+ * filter will be configured using any SSL context defined
+ * for the request, or a default context if one has not
+ * been explicitly configured.
+ *
+ * @return An appropriately configured SSLFilter for this connection.
+ * @exception GeneralSecurityException
+ */
protected SSLFilter createSSLFilter() throws GeneralSecurityException {
SSLContext context = request.getSSLContext();
if (context == null) {
@@ -700,9 +762,14 @@
context.init(null, TrustManagerFactoryImpl.X509_MANAGERS, null);
return context;
}
-
}
+ /**
+ * A FutureListener for managing connections used with
+ * proxied connections. This Future manages establishing
+ * the appropriate connection type with the proxy before
+ * handling the actual client request.
+ */
class ProxyFutureListener extends FutureListener {
public ProxyFutureListener(HttpRequestMessage request,
ResponseFuture response) {
@@ -710,6 +777,13 @@
}
@Override
+ /**
+ * Handle operation completion events. This is primarly
+ * to handle the tunneling protocol required by
+ * https requests through a proxy server.
+ *
+ * @param future The Future object associated with the operation.
+ */
public void operationComplete(IoFuture future) {
ConnectFuture connectFuture = (ConnectFuture)future;
if (connectFuture.isConnected()) {
@@ -736,20 +810,40 @@
}
}
+ /**
+ * Compose the connection request used for SSL proxy
+ * tunneling connections. This CONNECT request tells
+ * the proxy server to establish a connection with
+ * the remote target and tunnel it through to the
+ * client. Once the connection has been established,
+ * an SLL connection will be layered over the top
+ * of the connection, creating a secure channel between
+ * the client and the server.
+ *
+ * @return The request message to send back to the proxy for
+ * establishing the tunneled connection.
+ */
private HttpRequestMessage createConnectRequest() {
try {
HttpRequestMessage req = new HttpRequestMessage(new URL("http", request.getHost(), request.getPort(), ""), null);
req.setRequestMethod(HttpRequestMessage.REQUEST_CONNECT);
return req;
} catch (MalformedURLException e) {
- e.printStackTrace();
+ // ignored, shouldn't happen
} catch (ProtocolException e) {
- e.printStackTrace();
+ // ignored, shouldn't happen
}
// this can't happen
return null;
}
+ /**
+ * Add a proxy filter to the session filter chain.
+ * The proxy filter will be either a plain filter or a
+ * tunneling SSL filter.
+ *
+ * @param session
+ */
private void addProxyFilter(IoSession session) {
if (!session.getFilterChain().contains(PROXY_FILTER)) {
String scheme = request.getUrl().getProtocol();
@@ -758,7 +852,7 @@
try {
proxyFilter = new ProxyFilter(createSSLFilter());
} catch (GeneralSecurityException e) {
- e.printStackTrace(); // this normally cannot happen
+ // this normally cannot happen
}
} else {
proxyFilter = new ProxyFilter();
Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/auth/AuthChallengeParser.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/auth/AuthChallengeParser.java?rev=611863&r1=611862&r2=611863&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/auth/AuthChallengeParser.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/auth/AuthChallengeParser.java Mon Jan 14 09:30:43 2008
@@ -86,28 +86,4 @@
}
return map;
}
-
- /**
- * Extracts a map of challenges ordered by authentication scheme name
- *
- * @param headers the array of authorization challenges
- * @return a map of authorization challenges
- *
- * @throws MalformedChallengeException if any of challenge strings
- * is malformed
- */
-// public static Map parseChallenges(final Header[] headers)
-// throws MalformedChallengeException {
-// if (headers == null) {
-// throw new IllegalArgumentException("Array of challenges may not be null");
-// }
-// String challenge = null;
-// Map challengemap = new HashMap(headers.length);
-// for (int i = 0; i < headers.length; i++) {
-// challenge = headers[i].getValue();
-// String s = AuthChallengeParser.extractScheme(challenge);
-// challengemap.put(s, challenge);
-// }
-// return challengemap;
-// }
}
Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestMessage.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestMessage.java?rev=611863&r1=611862&r2=611863&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestMessage.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestMessage.java Mon Jan 14 09:30:43 2008
@@ -546,14 +546,36 @@
this.sslContext = sslContext;
}
+ /**
+ * Get the message proxy configuration. This controls
+ * how downstream filters handle the message connections.
+ *
+ * @return The current proxy configuration. Returns null if
+ * no proxying support is configured.
+ */
public ProxyConfiguration getProxyConfiguration() {
return proxyConfig;
}
+ /**
+ * Set the proxy configuration use to control proxied
+ * connections.
+ *
+ * @param config The new proxy configuration.
+ */
public void setProxyConfiguration(ProxyConfiguration config) {
proxyConfig = config;
}
+ /**
+ * Test if this request needs to go through a proxy
+ * server. To be proxied, there must be a proxy configuration
+ * set and the request target must not be specified in
+ * the proxy exclusion list.
+ *
+ * @return true if this request must go through a proxy server,
+ * false if a direct connection can be used.
+ */
public boolean isProxyEnabled() {
return proxyConfig != null && !proxyConfig.isExcluded(getUrl());
}
Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/SessionCache.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/SessionCache.java?rev=611863&r1=611862&r2=611863&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/SessionCache.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/SessionCache.java Mon Jan 14 09:30:43 2008
@@ -116,10 +116,24 @@
}
}
+ /**
+ * Generate a request key from an HTTP request message.
+ *
+ * @param msg The request message we need a key from.
+ *
+ * @return A String key instance for this request.
+ */
private String getKey(HttpRequestMessage msg) {
return getKey(msg.getHost(), msg.getPort());
}
+ /**
+ * Generate a session key from an InetSocketAddress
+ *
+ * @param remote The endpoint address of the connection.
+ *
+ * @return A string key for this endpoint.
+ */
private String getKey(InetSocketAddress remote) {
return getKey(remote.getHostName(), remote.getPort());
}
Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyConfiguration.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyConfiguration.java?rev=611863&r1=611862&r2=611863&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyConfiguration.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyConfiguration.java Mon Jan 14 09:30:43 2008
@@ -75,22 +75,55 @@
}
}
+ /**
+ * Get the proxy host name for http connections.
+ *
+ * @return The string name of the proxy host.
+ */
public String getHttpProxyHost() {
return httpProxyHost;
}
+ /**
+ * Get the port of the proxy server used for servicing
+ * http requests.
+ *
+ * @return The port number of the configured http proxy server.
+ */
public int getHttpProxyPort() {
return httpProxyPort;
}
+ /**
+ * Get the host of the proxy server for handling
+ * https requests. If not explicitly set this defaults
+ * to the http proxy host.
+ *
+ * @return The string name of the proxy host.
+ */
public String getHttpsProxyHost() {
return httpsProxyHost;
}
+ /**
+ * Get the port used to connect to the https proxy
+ * server. If not explictly set, this is the same as the
+ * http server.
+ *
+ * @return The connection port number for handling https requests.
+ */
public int getHttpsProxyPort() {
return httpsProxyPort;
}
+ /**
+ * Retrieve the exclusion list used for this configuration.
+ * If set, this returns a string containing the
+ * individual exclusion domains separated by ";".
+ *
+ * @return The string value of the exclusion list, or null
+ * if this has not been set.
+ */
public String getExclusionList() {
return exclusionList;
}
@@ -125,26 +158,65 @@
}
}
+ /**
+ * Returns the proxy authentication userid.
+ *
+ * @return The name of the authentication userid. Returns null
+ * if no user has been specified.
+ */
public String getProxyUser() {
return proxyUser;
}
+ /**
+ * Set the userid used for proxy server authentication.
+ *
+ * @param proxyUser The userid to be used by the authentication schema.
+ */
public void setProxyUser(String proxyUser) {
this.proxyUser = proxyUser;
}
+ /**
+ * Returns the configured password used to access the
+ * proxy server.
+ *
+ * @return The configured password. Returns null if no password is
+ * set.
+ */
public String getProxyPassword() {
return proxyPassword;
}
+ /**
+ * Set the password to be used for accessing the
+ * proxy server.
+ *
+ * @param proxyPassword
+ * The password to be used for authentication.
+ */
public void setProxyPassword(String proxyPassword) {
this.proxyPassword = proxyPassword;
}
+ /**
+ * Returns the authentication scheme used for logging
+ * in the proxy server.
+ *
+ * @return The configured authentication scheme. Returns null
+ * if one has not been set.
+ */
public AuthScheme getAuthScheme() {
return scheme;
}
+ /**
+ * Set the authentication scheme to be used for logging
+ * in the proxy server.
+ *
+ * @param scheme The scheme to be used for logging in. If null,
+ * no login will be attempted with the proxy server.
+ */
public void setAuthScheme(AuthScheme scheme) {
this.scheme = scheme;
}
Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyFilter.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyFilter.java?rev=611863&r1=611862&r2=611863&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyFilter.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyFilter.java Mon Jan 14 09:30:43 2008
@@ -15,15 +15,37 @@
private volatile boolean connectHandshakeComplete;
private final SSLFilter sslFilter;
+ /**
+ * Create a proxy filter for a plain (http request)
+ * to a proxy server.
+ */
public ProxyFilter() {
this(null);
}
+ /**
+ * Create a proxy filter that works in conjunction with
+ * an SSLFilter for a secure connection.
+ *
+ * @param sslFilter The SSL filter to use for the secure connection. If
+ * null, a plain connection will be used.
+ */
public ProxyFilter(SSLFilter sslFilter) {
this.sslFilter = sslFilter;
}
@Override
+ /**
+ * Process a message send event to the proxy. This
+ * will add any required proxy authentication headers
+ * to the request.
+ *
+ * @param nextFilter
+ * @param session
+ * @param message
+ *
+ * @exception Exception
+ */
public void messageSent(NextFilter nextFilter, IoSession session,
Object message) throws Exception {
HttpRequestMessage request = (HttpRequestMessage)message;
@@ -43,6 +65,14 @@
super.messageSent(nextFilter, session, message);
}
+ /**
+ * Returns the HttpRequestMessage instance currently
+ * being processed by the IoSession.
+ *
+ * @param session The current session using the filter.
+ *
+ * @return The request message being processed.
+ */
private HttpRequestMessage getRequest(IoSession session) {
HttpRequestMessage request =
(HttpRequestMessage)session.getAttribute(HttpIoHandler.CURRENT_REQUEST);
@@ -50,20 +80,51 @@
}
@Override
+ /**
+ * Process the messageReceived() filter response. this
+ * will handle any proxy handshaking and SSL connection
+ * creation required.
+ *
+ * @param nextFilter The next filter in the chain.
+ * @param session The IoSession this operation is associated with.
+ * @param message The message object under construction.
+ *
+ * @exception Exception
+ */
public void messageReceived(NextFilter nextFilter, IoSession session,
Object message) throws Exception {
if (needConnectHandshake()) {
// we need to complete the connect handshake
handleConnectResponse(session, message);
} else {
+ // the connection is established, just allow this
+ // to flow down the chain.
super.messageReceived(nextFilter, session, message);
}
}
+ /**
+ * Tests if we need to perform the SSL tunneling handshake.
+ * If this is an https request, we need to handle the
+ * tunneling here. If we've already established this,
+ * then the processing can continue with the next filter.
+ *
+ * @return true if we need to establish the handshake.
+ */
private boolean needConnectHandshake() {
return (sslFilter != null && !connectHandshakeComplete);
}
+ /**
+ * Handle the response from a CONNECT request sent to
+ * the proxy server. If we got a good CONNECT request
+ * back, we add the SSL filter to the chain and
+ * write the original request back to the proxy
+ * server.
+ *
+ * @param session The current session.
+ * @param message The message object representing the request.
+ */
private void handleConnectResponse(IoSession session, Object message) {
HttpResponseMessage response = (HttpResponseMessage)message;
int status = response.getStatusCode();