-
-
Save andreiverdes/ceb99ecbba42df5390e7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.io.OutputStream; | |
import java.net.HttpURLConnection; | |
import java.net.URI; | |
import java.net.URISyntaxException; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.zip.GZIPOutputStream; | |
import org.springframework.http.ContentCodingType; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpMethod; | |
import org.springframework.http.client.ClientHttpRequest; | |
import org.springframework.http.client.ClientHttpResponse; | |
final class OkHttpClientRequest implements ClientHttpRequest { | |
private final HttpURLConnection connection; | |
private final HttpHeaders headers = new HttpHeaders(); | |
private boolean executed = false; | |
private GZIPOutputStream compressedBody; | |
private OutputStream body; | |
public OkHttpClientRequest(HttpURLConnection connection) { | |
this.connection = connection; | |
} | |
@Override | |
public OutputStream getBody() throws IOException { | |
if (this.body == null) { | |
writeHeaders(headers); | |
this.connection.connect(); | |
this.body = this.connection.getOutputStream(); | |
} | |
if (shouldCompress()) { | |
return getCompressedBody(this.body); | |
} else { | |
return this.body; | |
} | |
} | |
@Override | |
public HttpHeaders getHeaders() { | |
return (this.executed ? HttpHeaders.readOnlyHttpHeaders(this.headers) : this.headers); | |
} | |
@Override | |
public URI getURI() { | |
try { | |
return this.connection.getURL().toURI(); | |
} catch (URISyntaxException ex) { | |
throw new IllegalStateException("Could not get HttpURLConnection URI: " + ex.getMessage(), ex); | |
} | |
} | |
@Override | |
public HttpMethod getMethod() { | |
return HttpMethod.valueOf(this.connection.getRequestMethod()); | |
} | |
@Override | |
public ClientHttpResponse execute() throws IOException { | |
try { | |
if (this.body != null) { | |
this.body.close(); | |
} else { | |
writeHeaders(headers); | |
this.connection.connect(); | |
} | |
} catch (IOException ex) { | |
// ignore | |
} | |
this.executed = true; | |
return new OkHttpClientResponse(connection); | |
} | |
private boolean shouldCompress() { | |
List<ContentCodingType> contentCodingTypes = this.headers.getContentEncoding(); | |
for (ContentCodingType contentCodingType : contentCodingTypes) { | |
if (contentCodingType.equals(ContentCodingType.GZIP)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
private OutputStream getCompressedBody(OutputStream body) throws IOException { | |
if (this.compressedBody == null) { | |
this.compressedBody = new GZIPOutputStream(body); | |
} | |
return this.compressedBody; | |
} | |
private void writeHeaders(HttpHeaders headers) { | |
for (Map.Entry<String, List<String>> entry : headers.entrySet()) { | |
String headerName = entry.getKey(); | |
for (String headerValue : entry.getValue()) { | |
this.connection.addRequestProperty(headerName, headerValue); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.io.InputStream; | |
import java.net.HttpURLConnection; | |
import java.util.List; | |
import java.util.zip.GZIPInputStream; | |
import org.springframework.http.ContentCodingType; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.client.ClientHttpResponse; | |
import org.springframework.util.StringUtils; | |
final class OkHttpClientResponse implements ClientHttpResponse { | |
private final HttpURLConnection connection; | |
private static final String AUTH_ERROR = "Received authentication challenge is null"; | |
private static final String AUTH_ERROR_JELLY_BEAN = "No authentication challenges found"; | |
private static final String PROXY_AUTH_ERROR = "Received HTTP_PROXY_AUTH (407) code while not using proxy"; | |
private HttpHeaders headers; | |
private GZIPInputStream compressedBody; | |
public OkHttpClientResponse(HttpURLConnection connection) { | |
this.connection = connection; | |
} | |
private int handleIOException(IOException ex) throws IOException { | |
if (AUTH_ERROR.equals(ex.getMessage()) || AUTH_ERROR_JELLY_BEAN.equals(ex.getMessage())) { | |
return HttpStatus.UNAUTHORIZED.value(); | |
} else if (PROXY_AUTH_ERROR.equals(ex.getMessage())) { | |
return HttpStatus.PROXY_AUTHENTICATION_REQUIRED.value(); | |
} else { | |
throw ex; | |
} | |
} | |
@Override | |
public InputStream getBody() throws IOException { | |
InputStream errorStream = this.connection.getErrorStream(); | |
InputStream body = (errorStream != null ? errorStream : this.connection.getInputStream()); | |
if (isCompressed()) { | |
return getCompressedBody(body); | |
} | |
return body; | |
} | |
@Override | |
public HttpHeaders getHeaders() { | |
if (this.headers == null) { | |
this.headers = new HttpHeaders(); | |
// Header field 0 is the status line for most HttpURLConnections, but not on GAE | |
String name = this.connection.getHeaderFieldKey(0); | |
if (StringUtils.hasLength(name)) { | |
this.headers.add(name, this.connection.getHeaderField(0)); | |
} | |
int i = 1; | |
while (true) { | |
name = this.connection.getHeaderFieldKey(i); | |
if (!StringUtils.hasLength(name)) { | |
break; | |
} | |
this.headers.add(name, this.connection.getHeaderField(i)); | |
i++; | |
} | |
} | |
return this.headers; | |
} | |
@Override | |
public int getRawStatusCode() throws IOException { | |
try { | |
return this.connection.getResponseCode(); | |
} catch (IOException ex) { | |
return handleIOException(ex); | |
} | |
} | |
@Override | |
public HttpStatus getStatusCode() throws IOException { | |
return HttpStatus.valueOf(getRawStatusCode()); | |
} | |
@Override | |
public String getStatusText() throws IOException { | |
try { | |
return this.connection.getResponseMessage(); | |
} catch (IOException ex) { | |
return HttpStatus.valueOf(handleIOException(ex)).getReasonPhrase(); | |
} | |
} | |
@Override | |
public void close() { | |
if (this.compressedBody != null) { | |
try { | |
this.compressedBody.close(); | |
} catch (IOException e) { | |
// ignore | |
} | |
} | |
this.connection.disconnect(); | |
} | |
private boolean isCompressed() { | |
List<ContentCodingType> contentCodingTypes = this.getHeaders().getContentEncoding(); | |
for (ContentCodingType contentCodingType : contentCodingTypes) { | |
if (contentCodingType.equals(ContentCodingType.GZIP)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
private InputStream getCompressedBody(InputStream body) throws IOException { | |
if (this.compressedBody == null) { | |
this.compressedBody = new GZIPInputStream(body); | |
} | |
return this.compressedBody; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.net.HttpURLConnection; | |
import java.net.Proxy; | |
import java.net.URI; | |
import org.springframework.http.HttpMethod; | |
import org.springframework.http.client.ClientHttpRequest; | |
import org.springframework.http.client.ClientHttpRequestFactory; | |
import com.squareup.okhttp.OkHttpClient; | |
public class OkHttpFactory implements ClientHttpRequestFactory { | |
private final OkHttpClient client = new OkHttpClient(); | |
private int connectTimeout = -1; | |
private int readTimeout = -1; | |
@Override | |
public ClientHttpRequest createRequest(final URI uri, final HttpMethod httpMethod) throws IOException { | |
final HttpURLConnection connection = this.client.open(uri.toURL()); | |
prepareConnection(connection, httpMethod.name()); | |
return new OkHttpClientRequest(connection); | |
} | |
public void setProxy(Proxy proxy) { | |
this.client.setProxy(proxy); | |
} | |
public void setConnectTimeout(int connectTimeout) { | |
this.connectTimeout = connectTimeout; | |
} | |
public void setReadTimeout(int readTimeout) { | |
this.readTimeout = readTimeout; | |
} | |
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException { | |
if (this.connectTimeout >= 0) { | |
connection.setConnectTimeout(this.connectTimeout); | |
} | |
if (this.readTimeout >= 0) { | |
connection.setReadTimeout(this.readTimeout); | |
} | |
connection.setDoInput(true); | |
if ("GET".equals(httpMethod)) { | |
connection.setInstanceFollowRedirects(true); | |
} else { | |
connection.setInstanceFollowRedirects(false); | |
} | |
if ("PUT".equals(httpMethod) || "POST".equals(httpMethod)) { | |
connection.setDoOutput(true); | |
} else { | |
connection.setDoOutput(false); | |
} | |
connection.setRequestMethod(httpMethod); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment