如何正确处理Hyper中的多个Set-Cookie标头?

时间:2016-12-24 09:47:30

标签: http-headers rust hyper

我正在使用Hyper发送HTTP请求,但是当响应中包含多个cookie时,Hyper会将它们组合成一个然后无法解析过程的cookie。

例如,这是一个简单的PHP脚本

<?php

setcookie("hello", "world");
setcookie("foo", "bar");

使用curl的响应:

$ curl -sLD - http://local.example.com/test.php
HTTP/1.1 200 OK
Date: Sat, 24 Dec 2016 09:24:04 GMT
Server: Apache/2.4.25 (Unix) PHP/7.0.14
X-Powered-By: PHP/7.0.14
Set-Cookie: hello=world
Set-Cookie: foo=bar
Content-Length: 0
Content-Type: text/html; charset=UTF-8

但是对于以下Rust代码:

let client = Client::new();
let response = client.get("http://local.example.com/test.php")
    .send()
    .unwrap();
println!("{:?}", response);
for header in response.headers.iter() {
    println!("{}: {}", header.name(), header.value_string());
}

...输出将是:

Response { status: Ok, headers: Headers { Date: Sat, 24 Dec 2016 09:31:54 GMT, Server: Apache/2.4.25 (Unix) PHP/7.0.14, X-Powered-By: PHP/7.0.14, Set-Cookie: hello=worldfoo=bar, Content-Length: 0, Content-Type: text/html; charset=UTF-8, }, version: Http11, url: "http://local.example.com/test.php", status_raw: RawStatus(200, "OK"), message: Http11Message { is_proxied: false, method: None, stream: Wrapper { obj: Some(Reading(SizedReader(remaining=0))) } } }
Date: Sat, 24 Dec 2016 09:31:54 GMT
Server: Apache/2.4.25 (Unix) PHP/7.0.14
X-Powered-By: PHP/7.0.14
Set-Cookie: hello=worldfoo=bar
Content-Length: 0
Content-Type: text/html; charset=UTF-8

这对我来说似乎很奇怪。我使用Wireshark捕获响应,其中有两个 Set-Cookie标头。我还检查了Hyper文档,但没有得到任何线索......

我注意到Hyper内部使用VecMap<HeaderName, Item>来存储标头。那么他们将它们连接成一个?然后,我应该如何将它们分成单独的饼干?

1 个答案:

答案 0 :(得分:2)

我认为Hyper更喜欢将Cookie保存在一起,以便更轻松地使用它们,例如使用CookieJar检查加密签名(参见this implementation outline)。

另一个原因可能是保持API简单。 Hyper中的标头按类型编制索引,您只能使用Headers::get获取该类型的单个实例。

在Hyper中,您通常使用相应的类型访问标头。在这种情况下,类型为SetCookie。例如:

if let Some (&SetCookie (ref cookies)) = response.headers.get() {
    for cookie in cookies.iter() {
        println! ("Got a cookie. Name: {}. Value: {}.", cookie.name, cookie.value);
    }
}

访问Set-Cookie的原始标头值没有多大意义,因为这样你就必须重新实现对引号和cookie属性的正确解析(参见RFC 6265, 4.1)。

P.S。请注意,在Hyper 10中,cookie不再被解析,because用于解析的crate会触发openssl依赖地狱。