2016-12-24 1 views
2

Я использую Hyper для отправки HTTP-запросов, но когда в ответ включается несколько файлов cookie, Hyper объединяет их в один, который затем не выполняет процедуру синтаксического анализа.Как правильно обрабатывать несколько заголовков Set-Cookie в Hyper?

Например, вот простой PHP скрипт

<?php 

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

Ответ с помощью завиток:

$ 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> для хранения заголовков. Так они объединяют их в один? Тогда как я могу разделить их на отдельные куки?

ответ

2

Я думаю, что Hyper предпочитает хранить куки вместе, чтобы упростить некоторые дополнительные вещи с ними, например, проверку криптографической подписи с помощью 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 делает меньше смысла, потому что тогда вы будете иметь переописать надлежащий разбор цитат и атрибутов печенья (см RFC 6265, 4.1).


P.S. Обратите внимание, что в Hyper 10 cookie больше не разбирается, because ящик, который использовался для синтаксического анализа, запускает адский аддон openssl.

+0

классный, это действительно полезно, спасибо. Я думаю, что 'hyper' может предпочесть комбинировать файлы cookie в одном поле заголовка с разделителем с запятой ... (http://hyper.rs/hyper/async/hyper/header/struct.Cookie.html) –

+0

Добро пожаловать! Да, при повторном использовании кода с серверной стороны библиотеки звучит как еще одна веская причина для сохранения файлов cookie. – ArtemGr

Смежные вопросы