/*
* Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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.amazonaws.http.apache.client.impl;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.DefaultRequest;
import com.amazonaws.ProxyAuthenticationMethod;
import com.amazonaws.Request;
import com.amazonaws.http.HttpMethodName;
import com.amazonaws.http.apache.request.impl.ApacheHttpRequestFactory;
import com.amazonaws.http.request.HttpRequestFactory;
import com.amazonaws.http.settings.HttpClientSettings;
import com.amazonaws.util.IOUtils;
import com.amazonaws.util.StringInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.hamcrest.Matchers;
import org.hamcrest.core.StringContains;
import org.junit.Assert;
import org.junit.Test;
public class ApacheDefaultHttpRequestFactoryTest {
public static final String CONTENT_TYPE = "Content-Type";
public static final String USER_AGENT = "User-Agent";
private static final HttpRequestFactory<HttpRequestBase> requestFactory =
new ApacheHttpRequestFactory();
private final String SERVICE_NAME = "fooService";
private final String ENDPOINT = "https://aws.amazon.com";
private final HttpClientSettings settings = HttpClientSettings.adapt(new ClientConfiguration());
public static byte[] drainInputStream(InputStream inputStream) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[1024];
long bytesRead = 0;
while ((bytesRead = inputStream.read(buffer)) > -1) {
byteArrayOutputStream.write(buffer, 0, (int) bytesRead);
}
return byteArrayOutputStream.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(byteArrayOutputStream, null);
}
}
@Test
public void uri_resourcepath_escapes_double_slash() throws IOException, URISyntaxException {
final Request<Object> request = newDefaultRequest(HttpMethodName.GET);
request.setResourcePath("//foo");
request.setEndpoint(new URI(ENDPOINT));
HttpRequestBase requestBase = requestFactory.create(request, settings);
URI expectredUri = requestBase.getURI();
Assert.assertEquals("/%2Ffoo", expectredUri.getRawPath());
}
@Test
public void query_parameters_moved_to_payload_for_post_request_with_no_payload
() throws IOException, URISyntaxException {
final Request<Object> request = newDefaultRequest(HttpMethodName.POST);
request.withParameter("foo", "bar")
.withParameter("alpha", "beta");
HttpRequestBase requestBase = requestFactory.create(request, settings);
Assert.assertThat(requestBase, Matchers.instanceOf(HttpPost
.class));
HttpPost post = (HttpPost) requestBase;
HttpEntity entity = post.getEntity();
byte[] actualContents = drainInputStream(entity.getContent());
Assert.assertTrue(actualContents.length > 0);
}
@Test
public void query_parameters_in_uri_for_all_non_post_requests() throws IOException, URISyntaxException {
final Request<Object> request = newDefaultRequest(HttpMethodName.GET);
request.withParameter("foo", "bar");
HttpRequestBase requestBase = requestFactory.create(request, settings);
Assert.assertEquals("foo=bar", requestBase.getURI().getQuery());
}
@Test
public void query_params_in_uri_for_post_request_with_payload() throws IOException, URISyntaxException {
final Request<Object> request = newDefaultRequest(HttpMethodName.POST);
request.withParameter("foo", "bar");
final String payload = "dummy string stream";
request.setContent(new StringInputStream(payload));
HttpRequestBase requestBase = requestFactory.create(request, settings);
Assert.assertThat(requestBase, Matchers.instanceOf(HttpPost
.class));
Assert.assertEquals("foo=bar", requestBase.getURI().getQuery());
Assert.assertThat(requestBase, Matchers.instanceOf(HttpPost
.class));
Assert.assertEquals(payload, IOUtils.toString(((HttpPost)requestBase).getEntity().getContent()));
}
@Test
public void get_request_returns_correct_apache_requests() throws IOException, URISyntaxException {
final Request<Object> request = newDefaultRequest(HttpMethodName.GET);
Assert.assertThat(requestFactory.create(request, settings), Matchers.instanceOf(HttpGet
.class));
}
@Test
public void patch_request_returns_correct_apache_requests() throws IOException, URISyntaxException {
final Request<Object> request = newDefaultRequest(HttpMethodName.PATCH);
Assert.assertThat(requestFactory.create(request, settings), Matchers.instanceOf(HttpPatch
.class));
}
@Test
public void delete_request_returns_correct_apache_requests() throws IOException, URISyntaxException {
final Request<Object> request = newDefaultRequest(HttpMethodName.DELETE);
Assert.assertThat(requestFactory.create(request, settings), Matchers.instanceOf(HttpDelete
.class));
}
@Test
public void head_request_returns_correct_apache_requests() throws IOException, URISyntaxException {
final Request<Object> request = newDefaultRequest(HttpMethodName.HEAD);
Assert.assertThat(requestFactory.create(request, settings), Matchers.instanceOf(HttpHead
.class));
}
@Test
public void request_has_default_content_type_set_when_not_explicitly_set() throws IOException,
URISyntaxException {
final Request<Object> request = newDefaultRequest(HttpMethodName.POST);
request.setContent(new StringInputStream("dummy string stream"));
HttpRequestBase requestBase = requestFactory.create(request, settings);
assertContentTypeContains("application/x-www-form-urlencoded",
requestBase.getHeaders(CONTENT_TYPE));
}
@Test
public void apache_request_has_content_type_set_when_not_explicitly_set() throws IOException,
URISyntaxException {
final Request<Object> request = newDefaultRequest(HttpMethodName.POST);
final String testContentype = "testContentType";
request.addHeader(HttpHeaders.CONTENT_TYPE, testContentype);
request.setContent(new StringInputStream("dummy string stream"));
HttpRequestBase requestBase = requestFactory.create(request, settings);
assertContentTypeContains(testContentype,
requestBase.getHeaders(CONTENT_TYPE));
}
@Test
public void request_has_no_proxy_config_when_proxy_disabled() throws Exception {
HttpRequestBase requestBase = requestFactory.create(newDefaultRequest(HttpMethodName.POST), settings);
Assert.assertThat(requestBase.getConfig().getProxyPreferredAuthSchemes(), Matchers.nullValue());
}
@Test
public void request_has_no_proxy_config_when_proxy_auth_disabled() throws Exception {
List<ProxyAuthenticationMethod> authMethods = Collections.singletonList(ProxyAuthenticationMethod.BASIC);
ClientConfiguration configuration = new ClientConfiguration().withProxyHost("localhost")
.withProxyPort(80)
.withProxyAuthenticationMethods(authMethods);
HttpClientSettings settings = HttpClientSettings.adapt(configuration);
HttpRequestBase requestBase = requestFactory.create(newDefaultRequest(HttpMethodName.POST), settings);
Assert.assertThat(requestBase.getConfig().getProxyPreferredAuthSchemes(), Matchers.nullValue());
}
@Test
public void request_has_proxy_config_when_proxy_auth_enabled() throws Exception {
List<ProxyAuthenticationMethod> authMethods = Arrays.asList(ProxyAuthenticationMethod.BASIC,
ProxyAuthenticationMethod.DIGEST,
ProxyAuthenticationMethod.KERBEROS,
ProxyAuthenticationMethod.NTLM,
ProxyAuthenticationMethod.SPNEGO);
List<String> expectedAuthMethods = Arrays.asList(AuthSchemes.BASIC,
AuthSchemes.DIGEST,
AuthSchemes.KERBEROS,
AuthSchemes.NTLM,
AuthSchemes.SPNEGO);
ClientConfiguration configuration = new ClientConfiguration().withProxyHost("localhost")
.withProxyPort(80)
.withProxyUsername("user")
.withProxyPassword("password")
.withProxyAuthenticationMethods(authMethods);
HttpClientSettings settings = HttpClientSettings.adapt(configuration);
HttpRequestBase requestBase = requestFactory.create(newDefaultRequest(HttpMethodName.POST), settings);
Assert.assertEquals(expectedAuthMethods, requestBase.getConfig().getProxyPreferredAuthSchemes());
}
private void assertContentTypeContains(String expected, Header[]
contentTypes) {
Assert.assertTrue(contentTypes.length == 1);
Header contentTypeHeader = contentTypes[0];
Assert.assertThat(contentTypeHeader.getValue(), StringContains
.containsString(expected));
}
private DefaultRequest<Object> newDefaultRequest(HttpMethodName httpMethod) throws
URISyntaxException {
final DefaultRequest<Object> request = new DefaultRequest<Object>
(null, SERVICE_NAME);
request.setEndpoint(new URI(ENDPOINT));
request.setHttpMethod(httpMethod);
return request;
}
}