diff --git a/examples/web_api.rs b/examples/web_api.rs index 35e98ba4..af2a6309 100644 --- a/examples/web_api.rs +++ b/examples/web_api.rs @@ -10,80 +10,88 @@ use hyper::{Body, Chunk, Client, Method, Request, Response, Server, StatusCode, use hyper::client::HttpConnector; use hyper::service::service_fn; -#[allow(unused, deprecated)] -use std::ascii::AsciiExt; - static NOTFOUND: &[u8] = b"Not Found"; -static URL: &str = "http://127.0.0.1:1337/web_api"; +static URL: &str = "http://127.0.0.1:1337/json_api"; static INDEX: &[u8] = b"test.html"; -static LOWERCASE: &[u8] = b"i am a lower case string"; +static POST_DATA: &str = r#"{"original": "data"}"#; -fn response_examples(req: Request, client: &Client) - -> Box, Error=hyper::Error> + Send> -{ +type GenericError = Box; +type ResponseFuture = Box, Error=GenericError> + Send>; + +fn client_request_response(client: &Client) -> ResponseFuture { + let req = Request::builder() + .method(Method::POST) + .uri(URL) + .header(header::CONTENT_TYPE, "application/json") + .body(POST_DATA.into()) + .unwrap(); + + Box::new(client.request(req).from_err().map(|web_res| { + // Compare the JSON we sent (before) with what we received (after): + let body = Body::wrap_stream(web_res.into_body().map(|b| { + Chunk::from(format!("POST request body: {}
Response: {}", + POST_DATA, + std::str::from_utf8(&b).unwrap())) + })); + + Response::new(body) + })) +} + +fn api_post_response(req: Request) -> ResponseFuture { + // A web api to run against + Box::new(req.into_body() + .concat2() // Concatenate all chunks in the body + .from_err() + .and_then(|entire_body| { + // TODO: Replace all unwraps with proper error handling + let str = String::from_utf8(entire_body.to_vec())?; + let mut data : serde_json::Value = serde_json::from_str(&str)?; + data["test"] = serde_json::Value::from("test_value"); + let json = serde_json::to_string(&data)?; + let response = Response::builder() + .status(StatusCode::OK) + .header(header::CONTENT_TYPE, "application/json") + .body(Body::from(json))?; + Ok(response) + }) + ) +} + +fn api_get_response() -> ResponseFuture { + let data = vec!["foo", "bar"]; + let res = match serde_json::to_string(&data) { + Ok(json) => { + Response::builder() + .header(header::CONTENT_TYPE, "application/json") + .body(Body::from(json)) + .unwrap() + } + Err(_) => { + Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from("Internal Server Error")) + .unwrap() + } + }; + + Box::new(future::ok(res)) +} + +fn response_examples(req: Request, client: &Client) -> ResponseFuture { match (req.method(), req.uri().path()) { (&Method::GET, "/") | (&Method::GET, "/index.html") => { let body = Body::from(INDEX); Box::new(future::ok(Response::new(body))) }, (&Method::GET, "/test.html") => { - // Run a web query against the web api below - - // build the request - let req = Request::builder() - .method(Method::POST) - .uri(URL) - .body(LOWERCASE.into()) - .unwrap(); - // use the request with client - let web_res_future = client.request(req); - - Box::new(web_res_future.map(|web_res| { - // return the response that came from the web api and the original text together - // to show the difference - let body = Body::wrap_stream(web_res.into_body().map(|b| { - Chunk::from(format!("before: {}
after: {}", - std::str::from_utf8(LOWERCASE).unwrap(), - std::str::from_utf8(&b).unwrap())) - })); - - Response::new(body) - })) + client_request_response(client) }, - (&Method::POST, "/web_api") => { - // A web api to run against. Uppercases the body and returns it back. - let body = Body::wrap_stream(req.into_body().map(|chunk| { - // uppercase the letters - let upper = chunk.iter().map(|byte| byte.to_ascii_uppercase()) - .collect::>(); - Chunk::from(upper) - })); - Box::new(future::ok(Response::new(body))) + (&Method::POST, "/json_api") => { + api_post_response(req) }, - (&Method::GET, "/json") => { - let data = vec!["foo", "bar"]; - let res = match serde_json::to_string(&data) { - Ok(json) => { - // return a json response - Response::builder() - .header(header::CONTENT_TYPE, "application/json") - .body(Body::from(json)) - .unwrap() - } - // This is unnecessary here because we know - // this can't fail. But if we were serializing json that came from another - // source we could handle an error like this. - Err(e) => { - eprintln!("serializing json: {}", e); - - Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from("Internal Server Error")) - .unwrap() - } - }; - - Box::new(future::ok(res)) + (&Method::GET, "/json_api") => { + api_get_response() } _ => { // Return 404 not found response. @@ -122,4 +130,3 @@ fn main() { server })); } -