use of java.net.HttpRetryException in project okhttp by square.
the class RetryAndFollowUpInterceptor method intercept.
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
streamAllocation = new StreamAllocation(client.connectionPool(), createAddress(request.url()), callStackTrace);
int followUpCount = 0;
Response priorResponse = null;
while (true) {
if (canceled) {
streamAllocation.release();
throw new IOException("Canceled");
}
Response response = null;
boolean releaseConnection = true;
try {
response = ((RealInterceptorChain) chain).proceed(request, streamAllocation, null, null);
releaseConnection = false;
} catch (RouteException e) {
// The attempt to connect via a route failed. The request will not have been sent.
if (!recover(e.getLastConnectException(), false, request)) {
throw e.getLastConnectException();
}
releaseConnection = false;
continue;
} catch (IOException e) {
// An attempt to communicate with a server failed. The request may have been sent.
boolean requestSendStarted = !(e instanceof ConnectionShutdownException);
if (!recover(e, requestSendStarted, request))
throw e;
releaseConnection = false;
continue;
} finally {
// We're throwing an unchecked exception. Release any resources.
if (releaseConnection) {
streamAllocation.streamFailed(null);
streamAllocation.release();
}
}
// Attach the prior response if it exists. Such responses never have a body.
if (priorResponse != null) {
response = response.newBuilder().priorResponse(priorResponse.newBuilder().body(null).build()).build();
}
Request followUp = followUpRequest(response);
if (followUp == null) {
if (!forWebSocket) {
streamAllocation.release();
}
return response;
}
closeQuietly(response.body());
if (++followUpCount > MAX_FOLLOW_UPS) {
streamAllocation.release();
throw new ProtocolException("Too many follow-up requests: " + followUpCount);
}
if (followUp.body() instanceof UnrepeatableRequestBody) {
streamAllocation.release();
throw new HttpRetryException("Cannot retry streamed HTTP body", response.code());
}
if (!sameConnection(response, followUp.url())) {
streamAllocation.release();
streamAllocation = new StreamAllocation(client.connectionPool(), createAddress(followUp.url()), callStackTrace);
} else if (streamAllocation.codec() != null) {
throw new IllegalStateException("Closing the body of " + response + " didn't close its backing stream. Bad interceptor?");
}
request = followUp;
priorResponse = response;
}
}
use of java.net.HttpRetryException in project okhttp by square.
the class URLConnectionTest method testAuthenticateWithStreamingPost.
private void testAuthenticateWithStreamingPost(StreamingMode streamingMode) throws Exception {
MockResponse pleaseAuthenticate = new MockResponse().setResponseCode(401).addHeader("WWW-Authenticate: Basic realm=\"protected area\"").setBody("Please authenticate.");
server.enqueue(pleaseAuthenticate);
Authenticator.setDefault(new RecordingAuthenticator());
urlFactory.setClient(urlFactory.client().newBuilder().authenticator(new JavaNetAuthenticator()).build());
connection = urlFactory.open(server.url("/").url());
connection.setDoOutput(true);
byte[] requestBody = { 'A', 'B', 'C', 'D' };
if (streamingMode == StreamingMode.FIXED_LENGTH) {
connection.setFixedLengthStreamingMode(requestBody.length);
} else if (streamingMode == StreamingMode.CHUNKED) {
connection.setChunkedStreamingMode(0);
}
OutputStream outputStream = connection.getOutputStream();
outputStream.write(requestBody);
outputStream.close();
try {
connection.getInputStream();
fail();
} catch (HttpRetryException expected) {
}
// no authorization header for the request...
RecordedRequest request = server.takeRequest();
assertNull(request.getHeader("Authorization"));
assertEquals("ABCD", request.getBody().readUtf8());
}
use of java.net.HttpRetryException in project cordova-android-chromeview by thedracle.
the class HttpURLConnectionImpl method getResponse.
/**
* Aggressively tries to get the final HTTP response, potentially making
* many HTTP requests in the process in order to cope with redirects and
* authentication.
*/
private HttpEngine getResponse() throws IOException {
initHttpEngine();
if (httpEngine.hasResponse()) {
return httpEngine;
}
while (true) {
if (!execute(true)) {
continue;
}
Retry retry = processResponseHeaders();
if (retry == Retry.NONE) {
httpEngine.automaticallyReleaseConnectionToPool();
return httpEngine;
}
// The first request was insufficient. Prepare for another...
String retryMethod = method;
OutputStream requestBody = httpEngine.getRequestBody();
// Although RFC 2616 10.3.2 specifies that a HTTP_MOVED_PERM
// redirect should keep the same method, Chrome, Firefox and the
// RI all issue GETs when following any redirect.
int responseCode = getResponseCode();
if (responseCode == HTTP_MULT_CHOICE || responseCode == HTTP_MOVED_PERM || responseCode == HTTP_MOVED_TEMP || responseCode == HTTP_SEE_OTHER) {
retryMethod = "GET";
requestBody = null;
}
if (requestBody != null && !(requestBody instanceof RetryableOutputStream)) {
throw new HttpRetryException("Cannot retry streamed HTTP body", httpEngine.getResponseCode());
}
if (retry == Retry.DIFFERENT_CONNECTION) {
httpEngine.automaticallyReleaseConnectionToPool();
}
httpEngine.release(false);
httpEngine = newHttpEngine(retryMethod, rawRequestHeaders, httpEngine.getConnection(), (RetryableOutputStream) requestBody);
}
}
use of java.net.HttpRetryException in project j2objc by google.
the class URLConnectionTest method testAuthenticateWithStreamingPost.
// JVM failure.
// /**
// * Test that HEAD requests don't have a body regardless of the response
// * headers. http://code.google.com/p/android/issues/detail?id=24672
// */
// public void testHeadAndContentLength() throws Exception {
// server.enqueue(new MockResponse()
// .clearHeaders()
// .addHeader("Content-Length: 100"));
// server.enqueue(new MockResponse().setBody("A"));
// server.play();
//
// HttpURLConnection connection1 = (HttpURLConnection) server.getUrl("/").openConnection();
// connection1.setRequestMethod("HEAD");
// assertEquals("100", connection1.getHeaderField("Content-Length"));
// assertContent("", connection1);
//
// HttpURLConnection connection2 = (HttpURLConnection) server.getUrl("/").openConnection();
// assertEquals("A", readAscii(connection2.getInputStream(), Integer.MAX_VALUE));
//
// assertEquals(0, server.takeRequest().getSequenceNumber());
// assertEquals(1, server.takeRequest().getSequenceNumber());
// }
// TODO(tball): b/28067294
// /**
// * Test that request body chunking works. This test has been relaxed from treating
// * the {@link java.net.HttpURLConnection#setChunkedStreamingMode(int)}
// * chunk length as being fixed because OkHttp no longer guarantees
// * the fixed chunk size. Instead, we check that chunking takes place
// * and we force the chunk size with flushes.
// */
// public void testSetChunkedStreamingMode() throws IOException, InterruptedException {
// server.enqueue(new MockResponse());
// server.play();
//
// HttpURLConnection urlConnection = (HttpURLConnection) server.getUrl("/").openConnection();
// // Later releases of Android ignore the value for chunkLength if it is > 0 and default to
// // a fixed chunkLength. During the change-over period while the chunkLength indicates the
// // chunk buffer size (inc. header) the chunkLength has to be >= 8. This enables the flush()
// // to dictate the size of the chunks.
// urlConnection.setChunkedStreamingMode(50 /* chunkLength */);
// urlConnection.setDoOutput(true);
// OutputStream outputStream = urlConnection.getOutputStream();
// String outputString = "ABCDEFGH";
// byte[] outputBytes = outputString.getBytes("US-ASCII");
// int targetChunkSize = 3;
// for (int i = 0; i < outputBytes.length; i += targetChunkSize) {
// int count = i + targetChunkSize < outputBytes.length ? 3 : outputBytes.length - i;
// outputStream.write(outputBytes, i, count);
// outputStream.flush();
// }
// assertEquals(200, urlConnection.getResponseCode());
//
// RecordedRequest request = server.takeRequest();
// assertEquals(outputString, new String(request.getBody(), "US-ASCII"));
// assertEquals(Arrays.asList(3, 3, 2), request.getChunkSizes());
// }
// TODO(tball): b/28067294
// public void testAuthenticateWithFixedLengthStreaming() throws Exception {
// testAuthenticateWithStreamingPost(StreamingMode.FIXED_LENGTH);
// }
// TODO(tball): b/28067294
// public void testAuthenticateWithChunkedStreaming() throws Exception {
// testAuthenticateWithStreamingPost(StreamingMode.CHUNKED);
// }
private void testAuthenticateWithStreamingPost(StreamingMode streamingMode) throws Exception {
MockResponse pleaseAuthenticate = new MockResponse().setResponseCode(401).addHeader("WWW-Authenticate: Basic realm=\"protected area\"").setBody("Please authenticate.");
server.enqueue(pleaseAuthenticate);
server.play();
Authenticator.setDefault(new SimpleAuthenticator());
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
connection.setDoOutput(true);
byte[] requestBody = { 'A', 'B', 'C', 'D' };
if (streamingMode == StreamingMode.FIXED_LENGTH) {
connection.setFixedLengthStreamingMode(requestBody.length);
} else if (streamingMode == StreamingMode.CHUNKED) {
connection.setChunkedStreamingMode(0);
}
OutputStream outputStream = connection.getOutputStream();
outputStream.write(requestBody);
outputStream.close();
try {
connection.getInputStream();
fail();
} catch (HttpRetryException expected) {
}
// no authorization header for the request...
RecordedRequest request = server.takeRequest();
assertContainsNoneMatching(request.getHeaders(), "Authorization: Basic .*");
assertEquals(Arrays.toString(requestBody), Arrays.toString(request.getBody()));
}
use of java.net.HttpRetryException in project XobotOS by xamarin.
the class HttpURLConnectionImpl method getResponse.
/**
* Aggressively tries to get the final HTTP response, potentially making
* many HTTP requests in the process in order to cope with redirects and
* authentication.
*/
private HttpEngine getResponse() throws IOException {
initHttpEngine();
if (httpEngine.hasResponse()) {
return httpEngine;
}
try {
while (true) {
httpEngine.sendRequest();
httpEngine.readResponse();
Retry retry = processResponseHeaders();
if (retry == Retry.NONE) {
httpEngine.automaticallyReleaseConnectionToPool();
break;
}
/*
* The first request was insufficient. Prepare for another...
*/
String retryMethod = method;
OutputStream requestBody = httpEngine.getRequestBody();
/*
* Although RFC 2616 10.3.2 specifies that a HTTP_MOVED_PERM
* redirect should keep the same method, Chrome, Firefox and the
* RI all issue GETs when following any redirect.
*/
int responseCode = getResponseCode();
if (responseCode == HTTP_MULT_CHOICE || responseCode == HTTP_MOVED_PERM || responseCode == HTTP_MOVED_TEMP || responseCode == HTTP_SEE_OTHER) {
retryMethod = HttpEngine.GET;
requestBody = null;
}
if (requestBody != null && !(requestBody instanceof RetryableOutputStream)) {
throw new HttpRetryException("Cannot retry streamed HTTP body", httpEngine.getResponseCode());
}
if (retry == Retry.DIFFERENT_CONNECTION) {
httpEngine.automaticallyReleaseConnectionToPool();
}
httpEngine.release(true);
httpEngine = newHttpEngine(retryMethod, rawRequestHeaders, httpEngine.getConnection(), (RetryableOutputStream) requestBody);
}
return httpEngine;
} catch (IOException e) {
httpEngineFailure = e;
throw e;
}
}
Aggregations