1use std::{io, net::SocketAddr, sync::Arc};
2
3use futures::future::IntoFuture;
4use futures::{Future, Poll, Stream};
5use hyper::{service::service_fn, Body, Chunk, Request, Response, Server};
6use log::debug;
7
8use ipp_proto::{
9 attribute::STATUS_MESSAGE, ipp::DelimiterTag, AsyncIppParser, IppAttribute, IppRequestResponse, IppValue,
10};
11
12use crate::handler::IppRequestHandler;
13
14struct DummyHandler;
15impl IppRequestHandler for DummyHandler {}
16
17#[derive(Debug)]
19pub enum ServerError {
20 HyperError(hyper::Error),
21 IOError(io::Error),
22}
23
24impl From<hyper::Error> for ServerError {
25 fn from(err: hyper::Error) -> Self {
26 ServerError::HyperError(err)
27 }
28}
29
30impl From<io::Error> for ServerError {
31 fn from(err: io::Error) -> Self {
32 ServerError::IOError(err)
33 }
34}
35
36pub struct IppServer {
38 inner: Box<dyn Future<Item = (), Error = ServerError> + Send>,
39}
40
41impl IppServer {
42 fn new(address: SocketAddr, handler: Arc<dyn IppRequestHandler + Send + Sync>) -> Result<IppServer, ServerError> {
43 let inner = Server::try_bind(&address)?
44 .serve(move || {
45 let handler = handler.clone();
46 service_fn(move |req: Request<Body>| {
47 let stream: Box<dyn Stream<Item = Chunk, Error = io::Error> + Send> = Box::new(
48 req.into_body()
49 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string())),
50 );
51
52 let handler = handler.clone();
53
54 AsyncIppParser::from(stream).map(move |result| {
55 debug!("Received request, payload present: {}", result.payload.is_some());
56
57 let request = IppRequestResponse::from_parse_result(result);
58 let req_id = request.header().request_id;
59
60 let response = match handler.handle_request(request) {
61 Ok(response) => response,
62 Err(status) => {
63 let mut response = IppRequestResponse::new_response(handler.version(), status, req_id);
64 response.attributes_mut().add(
65 DelimiterTag::OperationAttributes,
66 IppAttribute::new(
67 STATUS_MESSAGE,
68 IppValue::TextWithoutLanguage(status.to_string()),
69 ),
70 );
71 response
72 }
73 };
74 Response::new(Body::wrap_stream(response.into_stream()))
75 })
76 })
77 })
78 .map_err(ServerError::from);
79
80 Ok(IppServer { inner: Box::new(inner) })
81 }
82}
83
84impl Future for IppServer {
85 type Item = ();
86 type Error = ServerError;
87
88 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
89 self.inner.poll()
90 }
91}
92
93pub struct IppServerBuilder {
95 address: SocketAddr,
96 handler: Arc<dyn IppRequestHandler + Send + Sync>,
97}
98
99impl IppServerBuilder {
100 pub fn new<S>(address: S) -> IppServerBuilder
102 where
103 SocketAddr: From<S>,
104 {
105 IppServerBuilder {
106 address: address.into(),
107 handler: Arc::new(DummyHandler),
108 }
109 }
110
111 pub fn handler(mut self, handler: Arc<dyn IppRequestHandler + Send + Sync>) -> Self {
113 self.handler = handler;
114 self
115 }
116
117 pub fn build(self) -> impl Future<Item = IppServer, Error = ServerError> {
119 IppServer::new(self.address, self.handler).into_future()
120 }
121}