33use std:: { fmt, mem, str} ;
44use std:: sync:: Arc ;
55
6- use hyper:: { self , mime, server, Method } ;
7- use hyper:: header:: { self , Headers } ;
8- use unicase:: Ascii ;
6+ use hyper:: { self , service:: Service , Body , Method } ;
7+ use hyper:: header:: { self , HeaderMap , HeaderValue } ;
98
109use jsonrpc:: { self as core, FutureResult , Metadata , Middleware , NoopMiddleware } ;
1110use jsonrpc:: futures:: { Future , Poll , Async , Stream , future} ;
@@ -49,13 +48,13 @@ impl<M: Metadata, S: Middleware<M>> ServerHandler<M, S> {
4948 }
5049}
5150
52- impl < M : Metadata , S : Middleware < M > > server :: Service for ServerHandler < M , S > {
53- type Request = server :: Request ;
54- type Response = server :: Response ;
51+ impl < M : Metadata , S : Middleware < M > > Service for ServerHandler < M , S > {
52+ type ReqBody = Body ;
53+ type ResBody = Body ;
5554 type Error = hyper:: Error ;
5655 type Future = Handler < M , S > ;
5756
58- fn call ( & self , request : Self :: Request ) -> Self :: Future {
57+ fn call ( & mut self , request : hyper :: Request < Self :: ReqBody > ) -> Self :: Future {
5958 let is_host_allowed = utils:: is_host_allowed ( & request, & self . allowed_hosts ) ;
6059 let action = self . middleware . on_request ( request) ;
6160
@@ -98,11 +97,11 @@ impl<M: Metadata, S: Middleware<M>> server::Service for ServerHandler<M, S> {
9897pub enum Handler < M : Metadata , S : Middleware < M > > {
9998 Rpc ( RpcHandler < M , S > ) ,
10099 Error ( Option < Response > ) ,
101- Middleware ( Box < Future < Item =server :: Response , Error = hyper:: Error > + Send > ) ,
100+ Middleware ( Box < Future < Item = hyper :: Response < Body > , Error = hyper:: Error > + Send > ) ,
102101}
103102
104103impl < M : Metadata , S : Middleware < M > > Future for Handler < M , S > {
105- type Item = server :: Response ;
104+ type Item = hyper :: Response < Body > ;
106105 type Error = hyper:: Error ;
107106
108107 fn poll ( & mut self ) -> Poll < Self :: Item , Self :: Error > {
@@ -139,7 +138,7 @@ enum RpcHandlerState<M, F> where
139138 F : Future < Item = Option < core:: Response > , Error = ( ) > ,
140139{
141140 ReadingHeaders {
142- request : server :: Request ,
141+ request : hyper :: Request < Body > ,
143142 cors_domains : CorsDomains ,
144143 continue_on_invalid_cors : bool ,
145144 } ,
@@ -179,22 +178,22 @@ pub struct RpcHandler<M: Metadata, S: Middleware<M>> {
179178 jsonrpc_handler : Rpc < M , S > ,
180179 state : RpcHandlerState < M , S :: Future > ,
181180 is_options : bool ,
182- cors_header : cors:: CorsHeader < header:: AccessControlAllowOrigin > ,
181+ cors_header : cors:: CorsHeader < header:: HeaderValue > ,
183182 cors_max_age : Option < u32 > ,
184183 rest_api : RestApi ,
185184 max_request_body_size : usize ,
186185}
187186
188187impl < M : Metadata , S : Middleware < M > > Future for RpcHandler < M , S > {
189- type Item = server :: Response ;
188+ type Item = hyper :: Response < Body > ;
190189 type Error = hyper:: Error ;
191190
192191 fn poll ( & mut self ) -> Poll < Self :: Item , Self :: Error > {
193192 let new_state = match mem:: replace ( & mut self . state , RpcHandlerState :: Done ) {
194193 RpcHandlerState :: ReadingHeaders { request, cors_domains, continue_on_invalid_cors, } => {
195194 // Read cors header
196195 self . cors_header = utils:: cors_header ( & request, & cors_domains) ;
197- self . is_options = * request. method ( ) == Method :: Options ;
196+ self . is_options = * request. method ( ) == Method :: OPTIONS ;
198197 // Read other headers
199198 RpcPollState :: Ready ( self . read_headers ( request, continue_on_invalid_cors) )
200199 } ,
@@ -236,7 +235,7 @@ impl<M: Metadata, S: Middleware<M>> Future for RpcHandler<M, S> {
236235 let ( new_state, is_ready) = new_state. decompose ( ) ;
237236 match new_state {
238237 RpcHandlerState :: Writing ( res) => {
239- let mut response: server :: Response = res. into ( ) ;
238+ let mut response: hyper :: Response < Body > = res. into ( ) ;
240239 let cors_header = mem:: replace ( & mut self . cors_header , cors:: CorsHeader :: Invalid ) ;
241240 Self :: set_response_headers (
242241 response. headers_mut ( ) ,
@@ -259,7 +258,7 @@ impl<M: Metadata, S: Middleware<M>> Future for RpcHandler<M, S> {
259258}
260259
261260// Intermediate and internal error type to better distinguish
262- // error cases occuring during request body processing.
261+ // error cases occurring during request body processing.
263262enum BodyError {
264263 Hyper ( hyper:: Error ) ,
265264 Utf8 ( str:: Utf8Error ) ,
@@ -275,7 +274,7 @@ impl From<hyper::Error> for BodyError {
275274impl < M : Metadata , S : Middleware < M > > RpcHandler < M , S > {
276275 fn read_headers (
277276 & self ,
278- request : server :: Request ,
277+ request : hyper :: Request < Body > ,
279278 continue_on_invalid_cors : bool ,
280279 ) -> RpcHandlerState < M , S :: Future > {
281280 if self . cors_header == cors:: CorsHeader :: Invalid && !continue_on_invalid_cors {
@@ -285,30 +284,30 @@ impl<M: Metadata, S: Middleware<M>> RpcHandler<M, S> {
285284 let metadata = self . jsonrpc_handler . extractor . read_metadata ( & request) ;
286285
287286 // Proceed
288- match * request. method ( ) {
287+ match request. method ( ) . clone ( ) {
289288 // Validate the ContentType header
290289 // to prevent Cross-Origin XHRs with text/plain
291- Method :: Post if Self :: is_json ( request. headers ( ) . get :: < header :: ContentType > ( ) ) => {
290+ Method :: POST if Self :: is_json ( request. headers ( ) . get ( "content-type" ) ) => {
292291 let uri = if self . rest_api != RestApi :: Disabled { Some ( request. uri ( ) . clone ( ) ) } else { None } ;
293292 RpcHandlerState :: ReadingBody {
294293 metadata,
295294 request : Default :: default ( ) ,
296295 uri,
297- body : request. body ( ) ,
296+ body : request. into_body ( ) ,
298297 }
299298 } ,
300- Method :: Post if self . rest_api == RestApi :: Unsecure && request. uri ( ) . path ( ) . split ( '/' ) . count ( ) > 2 => {
299+ Method :: POST if self . rest_api == RestApi :: Unsecure && request. uri ( ) . path ( ) . split ( '/' ) . count ( ) > 2 => {
301300 RpcHandlerState :: ProcessRest {
302301 metadata,
303302 uri : request. uri ( ) . clone ( ) ,
304303 }
305304 } ,
306305 // Just return error for unsupported content type
307- Method :: Post => {
306+ Method :: POST => {
308307 RpcHandlerState :: Writing ( Response :: unsupported_content_type ( ) )
309308 } ,
310309 // Don't validate content type on options
311- Method :: Options => {
310+ Method :: OPTIONS => {
312311 RpcHandlerState :: Writing ( Response :: empty ( ) )
313312 } ,
314313 // Disallow other methods.
@@ -403,48 +402,53 @@ impl<M: Metadata, S: Middleware<M>> RpcHandler<M, S> {
403402 }
404403
405404 fn set_response_headers (
406- headers : & mut Headers ,
405+ headers : & mut HeaderMap ,
407406 is_options : bool ,
408- cors_header : Option < header :: AccessControlAllowOrigin > ,
407+ cors_header : Option < HeaderValue > ,
409408 cors_max_age : Option < u32 > ,
410409 ) {
411410 if is_options {
412- headers. set ( header:: Allow ( vec ! [
413- Method :: Options ,
414- Method :: Post ,
415- ] ) ) ;
416- headers. set ( header:: Accept ( vec ! [
417- header:: qitem( mime:: APPLICATION_JSON )
418- ] ) ) ;
411+ headers. append ( header:: ALLOW , Method :: OPTIONS . as_str ( ) . parse ( ) . expect ( "`Method` will always parse; qed" ) ) ;
412+ headers. append ( header:: ALLOW , Method :: POST . as_str ( ) . parse ( ) . expect ( "`Method` will always parse; qed" ) ) ;
413+
414+ headers. append ( header:: ACCEPT , HeaderValue :: from_static ( "application/json" ) ) ;
415+
419416 }
420417
421418 if let Some ( cors_domain) = cors_header {
422- headers. set ( header:: AccessControlAllowMethods ( vec ! [
423- Method :: Options ,
424- Method :: Post
425- ] ) ) ;
426- headers. set ( header:: AccessControlAllowHeaders ( vec ! [
427- Ascii :: new( "origin" . to_owned( ) ) ,
428- Ascii :: new( "content-type" . to_owned( ) ) ,
429- Ascii :: new( "accept" . to_owned( ) ) ,
430- ] ) ) ;
431- if let Some ( cors_max_age) = cors_max_age {
432- headers. set ( header:: AccessControlMaxAge ( cors_max_age) ) ;
419+ headers. append ( header:: ACCESS_CONTROL_ALLOW_METHODS , Method :: OPTIONS . as_str ( ) . parse ( )
420+ . expect ( "`Method` will always parse; qed" ) ) ;
421+ headers. append ( header:: ACCESS_CONTROL_ALLOW_METHODS , Method :: POST . as_str ( ) . parse ( )
422+ . expect ( "`Method` will always parse; qed" ) ) ;
423+
424+ headers. append ( header:: ACCESS_CONTROL_ALLOW_HEADERS , HeaderValue :: from_static ( "origin" ) ) ;
425+ headers. append ( header:: ACCESS_CONTROL_ALLOW_HEADERS , HeaderValue :: from_static ( "content-type" ) ) ;
426+ headers. append ( header:: ACCESS_CONTROL_ALLOW_HEADERS , HeaderValue :: from_static ( "accept" ) ) ;
427+
428+ if let Some ( cma) = cors_max_age {
429+ headers. append ( header:: ACCESS_CONTROL_MAX_AGE , HeaderValue :: from_str ( & cma. to_string ( ) )
430+ . expect ( "`u32` will always parse; qed" ) ) ;
433431 }
434- headers . set ( cors_domain ) ;
435- headers. set ( header:: Vary :: Items ( vec ! [
436- Ascii :: new ( "origin" . to_owned ( ) )
437- ] ) ) ;
432+
433+ headers. append ( header:: ACCESS_CONTROL_ALLOW_ORIGIN , cors_domain ) ;
434+
435+ headers . append ( header :: VARY , HeaderValue :: from_static ( "origin" ) ) ;
438436 }
439437 }
440438
441- fn is_json ( content_type : Option < & header:: ContentType > ) -> bool {
442- const APPLICATION_JSON_UTF_8 : & str = "application/json; charset=utf-8" ;
443-
439+ /// Returns true if the ` content_type` header indicates a valid JSON
440+ /// message.
441+ fn is_json ( content_type : Option < & header :: HeaderValue > ) -> bool {
444442 match content_type {
445- Some ( & header:: ContentType ( ref mime) )
446- if * mime == mime:: APPLICATION_JSON || * mime == APPLICATION_JSON_UTF_8 => true ,
447- _ => false
443+ Some ( header_val) => {
444+ match header_val. to_str ( ) {
445+ Ok ( header_str) => {
446+ header_str == "application/json" || header_str == "application/json; charset=utf-8"
447+ } ,
448+ Err ( _) => false ,
449+ }
450+ }
451+ _ => false ,
448452 }
449453 }
450454}
0 commit comments