【问题标题】:How to correctly handle multiple Set-Cookie headers in Hyper?如何正确处理 Hyper 中的多个 Set-Cookie 标头?
【发布时间】:2017-01-17 07:27:18
【问题描述】:

我正在使用 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&lt;HeaderName, Item&gt; 来存储标头。所以他们将它们连接到一个?那么之后我应该如何将它们分成单独的cookie呢?

【问题讨论】:

    标签: http-headers rust hyper


    【解决方案1】:

    我认为 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)。


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

    【讨论】:

    • 酷,这真的很有帮助,谢谢。我认为hyper 可能更喜欢将一个标头字段中的 cookie 与分号拆分... (hyper.rs/hyper/async/hyper/header/struct.Cookie.html)
    • 不客气!是的,在库的服务器端实现代码重用听起来像是将 cookie 放在一起的另一个好理由。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2018-09-16
    • 1970-01-01
    • 2019-11-29
    • 2019-11-12
    相关资源
    最近更新 更多