Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added apache http client support #148

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@
<artifactId>signpost-core</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
<scope>provided</scope>
</dependency>

<!-- test dependencies -->
<dependency>
Expand Down
27 changes: 20 additions & 7 deletions src/main/java/si/mazi/rescu/ClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,22 @@
*/
package si.mazi.rescu;

import java.lang.annotation.Annotation;
import java.net.Proxy.Type;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;

import com.fasterxml.jackson.databind.ObjectMapper;

import oauth.signpost.OAuthConsumer;
import si.mazi.rescu.clients.HttpConnectionType;
import si.mazi.rescu.serialization.jackson.DefaultJacksonObjectMapperFactory;
import si.mazi.rescu.serialization.jackson.JacksonConfigureListener;
import si.mazi.rescu.serialization.jackson.JacksonObjectMapperFactory;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import java.lang.annotation.Annotation;
import java.net.Proxy.Type;
import java.util.HashMap;
import java.util.Map;

public class ClientConfig {

private final Map<Class<? extends Annotation>, Params> defaultParamsMap = new HashMap<>();
Expand All @@ -50,13 +53,15 @@ public class ClientConfig {
private boolean ignoreHttpErrorCodes;
private boolean wrapUnexpectedExceptions;
private OAuthConsumer oAuthConsumer;
private HttpConnectionType connectionType;

public ClientConfig() {
httpConnTimeout = Config.getHttpConnTimeout();
httpReadTimeout = Config.getHttpReadTimeout();
proxyPort = Config.getProxyPort();
proxyHost = Config.getProxyHost();
proxyType = Config.getProxyType();
connectionType = Config.getConnectionType();
ignoreHttpErrorCodes = Config.isIgnoreHttpErrorCodes();
wrapUnexpectedExceptions = Config.isWrapUnexpectedExceptions();
}
Expand Down Expand Up @@ -154,6 +159,14 @@ public Type getProxyType() {
public void setProxyType(Type proxyType) {
this.proxyType = proxyType;
}

public HttpConnectionType getConnectionType() {
return connectionType;
}

public void setConnectionType(HttpConnectionType connectionType) {
this.connectionType = connectionType;
}

public boolean isIgnoreHttpErrorCodes() {
return ignoreHttpErrorCodes;
Expand Down
16 changes: 14 additions & 2 deletions src/main/java/si/mazi/rescu/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import si.mazi.rescu.clients.HttpConnectionType;

import java.io.IOException;
import java.io.InputStream;
import java.net.Proxy;
Expand Down Expand Up @@ -57,6 +59,8 @@ final class Config {

private static final String WRAP_UNEXPECTED_EXCEPTIONS = "rescu.http.wrapUnexpectedExceptions";

private static final String CONNECTION_TYPE = "rescu.http.connection_type";

private static final int httpConnTimeout;

private static final int httpReadTimeout;
Expand All @@ -70,6 +74,8 @@ final class Config {
private static final boolean ignoreHttpErrorCodes;

private static final boolean wrapUnexpectedExceptions;

private static final HttpConnectionType connectionType;

static {
Properties dfts = new Properties();
Expand All @@ -95,13 +101,15 @@ final class Config {
proxyType = Optional.ofNullable(properties.getProperty(PROXY_TYPE)).map(Proxy.Type::valueOf).orElse(null);
ignoreHttpErrorCodes = getBoolean(properties, IGNORE_HTTP_ERROR_CODES);
wrapUnexpectedExceptions = getBoolean(properties, WRAP_UNEXPECTED_EXCEPTIONS);

connectionType = Optional.ofNullable(properties.getProperty(CONNECTION_TYPE)).map(HttpConnectionType::valueOf).orElse(HttpConnectionType.DEFAULT);

log.debug("Configuration from rescu.properties:");
log.debug("httpConnTimeout = {}", httpConnTimeout);
log.debug("httpReadTimeout = {}", httpReadTimeout);
log.debug("proxyHost = {}", proxyHost);
log.debug("proxyPort = {}", proxyPort);
log.debug("proxyType = {}", proxyType);
log.debug("connectionType = {}", connectionType);
log.debug("ignoreHttpErrorCodes = {}", ignoreHttpErrorCodes);
}

Expand Down Expand Up @@ -132,7 +140,11 @@ public static Integer getProxyPort() {

public static Type getProxyType() {
return proxyType;
}
}

public static HttpConnectionType getConnectionType() {
return connectionType;
}

public static boolean isIgnoreHttpErrorCodes() {
return ignoreHttpErrorCodes;
Expand Down
118 changes: 57 additions & 61 deletions src/main/java/si/mazi/rescu/HttpTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,34 @@
*/
package si.mazi.rescu;

import oauth.signpost.OAuthConsumer;
import oauth.signpost.exception.OAuthException;
import oauth.signpost.http.HttpRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import si.mazi.rescu.oauth.RescuOAuthRequestAdapter;
import si.mazi.rescu.utils.HttpUtils;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import oauth.signpost.OAuthConsumer;
import oauth.signpost.exception.OAuthException;
import oauth.signpost.http.HttpRequest;
import si.mazi.rescu.clients.ApacheConnection;
import si.mazi.rescu.clients.HttpConnection;
import si.mazi.rescu.clients.HttpConnectionType;
import si.mazi.rescu.clients.JavaConnection;
import si.mazi.rescu.oauth.RescuOAuthRequestAdapter;
import si.mazi.rescu.utils.HttpUtils;

/**
* Various HTTP utility methods
*/
Expand Down Expand Up @@ -79,19 +81,22 @@ class HttpTemplate {
private final SSLSocketFactory sslSocketFactory;
private final HostnameVerifier hostnameVerifier;
private final OAuthConsumer oAuthConsumer;

private final HttpConnectionType connectionType;

HttpTemplate(int readTimeout, String proxyHost, Integer proxyPort, Proxy.Type proxyType,
SSLSocketFactory sslSocketFactory, HostnameVerifier hostnameVerifier, OAuthConsumer oAuthConsumer) {
this(0, readTimeout, proxyHost, proxyPort, proxyType, sslSocketFactory, hostnameVerifier, oAuthConsumer);
SSLSocketFactory sslSocketFactory, HostnameVerifier hostnameVerifier, OAuthConsumer oAuthConsumer, HttpConnectionType client) {
this(0, readTimeout, proxyHost, proxyPort, proxyType, sslSocketFactory, hostnameVerifier, oAuthConsumer, client);
}

HttpTemplate(int connTimeout, int readTimeout, String proxyHost, Integer proxyPort, Proxy.Type proxyType,
SSLSocketFactory sslSocketFactory, HostnameVerifier hostnameVerifier, OAuthConsumer oAuthConsumer) {
SSLSocketFactory sslSocketFactory, HostnameVerifier hostnameVerifier, OAuthConsumer oAuthConsumer, HttpConnectionType connectionType) {
this.connTimeout = connTimeout;
this.readTimeout = readTimeout;
this.sslSocketFactory = sslSocketFactory;
this.hostnameVerifier = hostnameVerifier;
this.oAuthConsumer = oAuthConsumer;
this.connectionType = connectionType;

defaultHttpHeaders.put("Accept-Charset", CHARSET_UTF_8);
// defaultHttpHeaders.put("Content-Type", "application/x-www-form-urlencoded");
Expand All @@ -108,7 +113,7 @@ class HttpTemplate {
}
}

HttpURLConnection send(String urlString, String requestBody, Map<String, String> httpHeaders, HttpMethod method) throws IOException {
HttpConnection send(String urlString, String requestBody, Map<String, String> httpHeaders, HttpMethod method) throws IOException {
if (requestBody != null && requestBody.length() > 0) {
log.debug("Executing {} request at {} body \n{}", method, urlString, truncate(requestBody, requestMaxLogLen));
} else {
Expand All @@ -120,11 +125,15 @@ HttpURLConnection send(String urlString, String requestBody, Map<String, String>
preconditionNotNull(httpHeaders, "httpHeaders should not be null");

int contentLength = requestBody == null ? 0 : requestBody.getBytes().length;
HttpURLConnection connection = configureURLConnection(method, urlString, httpHeaders, contentLength);
HttpConnection connection = configureURLConnection(method, urlString, httpHeaders, contentLength);

if (oAuthConsumer != null) {
HttpRequest request = new RescuOAuthRequestAdapter(connection, requestBody);

if (connection.getHttpConnectionType() != HttpConnectionType.java) {
throw new RuntimeException("OAuth not supported yet for " + connection.getHttpConnectionType());
}
JavaConnection jc = (JavaConnection) connection;

HttpRequest request = new RescuOAuthRequestAdapter(jc.getHttpURLConnection(), requestBody);
try {
oAuthConsumer.sign(request);
} catch (OAuthException e) {
Expand All @@ -141,7 +150,7 @@ HttpURLConnection send(String urlString, String requestBody, Map<String, String>
return connection;
}

InvocationResult receive(HttpURLConnection connection) throws IOException {
InvocationResult receive(HttpConnection connection) throws IOException {
int httpStatus = connection.getResponseCode();
log.debug("Request http status = {}", httpStatus);
if (log.isTraceEnabled()) {
Expand Down Expand Up @@ -169,24 +178,24 @@ InvocationResult receive(HttpURLConnection connection) throws IOException {
* @param urlString A string representation of a URL
* @param httpHeaders The HTTP headers (will override the defaults)
* @param contentLength The Content-Length request property
* @return An HttpURLConnection based on the given parameters
* @return An RescuHttpURLConnection based on the given parameters
* @throws IOException If something goes wrong
*/
private HttpURLConnection configureURLConnection(HttpMethod method, String urlString, Map<String, String> httpHeaders, int contentLength) throws IOException {
private HttpConnection configureURLConnection(HttpMethod method, String urlString, Map<String, String> httpHeaders, int contentLength) throws IOException {

preconditionNotNull(method, "method cannot be null");
preconditionNotNull(urlString, "urlString cannot be null");
preconditionNotNull(httpHeaders, "httpHeaders cannot be null");

HttpURLConnection connection = getHttpURLConnection(urlString);
connection.setRequestMethod(method.name());
HttpConnection connection = getRescuHttpURLConnection(urlString);
connection.setRequestMethod(method);

Map<String, String> headerKeyValues = new HashMap<>(defaultHttpHeaders);

headerKeyValues.putAll(httpHeaders);

for (Map.Entry<String, String> entry : headerKeyValues.entrySet()) {
connection.setRequestProperty(entry.getKey(), entry.getValue());
connection.addHeader(entry.getKey(), entry.getValue());
log.trace("Header request property: key='{}', value='{}'", entry.getKey(), entry.getValue());
}

Expand All @@ -195,30 +204,35 @@ private HttpURLConnection configureURLConnection(HttpMethod method, String urlSt
connection.setDoOutput(true);
connection.setDoInput(true);
}
connection.setRequestProperty("Content-Length", Integer.toString(contentLength));
connection.addHeader("Content-Length", Integer.toString(contentLength));

return connection;
}

protected HttpURLConnection getHttpURLConnection(String urlString) throws IOException {
HttpURLConnection connection = (HttpURLConnection) new URL(urlString).openConnection(proxy);

protected HttpConnection getRescuHttpURLConnection(String urlString) throws IOException {

//RescuHttpURLConnection connection = (RescuHttpURLConnection) new URL(urlString).openConnection(proxy);

HttpConnection connection = null;
switch (connectionType) {
case java: connection = JavaConnection.create(urlString, proxy); break;
case apache: connection = ApacheConnection.create(urlString, proxy); break;
default: throw new RuntimeException("Not supported connection type " + connectionType);
}

if (readTimeout > 0) {
connection.setReadTimeout(readTimeout);
}
if (connTimeout > 0) {
connection.setConnectTimeout(connTimeout);
}

if (connection instanceof HttpsURLConnection) {
HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;

if (connection.ssl()) {
if (sslSocketFactory != null) {
httpsConnection.setSSLSocketFactory(sslSocketFactory);
connection.setSSLSocketFactory(sslSocketFactory);
}

if (hostnameVerifier != null) {
httpsConnection.setHostnameVerifier(hostnameVerifier);
connection.setHostnameVerifier(hostnameVerifier);
}
}

Expand All @@ -235,7 +249,7 @@ protected HttpURLConnection getHttpURLConnection(String urlString) throws IOExce
* @return A String representation of the input stream
* @throws IOException If something goes wrong
*/
String readInputStreamAsEncodedString(InputStream inputStream, HttpURLConnection connection) throws IOException {
String readInputStreamAsEncodedString(InputStream inputStream, HttpConnection connection) throws IOException {
if (inputStream == null) {
return null;
}
Expand Down Expand Up @@ -265,32 +279,10 @@ String readInputStreamAsEncodedString(InputStream inputStream, HttpURLConnection
}
}

boolean izGzipped(HttpURLConnection connection) {
boolean izGzipped(HttpConnection connection) {
return "gzip".equalsIgnoreCase(connection.getHeaderField("Content-Encoding"));
}

/**
* Determine the response encoding if specified
*
* @param connection The HTTP connection
* @return The response encoding as a string (taken from "Content-Type")
*/
String getResponseEncoding(URLConnection connection) {

String charset = null;

String contentType = connection.getHeaderField("Content-Type");
if (contentType != null) {
for (String param : contentType.replace(" ", "").split(";")) {
if (param.startsWith("charset=")) {
charset = param.split("=", 2)[1];
break;
}
}
}
return charset;
}

private static void preconditionNotNull(Object what, String message) {
if (what == null) {
throw new NullPointerException(message);
Expand All @@ -312,4 +304,8 @@ private String truncate(String toTruncate, int maxLen) {
}
return toTruncate.substring(0, maxLen);
}

String getResponseEncoding(HttpConnection connection) {
return connection.getResponseEncoding();
}
}
Loading