1extern crate bytes;
2#[macro_use]
3extern crate error_chain;
4extern crate futures;
5extern crate hyper;
6#[macro_use]
7extern crate log;
8extern crate serde;
9#[macro_use]
10extern crate serde_derive;
11#[cfg(feature = "fst")]
12extern crate fst;
13extern crate http;
14extern crate serde_json;
15extern crate serde_qs;
16extern crate tokio;
17extern crate tokio_current_thread;
18extern crate tokio_io;
19#[cfg(feature = "uds")]
20extern crate tokio_uds;
21extern crate url;
22
23pub mod error {
24 use super::*;
25
26 error_chain!{
27 foreign_links {
28 Hyper(hyper::Error);
29 Http(http::Error);
30 Io(std::io::Error);
31 }
32
33 errors {
34 UnexpectedMethod(m: hyper::Method) {
35 description("badarg")
36 }
37 InvalidEndpoint {
38 description("invalid_endpoint")
39 }
40 DecodeJson(e: serde_json::Error) {
41 description("badarg")
42 }
43 EncodeJson(e: serde_json::Error) {
44 description("internal")
45 }
46 DecodeQs(e: serde_qs::Error) {
47 description("badarg")
48 }
49 }
50 }
51}
52
53type SyncObj<T> = std::rc::Rc<T>;
54
55pub mod async;
56pub mod reply;
57pub mod server;
58pub mod sync;
59
60pub use error::{Error, ErrorKind};
61pub use server::Server;
62use std::fmt::Debug;
63
64use futures::future::*;
65use futures::*;
66use hyper::header::*;
67use hyper::service::Service;
68use hyper::{Body, Request, Response};
69
70pub fn resp_err() -> Response<Body> {
71 Response::builder()
72 .status(hyper::StatusCode::BAD_REQUEST)
73 .body(Body::empty())
74 .unwrap_or_else(|_| Response::new(Body::empty()))
75}
76
77pub fn resp_serv_err<E>(e: E, status: hyper::StatusCode) -> Response<Body>
78where
79 E: Debug + std::error::Error,
80{
81 let reply = reply::ServiceReply::<(), E>::from(e);
82 let encoded = match serde_json::to_vec(&reply) {
83 Ok(v) => v,
84 Err(_e) => return resp_err(),
85 };
86
87 Response::builder()
88 .header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
89 .status(status)
90 .body(Body::from(encoded))
91 .unwrap_or_else(|_| Response::new(Body::empty()))
92}
93
94pub type HyperFuture = Box<Future<Item = Response<Body>, Error = hyper::Error>>;
95pub type HyperService =
96 Box<Service<ReqBody = Body, ResBody = Body, Error = hyper::Error, Future = HyperFuture>>;
97pub type HyperServiceSend = Box<
98 Service<
99 ReqBody = Body,
100 ResBody = Body,
101 Error = hyper::Error,
102 Future = Box<Future<Item = Response<Body>, Error = hyper::Error> + Send>,
103 >,
104>;
105
106fn parse_req<R>(req: Request<Body>) -> Box<Future<Item = R, Error = Error>>
108where
109 R: for<'de> serde::Deserialize<'de> + 'static,
110{
111 use hyper::Method;
112 match req.method().clone() {
113 Method::GET | Method::DELETE => {
114 let qs = req.uri().query().unwrap_or("");
115 let req: Result<R, Error> =
116 serde_qs::from_str(qs).map_err(|e| ErrorKind::DecodeQs(e).into());
117 Box::new(result(req))
118 }
119 Method::PUT | Method::POST => {
120 let buf = Vec::new();
121
122 let f = req
123 .into_body()
124 .map_err(Error::from)
125 .fold(buf, |mut buf, chunk| {
126 buf.extend_from_slice(&chunk);
127 if buf.len() > 1024 * 1024 * 4 {
129 Err(Error::from("body too large"))
130 } else {
131 Ok(buf)
132 }
133 })
134 .and_then(move |chunk: Vec<u8>| {
135 serde_json::from_slice(&chunk).map_err(|e| ErrorKind::DecodeJson(e).into())
136 });
137 Box::new(f)
138 }
139 m => Box::new(err(ErrorKind::UnexpectedMethod(m).into())),
140 }
141}
142
143#[derive(Serialize, Deserialize, Default, Clone, Copy, Debug)]
144pub struct Empty {}