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

3
我将使用Hyper发送HTTP请求,但当响应中包含多个cookie时,Hyper会将它们合并成一个,导致解析程序无法正常运行。例如,以下是一个简单的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>存储标头。所以他们把它们连接在一起了吗?那么我应该如何将它们划分为单独的cookie呢?

1个回答

2
我认为Hyper更喜欢将cookie放在一起,以便更容易地对它们进行一些额外的操作,比如使用CookieJar检查加密签名(请参见此实现概述)。
另一个原因可能是为了保持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)。
附言:请注意,在Hyper 10中不再解析cookie,因为用于解析的crate会触发openssl依赖关系问题。

很棒,这真的很有帮助,谢谢。我认为 hyper 可能更喜欢将 cookie 合并到一个分号分隔的标题字段中... (http://hyper.rs/hyper/async/hyper/header/struct.Cookie.html) - Frederick Zhang
不客气!是的,与库的服务器端实现有关的代码重用是保持Cookie在一起的另一个好理由。 - ArtemGr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接