Можно ли опубликовать файл JSON на маршрутизаторе с помощью Iron framework?

Я использую веб-фреймворк Iron (для языка программирования Rust) в приложении, и у меня есть путь, доступный для данных POST JSON при использовании Корзина маршрутизатора.

Это работает, но я должен процентно кодировать свои данные JSON и добавлять их в виде строки в конец моего HTTP-запроса POST, который работает, но немного утомительно, и я хотел бы в конечном итоге отправить необработанные файлы изображений POST.

Я хотел бы иметь возможность сделать что-то вроде следующей команды curl:

curl -v -i --header "Content-Type: application/json" -X POST -d @some_local_json_file.json http://my_server_ip_address:3000/example_path/post/json_object_here

В настоящее время я получаю сообщение об ошибке HTTP/1.1 404 Not Found:

curl -v -i --header "Content-Type: application/json" -X POST -d @some_local_json_file.json http://my_server_ip_address:3000/example_path/post/json
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying my_server_ip_address...
* Connected to my_server_ip_address (my_server_ip_address) port 3000 (#0)
> POST /example_path/post/json HTTP/1.1
> Host: my_server_ip_address:3000
> User-Agent: curl/7.45.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 2354
> Expect: 100-continue
> 
< HTTP/1.1 100 Continue
HTTP/1.1 100 Continue

* We are completely uploaded and fine
< HTTP/1.1 404 Not Found
HTTP/1.1 404 Not Found
< Date: Mon, 28 Dec 2015 22:44:03 GMT
Date: Mon, 28 Dec 2015 22:44:03 GMT
< Content-Length: 0
Content-Length: 0

< 
* Connection #0 to host my_server_ip_address left intact

Суть моей функции main выглядит так:

fn main() {
    // create the router
    let mut router = Router::new();

    router.post("/example_path/post/:json", post_to_documents);

    let mut mount = Mount::new();

    // mount the router
    mount.mount("/", router);

    Iron::new(mount).http("0.0.0.0:3000").unwrap();
}

И post_to_documents, перечисленное выше, похоже на:

fn post_to_documents(req: &mut Request) -> IronResult<Response>
{
    let document_url_encoded = req.extensions.get::<Router>()
                                             .unwrap()
                                             .find("json")
                                             .unwrap_or("/");
    // Just return Ok
    Ok(Response::with((status::Ok, "Ok")))
}

Я хочу иметь данные JSON в переменной document_url_encoded. (Я предполагаю, что это плохое имя, поскольку в этом случае он не будет закодирован в URL / процентах)


person chups    schedule 28.12.2015    source источник


Ответы (1)


У вас есть непонимание того, как работает HTTP POST, или, по крайней мере, как это работает при раскрытии через Iron и друзей. Запрос POST отправляется в отдельной части запроса из информации об URL/пути, и Iron раскрывает эти два понятия отдельно.

Вы используете Iron Router для сопоставления путей к функциям и извлечения простых параметров из пути. Вам необходимо также использовать железный анализатор тела для извлечения данных из ПОСТ тело. Он автоматически проанализирует JSON для вас, а также предоставит доступ к необработанным двоичным данным.

extern crate iron;
extern crate router;
extern crate mount;
extern crate bodyparser;

use iron::prelude::*;
use iron::status;
use router::Router;
use mount::Mount;

fn post_to_documents(req: &mut Request) -> IronResult<Response> {
    match req.extensions.get::<Router>().and_then(|r| r.find("json")) {
        Some(name) => println!("The name was {:?}", name),
        None => println!("There was no name!"),
    }

    match req.get::<bodyparser::Json>() {
        Ok(Some(json_body)) => println!("Parsed body:\n{:?}", json_body),
        Ok(None) => println!("No body"),
        Err(err) => println!("Error: {:?}", err)
    }

    Ok(Response::with((status::Ok, "Ok")))
}

fn main() {
    let mut router = Router::new();
    router.post("/documents/post/:json", post_to_documents, "new_document");

    let mut mount = Mount::new();
    mount.mount("/", router);

    Iron::new(mount).http("0.0.0.0:3000").unwrap();
}

У меня есть файл с именем input.json:

{"key": "value"}

И я запускаю эту команду:

curl -v -i --header "Content-Type: application/json" -X POST -d @input.json http://127.0.0.1:3000/documents/post/awesome

С этим выводом с сервера:

The name was "awesome"
Parsed body:
Object({"key": String("value")})

Я не могу объяснить, почему вы получаете ошибку 404.

Это было сделано с

  • анализатор тела 0.7.0
  • железо 0.5.1
  • монтировать 0.3.0
  • роутер 0.5.1
person Shepmaster    schedule 28.12.2015
comment
Ах, это имеет смысл. Спасибо! - person chups; 29.12.2015