diff --git a/google-http-client-android/pom.xml b/google-http-client-android/pom.xml
index f28dc3d1e..0db928781 100644
--- a/google-http-client-android/pom.xml
+++ b/google-http-client-android/pom.xml
@@ -48,9 +48,5 @@
Implementation is thread-safe, as long as any parameter modification to the {@link - * #getHttpClient() Apache HTTP Client} is only done at initialization time. For maximum efficiency, - * applications should use a single globally-shared instance of the HTTP transport. - * - *
Default settings are specified in {@link #newDefaultHttpClient()}. Use the {@link - * #ApacheHttpTransport(HttpClient)} constructor to override the Apache HTTP Client used. - * Alternatively, use {@link #ApacheHttpTransport()} and change the {@link #getHttpClient()}. Please - * read the Apache HTTP - * Client connection management tutorial for more complex configuration options. - * - * @since 1.0 - * @author Yaniv Inbar - */ -public final class ApacheHttpTransport extends HttpTransport { - - /** Apache HTTP client. */ - private final HttpClient httpClient; - - /** - * Constructor that uses {@link #newDefaultHttpClient()} for the Apache HTTP client. - * - *
Use {@link Builder} to modify HTTP client options. - * - * @since 1.3 - */ - public ApacheHttpTransport() { - this(newDefaultHttpClient()); - } - - /** - * Constructor that allows an alternative Apache HTTP client to be used. - * - *
Note that a few settings are overridden: - * - *
Use {@link Builder} for a more user-friendly way to modify the HTTP client options. - * - * @param httpClient Apache HTTP client to use - * @since 1.6 - */ - public ApacheHttpTransport(HttpClient httpClient) { - this.httpClient = httpClient; - HttpParams params = httpClient.getParams(); - if (params == null) { - params = newDefaultHttpClient().getParams(); - } - HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); - params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false); - } - - /** Returns a new instance of the default HTTP parameters we use. */ - static HttpParams newDefaultHttpParams() { - HttpParams params = new BasicHttpParams(); - // Turn off stale checking. Our connections break all the time anyway, - // and it's not worth it to pay the penalty of checking every time. - HttpConnectionParams.setStaleCheckingEnabled(params, false); - HttpConnectionParams.setSocketBufferSize(params, 8192); - ConnManagerParams.setMaxTotalConnections(params, 200); - ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRouteBean(20)); - return params; - } - - /** - * Creates a new instance of the Apache HTTP client that is used by the {@link - * #ApacheHttpTransport()} constructor. - * - *
Use this constructor if you want to customize the default Apache HTTP client. Settings: - * - *
Implementation is not thread-safe. - * - * @since 1.13 - */ - public static final class Builder { - - /** SSL socket factory. */ - private SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory(); - - /** HTTP parameters. */ - private final HttpParams params = newDefaultHttpParams(); - - /** - * HTTP proxy selector to use {@link ProxySelectorRoutePlanner} or {@code null} for {@link - * DefaultHttpRoutePlanner}. - */ - private ProxySelector proxySelector = ProxySelector.getDefault(); - - /** - * Sets the HTTP proxy to use {@link DefaultHttpRoutePlanner} or {@code null} to use {@link - * #setProxySelector(ProxySelector)} with {@link ProxySelector#getDefault()}. - * - *
By default it is {@code null}, which uses the proxy settings from system - * properties. - * - *
For example: - * - *
- * setProxy(new HttpHost("127.0.0.1", 8080)) - *- */ - public Builder setProxy(HttpHost proxy) { - ConnRouteParams.setDefaultProxy(params, proxy); - if (proxy != null) { - proxySelector = null; - } - return this; - } - - /** - * Sets the HTTP proxy selector to use {@link ProxySelectorRoutePlanner} or {@code null} for - * {@link DefaultHttpRoutePlanner}. - * - *
By default it is {@link ProxySelector#getDefault()} which uses the proxy settings from system - * properties. - */ - public Builder setProxySelector(ProxySelector proxySelector) { - this.proxySelector = proxySelector; - if (proxySelector != null) { - ConnRouteParams.setDefaultProxy(params, null); - } - return this; - } - /** - * Sets the SSL socket factory based on root certificates in a Java KeyStore. - * - *
Example usage: - * - *
- * trustCertificatesFromJavaKeyStore(new FileInputStream("certs.jks"), "password"); - *- * - * @param keyStoreStream input stream to the key store (closed at the end of this method in a - * finally block) - * @param storePass password protecting the key store file - * @since 1.14 - */ - public Builder trustCertificatesFromJavaKeyStore(InputStream keyStoreStream, String storePass) - throws GeneralSecurityException, IOException { - KeyStore trustStore = SecurityUtils.getJavaKeyStore(); - SecurityUtils.loadKeyStore(trustStore, keyStoreStream, storePass); - return trustCertificates(trustStore); - } - - /** - * Sets the SSL socket factory based root certificates generated from the specified stream using - * {@link CertificateFactory#generateCertificates(InputStream)}. - * - *
Example usage: - * - *
- * trustCertificatesFromStream(new FileInputStream("certs.pem")); - *- * - * @param certificateStream certificate stream - * @since 1.14 - */ - public Builder trustCertificatesFromStream(InputStream certificateStream) - throws GeneralSecurityException, IOException { - KeyStore trustStore = SecurityUtils.getJavaKeyStore(); - trustStore.load(null, null); - SecurityUtils.loadKeyStoreFromCertificates( - trustStore, SecurityUtils.getX509CertificateFactory(), certificateStream); - return trustCertificates(trustStore); - } - - /** - * Sets the SSL socket factory based on a root certificate trust store. - * - * @param trustStore certificate trust store (use for example {@link SecurityUtils#loadKeyStore} - * or {@link SecurityUtils#loadKeyStoreFromCertificates}) - * @since 1.14 - */ - public Builder trustCertificates(KeyStore trustStore) throws GeneralSecurityException { - SSLContext sslContext = SslUtils.getTlsSslContext(); - SslUtils.initSslContext(sslContext, trustStore, SslUtils.getPkixTrustManagerFactory()); - return setSocketFactory(new SSLSocketFactoryExtension(sslContext)); - } - - /** - * {@link Beta}
Be careful! Disabling certificate validation is dangerous and should only be done in
- * testing environments.
- */
- @Beta
- public Builder doNotValidateCertificate() throws GeneralSecurityException {
- socketFactory = new SSLSocketFactoryExtension(SslUtils.trustAllSSLContext());
- socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
- return this;
- }
-
- /** Sets the SSL socket factory ({@link SSLSocketFactory#getSocketFactory()} by default). */
- public Builder setSocketFactory(SSLSocketFactory socketFactory) {
- this.socketFactory = Preconditions.checkNotNull(socketFactory);
- return this;
- }
-
- /** Returns the SSL socket factory ({@link SSLSocketFactory#getSocketFactory()} by default). */
- public SSLSocketFactory getSSLSocketFactory() {
- return socketFactory;
- }
-
- /** Returns the HTTP parameters. */
- public HttpParams getHttpParams() {
- return params;
- }
-
- /** Returns a new instance of {@link ApacheHttpTransport} based on the options. */
- public ApacheHttpTransport build() {
- return new ApacheHttpTransport(newDefaultHttpClient(socketFactory, params, proxySelector));
- }
- }
-}
diff --git a/google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/SSLSocketFactoryExtension.java b/google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/SSLSocketFactoryExtension.java
deleted file mode 100644
index 4b9a624f2..000000000
--- a/google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/SSLSocketFactoryExtension.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2013 Google Inc.
- *
- * 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.
- */
-
-package com.google.api.client.http.apache;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-
-/**
- * Implementation of SSL socket factory that extends Apache's implementation to provide
- * functionality missing from the Android SDK that is available in Apache HTTP Client.
- *
- * @author Yaniv Inbar
- */
-final class SSLSocketFactoryExtension extends SSLSocketFactory {
-
- /** Wrapped Java SSL socket factory. */
- private final javax.net.ssl.SSLSocketFactory socketFactory;
-
- /** @param sslContext SSL context */
- SSLSocketFactoryExtension(SSLContext sslContext)
- throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException,
- KeyStoreException {
- super((KeyStore) null);
- socketFactory = sslContext.getSocketFactory();
- }
-
- @Override
- public Socket createSocket() throws IOException {
- return socketFactory.createSocket();
- }
-
- @Override
- public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
- throws IOException {
- SSLSocket sslSocket = (SSLSocket) socketFactory.createSocket(socket, host, port, autoClose);
- getHostnameVerifier().verify(host, sslSocket);
- return sslSocket;
- }
-}
diff --git a/google-http-client-apache-legacy/src/test/java/com/google/api/client/http/apache/ApacheHttpTransportTest.java b/google-http-client-apache-legacy/src/test/java/com/google/api/client/http/apache/ApacheHttpTransportTest.java
deleted file mode 100644
index 8176166db..000000000
--- a/google-http-client-apache-legacy/src/test/java/com/google/api/client/http/apache/ApacheHttpTransportTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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.
- */
-
-package com.google.api.client.http.apache;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import com.google.api.client.util.ByteArrayStreamingContent;
-import com.google.api.client.util.StringUtils;
-import junit.framework.TestCase;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpVersion;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.params.ClientPNames;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
-
-/**
- * Tests {@link ApacheHttpTransport}.
- *
- * @author Yaniv Inbar
- */
-public class ApacheHttpTransportTest extends TestCase {
-
- public void testApacheHttpTransport() {
- ApacheHttpTransport transport = new ApacheHttpTransport();
- DefaultHttpClient httpClient = (DefaultHttpClient) transport.getHttpClient();
- checkDefaultHttpClient(httpClient);
- checkHttpClient(httpClient);
- }
-
- public void testApacheHttpTransportWithParam() {
- ApacheHttpTransport transport = new ApacheHttpTransport(new DefaultHttpClient());
- checkHttpClient(transport.getHttpClient());
- }
-
- public void testNewDefaultHttpClient() {
- checkDefaultHttpClient(ApacheHttpTransport.newDefaultHttpClient());
- }
-
- public void testRequestsWithContent() throws Exception {
- HttpClient mockClient = mock(HttpClient.class);
- HttpResponse mockResponse = mock(HttpResponse.class);
- when(mockClient.execute(any(HttpUriRequest.class))).thenReturn(mockResponse);
-
- ApacheHttpTransport transport = new ApacheHttpTransport(mockClient);
-
- // Test GET.
- subtestUnsupportedRequestsWithContent(
- transport.buildRequest("GET", "http://www.test.url"), "GET");
- // Test DELETE.
- subtestUnsupportedRequestsWithContent(
- transport.buildRequest("DELETE", "http://www.test.url"), "DELETE");
- // Test HEAD.
- subtestUnsupportedRequestsWithContent(
- transport.buildRequest("HEAD", "http://www.test.url"), "HEAD");
-
- // Test PUT.
- execute(transport.buildRequest("PUT", "http://www.test.url"));
- // Test POST.
- execute(transport.buildRequest("POST", "http://www.test.url"));
- // Test PATCH.
- execute(transport.buildRequest("PATCH", "http://www.test.url"));
- }
-
- private void subtestUnsupportedRequestsWithContent(ApacheHttpRequest request, String method)
- throws Exception {
- try {
- execute(request);
- fail("expected " + IllegalArgumentException.class);
- } catch (IllegalArgumentException e) {
- // expected
- assertEquals(
- e.getMessage(),
- "Apache HTTP client does not support " + method + " requests with content.");
- }
- }
-
- private void execute(ApacheHttpRequest request) throws Exception {
- byte[] bytes = StringUtils.getBytesUtf8("abc");
- request.setStreamingContent(new ByteArrayStreamingContent(bytes));
- request.setContentType("text/html");
- request.setContentLength(bytes.length);
- request.execute();
- }
-
- private void checkDefaultHttpClient(DefaultHttpClient client) {
- HttpParams params = client.getParams();
- assertTrue(client.getConnectionManager() instanceof ThreadSafeClientConnManager);
- assertEquals(8192, params.getIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, -1));
- DefaultHttpRequestRetryHandler retryHandler =
- (DefaultHttpRequestRetryHandler) client.getHttpRequestRetryHandler();
- assertEquals(0, retryHandler.getRetryCount());
- assertFalse(retryHandler.isRequestSentRetryEnabled());
- }
-
- private void checkHttpClient(HttpClient client) {
- HttpParams params = client.getParams();
- assertFalse(params.getBooleanParameter(ClientPNames.HANDLE_REDIRECTS, true));
- assertEquals(HttpVersion.HTTP_1_1, HttpProtocolParams.getVersion(params));
- }
-}
diff --git a/google-http-client-apache/pom.xml b/google-http-client-apache-v2/pom.xml
similarity index 93%
rename from google-http-client-apache/pom.xml
rename to google-http-client-apache-v2/pom.xml
index 126ae7cc9..fab345615 100644
--- a/google-http-client-apache/pom.xml
+++ b/google-http-client-apache-v2/pom.xml
@@ -7,9 +7,9 @@
+ * Implementation is thread-safe, as long as any parameter modification to the
+ * {@link #getHttpClient() Apache HTTP Client} is only done at initialization time. For maximum
+ * efficiency, applications should use a single globally-shared instance of the HTTP transport.
+ *
+ * Default settings are specified in {@link #newDefaultHttpClient()}. Use the
+ * {@link #ApacheHttpTransport(HttpClient)} constructor to override the Apache HTTP Client used.
+ * Please read the Apache HTTP
+ * Client connection management tutorial for more complex configuration options.
+ *
+ * Note that in the previous version, we overrode several settings, however, we are no longer able
+ * to do so.
+ * If you choose to provide your own Apache HttpClient implementation, be sure that
+ * Settings:
+ *
+ *
+ *
+ * @param httpClient Apache HTTP client to use
+ *
+ * @since 1.30
+ */
+ public ApacheHttpTransport(HttpClient httpClient) {
+ this.httpClient = httpClient;
+ }
+
+ /**
+ * Creates a new instance of the Apache HTTP client that is used by the
+ * {@link #ApacheHttpTransport()} constructor.
+ *
+ *
+ *
+ *
+ * @return new instance of the Apache HTTP client
+ * @since 1.30
+ */
+ public static HttpClient newDefaultHttpClient() {
+ // Set socket buffer sizes to 8192
+ SocketConfig socketConfig =
+ SocketConfig.custom()
+ .setRcvBufSize(8192)
+ .setSndBufSize(8192)
+ .build();
+
+ PoolingHttpClientConnectionManager connectionManager =
+ new PoolingHttpClientConnectionManager(-1, TimeUnit.MILLISECONDS);
+ // Disable the stale connection check (previously configured in the HttpConnectionParams
+ connectionManager.setValidateAfterInactivity(-1);
+
+ return HttpClientBuilder.create()
+ .useSystemProperties()
+ .setSSLSocketFactory(SSLConnectionSocketFactory.getSocketFactory())
+ .setDefaultSocketConfig(socketConfig)
+ .setMaxConnTotal(200)
+ .setMaxConnPerRoute(20)
+ .setRoutePlanner(new SystemDefaultRoutePlanner(ProxySelector.getDefault()))
+ .setConnectionManager(connectionManager)
+ .disableRedirectHandling()
+ .disableAutomaticRetries()
+ .build();
+ }
+
+ @Override
+ public boolean supportsMethod(String method) {
+ return true;
+ }
+
+ @Override
+ protected ApacheHttpRequest buildRequest(String method, String url) {
+ HttpRequestBase requestBase;
+ if (method.equals(HttpMethods.DELETE)) {
+ requestBase = new HttpDelete(url);
+ } else if (method.equals(HttpMethods.GET)) {
+ requestBase = new HttpGet(url);
+ } else if (method.equals(HttpMethods.HEAD)) {
+ requestBase = new HttpHead(url);
+ } else if (method.equals(HttpMethods.PATCH)) {
+ requestBase = new HttpPatch(url);
+ } else if (method.equals(HttpMethods.POST)) {
+ requestBase = new HttpPost(url);
+ } else if (method.equals(HttpMethods.PUT)) {
+ requestBase = new HttpPut(url);
+ } else if (method.equals(HttpMethods.TRACE)) {
+ requestBase = new HttpTrace(url);
+ } else if (method.equals(HttpMethods.OPTIONS)) {
+ requestBase = new HttpOptions(url);
+ } else {
+ requestBase = new HttpExtensionMethod(method, url);
+ }
+ return new ApacheHttpRequest(httpClient, requestBase);
+ }
+
+ /**
+ * Shuts down the connection manager and releases allocated resources. This closes all
+ * connections, whether they are currently used or not.
+ *
+ * @since 1.30
+ */
+ @Override
+ public void shutdown() throws IOException {
+ if (httpClient instanceof CloseableHttpClient) {
+ ((CloseableHttpClient) httpClient).close();
+ }
+ }
+
+ /**
+ * Returns the Apache HTTP client.
+ *
+ * @since 1.30
+ */
+ public HttpClient getHttpClient() {
+ return httpClient;
+ }
+}
diff --git a/google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/ContentEntity.java b/google-http-client-apache-v2/src/main/java/com/google/api/client/http/apache/v2/ContentEntity.java
similarity index 94%
rename from google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/ContentEntity.java
rename to google-http-client-apache-v2/src/main/java/com/google/api/client/http/apache/v2/ContentEntity.java
index 343b35c50..8fc11e6d8 100644
--- a/google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/ContentEntity.java
+++ b/google-http-client-apache-v2/src/main/java/com/google/api/client/http/apache/v2/ContentEntity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Google Inc.
+ * Copyright 2019 Google LLC
*
* 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
@@ -12,7 +12,7 @@
* the License.
*/
-package com.google.api.client.http.apache;
+package com.google.api.client.http.apache.v2;
import com.google.api.client.util.Preconditions;
import com.google.api.client.util.StreamingContent;
@@ -21,7 +21,9 @@
import java.io.OutputStream;
import org.apache.http.entity.AbstractHttpEntity;
-/** @author Yaniv Inbar */
+/**
+ * @author Yaniv Inbar
+ */
final class ContentEntity extends AbstractHttpEntity {
/** Content length or less than zero if not known. */
diff --git a/google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/HttpExtensionMethod.java b/google-http-client-apache-v2/src/main/java/com/google/api/client/http/apache/v2/HttpExtensionMethod.java
similarity index 93%
rename from google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/HttpExtensionMethod.java
rename to google-http-client-apache-v2/src/main/java/com/google/api/client/http/apache/v2/HttpExtensionMethod.java
index 598833de5..360baaecb 100644
--- a/google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/HttpExtensionMethod.java
+++ b/google-http-client-apache-v2/src/main/java/com/google/api/client/http/apache/v2/HttpExtensionMethod.java
@@ -1,4 +1,6 @@
/*
+ * Copyright 2019 Google LLC
+ *
* 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
*
@@ -10,7 +12,7 @@
* the License.
*/
-package com.google.api.client.http.apache;
+package com.google.api.client.http.apache.v2;
import com.google.api.client.util.Preconditions;
import java.net.URI;
diff --git a/google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/package-info.java b/google-http-client-apache-v2/src/main/java/com/google/api/client/http/apache/v2/package-info.java
similarity index 85%
rename from google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/package-info.java
rename to google-http-client-apache-v2/src/main/java/com/google/api/client/http/apache/v2/package-info.java
index 0c2c23b4f..bc753838b 100644
--- a/google-http-client-apache-legacy/src/main/java/com/google/api/client/http/apache/package-info.java
+++ b/google-http-client-apache-v2/src/main/java/com/google/api/client/http/apache/v2/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Google Inc.
+ * Copyright 2019 Google LLC
*
* 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
@@ -13,9 +13,11 @@
*/
/**
- * HTTP Transport library for Google API's based on Apache HTTP Client version 4.
+ * HTTP Transport library for Google API's based on Apache HTTP Client version 4.5+
*
- * @since 1.0
+ * @since 1.30
* @author Yaniv Inbar
*/
-package com.google.api.client.http.apache;
+
+package com.google.api.client.http.apache.v2;
+
diff --git a/google-http-client-apache-v2/src/test/java/com/google/api/client/http/apache/v2/ApacheHttpTransportTest.java b/google-http-client-apache-v2/src/test/java/com/google/api/client/http/apache/v2/ApacheHttpTransportTest.java
new file mode 100644
index 000000000..dabd9bf3d
--- /dev/null
+++ b/google-http-client-apache-v2/src/test/java/com/google/api/client/http/apache/v2/ApacheHttpTransportTest.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * 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.
+ */
+
+package com.google.api.client.http.apache.v2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.api.client.http.LowLevelHttpResponse;
+import com.google.api.client.util.ByteArrayStreamingContent;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.http.Header;
+import org.apache.http.HttpClientConnection;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicHttpResponse;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestExecutor;
+import org.junit.Test;
+
+/**
+ * Tests {@link ApacheHttpTransport}.
+ *
+ * @author Yaniv Inbar
+ */
+public class ApacheHttpTransportTest {
+
+ @Test
+ public void testApacheHttpTransport() {
+ ApacheHttpTransport transport = new ApacheHttpTransport();
+ checkHttpTransport(transport);
+ }
+
+ @Test
+ public void testApacheHttpTransportWithParam() {
+ ApacheHttpTransport transport = new ApacheHttpTransport(HttpClients.custom().build());
+ checkHttpTransport(transport);
+ }
+
+ @Test
+ public void testNewDefaultHttpClient() {
+ HttpClient client = ApacheHttpTransport.newDefaultHttpClient();
+ checkHttpClient(client);
+ }
+
+ private void checkHttpTransport(ApacheHttpTransport transport) {
+ assertNotNull(transport);
+ HttpClient client = transport.getHttpClient();
+ checkHttpClient(client);
+ }
+
+ private void checkHttpClient(HttpClient client) {
+ assertNotNull(client);
+ // TODO(chingor): Is it possible to test this effectively? The newer HttpClient implementations
+ // are read-only and we're testing that we built the client with the right configuration
+ }
+
+ @Test
+ public void testRequestsWithContent() throws IOException {
+ HttpClient mockClient = mock(HttpClient.class);
+ HttpResponse mockResponse = mock(HttpResponse.class);
+ when(mockClient.execute(any(HttpUriRequest.class))).thenReturn(mockResponse);
+
+ ApacheHttpTransport transport = new ApacheHttpTransport(mockClient);
+
+ // Test GET.
+ subtestUnsupportedRequestsWithContent(
+ transport.buildRequest("GET", "http://www.test.url"), "GET");
+ // Test DELETE.
+ subtestUnsupportedRequestsWithContent(
+ transport.buildRequest("DELETE", "http://www.test.url"), "DELETE");
+ // Test HEAD.
+ subtestUnsupportedRequestsWithContent(
+ transport.buildRequest("HEAD", "http://www.test.url"), "HEAD");
+
+ // Test PATCH.
+ execute(transport.buildRequest("PATCH", "http://www.test.url"));
+ // Test PUT.
+ execute(transport.buildRequest("PUT", "http://www.test.url"));
+ // Test POST.
+ execute(transport.buildRequest("POST", "http://www.test.url"));
+ // Test PATCH.
+ execute(transport.buildRequest("PATCH", "http://www.test.url"));
+ }
+
+ private void subtestUnsupportedRequestsWithContent(ApacheHttpRequest request, String method)
+ throws IOException {
+ try {
+ execute(request);
+ fail("expected " + IllegalArgumentException.class);
+ } catch (IllegalArgumentException e) {
+ // expected
+ assertEquals(e.getMessage(),
+ "Apache HTTP client does not support " + method + " requests with content.");
+ }
+ }
+
+ private void execute(ApacheHttpRequest request) throws IOException {
+ byte[] bytes = "abc".getBytes(StandardCharsets.UTF_8);
+ request.setStreamingContent(new ByteArrayStreamingContent(bytes));
+ request.setContentType("text/html");
+ request.setContentLength(bytes.length);
+ request.execute();
+ }
+
+ @Test
+ public void testRequestShouldNotFollowRedirects() throws IOException {
+ final AtomicInteger requestsAttempted = new AtomicInteger(0);
+ HttpRequestExecutor requestExecutor = new HttpRequestExecutor() {
+ @Override
+ public HttpResponse execute(HttpRequest request, HttpClientConnection connection,
+ HttpContext context) throws IOException, HttpException {
+ HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 302, null);
+ response.addHeader("location", "https://google.com/path");
+ requestsAttempted.incrementAndGet();
+ return response;
+ }
+ };
+ HttpClient client = HttpClients.custom().setRequestExecutor(requestExecutor).build();
+ ApacheHttpTransport transport = new ApacheHttpTransport(client);
+ ApacheHttpRequest request = transport.buildRequest("GET", "https://google.com");
+ LowLevelHttpResponse response = request.execute();
+ assertEquals(1, requestsAttempted.get());
+ assertEquals(302, response.getStatusCode());
+ }
+
+ @Test
+ public void testRequestCanSetHeaders() {
+ final AtomicBoolean interceptorCalled = new AtomicBoolean(false);
+ HttpClient client = HttpClients.custom().addInterceptorFirst(new HttpRequestInterceptor() {
+ @Override
+ public void process(HttpRequest request, HttpContext context)
+ throws HttpException, IOException {
+ Header header = request.getFirstHeader("foo");
+ assertNotNull("Should have found header", header);
+ assertEquals("bar", header.getValue());
+ interceptorCalled.set(true);
+ throw new IOException("cancelling request");
+ }
+ }).build();
+
+ ApacheHttpTransport transport = new ApacheHttpTransport(client);
+ ApacheHttpRequest request = transport.buildRequest("GET", "https://google.com");
+ request.addHeader("foo", "bar");
+ try {
+ LowLevelHttpResponse response = request.execute();
+ fail("should not actually make the request");
+ } catch (IOException exception) {
+ assertEquals("cancelling request", exception.getMessage());
+ }
+ assertTrue("Expected to have called our test interceptor", interceptorCalled.get());
+ }
+}
diff --git a/google-http-client-apache/src/test/java/com/google/api/client/http/apache/ApacheHttpTransportTest.java b/google-http-client-apache/src/test/java/com/google/api/client/http/apache/ApacheHttpTransportTest.java
deleted file mode 100644
index 8176166db..000000000
--- a/google-http-client-apache/src/test/java/com/google/api/client/http/apache/ApacheHttpTransportTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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.
- */
-
-package com.google.api.client.http.apache;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import com.google.api.client.util.ByteArrayStreamingContent;
-import com.google.api.client.util.StringUtils;
-import junit.framework.TestCase;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpVersion;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.params.ClientPNames;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
-
-/**
- * Tests {@link ApacheHttpTransport}.
- *
- * @author Yaniv Inbar
- */
-public class ApacheHttpTransportTest extends TestCase {
-
- public void testApacheHttpTransport() {
- ApacheHttpTransport transport = new ApacheHttpTransport();
- DefaultHttpClient httpClient = (DefaultHttpClient) transport.getHttpClient();
- checkDefaultHttpClient(httpClient);
- checkHttpClient(httpClient);
- }
-
- public void testApacheHttpTransportWithParam() {
- ApacheHttpTransport transport = new ApacheHttpTransport(new DefaultHttpClient());
- checkHttpClient(transport.getHttpClient());
- }
-
- public void testNewDefaultHttpClient() {
- checkDefaultHttpClient(ApacheHttpTransport.newDefaultHttpClient());
- }
-
- public void testRequestsWithContent() throws Exception {
- HttpClient mockClient = mock(HttpClient.class);
- HttpResponse mockResponse = mock(HttpResponse.class);
- when(mockClient.execute(any(HttpUriRequest.class))).thenReturn(mockResponse);
-
- ApacheHttpTransport transport = new ApacheHttpTransport(mockClient);
-
- // Test GET.
- subtestUnsupportedRequestsWithContent(
- transport.buildRequest("GET", "http://www.test.url"), "GET");
- // Test DELETE.
- subtestUnsupportedRequestsWithContent(
- transport.buildRequest("DELETE", "http://www.test.url"), "DELETE");
- // Test HEAD.
- subtestUnsupportedRequestsWithContent(
- transport.buildRequest("HEAD", "http://www.test.url"), "HEAD");
-
- // Test PUT.
- execute(transport.buildRequest("PUT", "http://www.test.url"));
- // Test POST.
- execute(transport.buildRequest("POST", "http://www.test.url"));
- // Test PATCH.
- execute(transport.buildRequest("PATCH", "http://www.test.url"));
- }
-
- private void subtestUnsupportedRequestsWithContent(ApacheHttpRequest request, String method)
- throws Exception {
- try {
- execute(request);
- fail("expected " + IllegalArgumentException.class);
- } catch (IllegalArgumentException e) {
- // expected
- assertEquals(
- e.getMessage(),
- "Apache HTTP client does not support " + method + " requests with content.");
- }
- }
-
- private void execute(ApacheHttpRequest request) throws Exception {
- byte[] bytes = StringUtils.getBytesUtf8("abc");
- request.setStreamingContent(new ByteArrayStreamingContent(bytes));
- request.setContentType("text/html");
- request.setContentLength(bytes.length);
- request.execute();
- }
-
- private void checkDefaultHttpClient(DefaultHttpClient client) {
- HttpParams params = client.getParams();
- assertTrue(client.getConnectionManager() instanceof ThreadSafeClientConnManager);
- assertEquals(8192, params.getIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, -1));
- DefaultHttpRequestRetryHandler retryHandler =
- (DefaultHttpRequestRetryHandler) client.getHttpRequestRetryHandler();
- assertEquals(0, retryHandler.getRetryCount());
- assertFalse(retryHandler.isRequestSentRetryEnabled());
- }
-
- private void checkHttpClient(HttpClient client) {
- HttpParams params = client.getParams();
- assertFalse(params.getBooleanParameter(ClientPNames.HANDLE_REDIRECTS, true));
- assertEquals(HttpVersion.HTTP_1_1, HttpProtocolParams.getVersion(params));
- }
-}
diff --git a/google-http-client-assembly/assembly.xml b/google-http-client-assembly/assembly.xml
index 80ee72de1..45478f40a 100644
--- a/google-http-client-assembly/assembly.xml
+++ b/google-http-client-assembly/assembly.xml
@@ -39,8 +39,8 @@