下面列出了java.net.HttpURLConnection#HTTP_MULT_CHOICE 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Returns true if this response can be stored to later serve another
* request.
*/
public boolean isCacheable(RequestHeaders request) {
// Always go to network for uncacheable response codes (RFC 2616, 13.4),
// This implementation doesn't support caching partial content.
int responseCode = headers.getResponseCode();
if (responseCode != HttpURLConnection.HTTP_OK
&& responseCode != HttpURLConnection.HTTP_NOT_AUTHORITATIVE
&& responseCode != HttpURLConnection.HTTP_MULT_CHOICE
&& responseCode != HttpURLConnection.HTTP_MOVED_PERM
&& responseCode != HttpURLConnection.HTTP_GONE) {
return false;
}
// Responses to authorized requests aren't cacheable unless they include
// a 'public', 'must-revalidate' or 's-maxage' directive.
if (request.hasAuthorization() && !isPublic && !mustRevalidate && sMaxAgeSeconds == -1) {
return false;
}
if (noStore) {
return false;
}
return true;
}
/**
* Returns true if this response can be stored to later serve another
* request.
*/
public boolean isCacheable(RequestHeaders request) {
// Always go to network for uncacheable response codes (RFC 2616, 13.4),
// This implementation doesn't support caching partial content.
int responseCode = headers.getResponseCode();
if (responseCode != HttpURLConnection.HTTP_OK && responseCode != HttpURLConnection.HTTP_NOT_AUTHORITATIVE && responseCode != HttpURLConnection.HTTP_MULT_CHOICE && responseCode != HttpURLConnection.HTTP_MOVED_PERM && responseCode != HttpURLConnection.HTTP_GONE) {
return false;
}
// Responses to authorized requests aren't cacheable unless they include
// a 'public', 'must-revalidate' or 's-maxage' directive.
if (request.hasAuthorization() && !isPublic && !mustRevalidate && sMaxAgeSeconds == -1) {
return false;
}
if (noStore) {
return false;
}
return true;
}
/**
* Returns true if this response can be stored to later serve another
* request.
*/
public boolean isCacheable(RequestHeaders request) {
// Always go to network for uncacheable response codes (RFC 2616, 13.4),
// This implementation doesn't support caching partial content.
int responseCode = headers.getResponseCode();
if (responseCode != HttpURLConnection.HTTP_OK
&& responseCode != HttpURLConnection.HTTP_NOT_AUTHORITATIVE
&& responseCode != HttpURLConnection.HTTP_MULT_CHOICE
&& responseCode != HttpURLConnection.HTTP_MOVED_PERM
&& responseCode != HttpURLConnection.HTTP_GONE) {
return false;
}
// Responses to authorized requests aren't cacheable unless they include
// a 'public', 'must-revalidate' or 's-maxage' directive.
if (request.hasAuthorization() && !isPublic && !mustRevalidate && sMaxAgeSeconds == -1) {
return false;
}
if (noStore) {
return false;
}
return true;
}
public static URI unredirect(URI uri) throws IOException {
if (!REDIRECTOR_DOMAINS.contains(uri.getHost())) {
return uri;
}
URL url = uri.toURL();
HttpURLConnection connection = safelyOpenConnection(url);
connection.setInstanceFollowRedirects(false);
connection.setDoInput(false);
connection.setRequestMethod("HEAD");
connection.setRequestProperty("User-Agent", "ZXing (Android)");
try {
int responseCode = safelyConnect(connection);
switch (responseCode) {
case HttpURLConnection.HTTP_MULT_CHOICE:
case HttpURLConnection.HTTP_MOVED_PERM:
case HttpURLConnection.HTTP_MOVED_TEMP:
case HttpURLConnection.HTTP_SEE_OTHER:
case 307: // No constant for 307 Temporary Redirect ?
String location = connection.getHeaderField("Location");
if (location != null) {
try {
return new URI(location);
} catch (URISyntaxException e) {
// nevermind
}
}
}
return uri;
} finally {
connection.disconnect();
}
}
public static URI unredirect(URI uri) throws IOException {
if (!REDIRECTOR_DOMAINS.contains(uri.getHost())) {
return uri;
}
URL url = uri.toURL();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setInstanceFollowRedirects(false);
connection.setDoInput(false);
connection.setRequestMethod("HEAD");
connection.setRequestProperty("User-Agent", "ZXing (Android)");
try {
connection.connect();
switch (connection.getResponseCode()) {
case HttpURLConnection.HTTP_MULT_CHOICE:
case HttpURLConnection.HTTP_MOVED_PERM:
case HttpURLConnection.HTTP_MOVED_TEMP:
case HttpURLConnection.HTTP_SEE_OTHER:
case 307: // No constant for 307 Temporary Redirect ?
String location = connection.getHeaderField("Location");
if (location != null) {
try {
return new URI(location);
} catch (URISyntaxException e) {
// nevermind
}
}
}
return uri;
} finally {
connection.disconnect();
}
}
private static boolean isRedirection(int code) {
return code == HttpURLConnection.HTTP_MOVED_PERM
|| code == HttpURLConnection.HTTP_MOVED_TEMP
|| code == HttpURLConnection.HTTP_SEE_OTHER
|| code == HttpURLConnection.HTTP_MULT_CHOICE
|| code == Constants.HTTP_TEMPORARY_REDIRECT
|| code == Constants.HTTP_PERMANENT_REDIRECT;
}
public static URI unredirect(URI uri) throws IOException {
if (!REDIRECTOR_DOMAINS.contains(uri.getHost())) {
return uri;
}
URL url = uri.toURL();
HttpURLConnection connection = safelyOpenConnection(url);
connection.setInstanceFollowRedirects(false);
connection.setDoInput(false);
connection.setRequestMethod("HEAD");
connection.setRequestProperty("User-Agent", "ZXing (Android)");
try {
int responseCode = safelyConnect(connection);
switch (responseCode) {
case HttpURLConnection.HTTP_MULT_CHOICE:
case HttpURLConnection.HTTP_MOVED_PERM:
case HttpURLConnection.HTTP_MOVED_TEMP:
case HttpURLConnection.HTTP_SEE_OTHER:
case 307: // No constant for 307 Temporary Redirect ?
String location = connection.getHeaderField("Location");
if (location != null) {
try {
return new URI(location);
} catch (URISyntaxException e) {
// nevermind
}
}
}
return uri;
} finally {
connection.disconnect();
}
}
private static boolean isHttpRedirect(int responseCode) {
switch (responseCode) {
case HttpURLConnection.HTTP_MULT_CHOICE:
case HttpURLConnection.HTTP_MOVED_PERM:
case HttpURLConnection.HTTP_MOVED_TEMP:
case HttpURLConnection.HTTP_SEE_OTHER:
case HTTP_TEMPORARY_REDIRECT:
case HTTP_PERMANENT_REDIRECT:
return true;
default:
return false;
}
}
public static URI unredirect(URI uri) throws IOException {
if (!REDIRECTOR_DOMAINS.contains(uri.getHost())) {
return uri;
}
URL url = uri.toURL();
HttpURLConnection connection = safelyOpenConnection(url);
connection.setInstanceFollowRedirects(false);
connection.setDoInput(false);
connection.setRequestMethod("HEAD");
connection.setRequestProperty("User-Agent", "ZXing (Android)");
try {
int responseCode = safelyConnect(connection);
switch (responseCode) {
case HttpURLConnection.HTTP_MULT_CHOICE:
case HttpURLConnection.HTTP_MOVED_PERM:
case HttpURLConnection.HTTP_MOVED_TEMP:
case HttpURLConnection.HTTP_SEE_OTHER:
case 307: // No constant for 307 Temporary Redirect ?
String location = connection.getHeaderField("Location");
if (location != null) {
try {
return new URI(location);
} catch (URISyntaxException e) {
// nevermind
}
}
}
return uri;
} finally {
connection.disconnect();
}
}
public static URI unredirect(URI uri) throws IOException {
if (!REDIRECTOR_DOMAINS.contains(uri.getHost())) {
return uri;
}
URL url = uri.toURL();
HttpURLConnection connection = safelyOpenConnection(url);
connection.setInstanceFollowRedirects(false);
connection.setDoInput(false);
connection.setRequestMethod("HEAD");
connection.setRequestProperty("User-Agent", "ZXing (Android)");
try {
int responseCode = safelyConnect(connection);
switch (responseCode) {
case HttpURLConnection.HTTP_MULT_CHOICE:
case HttpURLConnection.HTTP_MOVED_PERM:
case HttpURLConnection.HTTP_MOVED_TEMP:
case HttpURLConnection.HTTP_SEE_OTHER:
case 307: // No constant for 307 Temporary Redirect ?
String location = connection.getHeaderField("Location");
if (location != null) {
try {
return new URI(location);
} catch (URISyntaxException e) {
// nevermind
}
}
}
return uri;
} finally {
connection.disconnect();
}
}
protected <T> void responseHandler(AsyncResult<HttpResponse<T>> ar, CompletableFuture<T> promise, Predicate<Integer> expectedCodePredicate,
String expectedCodeOrCodes, String warnMessage, boolean throwException) {
try {
if (ar.succeeded()) {
HttpResponse<T> response = ar.result();
T body = response.body();
if (expectedCodePredicate.negate().test(response.statusCode())) {
log.error("expected-code: {}, response-code: {}, body: {}, op: {}", expectedCodeOrCodes, response.statusCode(), response.body(), warnMessage);
promise.completeExceptionally(new RuntimeException("Status " + response.statusCode() + " body: " + (body != null ? body.toString() : null)));
} else if (response.statusCode() < HTTP_OK || response.statusCode() >= HttpURLConnection.HTTP_MULT_CHOICE) {
if (throwException) {
promise.completeExceptionally(new RuntimeException(body == null ? "null" : body.toString()));
} else {
promise.complete(ar.result().body());
}
} else {
promise.complete(ar.result().body());
}
} else {
log.warn("Request failed: {}", warnMessage, ar.cause());
promise.completeExceptionally(ar.cause());
}
} catch (io.vertx.core.json.DecodeException decEx) {
if (ar.result().bodyAsString().toLowerCase().contains("application is not available")) {
log.warn("'{}' is not available.", apiClientName(), ar.cause());
throw new IllegalStateException(String.format("'%s' is not available.", apiClientName()));
} else {
log.warn("Unexpected object received", ar.cause());
throw new IllegalStateException("JsonObject expected, but following object was received: " + ar.result().bodyAsString());
}
}
}
private static boolean isRedirect(int code) {
return code == HttpURLConnection.HTTP_MOVED_PERM
|| code == HttpURLConnection.HTTP_MOVED_TEMP
|| code == HttpURLConnection.HTTP_SEE_OTHER
|| code == HttpURLConnection.HTTP_MULT_CHOICE
|| code == HTTP_TEMPORARY_REDIRECT
|| code == HTTP_PERMANENT_REDIRECT;
}
public static URI unredirect(URI uri) throws IOException {
if (!REDIRECTOR_DOMAINS.contains(uri.getHost())) {
return uri;
}
URL url = uri.toURL();
HttpURLConnection connection = safelyOpenConnection(url);
connection.setInstanceFollowRedirects(false);
connection.setDoInput(false);
connection.setRequestMethod("HEAD");
connection.setRequestProperty("User-Agent", "ZXing (Android)");
try {
int responseCode = safelyConnect(connection);
switch (responseCode) {
case HttpURLConnection.HTTP_MULT_CHOICE:
case HttpURLConnection.HTTP_MOVED_PERM:
case HttpURLConnection.HTTP_MOVED_TEMP:
case HttpURLConnection.HTTP_SEE_OTHER:
case 307: // No constant for 307 Temporary Redirect ?
String location = connection.getHeaderField("Location");
if (location != null) {
try {
return new URI(location);
} catch (URISyntaxException e) {
// nevermind
}
}
}
return uri;
} finally {
connection.disconnect();
}
}
/**
* Map from HTTP status code to reason description.
* Sentry HTTP breadcrumbs expect a text description of the HTTP status-code.
* This function implements a look-up table with a default value for unknown status-codes.
* @param statusCode an integer HTTP status code, expected to be in the range [200,505].
* @return a non-empty string in all cases.
*/
private static String httpReason(int statusCode) {
switch (statusCode) {
// 2xx
case HttpURLConnection.HTTP_OK: return "OK";
case HttpURLConnection.HTTP_CREATED: return "Created";
case HttpURLConnection.HTTP_ACCEPTED: return "Accepted";
case HttpURLConnection.HTTP_NOT_AUTHORITATIVE: return "Non-Authoritative Information";
case HttpURLConnection.HTTP_NO_CONTENT: return "No Content";
case HttpURLConnection.HTTP_RESET: return "Reset Content";
case HttpURLConnection.HTTP_PARTIAL: return "Partial Content";
// 3xx
case HttpURLConnection.HTTP_MULT_CHOICE: return "Multiple Choices";
case HttpURLConnection.HTTP_MOVED_PERM: return "Moved Permanently";
case HttpURLConnection.HTTP_MOVED_TEMP: return "Temporary Redirect";
case HttpURLConnection.HTTP_SEE_OTHER: return "See Other";
case HttpURLConnection.HTTP_NOT_MODIFIED: return "Not Modified";
case HttpURLConnection.HTTP_USE_PROXY: return "Use Proxy";
// 4xx
case HttpURLConnection.HTTP_BAD_REQUEST: return "Bad Request";
case HttpURLConnection.HTTP_UNAUTHORIZED: return "Unauthorized";
case HttpURLConnection.HTTP_PAYMENT_REQUIRED: return "Payment Required";
case HttpURLConnection.HTTP_FORBIDDEN: return "Forbidden";
case HttpURLConnection.HTTP_NOT_FOUND: return "Not Found";
case HttpURLConnection.HTTP_BAD_METHOD: return "Method Not Allowed";
case HttpURLConnection.HTTP_NOT_ACCEPTABLE: return "Not Acceptable";
case HttpURLConnection.HTTP_PROXY_AUTH: return "Proxy Authentication Required";
case HttpURLConnection.HTTP_CLIENT_TIMEOUT: return "Request Time-Out";
case HttpURLConnection.HTTP_CONFLICT: return "Conflict";
case HttpURLConnection.HTTP_GONE: return "Gone";
case HttpURLConnection.HTTP_LENGTH_REQUIRED: return "Length Required";
case HttpURLConnection.HTTP_PRECON_FAILED: return "Precondition Failed";
case HttpURLConnection.HTTP_ENTITY_TOO_LARGE: return "Request Entity Too Large";
case HttpURLConnection.HTTP_REQ_TOO_LONG: return "Request-URI Too Large";
case HttpURLConnection.HTTP_UNSUPPORTED_TYPE: return "Unsupported Media Type";
// 5xx
case HttpURLConnection.HTTP_INTERNAL_ERROR: return "Internal Server Error";
case HttpURLConnection.HTTP_NOT_IMPLEMENTED: return "Not Implemented";
case HttpURLConnection.HTTP_BAD_GATEWAY: return "Bad Gateway";
case HttpURLConnection.HTTP_UNAVAILABLE: return "Service Unavailable";
case HttpURLConnection.HTTP_GATEWAY_TIMEOUT: return "Gateway Timeout";
case HttpURLConnection.HTTP_VERSION: return "Version Not Supported";
default: return "unknown";
}
}
/**
* Establishes a connection, following redirects to do so where permitted.
*/
private HttpURLConnection makeConnection(DataSpec dataSpec) throws IOException {
URL url = new URL(dataSpec.uri.toString());
@HttpMethod int httpMethod = dataSpec.httpMethod;
byte[] httpBody = dataSpec.httpBody;
long position = dataSpec.position;
long length = dataSpec.length;
boolean allowGzip = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP);
boolean allowIcyMetadata = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_ICY_METADATA);
if (!allowCrossProtocolRedirects) {
// HttpURLConnection disallows cross-protocol redirects, but otherwise performs redirection
// automatically. This is the behavior we want, so use it.
return makeConnection(
url,
httpMethod,
httpBody,
position,
length,
allowGzip,
allowIcyMetadata,
/* followRedirects= */ true);
}
// We need to handle redirects ourselves to allow cross-protocol redirects.
int redirectCount = 0;
while (redirectCount++ <= MAX_REDIRECTS) {
HttpURLConnection connection =
makeConnection(
url,
httpMethod,
httpBody,
position,
length,
allowGzip,
allowIcyMetadata,
/* followRedirects= */ false);
int responseCode = connection.getResponseCode();
String location = connection.getHeaderField("Location");
if ((httpMethod == DataSpec.HTTP_METHOD_GET || httpMethod == DataSpec.HTTP_METHOD_HEAD)
&& (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER
|| responseCode == HTTP_STATUS_TEMPORARY_REDIRECT
|| responseCode == HTTP_STATUS_PERMANENT_REDIRECT)) {
connection.disconnect();
url = handleRedirect(url, location);
} else if (httpMethod == DataSpec.HTTP_METHOD_POST
&& (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER)) {
// POST request follows the redirect and is transformed into a GET request.
connection.disconnect();
httpMethod = DataSpec.HTTP_METHOD_GET;
httpBody = null;
url = handleRedirect(url, location);
} else {
return connection;
}
}
// If we get here we've been redirected more times than are permitted.
throw new NoRouteToHostException("Too many redirects: " + redirectCount);
}
/**
* Establishes a connection, following redirects to do so where permitted.
*/
private HttpURLConnection makeConnection(DataSpec dataSpec) throws IOException {
URL url = new URL(dataSpec.uri.toString());
byte[] postBody = dataSpec.postBody;
long position = dataSpec.position;
long length = dataSpec.length;
boolean allowGzip = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP);
if (!allowCrossProtocolRedirects) {
// HttpURLConnection disallows cross-protocol redirects, but otherwise performs redirection
// automatically. This is the behavior we want, so use it.
return makeConnection(url, postBody, position, length, allowGzip, true /* followRedirects */);
}
// We need to handle redirects ourselves to allow cross-protocol redirects.
int redirectCount = 0;
while (redirectCount++ <= MAX_REDIRECTS) {
HttpURLConnection connection = makeConnection(
url, postBody, position, length, allowGzip, false /* followRedirects */);
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER
|| (postBody == null
&& (responseCode == 307 /* HTTP_TEMP_REDIRECT */
|| responseCode == 308 /* HTTP_PERM_REDIRECT */))) {
// For 300, 301, 302, and 303 POST requests follow the redirect and are transformed into
// GET requests. For 307 and 308 POST requests are not redirected.
postBody = null;
String location = connection.getHeaderField("Location");
connection.disconnect();
url = handleRedirect(url, location);
} else {
return connection;
}
}
// If we get here we've been redirected more times than are permitted.
throw new NoRouteToHostException("Too many redirects: " + redirectCount);
}
/**
* Establishes a connection, following redirects to do so where permitted.
*/
private HttpURLConnection makeConnection(DataSpec dataSpec) throws IOException {
URL url = new URL(dataSpec.uri.toString());
byte[] postBody = dataSpec.postBody;
long position = dataSpec.position;
long length = dataSpec.length;
boolean allowGzip = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP);
if (!allowCrossProtocolRedirects) {
// HttpURLConnection disallows cross-protocol redirects, but otherwise performs redirection
// automatically. This is the behavior we want, so use it.
return makeConnection(url, postBody, position, length, allowGzip, true /* followRedirects */);
}
// We need to handle redirects ourselves to allow cross-protocol redirects.
int redirectCount = 0;
while (redirectCount++ <= MAX_REDIRECTS) {
HttpURLConnection connection = makeConnection(
url, postBody, position, length, allowGzip, false /* followRedirects */);
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER
|| (postBody == null
&& (responseCode == 307 /* HTTP_TEMP_REDIRECT */
|| responseCode == 308 /* HTTP_PERM_REDIRECT */))) {
// For 300, 301, 302, and 303 POST requests follow the redirect and are transformed into
// GET requests. For 307 and 308 POST requests are not redirected.
postBody = null;
String location = connection.getHeaderField("Location");
connection.disconnect();
url = handleRedirect(url, location);
} else {
return connection;
}
}
// If we get here we've been redirected more times than are permitted.
throw new NoRouteToHostException("Too many redirects: " + redirectCount);
}
private static boolean isHttpSuccess(int responseCode) {
return (responseCode >= HttpURLConnection.HTTP_OK
&& responseCode < HttpURLConnection.HTTP_MULT_CHOICE);
}
/**
* Establishes a connection, following redirects to do so where permitted.
*/
private HttpURLConnection makeConnection(DataSpec dataSpec) throws IOException {
URL url = new URL(dataSpec.uri.toString());
@HttpMethod int httpMethod = dataSpec.httpMethod;
byte[] httpBody = dataSpec.httpBody;
long position = dataSpec.position;
long length = dataSpec.length;
boolean allowGzip = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP);
boolean allowIcyMetadata = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_ICY_METADATA);
if (!allowCrossProtocolRedirects) {
// HttpURLConnection disallows cross-protocol redirects, but otherwise performs redirection
// automatically. This is the behavior we want, so use it.
return makeConnection(
url,
httpMethod,
httpBody,
position,
length,
allowGzip,
allowIcyMetadata,
/* followRedirects= */ true);
}
// We need to handle redirects ourselves to allow cross-protocol redirects.
int redirectCount = 0;
while (redirectCount++ <= MAX_REDIRECTS) {
HttpURLConnection connection =
makeConnection(
url,
httpMethod,
httpBody,
position,
length,
allowGzip,
allowIcyMetadata,
/* followRedirects= */ false);
int responseCode = connection.getResponseCode();
String location = connection.getHeaderField("Location");
if ((httpMethod == DataSpec.HTTP_METHOD_GET || httpMethod == DataSpec.HTTP_METHOD_HEAD)
&& (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER
|| responseCode == HTTP_STATUS_TEMPORARY_REDIRECT
|| responseCode == HTTP_STATUS_PERMANENT_REDIRECT)) {
connection.disconnect();
url = handleRedirect(url, location);
} else if (httpMethod == DataSpec.HTTP_METHOD_POST
&& (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER)) {
// POST request follows the redirect and is transformed into a GET request.
connection.disconnect();
httpMethod = DataSpec.HTTP_METHOD_GET;
httpBody = null;
url = handleRedirect(url, location);
} else {
return connection;
}
}
// If we get here we've been redirected more times than are permitted.
throw new NoRouteToHostException("Too many redirects: " + redirectCount);
}
/**
* Establishes a connection, following redirects to do so where permitted.
*/
private HttpURLConnection makeConnection(DataSpec dataSpec) throws IOException {
URL url = new URL(dataSpec.uri.toString());
@HttpMethod int httpMethod = dataSpec.httpMethod;
byte[] httpBody = dataSpec.httpBody;
long position = dataSpec.position;
long length = dataSpec.length;
boolean allowGzip = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP);
if (!allowCrossProtocolRedirects) {
// HttpURLConnection disallows cross-protocol redirects, but otherwise performs redirection
// automatically. This is the behavior we want, so use it.
return makeConnection(
url,
httpMethod,
httpBody,
position,
length,
allowGzip,
/* followRedirects= */ true,
dataSpec.httpRequestHeaders);
}
// We need to handle redirects ourselves to allow cross-protocol redirects.
int redirectCount = 0;
while (redirectCount++ <= MAX_REDIRECTS) {
HttpURLConnection connection =
makeConnection(
url,
httpMethod,
httpBody,
position,
length,
allowGzip,
/* followRedirects= */ false,
dataSpec.httpRequestHeaders);
int responseCode = connection.getResponseCode();
String location = connection.getHeaderField("Location");
if ((httpMethod == DataSpec.HTTP_METHOD_GET || httpMethod == DataSpec.HTTP_METHOD_HEAD)
&& (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER
|| responseCode == HTTP_STATUS_TEMPORARY_REDIRECT
|| responseCode == HTTP_STATUS_PERMANENT_REDIRECT)) {
connection.disconnect();
url = handleRedirect(url, location);
} else if (httpMethod == DataSpec.HTTP_METHOD_POST
&& (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER)) {
// POST request follows the redirect and is transformed into a GET request.
connection.disconnect();
httpMethod = DataSpec.HTTP_METHOD_GET;
httpBody = null;
url = handleRedirect(url, location);
} else {
return connection;
}
}
// If we get here we've been redirected more times than are permitted.
throw new NoRouteToHostException("Too many redirects: " + redirectCount);
}