@@ -2,6 +2,8 @@ use std::mem::MaybeUninit;
2
2
3
3
#[ cfg( feature = "client" ) ]
4
4
use std:: fmt:: { self , Write as _} ;
5
+ #[ cfg( feature = "server" ) ]
6
+ use std:: sync:: Arc ;
5
7
6
8
use bytes:: Bytes ;
7
9
use bytes:: BytesMut ;
@@ -16,6 +18,8 @@ use smallvec::{smallvec, smallvec_inline, SmallVec};
16
18
use crate :: body:: DecodedLength ;
17
19
#[ cfg( feature = "server" ) ]
18
20
use crate :: common:: date;
21
+ #[ cfg( feature = "server" ) ]
22
+ use crate :: error:: Kind ;
19
23
use crate :: error:: Parse ;
20
24
use crate :: ext:: HeaderCaseMap ;
21
25
#[ cfg( feature = "ffi" ) ]
@@ -27,6 +31,8 @@ use crate::proto::h1::{
27
31
#[ cfg( feature = "client" ) ]
28
32
use crate :: proto:: RequestHead ;
29
33
use crate :: proto:: { BodyLength , MessageHead , RequestLine } ;
34
+ #[ cfg( feature = "server" ) ]
35
+ use crate :: server:: conn:: http1:: Http1ErrorResponder ;
30
36
31
37
pub ( crate ) const DEFAULT_MAX_HEADERS : usize = 100 ;
32
38
const AVERAGE_HEADER_SIZE : usize = 30 ; // totally scientific
@@ -127,6 +133,30 @@ pub(crate) enum Client {}
127
133
#[ cfg( feature = "server" ) ]
128
134
pub ( crate ) enum Server { }
129
135
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
+
130
160
#[ cfg( feature = "server" ) ]
131
161
impl Http1Transaction for Server {
132
162
type Incoming = RequestLine ;
@@ -460,24 +490,19 @@ impl Http1Transaction for Server {
460
490
ret. map ( |( ) | encoder)
461
491
}
462
492
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) )
481
506
}
482
507
483
508
fn is_server ( ) -> bool {
@@ -1216,7 +1241,10 @@ impl Http1Transaction for Client {
1216
1241
Ok ( body)
1217
1242
}
1218
1243
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 > > {
1220
1248
// we can't tell the server about any errors it creates
1221
1249
None
1222
1250
}
0 commit comments