1+ use std:: io:: { self , Write } ;
2+ use std:: error:: Error ;
3+ use std:: fmt:: { self , Formatter , Display } ;
14use hyper;
25use hyper:: http:: h1:: Incoming ;
36use hyper:: http:: h1:: parse_response;
7+ use hyper:: http:: h1:: parse_request;
48use hyper:: http:: RawStatus ;
9+ use hyper:: status:: StatusCode ;
510use hyper:: method:: Method ;
611use hyper:: uri:: RequestUri ;
712use hyper:: buffer:: BufReader ;
8- use std:: io:: { self , Write } ;
913use tokio_io:: codec:: { Decoder , Encoder } ;
1014use bytes:: BytesMut ;
1115use bytes:: BufMut ;
1216use result:: WebSocketError ;
1317
1418#[ derive( Copy , Clone , Debug ) ]
15- pub struct HttpCodec ;
19+ pub struct HttpClientCodec ;
1620
17- impl Encoder for HttpCodec {
21+ impl Encoder for HttpClientCodec {
1822 type Item = Incoming < ( Method , RequestUri ) > ;
1923 type Error = io:: Error ;
2024
@@ -33,9 +37,9 @@ impl Encoder for HttpCodec {
3337 }
3438}
3539
36- impl Decoder for HttpCodec {
40+ impl Decoder for HttpClientCodec {
3741 type Item = Incoming < RawStatus > ;
38- type Error = WebSocketError ;
42+ type Error = HttpCodecError ;
3943
4044 fn decode ( & mut self , src : & mut BytesMut ) -> Result < Option < Self :: Item > , Self :: Error > {
4145 // check if we get a request from hyper
@@ -58,3 +62,88 @@ impl Decoder for HttpCodec {
5862 Ok ( Some ( response) )
5963 }
6064}
65+
66+ #[ derive( Copy , Clone , Debug ) ]
67+ pub struct HttpServerCodec ;
68+
69+ impl Encoder for HttpServerCodec {
70+ type Item = Incoming < RawStatus > ;
71+ type Error = io:: Error ;
72+
73+ fn encode ( & mut self , item : Self :: Item , dst : & mut BytesMut ) -> Result < ( ) , Self :: Error > {
74+ // TODO: optomize this!
75+ let status = StatusCode :: from_u16 ( item. subject . 0 ) ;
76+ let response = format ! ( "{} {}\r \n {}\r \n " , item. version, status, item. headers) ;
77+ let byte_len = response. as_bytes ( ) . len ( ) ;
78+ if byte_len > dst. remaining_mut ( ) {
79+ dst. reserve ( byte_len) ;
80+ }
81+ dst. writer ( ) . write ( response. as_bytes ( ) ) . map ( |_| ( ) )
82+ }
83+ }
84+
85+ impl Decoder for HttpServerCodec {
86+ type Item = Incoming < ( Method , RequestUri ) > ;
87+ type Error = HttpCodecError ;
88+
89+ fn decode ( & mut self , src : & mut BytesMut ) -> Result < Option < Self :: Item > , Self :: Error > {
90+ // check if we get a request from hyper
91+ // TODO: this is ineffecient, but hyper does not give us a better way to parse
92+ let ( response, bytes_read) = {
93+ let mut reader = BufReader :: new ( & * src as & [ u8 ] ) ;
94+ let res = match parse_request ( & mut reader) {
95+ Err ( hyper:: Error :: Io ( ref e) ) if e. kind ( ) == io:: ErrorKind :: UnexpectedEof => {
96+ return Ok ( None )
97+ }
98+ Err ( hyper:: Error :: TooLarge ) => return Ok ( None ) ,
99+ Err ( e) => return Err ( e. into ( ) ) ,
100+ Ok ( r) => r,
101+ } ;
102+ let ( _, _, pos, _) = reader. into_parts ( ) ;
103+ ( res, pos)
104+ } ;
105+
106+ src. split_to ( bytes_read) ;
107+ Ok ( Some ( response) )
108+ }
109+ }
110+
111+ #[ derive( Debug ) ]
112+ pub enum HttpCodecError {
113+ Io ( io:: Error ) ,
114+ Http ( hyper:: Error ) ,
115+ }
116+
117+ impl Display for HttpCodecError {
118+ fn fmt ( & self , fmt : & mut Formatter ) -> Result < ( ) , fmt:: Error > {
119+ fmt. write_str ( self . description ( ) )
120+ }
121+ }
122+
123+ impl Error for HttpCodecError {
124+ fn description ( & self ) -> & str {
125+ match * self {
126+ HttpCodecError :: Io ( ref e) => e. description ( ) ,
127+ HttpCodecError :: Http ( ref e) => e. description ( ) ,
128+ }
129+ }
130+
131+ fn cause ( & self ) -> Option < & Error > {
132+ match * self {
133+ HttpCodecError :: Io ( ref error) => Some ( error) ,
134+ HttpCodecError :: Http ( ref error) => Some ( error) ,
135+ }
136+ }
137+ }
138+
139+ impl From < io:: Error > for HttpCodecError {
140+ fn from ( err : io:: Error ) -> HttpCodecError {
141+ HttpCodecError :: Io ( err)
142+ }
143+ }
144+
145+ impl From < hyper:: Error > for HttpCodecError {
146+ fn from ( err : hyper:: Error ) -> HttpCodecError {
147+ HttpCodecError :: Http ( err)
148+ }
149+ }
0 commit comments