Okhttp: why not support 307 post REDIRECT

Created on 16 Jan 2017  路  4Comments  路  Source: square/okhttp

  • [ ] Feature Request. Start by telling us what problem you鈥檙e trying to solve. Often a solution
    already exists! Don鈥檛 send pull requests to implement new features without first getting our
    support. Sometimes we leave features out on purpose to keep the project small.

why not support 307 REDIRECT

case HTTP_TEMP_REDIRECT:
// "If the 307 or 308 status code is received in response to a request other than GET
// or HEAD, the user agent MUST NOT automatically redirect the request"
if (!method.equals("GET") && !method.equals("HEAD")) {
return null;
}

Doing so can do
case HTTP_TEMP_REDIRECT:
// Does the client allow redirects?
if (!client.followRedirects()) return null;

    String location = userResponse.header("Location");
    if (location == null) return null;
    HttpUrl url = userRequest.url().resolve(location);

    // Don't follow redirects to unsupported protocols.
    if (url == null) return null;

    // If configured, don't follow redirects between SSL and non-SSL.
    boolean sameScheme = url.scheme().equals(userRequest.url().scheme());
    if (!sameScheme && !client.followSslRedirects()) return null;

    // Redirects don't include a request body.
    Request.Builder requestBuilder = userRequest.newBuilder();
    if (HttpMethod.permitsRequestBody(method)) {
      if (HttpMethod.redirectsToGet(method)) {
        requestBuilder.method("GET", null);
      } else {
        requestBuilder.method(method, null);
      }
      requestBuilder.removeHeader("Transfer-Encoding");
      requestBuilder.removeHeader("Content-Length");
      requestBuilder.removeHeader("Content-Type");
    }

    // When redirecting across hosts, drop all authentication headers. This
    // is potentially annoying to the application layer since they have no
    // way to retain them.
    if (!sameConnection(url)) {
      requestBuilder.removeHeader("Authorization");
    }

    return requestBuilder.url(url).build();
enhancement

Most helpful comment

The current behavior seems at odds with RFC 7231 section 6.4.7:

The 307 (Temporary Redirect) status code indicates that ... the user agent MUST NOT change the request method if it performs an automatic redirection to that URI. The user agent MAY use the Location field value for automatic redirection.

The code in RetryAndFollowUpInterceptor quotes RFC 2616, but that is obsoleted by 7231:
```java
// "If the 307 or 308 status code is received in response to a request other than GET
// or HEAD, the user agent MUST NOT automatically redirect the request"

All 4 comments

The current behavior seems at odds with RFC 7231 section 6.4.7:

The 307 (Temporary Redirect) status code indicates that ... the user agent MUST NOT change the request method if it performs an automatic redirection to that URI. The user agent MAY use the Location field value for automatic redirection.

The code in RetryAndFollowUpInterceptor quotes RFC 2616, but that is obsoleted by 7231:
```java
// "If the 307 or 308 status code is received in response to a request other than GET
// or HEAD, the user agent MUST NOT automatically redirect the request"

This is our current workaround (not great):
```java
try (Response response = client.newCall(request).execute()) {
if ((response.code() == 307) || (response.code() == 308)) {
String location = response.header(LOCATION);
if (location != null) {
request = request.newBuilder().url(location).build();
return execute(codec, client, request);
}
}

return handleResponse(response);

}

Where did you add this workaround @electrum? Thanks!

This is our current workaround (not great):

try (Response response = client.newCall(request).execute()) {
    if ((response.code() == 307) || (response.code() == 308)) {
        String location = response.header(LOCATION);
        if (location != null) {
            request = request.newBuilder().url(location).build();
            return execute(codec, client, request);
        }
    }

    return handleResponse(response);
}

Just wondering whats the essence of setFollowSslRedirects() and setFollowRedirects() which are actually enabled by default but don't seem to work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

albka1986 picture albka1986  路  3Comments

TheLester picture TheLester  路  3Comments

yschimke picture yschimke  路  3Comments

tangjiabing picture tangjiabing  路  3Comments

sargunv picture sargunv  路  3Comments