我正在使用httpclient 4.2.5来制作必须处理重定向的http请求。 以下是了解上下文的一个小例子:
如果C通过request.getRequestURL()
(HttpServlet API)解析请求URL,它包含例如来自步骤1的原始请求的主机和端口,这是错误的。
问题存在于步骤2中,其中httpclient处理重定向。它只是将原始请求(步骤1)中的所有标题复制到当前请求(步骤3)。我已经看过负责任的代码,通过grepcode:
DefaultRequestDirector
HttpUriRequest redirect = redirectStrategy.getRedirect(request, response, context);
HttpRequest orig = request.getOriginal();
redirect.setHeaders(orig.getAllHeaders());
我真的不明白为什么原始请求的所有标题都被复制到当前请求中 例如。使用cURL进行简单测试就是按预期进行,C将接收正确的主机和端口。
实现我自己的重定向策略没有用,因为原始标题会在它之后复制。
答案 0 :(得分:3)
尝试使用HttpClient
从bitbucket的下载部分下载文件时遇到了同样的问题。在第一个请求后,bitbucket向CDN发送重定向,然后在设置Authorization
标头时发出抱怨。
我通过更改DefaultRedirectStrategy.getRedirect()
方法来处理它,以返回不允许设置Authorization
标头的重定向对象。
我使用Scala,所以这里是代码:
val http = new DefaultHttpClient()
http.setRedirectStrategy(new DefaultRedirectStrategy() {
override def getRedirect(
request: HttpRequest, response: HttpResponse, context: HttpContext
): HttpRequestBase = {
val uri: URI = getLocationURI(request, response, context)
val method: String = request.getRequestLine.getMethod
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
new HttpHead(uri) {
override def setHeaders(headers: Array[Header]) {
super.setHeaders(headers.filterNot(_.getName == "Authorization"))
}
}
}
else {
new HttpGet(uri) {
override def setHeaders(headers: Array[Header]) {
super.setHeaders(headers.filterNot(_.getName == "Authorization"))
}
}
}
}
})
答案 1 :(得分:0)
请注意orig.getAllHeaders()
会返回调用者添加到邮件中的明确标题数组。上面发布的DefaultRequestDirector
代码会HttpClient
,Host
,Content-Length
自动生成 not 自动生成的复制请求标头等等。
您发布会话的有线日志,显示问题我可能会告诉您为什么重定向无法按预期工作。