14
14
//! let mut res = Response::new(200);
15
15
//! timings.apply(&mut res);
16
16
//!
17
- //! let timings = ServerTiming::from_headers(res).unwrap();
17
+ //! let timings = ServerTiming::from_headers(res)? .unwrap();
18
18
//! let entry = timings.iter().next().unwrap();
19
19
//! assert_eq!(entry.name(), "server");
20
20
//! #
@@ -56,7 +56,7 @@ use crate::headers::{HeaderName, HeaderValue, Headers, ToHeaderValues, SERVER_TI
56
56
/// let mut res = Response::new(200);
57
57
/// timings.apply(&mut res);
58
58
///
59
- /// let timings = ServerTiming::from_headers(res).unwrap();
59
+ /// let timings = ServerTiming::from_headers(res)? .unwrap();
60
60
/// let entry = timings.iter().next().unwrap();
61
61
/// assert_eq!(entry.name(), "server");
62
62
/// #
@@ -74,12 +74,17 @@ impl ServerTiming {
74
74
}
75
75
76
76
/// Create a new instance from headers.
77
- pub fn from_headers ( headers : impl AsRef < Headers > ) -> Option < Self > {
77
+ pub fn from_headers ( headers : impl AsRef < Headers > ) -> crate :: Result < Option < Self > > {
78
78
let mut timings = vec ! [ ] ;
79
- for value in headers. as_ref ( ) . get ( SERVER_TIMING ) ? {
80
- parse_header ( value. as_str ( ) , & mut timings) . ok ( ) ?;
79
+ let headers = match headers. as_ref ( ) . get ( SERVER_TIMING ) {
80
+ Some ( headers) => headers,
81
+ None => return Ok ( None ) ,
82
+ } ;
83
+
84
+ for value in headers {
85
+ parse_header ( value. as_str ( ) , & mut timings) ?;
81
86
}
82
- Some ( Self { timings } )
87
+ Ok ( Some ( Self { timings } ) )
83
88
}
84
89
85
90
/// Sets the `Server-Timing` header.
@@ -102,6 +107,8 @@ impl ServerTiming {
102
107
_ => write ! ( output, ", {}" , timing) . unwrap ( ) ,
103
108
} ;
104
109
}
110
+
111
+ // SAFETY: the internal string is validated to be ASCII.
105
112
unsafe { HeaderValue :: from_bytes_unchecked ( output. into ( ) ) }
106
113
}
107
114
@@ -240,7 +247,7 @@ mod test {
240
247
let mut headers = Headers :: new ( ) ;
241
248
timings. apply ( & mut headers) ;
242
249
243
- let timings = ServerTiming :: from_headers ( headers) . unwrap ( ) ;
250
+ let timings = ServerTiming :: from_headers ( headers) ? . unwrap ( ) ;
244
251
let entry = timings. iter ( ) . next ( ) . unwrap ( ) ;
245
252
assert_eq ! ( entry. name( ) , "server" ) ;
246
253
Ok ( ( ) )
@@ -254,9 +261,18 @@ mod test {
254
261
let mut headers = Headers :: new ( ) ;
255
262
timings. apply ( & mut headers) ;
256
263
257
- let timings = ServerTiming :: from_headers ( headers) . unwrap ( ) ;
264
+ let timings = ServerTiming :: from_headers ( headers) ? . unwrap ( ) ;
258
265
let entry = timings. iter ( ) . next ( ) . unwrap ( ) ;
259
266
assert_eq ! ( entry. name( ) , "server" ) ;
260
267
Ok ( ( ) )
261
268
}
269
+
270
+ #[ test]
271
+ fn bad_request_on_parse_error ( ) -> crate :: Result < ( ) > {
272
+ let mut headers = Headers :: new ( ) ;
273
+ headers. insert ( SERVER_TIMING , "server; <nori ate your param omnom>" ) ;
274
+ let err = ServerTiming :: from_headers ( headers) . unwrap_err ( ) ;
275
+ assert_eq ! ( err. status( ) , 400 ) ;
276
+ Ok ( ( ) )
277
+ }
262
278
}
0 commit comments