问题
I have tomcat connector in it's server.xml config file that should redirect all http traffic to https:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
<Connector SSLEnabled="true" clientAuth="false" keystoreFile="path/to/keystore/ks.jks" keystorePass="changeit" maxThreads="150" port="8443" protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS"/>
If a request is sent to non-secure port 8080, response will have status code 302. Which is fine for GET requests, but not for POST requests. Why? Because those requests are made via RestTemplate
with LaxRedirectStrategy
which in case of 302 transforms POST to GET, which causes exception "GET not supported...". One solution could be to extend LaxRedirectStrategy
and override getRedirect()
method like so:
LaxRedirectStrategy:
@Override
public HttpUriRequest getRedirect(final HttpRequest request,
final HttpResponse response,final HttpContext context)
throws ProtocolException {
final URI uri = getLocationURI(request, response, context);
final String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
return new HttpHead(uri);
} else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
return new HttpGet(uri);
} else {
final int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_TEMPORARY_REDIRECT) {
return RequestBuilder.copy(request).setUri(uri).build();
} else {
return new HttpGet(uri);
}
}
}
and my own implementation (extension):
ReLaxRedirectStrategy:
@Override
public HttpUriRequest getRedirect(final HttpRequest request,
final HttpResponse response,final HttpContext context)
throws ProtocolException {
final URI uri = getLocationURI(request, response, context);
final String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
return new HttpHead(uri);
} else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
return new HttpGet(uri);
} else {
final int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_TEMPORARY_REDIRECT
|| status == HttpStatus.SC_MOVED_TEMPORARILY) { // HERE IS THE DIFFERENCE
return RequestBuilder.copy(request).setUri(uri).build();
} else {
return new HttpGet(uri);
}
}
}
I was wondering if there's a way to make tomcat return 307 instead of 302 to avoid code overriding and possible errors in case Apache's httpcomponents get updated in the future.
EDIT #1 I'll probably end up with version 2 of ReLaxRedirectStrategy
if I don't find a better solution:
ReLaxRedirectStrategyV2:
@Override
public HttpUriRequest getRedirect(final HttpRequest request,
final HttpResponse response,final HttpContext context)
throws ProtocolException {
final String method = request.getRequestLine().getMethod();
final int status = response.getStatusLine().getStatusCode();
if (method.equalsIgnoreCase(HttpPost.METHOD_NAME)
&& status == HttpStatus.SC_MOVED_TEMPORARILY) {
final URI uri = getLocationURI(request, response, context);
return RequestBuilder.copy(request).setUri(uri).build();
} else {
return super.getRedirect(request, response, context);
}
}
This way overridden code is minimal. If response to POST request has status 302, code will do what I want, else it will do whatever is defined in superclass.
来源:https://stackoverflow.com/questions/33754664/is-it-possible-for-tomcat-to-return-status-code-307-temporary-redirect-instead