域转发后跟随302重定向时,后续get请求返回原域,造成循环

When following 302 redirect after domain forward, subsequent get requested back to original domain, causing a loop

第一个请求 http://example.com

GET / HTTP/1.1
Host: example.com
Connection: close
User-Agent: Paw/2.3.3 (Macintosh; OS X/10.11.4) GCDHTTPRequest

此时,DNS 通过 302 将请求转发给 https://www.example.com。 (注意协议更改)

HTTP/1.1 302 Found
Location: https://www.example.com

此时 Paw 发出以下请求(此时是 https):

GET / HTTP/1.1
Host: www.example.com

并得到这样的回应:

HTTP/1.1 302 Found
Server: Cowboy
Connection: close
X-Powered-By: Express
X-Frame-Options: SAMEORIGIN
Location: /verify-age

这里是事情变得有趣的地方。没有主机名信息的位置实际上会向 原始 主机名和协议发出下一个请求!! (现在返回到此请求的 http?!):

GET /verify-age HTTP/1.1
Host: example.com

它被 DNS 服务器拦截,当然响应 302:

HTTP/1.1 302 Found
Location: https://www.example.com

回到正确的协议和 url,当然循环回到 302 重定向到 /verify-age,它切换回原来的协议和主机名!我们陷入了这个循环。奇怪的是 Chrome 不遵循这个循环,但 Paw 遵循。那么谁在这里不好呢?域名系统?爪子?节点? Chrome?

这很有趣。而RFC2616 required that that Location header field value consists of a single absolute URI (Location = "Location" ":" absoluteURI), this was modified in RFC7231 which relaxed the original constraint, allowing the use of relative URLs (Location = URI-reference), reffering to RFC3986用于位置值计算。

在 RFC3986 的第 5.1 节中明确指出:

Note that if the retrieval was the result of a redirected request, the last URI used (i.e., the URI that resulted in the actual retrieval of the representation) is the base URI.

所以我的猜测是,向原始主机名发出下一个请求的浏览器在这里是错误的。

更新: 此错误已在 Paw 2.3.4

中修复

我确认这是 Paw 的一个错误,我已经能够自己重现它。我们将在 10 天内发布的 Paw 的下一个错误修复版本中修复此问题。感谢您报告此事,对于给您带来的不便,我们深表歉意。