@@ -2,6 +2,8 @@ use std::mem::MaybeUninit;
22
33#[ cfg( feature = "client" ) ]  
44use  std:: fmt:: { self ,  Write  as  _} ; 
5+ #[ cfg( feature = "server" ) ]  
6+ use  std:: sync:: Arc ; 
57
68use  bytes:: Bytes ; 
79use  bytes:: BytesMut ; 
@@ -16,6 +18,8 @@ use smallvec::{smallvec, smallvec_inline, SmallVec};
1618use  crate :: body:: DecodedLength ; 
1719#[ cfg( feature = "server" ) ]  
1820use  crate :: common:: date; 
21+ #[ cfg( feature = "server" ) ]  
22+ use  crate :: error:: Kind ; 
1923use  crate :: error:: Parse ; 
2024use  crate :: ext:: HeaderCaseMap ; 
2125#[ cfg( feature = "ffi" ) ]  
@@ -27,6 +31,8 @@ use crate::proto::h1::{
2731#[ cfg( feature = "client" ) ]  
2832use  crate :: proto:: RequestHead ; 
2933use  crate :: proto:: { BodyLength ,  MessageHead ,  RequestLine } ; 
34+ #[ cfg( feature = "server" ) ]  
35+ use  crate :: server:: conn:: http1:: Http1ErrorResponder ; 
3036
3137pub ( crate )  const  DEFAULT_MAX_HEADERS :  usize  = 100 ; 
3238const  AVERAGE_HEADER_SIZE :  usize  = 30 ;  // totally scientific 
@@ -127,6 +133,30 @@ pub(crate) enum Client {}
127133#[ cfg( feature = "server" ) ]  
128134pub ( crate )  enum  Server  { } 
129135
136+ #[ cfg( feature = "server" ) ]  
137+ pub ( crate )  fn  default_error_response ( kind :  & Kind )  -> Option < crate :: Response < ( ) > >  { 
138+     use  crate :: error:: Kind ; 
139+     use  crate :: error:: Parse ; 
140+     use  http:: StatusCode ; 
141+     let  status = match  kind { 
142+         Kind :: Parse ( Parse :: Method ) 
143+         | Kind :: Parse ( Parse :: Header ( _) ) 
144+         | Kind :: Parse ( Parse :: Uri ) 
145+         | Kind :: Parse ( Parse :: Version )  => StatusCode :: BAD_REQUEST , 
146+         Kind :: Parse ( Parse :: TooLarge )  => StatusCode :: REQUEST_HEADER_FIELDS_TOO_LARGE , 
147+         Kind :: Parse ( Parse :: UriTooLong )  => StatusCode :: URI_TOO_LONG , 
148+         _ => return  None , 
149+     } ; 
150+ 
151+     debug ! ( "building automatic response ({}) for parse error" ,  status) ; 
152+     let  msg = MessageHead  { 
153+         subject :  status, 
154+         ..Default :: default ( ) 
155+     } 
156+     . into_response ( ( ) ) ; 
157+     Some ( msg) 
158+ } 
159+ 
130160#[ cfg( feature = "server" ) ]  
131161impl  Http1Transaction  for  Server  { 
132162    type  Incoming  = RequestLine ; 
@@ -460,24 +490,19 @@ impl Http1Transaction for Server {
460490        ret. map ( |( ) | encoder) 
461491    } 
462492
463-     fn  on_error ( err :  & crate :: Error )  -> Option < MessageHead < Self :: Outgoing > >  { 
464-         use  crate :: error:: Kind ; 
465-         let  status = match  * err. kind ( )  { 
466-             Kind :: Parse ( Parse :: Method ) 
467-             | Kind :: Parse ( Parse :: Header ( _) ) 
468-             | Kind :: Parse ( Parse :: Uri ) 
469-             | Kind :: Parse ( Parse :: Version )  => StatusCode :: BAD_REQUEST , 
470-             Kind :: Parse ( Parse :: TooLarge )  => StatusCode :: REQUEST_HEADER_FIELDS_TOO_LARGE , 
471-             Kind :: Parse ( Parse :: UriTooLong )  => StatusCode :: URI_TOO_LONG , 
472-             _ => return  None , 
473-         } ; 
474- 
475-         debug ! ( "sending automatic response ({}) for parse error" ,  status) ; 
476-         let  msg = MessageHead  { 
477-             subject :  status, 
478-             ..Default :: default ( ) 
479-         } ; 
480-         Some ( msg) 
493+     fn  on_error ( 
494+         err :  & crate :: Error , 
495+         responder :  & Option < Arc < dyn  Http1ErrorResponder > > , 
496+     )  -> Option < MessageHead < Self :: Outgoing > >  { 
497+         use  crate :: server:: conn:: http1:: Http1ErrorReason ; 
498+         let  reason = Http1ErrorReason :: from_kind ( err. kind ( ) ) ; 
499+         responder
500+             . as_ref ( ) 
501+             . map_or_else ( 
502+                 || default_error_response ( err. kind ( ) ) , 
503+                 |er| er. respond ( & reason) , 
504+             ) 
505+             . map ( |rsp| MessageHead :: from_response ( rsp) ) 
481506    } 
482507
483508    fn  is_server ( )  -> bool  { 
@@ -1216,7 +1241,10 @@ impl Http1Transaction for Client {
12161241        Ok ( body) 
12171242    } 
12181243
1219-     fn  on_error ( _err :  & crate :: Error )  -> Option < MessageHead < Self :: Outgoing > >  { 
1244+     fn  on_error ( 
1245+         _err :  & crate :: Error , 
1246+         #[ cfg( feature = "server" ) ]   _responder :  & Option < Arc < dyn  Http1ErrorResponder > > , 
1247+     )  -> Option < MessageHead < Self :: Outgoing > >  { 
12201248        // we can't tell the server about any errors it creates 
12211249        None 
12221250    } 
0 commit comments