@@ -17,93 +17,6 @@ pub struct PathAndQuery {
1717const NONE : u16 = u16:: MAX ;
1818
1919impl PathAndQuery {
20- fn from_shared ( mut src : Bytes ) -> Result < Self , InvalidUri > {
21- let mut query = NONE ;
22- let mut fragment = None ;
23-
24- // block for iterator borrow
25- {
26- let mut iter = src. as_ref ( ) . iter ( ) . enumerate ( ) ;
27-
28- // path ...
29- for ( i, & b) in & mut iter {
30- // See https://url.spec.whatwg.org/#path-state
31- match b {
32- b'?' => {
33- debug_assert_eq ! ( query, NONE ) ;
34- query = i as u16 ;
35- break ;
36- }
37- b'#' => {
38- fragment = Some ( i) ;
39- break ;
40- }
41-
42- // This is the range of bytes that don't need to be
43- // percent-encoded in the path. If it should have been
44- // percent-encoded, then error.
45- #[ rustfmt:: skip]
46- 0x21 |
47- 0x24 ..=0x3B |
48- 0x3D |
49- 0x40 ..=0x5F |
50- 0x61 ..=0x7A |
51- 0x7C |
52- 0x7E => { }
53-
54- // These are code points that are supposed to be
55- // percent-encoded in the path but there are clients
56- // out there sending them as is and httparse accepts
57- // to parse those requests, so they are allowed here
58- // for parity.
59- //
60- // For reference, those are code points that are used
61- // to send requests with JSON directly embedded in
62- // the URI path. Yes, those things happen for real.
63- #[ rustfmt:: skip]
64- b'"' |
65- b'{' | b'}' => { }
66-
67- _ => return Err ( ErrorKind :: InvalidUriChar . into ( ) ) ,
68- }
69- }
70-
71- // query ...
72- if query != NONE {
73- for ( i, & b) in iter {
74- match b {
75- // While queries *should* be percent-encoded, most
76- // bytes are actually allowed...
77- // See https://url.spec.whatwg.org/#query-state
78- //
79- // Allowed: 0x21 / 0x24 - 0x3B / 0x3D / 0x3F - 0x7E
80- #[ rustfmt:: skip]
81- 0x21 |
82- 0x24 ..=0x3B |
83- 0x3D |
84- 0x3F ..=0x7E => { }
85-
86- b'#' => {
87- fragment = Some ( i) ;
88- break ;
89- }
90-
91- _ => return Err ( ErrorKind :: InvalidUriChar . into ( ) ) ,
92- }
93- }
94- }
95- }
96-
97- if let Some ( i) = fragment {
98- src. truncate ( i) ;
99- }
100-
101- Ok ( PathAndQuery {
102- data : unsafe { ByteStr :: from_utf8_unchecked ( src) } ,
103- query,
104- } )
105- }
106-
10720 /// Convert a `PathAndQuery` from a static string.
10821 ///
10922 /// This function will not perform any copying, however the string is
@@ -278,8 +191,91 @@ impl PathAndQuery {
278191impl TryFrom < Bytes > for PathAndQuery {
279192 type Error = InvalidUri ;
280193 #[ inline]
281- fn try_from ( bytes : Bytes ) -> Result < Self , Self :: Error > {
282- PathAndQuery :: from_shared ( bytes)
194+ fn try_from ( mut bytes : Bytes ) -> Result < Self , Self :: Error > {
195+ let mut query = NONE ;
196+ let mut fragment = None ;
197+
198+ // block for iterator borrow
199+ {
200+ let mut iter = bytes. as_ref ( ) . iter ( ) . enumerate ( ) ;
201+
202+ // path ...
203+ for ( i, & b) in & mut iter {
204+ // See https://url.spec.whatwg.org/#path-state
205+ match b {
206+ b'?' => {
207+ debug_assert_eq ! ( query, NONE ) ;
208+ query = i as u16 ;
209+ break ;
210+ }
211+ b'#' => {
212+ fragment = Some ( i) ;
213+ break ;
214+ }
215+
216+ // This is the range of bytes that don't need to be
217+ // percent-encoded in the path. If it should have been
218+ // percent-encoded, then error.
219+ #[ rustfmt:: skip]
220+ 0x21 |
221+ 0x24 ..=0x3B |
222+ 0x3D |
223+ 0x40 ..=0x5F |
224+ 0x61 ..=0x7A |
225+ 0x7C |
226+ 0x7E => { }
227+
228+ // These are code points that are supposed to be
229+ // percent-encoded in the path but there are clients
230+ // out there sending them as is and httparse accepts
231+ // to parse those requests, so they are allowed here
232+ // for parity.
233+ //
234+ // For reference, those are code points that are used
235+ // to send requests with JSON directly embedded in
236+ // the URI path. Yes, those things happen for real.
237+ #[ rustfmt:: skip]
238+ b'"' |
239+ b'{' | b'}' => { }
240+
241+ _ => return Err ( ErrorKind :: InvalidUriChar . into ( ) ) ,
242+ }
243+ }
244+
245+ // query ...
246+ if query != NONE {
247+ for ( i, & b) in iter {
248+ match b {
249+ // While queries *should* be percent-encoded, most
250+ // bytes are actually allowed...
251+ // See https://url.spec.whatwg.org/#query-state
252+ //
253+ // Allowed: 0x21 / 0x24 - 0x3B / 0x3D / 0x3F - 0x7E
254+ #[ rustfmt:: skip]
255+ 0x21 |
256+ 0x24 ..=0x3B |
257+ 0x3D |
258+ 0x3F ..=0x7E => { }
259+
260+ b'#' => {
261+ fragment = Some ( i) ;
262+ break ;
263+ }
264+
265+ _ => return Err ( ErrorKind :: InvalidUriChar . into ( ) ) ,
266+ }
267+ }
268+ }
269+ }
270+
271+ if let Some ( i) = fragment {
272+ bytes. truncate ( i) ;
273+ }
274+
275+ Ok ( PathAndQuery {
276+ data : unsafe { ByteStr :: from_utf8_unchecked ( bytes) } ,
277+ query,
278+ } )
283279 }
284280}
285281
0 commit comments