为什么在 hyper 中匹配请求路径后没有任何反应?

Why does nothing happen after matching on a request's path in hyper?

我正在尝试使用 hyper 0.11.2 阅读已发布的 JSON。打印 "Reached" 后我没有看到任何事情发生。

fn call(&self, req: hyper::server::Request) -> Self::Future {
    let mut response: Response = Response::new();

    match (req.method(), req.path()) {
        (&Method::Post, "/assests") => {
             println!("Reached ... "); //POST: 200 OK
            //let (method, uri, _version, head 
            let mut res: Response = Response::new();
            if let Some(len) = req.headers().get::<ContentLength>() {
                res.headers_mut().set(len.clone());
            }

            println!("Reached xxx {:?}", req.body());
            res.with_body("req.body()");
        }
        _ => {
            response.set_status(StatusCode::NotFound);
        }
    };

    futures::future::ok(response)
}

输出:

Reached ...
Reached xxx Body(Body { [stream of values] })

您创建了一个名为 response 的新 Response,然后创建了一个名为 res 的第二个 Response。然后您修改 res 然后将其丢弃,从您的函数中 returning response 。如果您 return 您修改的内容,您的服务器 return 就是 字符串 "req.body()",正如您指定的那样。

fn call(&self, req: hyper::server::Request) -> Self::Future {
    let mut response: Response = Response::new();

    match (req.method(), req.path()) {
        (&Method::Post, "/assets") => {
            if let Some(len) = req.headers().get::<ContentLength>() {
                response.headers_mut().set(len.clone());
            }

            response = response.with_body("req.body()");
        }
        _ => {
            response.set_status(StatusCode::NotFound);
        }
    };

    futures::future::ok(response)
}

不会 将内容长度设置为无效值 — 您的 returned 字符串与上传数据的长度不匹配。

Below code works, able to parse JSON on POST


#[deny(warnings)]

use hyper::{Post, StatusCode};
use hyper::header::ContentLength;
use hyper::server::{Http, Service, Request, Response};
use futures::{future, Future, Stream}; 
use futures;
use hyper;
use serde_json;
use std::io;
use std::error::Error;


pub struct Persistence;

const SERVICE: &'static str = "Persistence Service";
const SUCCESS: &'static str = r#"{"status": "success"}"#;

impl Service for Persistence {
      type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = futures::BoxFuture<Response, hyper::Error>;

    fn call(&self, req: Request) -> Self::Future {
        let (method, uri, _version, headers, body) = req.deconstruct();
        match (method, uri.path()) {
            (Post, "/assests") => {
                let mut res = Response::new();
                let vec;
                if let Some(len) = headers.get::<ContentLength>() {
                    vec = Vec::with_capacity(**len as usize);
                    res.headers_mut().set(len.clone());
                } else {
                    vec = vec![];
                }
                body.fold(vec, |mut acc, chunk| {
                    acc.extend_from_slice(chunk.as_ref());
                    Ok::<_, hyper::Error>(acc)
                }).and_then(move |value| {
                     use serde_json;

                        let v: serde_json::Value = serde_json::from_slice(&value).map_err(|e| {
                            io::Error::new(
                                io::ErrorKind::Other,
                                e
                            )
                        })?;  
                    println!("value..... {:?}", &v);
                    Ok(res.with_body(SUCCESS))

                }).boxed()
            },
            _ => future::ok(Response::new().with_status(StatusCode::NotFound)).boxed()
        }
    }

}

非常感谢@Shepmaster :) hip hip hurray!!

根据https://hyper.rs/guides/server/handle_post/#handling-json-and-other-data-types

这是代码:

extern crate futures;
extern crate hyper;
extern crate serde_json;

use futures::Future;
use futures::{Stream};

use hyper::{Get, Post, StatusCode};
use hyper::header::{ContentLength};
use hyper::server::{Http, Service, Request, Response};

static INDEX: &'static [u8] = b"Try POST /echo";

struct Echo;

impl Service for Echo {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;

    fn call(&self, req: Request) -> Self::Future {
        match (req.method(), req.path()) {
            (&Get, "/") | (&Get, "/echo") => {
                Box::new(futures::future::ok(
                    Response::new()
                        .with_header(ContentLength(INDEX.len() as u64))
                        .with_body(INDEX)))
            },
            (&Post, "/echo") => {
        Box::new(req.body().concat2().map(|b| {
                    let bad_request: &[u8] = b"Missing field";
                    let json: serde_json::Value =
                        if let Ok(j) = serde_json::from_slice(b.as_ref()) {
                        j
                        } else {
                            return Response::new()
                                .with_status(StatusCode::BadRequest)
                                .with_header(ContentLength(bad_request.len() as u64))
                                .with_body(bad_request);
                    };

                    // use json as you like

                    let body = serde_json::to_string(&json).unwrap();
                    Response::new()
                        .with_header(ContentLength(body.len() as u64))
                        .with_body(body)
                }))
            },
            _ => {
                Box::new(futures::future::ok(
                    Response::new().with_status(StatusCode::NotFound)))
            }
        }
    }
}


fn main() {
    let addr = "127.0.0.1:1337".parse().unwrap();

    let server = Http::new().bind(&addr, || Ok(Echo)).unwrap();
    println!("Listening on http://{} with 1 thread.", server.local_addr().unwrap());
    server.run().unwrap();
}