Передача данных для запроса GET с помощью Hyper

Я работаю над Twitter API для Rust, и у меня возникают проблемы с передачей аргументов в мой запрос GET. Код, который я использую для запроса, приведен ниже. data_body - это что-то вроде screen_name = a_user, а заголовок авторизации - это авторизация OAuth, требуемая Twitter (это не проблема, поскольку он работает со всеми моими другими запросами).

let mut res = client.get("http://httpbin.org/get")
    .body(&data_body[..])
    .header(Authorization(authorization_header))
    .header(ContentType::form_url_encoded())
    .send().unwrap();

Я начал отправлять это на httpbin.org, чтобы увидеть необработанный запрос. То, что я получаю, показано ниже.

{
  "args": {}, 
  "headers": {
    "Authorization": "OAuth oauth_consumer_key=\"\", oauth_nonce=\"RH9vZYMCbAtfQAuVh44fhlyGQfQqBCPq\", oauth_signature=\"dTbOyaURct0auVlC%2B8Y7vDFpus0%3D\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1452648640\", oauth_token=\"\", oauth_version=\"1.0\"", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org"
  }, 
  "origin": "0.0.0.0", 
  "url": "http://httpbin.org/get"
}

Запрос curl, предоставленный документами API Twitter, содержит часть данных для запроса GET ниже (я заменил свои ключи пустыми строками). Я могу подтвердить, что это работает для GET.

curl --get 'https://api.twitter.com/1.1/users/show.json' --data 'screen_name=twitterdev' --header 'Authorization: OAuth oauth_consumer_key="", oauth_nonce="6a37886cb38b2f5e12dee8fd47aa097c", oauth_signature="zhXDA5JbKRmw2xbJcEqK9sxuu5E%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1452647580", oauth_token="", oauth_version="1.0"' --verbose

Я пробовал кучу разных ContentType из Hyper API, но не могу заполнить раздел args HTTP-запроса. Я думаю, что проблема в этом, но у меня нет большого опыта работы с HTTP, поэтому я вполне могу ошибаться. В конечном итоге запрос возвращает 403 (Неавторизованный), который запускается отсутствующими аргументами. Я знаю, что мой заголовок OAuth создается правильно, потому что он работает со всеми запросами POST, и когда я копирую одноразовый номер и метку времени из команды curl, которую я получаю из API Twitter, подпись совпадает.


person hamersaw    schedule 13.01.2016    source источник


Ответы (2)


Как сказал @hamersaw, «параметры GET» являются частью URL-адреса в строке запроса. Если вам нужно установить параметры программно (если они не всегда одинаковы), _ 1_ может позаботиться об экранировании / кодировании за вас:

use hyper::Url;
let mut url = Url::parse("https://api.twitter.com/1.1/users/show.json").unwrap();
url.set_query_from_pairs([
    ("screen_name", "twitterdev"),
].iter().cloned());
let res = client.get(url) // ...
person Simon Sapin    schedule 26.02.2016
comment
В Hyper 0.9 это url.query_pairs_mut().append_pair(key, value) - person joeforker; 30.12.2016

Догадаться. Оказывается, в запросе GET вы должны добавить тело запроса, и он автоматически заполнит пакет. Ниже приведен код, чтобы он заработал.

let mut res = client.get("http://httpbin.org/get?screen_name=twitter")
    .header(Authorization(authorization_header))
    .send().unwrap();
person hamersaw    schedule 13.01.2016
comment
Это не тело запроса, это параметры запроса (часть URL-адреса). - person Markus Unterwaditzer; 14.01.2016