diff options
author | slewis | 2011-09-20 20:14:16 +0000 |
---|---|---|
committer | slewis | 2011-09-20 20:14:16 +0000 |
commit | 3bfdbc0f7d63cbb1af17c87e503783395c25fcfe (patch) | |
tree | d37885710532e87992dd7f25dbb67fa29335b7f4 | |
parent | d0e7cce9f5025ee3f07f5a175d82e8459eb9933a (diff) | |
download | org.eclipse.ecf-3bfdbc0f7d63cbb1af17c87e503783395c25fcfe.tar.gz org.eclipse.ecf-3bfdbc0f7d63cbb1af17c87e503783395c25fcfe.tar.xz org.eclipse.ecf-3bfdbc0f7d63cbb1af17c87e503783395c25fcfe.zip |
Fixes for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=297742.
This enables the use of a single http session for multiple downloads.
It has contributions from Henrich Kraemer and Meng Zin Zhu.
8 files changed, 348 insertions, 79 deletions
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/META-INF/MANIFEST.MF b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/META-INF/MANIFEST.MF index 95b0aeeb2..cf5e8a3ca 100644 --- a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/META-INF/MANIFEST.MF +++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin.name Bundle-SymbolicName: org.eclipse.ecf.provider.filetransfer.httpclient;singleton:=true -Bundle-Version: 4.0.0.qualifier +Bundle-Version: 4.0.1.qualifier Bundle-Localization: plugin Bundle-Activator: org.eclipse.ecf.internal.provider.filetransfer.httpclient.Activator Require-Bundle: org.eclipse.equinox.common, @@ -25,6 +25,5 @@ Import-Package: org.apache.commons.httpclient;version="[3.0.1,3.1.0]", Export-Package: org.eclipse.ecf.internal.provider.filetransfer.httpclient;x-internal:=true, org.eclipse.ecf.provider.filetransfer.httpclient Bundle-Vendor: %plugin.provider -Bundle-RequiredExecutionEnvironment: CDC-1.1/Foundation-1.1, - J2SE-1.4 +Bundle-RequiredExecutionEnvironment: J2SE-1.4 Bundle-ActivationPolicy: lazy diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient/Activator.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient/Activator.java index b34d34237..a725abc58 100644 --- a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient/Activator.java +++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient/Activator.java @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2007 IBM, Composent Inc. and others. + * Copyright (c) 2007, 2011 IBM, Composent Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Chris Aniszczyk - initial API and implementation + * Henrich Kraemer - Bug 297742 - [transport] Investigate how to maintain HTTP session *****************************************************************************/ package org.eclipse.ecf.internal.provider.filetransfer.httpclient; @@ -37,6 +38,8 @@ public class Activator implements BundleActivator { private ISSLSocketFactoryModifier sslSocketFactoryModifier; + private ConnectionManagerHelper cmHelper; + /** * The constructor */ @@ -64,6 +67,13 @@ public class Activator implements BundleActivator { } + public ConnectionManagerHelper getConnectionManagerHelper() { + if (cmHelper == null) { + cmHelper = new ConnectionManagerHelper(); + } + return cmHelper; + } + public ISSLSocketFactoryModifier getSSLSocketFactoryModifier() { return sslSocketFactoryModifier; } @@ -81,6 +91,9 @@ public class Activator implements BundleActivator { if (logServiceTracker != null) { logServiceTracker.close(); } + if (cmHelper != null) { + cmHelper.shutdown(); + } this.context = null; plugin = null; } diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient/ConnectionManagerHelper.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient/ConnectionManagerHelper.java new file mode 100644 index 000000000..4a08b8c14 --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient/ConnectionManagerHelper.java @@ -0,0 +1,171 @@ +/*******************************************************************************
+* Copyright (c) 2011 IBM, and others.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* IBM Corporation - initial API and implementation
+******************************************************************************/
+
+package org.eclipse.ecf.internal.provider.filetransfer.httpclient;
+
+import java.util.Map;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpConnectionManager;
+import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
+import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
+import org.eclipse.ecf.core.util.Trace;
+import org.eclipse.ecf.filetransfer.IRetrieveFileTransferOptions;
+import org.eclipse.ecf.provider.filetransfer.httpclient.HttpClientOptions;
+
+public class ConnectionManagerHelper {
+
+ public static final int DEFAULT_CONNECTION_TIMEOUT = HttpClientOptions.RETRIEVE_DEFAULT_CONNECTION_TIMEOUT;
+ public static final int DEFAULT_READ_TIMEOUT = HttpClientOptions.RETRIEVE_DEFAULT_READ_TIMEOUT;
+
+ private MultiThreadedHttpConnectionManager connectionManager;
+
+ public ConnectionManagerHelper() {
+ }
+
+ private static int getIntegerProperty(String prop, int intDefault) {
+ int retVal = intDefault;
+ String systemProp = System.getProperty(prop);
+ if (systemProp != null) {
+ try {
+ retVal = Integer.parseInt(systemProp);
+ } catch (NumberFormatException e) {
+ Trace.trace(Activator.PLUGIN_ID, "Bad value for property '" + prop + "' : " + e + ". Using default value " + intDefault + "."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+ }
+ return retVal;
+ }
+
+ private static long getLongProperty(String prop, long longDefault) {
+ long retVal = longDefault;
+ String systemProp = System.getProperty(prop);
+ if (systemProp != null) {
+ try {
+ retVal = Long.parseLong(systemProp);
+ } catch (NumberFormatException e) {
+ Trace.trace(Activator.PLUGIN_ID, "Bad value for property '" + prop + "' : " + e + ". Using default value " + longDefault + "."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+ }
+ return retVal;
+ }
+
+ private static boolean shouldReuseConnectionsOption() {
+ boolean retVal = ConnectionOptions.REUSE_CONNECTIONS_DEFAULT;
+ String systemProp = System.getProperty(ConnectionOptions.PROP_REUSE_CONNECTIONS);
+ if (systemProp != null) {
+ retVal = Boolean.valueOf(systemProp).booleanValue();
+ }
+ return retVal;
+ }
+
+ public static int getConnectTimeout(final Map options) {
+ int result = DEFAULT_CONNECTION_TIMEOUT;
+ Map localOptions = options;
+ if (localOptions != null) {
+ // See if the connect timeout option is present, if so set
+ Object o = localOptions.get(IRetrieveFileTransferOptions.CONNECT_TIMEOUT);
+ if (o != null) {
+ if (o instanceof Integer) {
+ result = ((Integer) o).intValue();
+ } else if (o instanceof String) {
+ result = new Integer(((String) o)).intValue();
+ }
+ return result;
+ }
+ o = localOptions.get("org.eclipse.ecf.provider.filetransfer.httpclient.retrieve.connectTimeout"); //$NON-NLS-1$
+ if (o != null) {
+ if (o instanceof Integer) {
+ result = ((Integer) o).intValue();
+ } else if (o instanceof String) {
+ result = new Integer(((String) o)).intValue();
+ }
+ }
+ }
+ return result;
+ }
+
+ public static int getSocketReadTimeout(Map options) {
+ int result = DEFAULT_READ_TIMEOUT;
+ Map localOptions = options;
+ if (localOptions != null) {
+ // See if the connect timeout option is present, if so set
+ Object o = localOptions.get(IRetrieveFileTransferOptions.READ_TIMEOUT);
+ if (o != null) {
+ if (o instanceof Integer) {
+ result = ((Integer) o).intValue();
+ } else if (o instanceof String) {
+ result = new Integer(((String) o)).intValue();
+ }
+ return result;
+ }
+ o = localOptions.get("org.eclipse.ecf.provider.filetransfer.httpclient.retrieve.readTimeout"); //$NON-NLS-1$
+ if (o != null) {
+ if (o instanceof Integer) {
+ result = ((Integer) o).intValue();
+ } else if (o instanceof String) {
+ result = new Integer(((String) o)).intValue();
+ }
+ }
+ }
+ return result;
+ }
+
+ public synchronized void initConnectionManager(HttpClient httpClient, Map options) {
+ if (!shouldReuseConnectionsOption()) {
+ Trace.trace(Activator.PLUGIN_ID, "Connections are not reused. To reuse connections set system property '" + ConnectionOptions.PROP_REUSE_CONNECTIONS + "' to true."); //$NON-NLS-1$ //$NON-NLS-2$
+ initParameters(httpClient, new MultiThreadedHttpConnectionManager(), false, options);
+ return;
+ }
+ if (connectionManager == null) {
+ connectionManager = new MultiThreadedHttpConnectionManager();
+ Trace.trace(Activator.PLUGIN_ID, "Created shared connection manager."); //$NON-NLS-1$
+ } else {
+ Trace.trace(Activator.PLUGIN_ID, "Reusing shared connection manager."); //$NON-NLS-1$
+ }
+ initParameters(httpClient, connectionManager, true, options);
+ }
+
+ private static void initParameters(HttpClient httpClient, HttpConnectionManager cm, boolean cmIsShared, Map options) {
+
+ if (cmIsShared) {
+ long closeIdlePeriod = getLongProperty(ConnectionOptions.PROP_POOL_CLOSE_IDLE_PERIOD, ConnectionOptions.POOL_CLOSE_IDLE_PERIOD_DEFAULT);
+ if (closeIdlePeriod > 0) {
+ Trace.trace(Activator.PLUGIN_ID, "Closing connections which were idle at least " + closeIdlePeriod + " milliseconds."); //$NON-NLS-1$ //$NON-NLS-2$
+ cm.closeIdleConnections(closeIdlePeriod);
+ }
+ }
+
+ // HttpClient parameters can be traced independently
+ httpClient.setHttpConnectionManager(cm);
+ int readTimeout = getSocketReadTimeout(options);
+ cm.getParams().setSoTimeout(readTimeout);
+ int connectTimeout = getConnectTimeout(options);
+ cm.getParams().setConnectionTimeout(connectTimeout);
+
+ if (cmIsShared) {
+ HttpConnectionManagerParams cmParams = cm.getParams();
+ int maxHostConnections = getIntegerProperty(ConnectionOptions.PROP_MAX_CONNECTIONS_PER_HOST, ConnectionOptions.MAX_CONNECTIONS_PER_HOST_DEFAULT);
+ int maxTotalConnections = getIntegerProperty(ConnectionOptions.PROP_MAX_TOTAL_CONNECTIONS, ConnectionOptions.MAX_TOTAL_CONNECTIONS_DEFAULT);
+
+ cmParams.setDefaultMaxConnectionsPerHost(maxHostConnections);
+ cmParams.setMaxTotalConnections(maxTotalConnections);
+ long connectionManagerTimeout = getLongProperty(ConnectionOptions.PROP_POOL_CONNECTION_TIMEOUT, ConnectionOptions.POOL_CONNECTION_TIMEOUT_DEFAULT);
+ httpClient.getParams().setConnectionManagerTimeout(connectionManagerTimeout);
+ }
+ }
+
+ public synchronized void shutdown() {
+ if (connectionManager != null) {
+ connectionManager.shutdown();
+ connectionManager = null;
+ }
+ }
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient/ConnectionOptions.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient/ConnectionOptions.java new file mode 100644 index 000000000..500e23ddf --- /dev/null +++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient/ConnectionOptions.java @@ -0,0 +1,127 @@ +/*******************************************************************************
+* Copyright (c) 2011 IBM, and others.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* IBM Corporation - initial API and implementation
+******************************************************************************/
+package org.eclipse.ecf.internal.provider.filetransfer.httpclient;
+
+/**
+ * Options to enable reusing socket connections.
+ * <p>
+ * System property {@link #PROP_REUSE_CONNECTIONS} determines whether this file transfer
+ * provider reuses connections.
+ * </p> <p>
+ * Without connection reuse each transfer or browse operations uses its
+ * own connection independent connection. As a result no connections are reused.
+ * </p>
+ * <p> With connection reuse enable a single connection pool is used. Details
+ * of its behavior can be further customized with the following system properties:
+ * <ul>
+ * <li>{@link #PROP_MAX_TOTAL_CONNECTIONS}</li>
+ * <li>{@link #PROP_MAX_CONNECTIONS_PER_HOST}</li>
+ * <li>{@link #PROP_POOL_CONNECTION_TIMEOUT}</li>
+ * <li>{@link #PROP_POOL_CLOSE_IDLE_PERIOD}</li>
+ * </ul>
+ * Changing this and any of the other system properties does not affect connections
+ * already made.
+ * </p>
+ * @since 4.0.1
+ */
+public interface ConnectionOptions {
+ /**
+ * System property name to enable connection reuse for this provider.
+ * <p>
+ * The boolean value of this system property determines connection reuse.
+ * The default value of this property is {@value #REUSE_CONNECTIONS_DEFAULT} as
+ * defined by {@link #REUSE_CONNECTIONS_DEFAULT}. </p>
+ */
+ public String PROP_REUSE_CONNECTIONS = "org.eclipse.ecf.provider.filetransfer.httpclient.reuseConnections.enabled"; //$NON-NLS-1$
+ public boolean REUSE_CONNECTIONS_DEFAULT = true;
+
+ /**
+ * System property name to specify maximum number of total connections in connection reuse mode.
+ * <p>
+ * This property only applies when connection reuse is enabled by {@link #PROP_REUSE_CONNECTIONS}.
+ * </p><p>
+ * The default value of this property is {@value #MAX_TOTAL_CONNECTIONS_DEFAULT} as
+ * defined by {@link #MAX_TOTAL_CONNECTIONS_DEFAULT}. </p>
+ * <p>
+ * When the maximum number of connections are being used simultaneously another connection request
+ * waits until a connection becomes available to the connection pool. The maximum wait time can
+ * be adjusted using {@link #PROP_POOL_CONNECTION_TIMEOUT}.
+ * </p><p>
+ * </p>
+ */
+ public String PROP_MAX_TOTAL_CONNECTIONS = "org.eclipse.ecf.provider.filetransfer.httpclient.maxConnectionsTotal"; //$NON-NLS-1$
+ public int MAX_TOTAL_CONNECTIONS_DEFAULT = 200; // HttpClient default is 20.
+
+ /**
+ * System property name to specify maximum number of connections per host in connection reuse mode.
+ * <p>
+ * This property only applies when connection reuse is enabled by {@link #PROP_REUSE_CONNECTIONS}.
+ * </p><p>
+ * The default value of this property is {@value #MAX_CONNECTIONS_PER_HOST_DEFAULT} as
+ * defined by {@link #MAX_CONNECTIONS_PER_HOST_DEFAULT}. </p>
+ * <p>
+ * When the maximum number of connections are being used simultaneously another connection request
+ * waits until a connection becomes available to the connection pool. The maximum wait time can
+ * be adjusted using {@link #PROP_POOL_CONNECTION_TIMEOUT}.
+ * </p><p>
+ * </p>
+ */
+ public String PROP_MAX_CONNECTIONS_PER_HOST = "org.eclipse.ecf.provider.filetransfer.httpclient.maxConnectionsPerHost"; //$NON-NLS-1$
+ public int MAX_CONNECTIONS_PER_HOST_DEFAULT = 4; // HttpClient default is 2.
+
+ /**
+ * Property for connection pool timeout.
+ * <p>
+ * This property only applies when connection reuse is enabled by {@link #PROP_REUSE_CONNECTIONS}.
+ * </p><p>
+ * This is the name for a system property to change the timeout value for a
+ * caller waits until a connection becomes available in the connection pool.
+ * </p>
+ * <p>
+ * The value is a long value and its unit is milliseconds.
+ * With the value 0 no timeouts are used so that the caller waits until a connection becomes available.
+ * </p><p>
+ * The default value of this property is {@value #POOL_CONNECTION_TIMEOUT_DEFAULT} as
+ * defined by {@link #POOL_CONNECTION_TIMEOUT_DEFAULT}. </p>
+ * </p>
+ */
+ public String PROP_POOL_CONNECTION_TIMEOUT = "org.eclipse.ecf.provider.filetransfer.httpclient.poolConnectionTimeout"; //$NON-NLS-1$
+
+ public long POOL_CONNECTION_TIMEOUT_DEFAULT = 0;
+
+ /**
+ * Property to set period after which idle connections are closed.
+ * <p>
+ * This setting only applies when reusing connection is enabled (see {@link #PROP_REUSE_CONNECTIONS}.
+ * <p></p>
+ * This is the name for a system property to change the time period after
+ * which an idle connection can be closed by the ECF HttpClient based provider.
+ * Currently idle connections are only closed when another transfer is made.
+ * </p>
+ * <p>
+ * The value is a long value and its unit is milliseconds.
+ * When the value is 0 (or negative) idle connections are never closed except on shutdown.
+ * </p><p>
+ * The default is {@value #POOL_CLOSE_IDLE_PERIOD_DEFAULT} as
+ * defined by {@link #POOL_CLOSE_IDLE_PERIOD_DEFAULT}.
+ * </p>
+ */
+ public String PROP_POOL_CLOSE_IDLE_PERIOD = "org.eclipse.ecf.provider.filetransfer.httpclient.poolCloseIdle"; //$NON-NLS-1$
+
+ /**
+ * Default period before idle connections are closed.
+ * <p>
+ * The default period after which idle connections can be closed is 3 minutes.
+ * </p>
+ */
+ public long POOL_CLOSE_IDLE_PERIOD_DEFAULT = 3 * 60 * 1000;
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientBrowseFileTransferFactory.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientBrowseFileTransferFactory.java index d2edd7ce8..061a02ae4 100644 --- a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientBrowseFileTransferFactory.java +++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientBrowseFileTransferFactory.java @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2007 IBM, Composent Inc. and others. + * Copyright (c) 2007, 2011 IBM, Composent Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,13 +7,13 @@ * * Contributors: * Composent, Inc. - initial API and implementation + * Henrich Kraemer - Bug 297742 - [transport] Investigate how to maintain HTTP session *****************************************************************************/ package org.eclipse.ecf.provider.filetransfer.httpclient; import java.net.MalformedURLException; import java.net.URL; import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.eclipse.core.runtime.Assert; import org.eclipse.ecf.core.identity.IDFactory; import org.eclipse.ecf.core.identity.Namespace; @@ -50,7 +50,7 @@ public class HttpClientBrowseFileTransferFactory implements IRemoteFileSystemBro throw new RemoteFileSystemException(NLS.bind("Exception creating URL for {0}", directoryOrFileId)); //$NON-NLS-1$ } - HttpClientFileSystemBrowser browser = new HttpClientFileSystemBrowser(new HttpClient(new MultiThreadedHttpConnectionManager()), directoryOrFileId, listener, url, connectContext, proxy); + HttpClientFileSystemBrowser browser = new HttpClientFileSystemBrowser(new HttpClient(), directoryOrFileId, listener, url, connectContext, proxy); return browser.sendBrowseRequest(); } diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientFileSystemBrowser.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientFileSystemBrowser.java index 8c445358a..daa428875 100644 --- a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientFileSystemBrowser.java +++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientFileSystemBrowser.java @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2008, 2010 Composent, Inc., IBM and others. + * Copyright (c) 2008, 2011 Composent, Inc., IBM and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * Composent, Inc. - initial API and implementation * Henrich Kraemer - bug 263869, testHttpsReceiveFile fails using HTTP proxy + * Henrich Kraemer - Bug 297742 - [transport] Investigate how to maintain HTTP session *****************************************************************************/ package org.eclipse.ecf.provider.filetransfer.httpclient; @@ -17,6 +18,7 @@ import java.net.HttpURLConnection; import java.net.Socket; import java.net.URL; import java.util.Iterator; +import java.util.Map; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HostConfiguration; @@ -152,7 +154,6 @@ public class HttpClientFileSystemBrowser extends AbstractFileSystemBrowser { } } } - } protected boolean hasForceNTLMProxyOption() { @@ -179,6 +180,11 @@ public class HttpClientFileSystemBrowser extends AbstractFileSystemBrowser { setupProxy(proxy); } + private void initHttpClientConnectionManager() { + Map options = null; //Currently there is no API to pass in options to browse request + Activator.getDefault().getConnectionManagerHelper().initConnectionManager(httpClient, options); + } + /* (non-Javadoc) * @see org.eclipse.ecf.provider.filetransfer.browse.AbstractFileSystemBrowser#runRequest() */ @@ -186,9 +192,7 @@ public class HttpClientFileSystemBrowser extends AbstractFileSystemBrowser { Trace.entering(Activator.PLUGIN_ID, DebugOptions.METHODS_ENTERING, this.getClass(), "runRequest"); //$NON-NLS-1$ setupProxies(); // set timeout - httpClient.getHttpConnectionManager().getParams().setSoTimeout(DEFAULT_CONNECTION_TIMEOUT); - httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT); - httpClient.getParams().setConnectionManagerTimeout(DEFAULT_CONNECTION_TIMEOUT); + initHttpClientConnectionManager(); String urlString = directoryOrFile.toString(); CredentialsProvider credProvider = new HttpClientProxyCredentialProvider() { @@ -216,6 +220,7 @@ public class HttpClientFileSystemBrowser extends AbstractFileSystemBrowser { headMethod.getParams().setParameter(CredentialsProvider.PROVIDER, credProvider); // set max-age for cache control to 0 for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=249990 headMethod.addRequestHeader("Cache-Control", "max-age=0"); //$NON-NLS-1$//$NON-NLS-2$ + headMethod.addRequestHeader("Connection", "Keep-Alive"); //$NON-NLS-1$ //$NON-NLS-2$ long lastModified = 0; long fileLength = -1; diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientRetrieveFileTransfer.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientRetrieveFileTransfer.java index 5bb12eb45..7c951d1ff 100644 --- a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientRetrieveFileTransfer.java +++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientRetrieveFileTransfer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 Composent, Inc., IBM All rights reserved. This + * Copyright (c) 2004, 2011 Composent, Inc., IBM All rights reserved. This * program and the accompanying materials are made available under the terms of * the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html @@ -9,6 +9,7 @@ * Maarten Meijer - bug 237936, added gzip encoded transfer default * Henrich Kraemer - bug 263869, testHttpsReceiveFile fails using HTTP proxy * Henrich Kraemer - bug 263613, [transport] Update site contacting / downloading is not cancelable + * Henrich Kraemer - Bug 297742 - [transport] Investigate how to maintain HTTP session ******************************************************************************/ package org.eclipse.ecf.provider.filetransfer.httpclient; @@ -69,6 +70,7 @@ import org.eclipse.ecf.filetransfer.events.socket.ISocketListener; import org.eclipse.ecf.filetransfer.identity.IFileID; import org.eclipse.ecf.internal.provider.filetransfer.httpclient.Activator; import org.eclipse.ecf.internal.provider.filetransfer.httpclient.ConnectingSocketMonitor; +import org.eclipse.ecf.internal.provider.filetransfer.httpclient.ConnectionManagerHelper; import org.eclipse.ecf.internal.provider.filetransfer.httpclient.DebugOptions; import org.eclipse.ecf.internal.provider.filetransfer.httpclient.ECFHttpClientProtocolSocketFactory; import org.eclipse.ecf.internal.provider.filetransfer.httpclient.ECFHttpClientSecureProtocolSocketFactory; @@ -270,11 +272,11 @@ public class HttpClientRetrieveFileTransfer extends AbstractRetrieveFileTransfer // changing to 2 minutes (120000) as per bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=266246 // 10/26/2009: Added being able to set with system property with name org.eclipse.ecf.provider.filetransfer.httpclient.retrieve.connectTimeout // for https://bugs.eclipse.org/bugs/show_bug.cgi?id=292995 - protected static final int DEFAULT_CONNECTION_TIMEOUT = HttpClientOptions.RETRIEVE_DEFAULT_CONNECTION_TIMEOUT; + protected static final int DEFAULT_CONNECTION_TIMEOUT = ConnectionManagerHelper.DEFAULT_CONNECTION_TIMEOUT; // changing to 2 minutes (120000) as per bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=266246 // 10/26/2009: Added being able to set with system property with name org.eclipse.ecf.provider.filetransfer.httpclient.retrieve.readTimeout // for https://bugs.eclipse.org/bugs/show_bug.cgi?id=292995 - protected static final int DEFAULT_READ_TIMEOUT = HttpClientOptions.RETRIEVE_DEFAULT_READ_TIMEOUT; + protected static final int DEFAULT_READ_TIMEOUT = ConnectionManagerHelper.DEFAULT_READ_TIMEOUT; protected static final int HTTP_PORT = 80; @@ -315,9 +317,8 @@ public class HttpClientRetrieveFileTransfer extends AbstractRetrieveFileTransfer private ConnectingSocketMonitor connectingSockets; private FileTransferJob connectJob; - public HttpClientRetrieveFileTransfer(HttpClient httpClient) { - this.httpClient = httpClient; - Assert.isNotNull(this.httpClient); + public HttpClientRetrieveFileTransfer(HttpClient client) { + this.httpClient = client; proxyHelper = new JREProxyHelper(); connectingSockets = new ConnectingSocketMonitor(1); socketEventSource = new SocketEventSource() { @@ -604,58 +605,18 @@ public class HttpClientRetrieveFileTransfer extends AbstractRetrieveFileTransfer } protected int getSocketReadTimeout() { - int result = DEFAULT_READ_TIMEOUT; - Map localOptions = getOptions(); - if (localOptions != null) { - // See if the connect timeout option is present, if so set - Object o = localOptions.get(IRetrieveFileTransferOptions.READ_TIMEOUT); - if (o != null) { - if (o instanceof Integer) { - result = ((Integer) o).intValue(); - } else if (o instanceof String) { - result = new Integer(((String) o)).intValue(); - } - return result; - } - o = localOptions.get("org.eclipse.ecf.provider.filetransfer.httpclient.retrieve.readTimeout"); //$NON-NLS-1$ - if (o != null) { - if (o instanceof Integer) { - result = ((Integer) o).intValue(); - } else if (o instanceof String) { - result = new Integer(((String) o)).intValue(); - } - } - } - return result; + return ConnectionManagerHelper.getSocketReadTimeout(getOptions()); } /** * @since 4.0 */ protected int getConnectTimeout() { - int result = DEFAULT_CONNECTION_TIMEOUT; - Map localOptions = getOptions(); - if (localOptions != null) { - // See if the connect timeout option is present, if so set - Object o = localOptions.get(IRetrieveFileTransferOptions.CONNECT_TIMEOUT); - if (o != null) { - if (o instanceof Integer) { - result = ((Integer) o).intValue(); - } else if (o instanceof String) { - result = new Integer(((String) o)).intValue(); - } - return result; - } - o = localOptions.get("org.eclipse.ecf.provider.filetransfer.httpclient.retrieve.connectTimeout"); //$NON-NLS-1$ - if (o != null) { - if (o instanceof Integer) { - result = ((Integer) o).intValue(); - } else if (o instanceof String) { - result = new Integer(((String) o)).intValue(); - } - } - } - return result; + return ConnectionManagerHelper.getConnectTimeout(getOptions()); + } + + private void initHttpClientConnectionManager() { + Activator.getDefault().getConnectionManagerHelper().initConnectionManager(httpClient, getOptions()); } /* (non-Javadoc) @@ -670,17 +631,14 @@ public class HttpClientRetrieveFileTransfer extends AbstractRetrieveFileTransfer int code = -1; try { - httpClient.getHttpConnectionManager().getParams().setSoTimeout(getSocketReadTimeout()); - int connectTimeout = getConnectTimeout(); - httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(connectTimeout); - httpClient.getParams().setConnectionManagerTimeout(connectTimeout); - + initHttpClientConnectionManager(); setupAuthentication(urlString); CredentialsProvider credProvider = new ECFCredentialsProvider(); setupHostAndPort(credProvider, urlString); getMethod = new GzipGetMethod(hostConfigHelper.getTargetRelativePath()); + getMethod.addRequestHeader("Connection", "Keep-Alive"); //$NON-NLS-1$ //$NON-NLS-2$ getMethod.setFollowRedirects(true); // Define a CredentialsProvider - found that possibility while debugging in org.apache.commons.httpclient.HttpMethodDirector.processProxyAuthChallenge(HttpMethod) // Seems to be another way to select the credentials. @@ -917,10 +875,7 @@ public class HttpClientRetrieveFileTransfer extends AbstractRetrieveFileTransfer int code = -1; try { - httpClient.getHttpConnectionManager().getParams().setSoTimeout(getSocketReadTimeout()); - int connectTimeout = getConnectTimeout(); - httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(connectTimeout); - httpClient.getParams().setConnectionManagerTimeout(connectTimeout); + initHttpClientConnectionManager(); CredentialsProvider credProvider = new ECFCredentialsProvider(); setupAuthentication(urlString); @@ -928,6 +883,7 @@ public class HttpClientRetrieveFileTransfer extends AbstractRetrieveFileTransfer setupHostAndPort(credProvider, urlString); getMethod = new GzipGetMethod(hostConfigHelper.getTargetRelativePath()); + getMethod.addRequestHeader("Connection", "Keep-Alive"); //$NON-NLS-1$ //$NON-NLS-2$ getMethod.setFollowRedirects(true); // Define a CredentialsProvider - found that possibility while debugging in org.apache.commons.httpclient.HttpMethodDirector.processProxyAuthChallenge(HttpMethod) // Seems to be another way to select the credentials. diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientRetrieveFileTransferFactory.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientRetrieveFileTransferFactory.java index bce6b3cab..ccb2689d4 100644 --- a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientRetrieveFileTransferFactory.java +++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient/src/org/eclipse/ecf/provider/filetransfer/httpclient/HttpClientRetrieveFileTransferFactory.java @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2007 IBM, Composent Inc. and others. + * Copyright (c) 2007, 2011 IBM, Composent Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,20 +7,18 @@ * * Contributors: * Composent, Inc. - initial API and implementation + * Henrich Kraemer - Bug 297742 - [transport] Investigate how to maintain HTTP session *****************************************************************************/ package org.eclipse.ecf.provider.filetransfer.httpclient; import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransfer; import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransferFactory; -public class HttpClientRetrieveFileTransferFactory implements - IRetrieveFileTransferFactory { +public class HttpClientRetrieveFileTransferFactory implements IRetrieveFileTransferFactory { public IRetrieveFileTransfer newInstance() { - return new HttpClientRetrieveFileTransfer(new HttpClient( - new MultiThreadedHttpConnectionManager())); + return new HttpClientRetrieveFileTransfer(new HttpClient()); } } |