在 HTTPClient 中重定向时覆盖的标头值 [英] Header values overwritten on redirect in HTTPClient
问题描述
我正在使用 httpclient 4.2.5 来发出必须处理重定向的 http 请求.这是一个理解上下文的小例子:
I'm using httpclient 4.2.5 to make http requests which have to handle redirects as well. Here is a little example to understand the context:
- A 向 B 发送 http 请求(使用 httpclient 4.2.5)
- B 将 302 重定向(包含到 C 的 url)发送回 A
- A 跟随重定向到 C
- C 检索请求 URL 并对其进行一些处理
如果 C 通过 request.getRequestURL()
(HttpServlet API) 解析请求 URL,它包含例如步骤1中的原始请求的主机和端口,这是错误的.
If C parses the request URL by request.getRequestURL()
(HttpServlet API) it contains e.g. host and port of the original request from step 1, which is wrong.
问题存在于第 2 步,httpclient 处理重定向.它只是将原始请求(步骤 1)中的所有标头复制到当前请求(步骤 3).我已经通过 grepcode 查看了负责代码:
DefaultRequestDirector
The problem exists in step 2, where httpclient handles the redirect. It just copies all headers from the original request (step 1) to the current request (step 3). I already had a look at the responsible code, via grepcode:
DefaultRequestDirector
HttpUriRequest redirect = redirectStrategy.getRedirect(request, response, context);
HttpRequest orig = request.getOriginal();
redirect.setHeaders(orig.getAllHeaders());
我真的不明白为什么原始请求的所有标头都被复制到当前请求中.
例如.使用 cURL 进行简单测试是按预期进行的,C 将收到正确的主机和端口.
I don't really understand why all headers of the original request are copied to the current request.
E.g. using cURL for a simple test is doing it as expected, C would receive the correct host and port.
实施我自己的重定向策略无济于事,因为原始标头是在它之后复制的.
Implementing my own redirect strategy does not help because the original headers are copied after it.
推荐答案
我在尝试使用 HttpClient
从 bitbucket 的下载部分下载文件时遇到了同样的问题.在第一个请求之后,bitbucket 将重定向发送到 CDN,然后它会抱怨是否设置了 Authorization
标头.
I had the same problem when trying to download files from bitbucket's download section using HttpClient
. After the first request bitbucket sends a redirect to CDN which then complains if the Authorization
header is set.
我通过更改 DefaultRedirectStrategy.getRedirect()
方法以返回不允许设置 Authorization
标头的重定向对象来解决这个问题.
I worked around it by changing DefaultRedirectStrategy.getRedirect()
method to return redirect object which does not allow Authorization
headers to be set.
我使用 Scala,所以代码如下:
I work with Scala so here is the code:
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"))
}
}
}
}
})
这篇关于在 HTTPClient 中重定向时覆盖的标头值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!