diff --git a/core/src/main/java/org/jclouds/Constants.java b/core/src/main/java/org/jclouds/Constants.java
index f9d89f8361..388cc25700 100644
--- a/core/src/main/java/org/jclouds/Constants.java
+++ b/core/src/main/java/org/jclouds/Constants.java
@@ -339,6 +339,13 @@ public final class Constants {
*/
public static final String PROPERTY_STRIP_EXPECT_HEADER = "jclouds.strip-expect-header";
+ /**
+ * String property.
+ *
+ * This will override the user agent header in http request.
+ */
+ public static final String PROPERTY_USER_AGENT = "jclouds.user-agent";
+
/**
* When true, add the Connection: close header. Useful when interacting with
* providers that don't properly support persistent connections. Defaults to false.
diff --git a/core/src/main/java/org/jclouds/apis/internal/BaseApiMetadata.java b/core/src/main/java/org/jclouds/apis/internal/BaseApiMetadata.java
index e516e2361d..e074a6c125 100644
--- a/core/src/main/java/org/jclouds/apis/internal/BaseApiMetadata.java
+++ b/core/src/main/java/org/jclouds/apis/internal/BaseApiMetadata.java
@@ -33,6 +33,7 @@ import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT;
import static org.jclouds.Constants.PROPERTY_STRIP_EXPECT_HEADER;
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
+import static org.jclouds.Constants.PROPERTY_USER_AGENT;
import static org.jclouds.reflect.Reflection2.typeToken;
import java.net.URI;
@@ -40,6 +41,7 @@ import java.util.Properties;
import java.util.Set;
import org.jclouds.Context;
+import org.jclouds.JcloudsVersion;
import org.jclouds.View;
import org.jclouds.apis.ApiMetadata;
@@ -75,6 +77,10 @@ public abstract class BaseApiMetadata implements ApiMetadata {
props.setProperty(PROPERTY_SESSION_INTERVAL, 60 + "");
props.setProperty(PROPERTY_PRETTY_PRINT_PAYLOADS, "true");
props.setProperty(PROPERTY_STRIP_EXPECT_HEADER, "false");
+ props.setProperty(PROPERTY_USER_AGENT,
+ String.format("jclouds/%s java/%s",
+ JcloudsVersion.get(),
+ System.getProperty("java.version")));
props.setProperty(PROPERTY_CONNECTION_CLOSE_HEADER, "false");
// By default, we allow maximum parallel deletes to be equal to the number
diff --git a/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java b/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java
index 468f500db7..f64f4a797e 100644
--- a/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java
+++ b/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java
@@ -22,6 +22,7 @@ import static com.google.common.net.HttpHeaders.CONTENT_LENGTH;
import static com.google.common.net.HttpHeaders.HOST;
import static com.google.common.net.HttpHeaders.USER_AGENT;
import static org.jclouds.Constants.PROPERTY_IDEMPOTENT_METHODS;
+import static org.jclouds.Constants.PROPERTY_USER_AGENT;
import static org.jclouds.http.HttpUtils.filterOutContentHeaders;
import static org.jclouds.io.Payloads.newInputStreamPayload;
import static org.jclouds.util.Closeables2.closeQuietly;
@@ -43,7 +44,6 @@ import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
-import org.jclouds.JcloudsVersion;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpUtils;
@@ -64,22 +64,20 @@ import com.google.inject.Inject;
@Singleton
public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorService {
-
- public static final String DEFAULT_USER_AGENT = String.format("jclouds/%s java/%s", JcloudsVersion.get(),
- System.getProperty("java.version"));
-
protected final Supplier untrustedSSLContextProvider;
protected final Function proxyForURI;
protected final HostnameVerifier verifier;
@Inject(optional = true)
protected Supplier sslContextSupplier;
+ protected final String userAgent;
@Inject
public JavaUrlHttpCommandExecutorService(HttpUtils utils, ContentMetadataCodec contentMetadataCodec,
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
DelegatingErrorHandler errorHandler, HttpWire wire, @Named("untrusted") HostnameVerifier verifier,
@Named("untrusted") Supplier untrustedSSLContextProvider, Function proxyForURI,
- @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods) {
+ @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods,
+ @Named(PROPERTY_USER_AGENT) String userAgent) {
super(utils, contentMetadataCodec, retryHandler, ioRetryHandler, errorHandler, wire, idempotentMethods);
if (utils.getMaxConnections() > 0) {
System.setProperty("http.maxConnections", String.valueOf(checkNotNull(utils, "utils").getMaxConnections()));
@@ -87,6 +85,7 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
this.untrustedSSLContextProvider = checkNotNull(untrustedSSLContextProvider, "untrustedSSLContextProvider");
this.verifier = checkNotNull(verifier, "verifier");
this.proxyForURI = checkNotNull(proxyForURI, "proxyForURI");
+ this.userAgent = userAgent;
}
@Override
@@ -149,7 +148,7 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
}
connection.setRequestProperty(HOST, host);
if (connection.getRequestProperty(USER_AGENT) == null) {
- connection.setRequestProperty(USER_AGENT, DEFAULT_USER_AGENT);
+ connection.setRequestProperty(USER_AGENT, userAgent);
}
Payload payload = request.getPayload();
if (payload != null) {
diff --git a/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java b/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java
index 65cd854554..35fe0ef67f 100644
--- a/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java
+++ b/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java
@@ -17,6 +17,7 @@
package org.jclouds.http.internal;
import static org.jclouds.Constants.PROPERTY_IDEMPOTENT_METHODS;
+import static org.jclouds.Constants.PROPERTY_USER_AGENT;
import java.net.Proxy;
import java.net.URI;
@@ -90,10 +91,11 @@ public class TrackingJavaUrlHttpCommandExecutorService extends JavaUrlHttpComman
DelegatingErrorHandler errorHandler, HttpWire wire, @Named("untrusted") HostnameVerifier verifier,
@Named("untrusted") Supplier untrustedSSLContextProvider, Function proxyForURI,
List commandsInvoked,
- @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods)
+ @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods,
+ @Named(PROPERTY_USER_AGENT) String userAgent)
throws SecurityException, NoSuchFieldException {
super(utils, contentMetadataCodec, retryHandler, ioRetryHandler, errorHandler, wire, verifier,
- untrustedSSLContextProvider, proxyForURI, idempotentMethods);
+ untrustedSSLContextProvider, proxyForURI, idempotentMethods, userAgent);
this.commandsInvoked = commandsInvoked;
}
diff --git a/drivers/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java b/drivers/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java
index cfca7ca7ef..3ef7af99c5 100644
--- a/drivers/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java
+++ b/drivers/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java
@@ -19,6 +19,7 @@ package org.jclouds.http.apachehc;
import static com.google.common.hash.Hashing.md5;
import static com.google.common.io.BaseEncoding.base64;
import static org.jclouds.Constants.PROPERTY_IDEMPOTENT_METHODS;
+import static org.jclouds.Constants.PROPERTY_USER_AGENT;
import static org.jclouds.http.HttpUtils.filterOutContentHeaders;
import java.io.IOException;
@@ -28,6 +29,7 @@ import javax.inject.Inject;
import javax.inject.Named;
import org.apache.http.Header;
+import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
@@ -54,15 +56,18 @@ import com.google.common.collect.Multimap;
public class ApacheHCHttpCommandExecutorService extends BaseHttpCommandExecutorService {
private final HttpClient client;
private final ApacheHCUtils apacheHCUtils;
+ private final String userAgent;
@Inject
ApacheHCHttpCommandExecutorService(HttpUtils utils, ContentMetadataCodec contentMetadataCodec,
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
DelegatingErrorHandler errorHandler, HttpWire wire, HttpClient client,
- @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods) {
+ @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods,
+ @Named(PROPERTY_USER_AGENT) String userAgent) {
super(utils, contentMetadataCodec, retryHandler, ioRetryHandler, errorHandler, wire, idempotentMethods);
this.client = client;
this.apacheHCUtils = new ApacheHCUtils(contentMetadataCodec);
+ this.userAgent = userAgent;
}
@Override
@@ -73,6 +78,10 @@ public class ApacheHCHttpCommandExecutorService extends BaseHttpCommandExecutorS
returnVal.addHeader("Content-MD5", md5);
}
+ if (!returnVal.containsHeader(HttpHeaders.USER_AGENT)) {
+ returnVal.addHeader(HttpHeaders.USER_AGENT, userAgent);
+ }
+
return returnVal;
}
diff --git a/drivers/okhttp/src/main/java/org/jclouds/http/okhttp/OkHttpCommandExecutorService.java b/drivers/okhttp/src/main/java/org/jclouds/http/okhttp/OkHttpCommandExecutorService.java
index f3e4ed07da..ddf62c1451 100644
--- a/drivers/okhttp/src/main/java/org/jclouds/http/okhttp/OkHttpCommandExecutorService.java
+++ b/drivers/okhttp/src/main/java/org/jclouds/http/okhttp/OkHttpCommandExecutorService.java
@@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.net.HttpHeaders.ACCEPT;
import static com.google.common.net.HttpHeaders.USER_AGENT;
import static org.jclouds.Constants.PROPERTY_IDEMPOTENT_METHODS;
+import static org.jclouds.Constants.PROPERTY_USER_AGENT;
import static org.jclouds.http.HttpUtils.filterOutContentHeaders;
import static org.jclouds.io.Payloads.newInputStreamPayload;
@@ -34,7 +35,6 @@ import okio.BufferedSink;
import okio.Okio;
import okio.Source;
-import org.jclouds.JcloudsVersion;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpUtils;
@@ -59,21 +59,20 @@ import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
public final class OkHttpCommandExecutorService extends BaseHttpCommandExecutorService {
-
- private static final String DEFAULT_USER_AGENT = String.format("jclouds-okhttp/%s java/%s", JcloudsVersion.get(),
- System.getProperty("java.version"));
-
private final Function proxyForURI;
private final OkHttpClient globalClient;
+ private final String userAgent;
@Inject
OkHttpCommandExecutorService(HttpUtils utils, ContentMetadataCodec contentMetadataCodec,
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
DelegatingErrorHandler errorHandler, HttpWire wire, Function proxyForURI, OkHttpClient okHttpClient,
- @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods) {
+ @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods,
+ @Named(PROPERTY_USER_AGENT) String userAgent) {
super(utils, contentMetadataCodec, retryHandler, ioRetryHandler, errorHandler, wire, idempotentMethods);
this.proxyForURI = proxyForURI;
this.globalClient = okHttpClient;
+ this.userAgent = userAgent;
}
@Override
@@ -105,7 +104,7 @@ public final class OkHttpCommandExecutorService extends BaseHttpCommandExecutorS
builder.addHeader(ACCEPT, "*/*");
}
if (request.getFirstHeaderOrNull(USER_AGENT) == null) {
- builder.addHeader(USER_AGENT, DEFAULT_USER_AGENT);
+ builder.addHeader(USER_AGENT, userAgent);
}
for (Map.Entry entry : request.getHeaders().entries()) {
builder.addHeader(entry.getKey(), entry.getValue());
diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/config/DynECTHttpApiModule.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/config/DynECTHttpApiModule.java
index bfc12a71c4..a4ca1944c3 100644
--- a/providers/dynect/src/main/java/org/jclouds/dynect/v3/config/DynECTHttpApiModule.java
+++ b/providers/dynect/src/main/java/org/jclouds/dynect/v3/config/DynECTHttpApiModule.java
@@ -17,6 +17,7 @@
package org.jclouds.dynect.v3.config;
import static org.jclouds.Constants.PROPERTY_IDEMPOTENT_METHODS;
+import static org.jclouds.Constants.PROPERTY_USER_AGENT;
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
@@ -104,10 +105,11 @@ public class DynECTHttpApiModule extends HttpApiModule {
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
DelegatingErrorHandler errorHandler, HttpWire wire, @Named("untrusted") HostnameVerifier verifier,
@Named("untrusted") Supplier untrustedSSLContextProvider, Function proxyForURI,
- @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods)
+ @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods,
+ @Named(PROPERTY_USER_AGENT) String userAgent)
throws SecurityException, NoSuchFieldException {
super(utils, contentMetadataCodec, retryHandler, ioRetryHandler, errorHandler, wire, verifier,
- untrustedSSLContextProvider, proxyForURI, idempotentMethods);
+ untrustedSSLContextProvider, proxyForURI, idempotentMethods, userAgent);
}
/**
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/ResponseStatusFromPayloadHttpCommandExecutorService.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/ResponseStatusFromPayloadHttpCommandExecutorService.java
index 4887c134b0..8b0f47d83d 100644
--- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/ResponseStatusFromPayloadHttpCommandExecutorService.java
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/ResponseStatusFromPayloadHttpCommandExecutorService.java
@@ -17,6 +17,7 @@
package org.jclouds.profitbricks.http;
import static org.jclouds.Constants.PROPERTY_IDEMPOTENT_METHODS;
+import static org.jclouds.Constants.PROPERTY_USER_AGENT;
import static org.jclouds.util.Closeables2.closeQuietly;
import java.io.ByteArrayInputStream;
@@ -69,8 +70,10 @@ public class ResponseStatusFromPayloadHttpCommandExecutorService extends JavaUrl
DelegatingErrorHandler errorHandler, HttpWire wire, @Named("untrusted") HostnameVerifier verifier,
@Named("untrusted") Supplier untrustedSSLContextProvider, Function proxyForURI,
ParseSax faultHandler,
- @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods) {
- super(utils, contentMetadataCodec, retryHandler, ioRetryHandler, errorHandler, wire, verifier, untrustedSSLContextProvider, proxyForURI, idempotentMethods);
+ @Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods,
+ @Named(PROPERTY_USER_AGENT) String userAgent) {
+ super(utils, contentMetadataCodec, retryHandler, ioRetryHandler, errorHandler, wire, verifier, untrustedSSLContextProvider, proxyForURI,
+ idempotentMethods, userAgent);
this.faultHandler = faultHandler;
}