Make user agent header configurable

Jclouds sends default user agent string with each request to cloud
services. But some of the application would like to overide this and
send custom user agent instead.

This commit define a string property to overide this default user agent
string. This property will be applied to all outgoing http request to
cloud services

JCLOUDS-819
This commit is contained in:
Vijay Panghal 2016-12-15 11:04:02 -08:00 committed by Ignasi Barrera
parent fa746ff162
commit 79ad45d6b9
8 changed files with 48 additions and 21 deletions

View File

@ -339,6 +339,13 @@ public final class Constants {
*/
public static final String PROPERTY_STRIP_EXPECT_HEADER = "jclouds.strip-expect-header";
/**
* String property.
* <p/>
* 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.

View File

@ -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

View File

@ -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<HttpURLConnection> {
public static final String DEFAULT_USER_AGENT = String.format("jclouds/%s java/%s", JcloudsVersion.get(),
System.getProperty("java.version"));
protected final Supplier<SSLContext> untrustedSSLContextProvider;
protected final Function<URI, Proxy> proxyForURI;
protected final HostnameVerifier verifier;
@Inject(optional = true)
protected Supplier<SSLContext> 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<SSLContext> untrustedSSLContextProvider, Function<URI, Proxy> 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) {

View File

@ -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<SSLContext> untrustedSSLContextProvider, Function<URI, Proxy> proxyForURI,
List<HttpCommand> 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;
}

View File

@ -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<HttpUriRequest> {
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;
}

View File

@ -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<Request> {
private static final String DEFAULT_USER_AGENT = String.format("jclouds-okhttp/%s java/%s", JcloudsVersion.get(),
System.getProperty("java.version"));
private final Function<URI, Proxy> proxyForURI;
private final OkHttpClient globalClient;
private final String userAgent;
@Inject
OkHttpCommandExecutorService(HttpUtils utils, ContentMetadataCodec contentMetadataCodec,
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
DelegatingErrorHandler errorHandler, HttpWire wire, Function<URI, Proxy> 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<String, String> entry : request.getHeaders().entries()) {
builder.addHeader(entry.getKey(), entry.getValue());

View File

@ -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<DynECTApi> {
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
DelegatingErrorHandler errorHandler, HttpWire wire, @Named("untrusted") HostnameVerifier verifier,
@Named("untrusted") Supplier<SSLContext> untrustedSSLContextProvider, Function<URI, Proxy> 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);
}
/**

View File

@ -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<SSLContext> untrustedSSLContextProvider, Function<URI, Proxy> proxyForURI,
ParseSax<ServiceFault> 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;
}