为什么在 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();
}
我正在尝试使用 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();
}