http_box/http1/
parser.rs

1// +-----------------------------------------------------------------------------------------------+
2// | Copyright 2016 Sean Kerr                                                                      |
3// |                                                                                               |
4// | Licensed under the Apache License, Version 2.0 (the "License");                               |
5// | you may not use this file except in compliance with the License.                              |
6// | You may obtain a copy of the License at                                                       |
7// |                                                                                               |
8// |  http://www.apache.org/licenses/LICENSE-2.0                                                   |
9// |                                                                                               |
10// | Unless required by applicable law or agreed to in writing, software                           |
11// | distributed under the License is distributed on an "AS IS" BASIS,                             |
12// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                      |
13// | See the License for the specific language governing permissions and                           |
14// | limitations under the License.                                                                |
15// +-----------------------------------------------------------------------------------------------+
16
17//! HTTP 1.x parser.
18
19#![allow(dead_code)]
20
21use byte::{ is_header_field, is_quoted_header_field, is_token };
22use fsm::{ ParserValue, Success };
23use http1::http_handler::HttpHandler;
24use http1::parser_error::ParserError;
25use http1::parser_state::ParserState;
26use http1::parser_type::ParserType;
27
28use byte_slice::ByteStream;
29
30// -------------------------------------------------------------------------------------------------
31// MASKS AND SHIFTS
32// -------------------------------------------------------------------------------------------------
33
34/// State flag mask.
35const FLAG_MASK: u32 = 0xF;
36
37/// State flag shift.
38const FLAG_SHIFT: u8 = 0;
39
40/// Lower 14 bits mask.
41const LOWER14_MASK: u32 = 0x3FFF;
42
43/// Lower 14 bits shift.
44const LOWER14_SHIFT: u8 = 4;
45
46/// Upper 14 bits mask.
47const UPPER14_MASK: u32 = 0x3FFF;
48
49/// Upper 14 bits shift.
50const UPPER14_SHIFT: u8 = 18;
51
52// -------------------------------------------------------------------------------------------------
53// MACROS
54// -------------------------------------------------------------------------------------------------
55
56/// Retrieve the lower 14 bits.
57macro_rules! get_lower14 {
58    ($parser:expr) => ({
59        ($parser.bit_data >> LOWER14_SHIFT) & LOWER14_MASK
60    });
61}
62
63/// Retrieve the upper 14 bits.
64macro_rules! get_upper14 {
65    ($parser:expr) => ({
66        ($parser.bit_data >> UPPER14_SHIFT) & UPPER14_MASK
67    });
68}
69
70/// Convert hex byte to a numeric value.
71///
72/// This assumes the byte is 0-9, A-F, or a-f.
73macro_rules! hex_to_byte {
74    ($byte:expr) => (
75        if $byte > 0x2F && $byte < 0x3A {
76            // digit
77            $byte - b'0'
78        } else if $byte > 0x40 && $byte < 0x5B {
79            // upper-case
80            $byte - 0x37
81        } else {
82            // lower-case
83            $byte - 0x57
84        }
85    );
86}
87
88/// Increase the lower 14 bits.
89macro_rules! inc_lower14 {
90    ($parser:expr, $length:expr) => ({
91        set_lower14!(
92            $parser,
93            get_lower14!($parser) as usize + $length as usize
94        );
95    });
96}
97
98/// Increase the upper 14 bits.
99macro_rules! inc_upper14 {
100    ($parser:expr, $length:expr) => ({
101        set_upper14!(
102            $parser,
103            get_upper14!($parser) as usize + $length as usize
104        );
105    });
106}
107
108/// Set the lower 14 bits.
109macro_rules! set_lower14 {
110    ($parser:expr, $bits:expr) => ({
111        let bits = $bits as u32;
112
113        $parser.bit_data &= !(LOWER14_MASK << LOWER14_SHIFT);
114        $parser.bit_data |= bits << LOWER14_SHIFT;
115    });
116}
117
118/// Set the upper 14 bits.
119macro_rules! set_upper14 {
120    ($parser:expr, $bits:expr) => ({
121        let bits = $bits as u32;
122
123        $parser.bit_data &= !(UPPER14_MASK << UPPER14_SHIFT);
124        $parser.bit_data |= bits << UPPER14_SHIFT;
125    });
126}
127
128// -------------------------------------------------------------------------------------------------
129
130/// HTTP 1.x parser.
131pub struct Parser<'a, T: HttpHandler + 'a> {
132    /// Bit data that stores parser state details, along with HTTP major/minor versions.
133    bit_data: u32,
134
135    /// Multipart boundary.
136    boundary: Option<&'a [u8]>,
137
138    /// Total byte count processed.
139    byte_count: usize,
140
141    /// Length storage.
142    length: usize,
143
144    /// Parser type.
145    parser_type: ParserType,
146
147    /// Current state.
148    state: ParserState,
149
150    /// Current state function.
151    state_function: fn(&mut Parser<'a, T>, &mut T, &mut ByteStream)
152                    -> Result<ParserValue, ParserError>
153}
154
155impl<'a, T: HttpHandler + 'a> Parser<'a, T> {
156    /// Create a new `Parser` and initialize it for head parsing.
157    pub fn new() -> Parser<'a, T> {
158         Parser{
159            bit_data:       0,
160            boundary:       None,
161            byte_count:     0,
162            length:         0,
163            parser_type:    ParserType::Head,
164            state:          ParserState::StripDetect,
165            state_function: Parser::detect1
166        }
167    }
168
169    /// Initialize this `Parser` for chunked transfer encoding parsing.
170    pub fn init_chunked(&mut self) {
171        self.parser_type = ParserType::Chunked;
172
173        self.reset();
174    }
175
176    /// Initialize this `Parser` for head parsing.
177    pub fn init_head(&mut self) {
178        self.parser_type = ParserType::Head;
179
180        self.reset();
181    }
182
183    /// Initialize this `Parser` for multipart parsing.
184    pub fn init_multipart(&mut self) {
185        self.parser_type = ParserType::Multipart;
186
187        self.reset();
188    }
189
190    /// Initialize this `Parser` for URL encoded parsing.
191    pub fn init_url_encoded(&mut self) {
192        self.parser_type = ParserType::UrlEncoded;
193
194        self.reset();
195    }
196
197    /// Retrieve the total byte count processed since the instantiation of `Parser`.
198    ///
199    /// The byte count is updated when `resume()` completes. This means that if a
200    /// call to `byte_count()` is executed from within a callback, it will be accurate within
201    /// `stream.len()` bytes. For precise accuracy, the best time to retrieve the byte count is
202    /// outside of all callbacks.
203    pub fn byte_count(&self) -> usize {
204        self.byte_count
205    }
206
207    /// Main parser loop.
208    ///
209    /// # Arguments
210    ///
211    /// **`handler`**
212    ///
213    /// The handler implementation.
214    #[inline]
215    fn parse(&mut self, mut handler: &mut T, mut context: &mut ByteStream)
216    -> Result<Success, ParserError> {
217        loop {
218            match (self.state_function)(self, &mut handler, &mut context) {
219                Ok(ParserValue::Continue) => {
220                },
221                Ok(ParserValue::Exit(success)) => {
222                    self.byte_count += context.stream_index;
223
224                    if let Success::Finished(_) = success {
225                        self.state = ParserState::Finished;
226                    }
227
228                    return Ok(success);
229                },
230                Err(error) => {
231                    self.byte_count     += context.stream_index;
232                    self.state           = ParserState::Dead;
233                    self.state_function  = Parser::dead;
234
235                    return Err(error);
236                }
237            }
238        }
239    }
240
241    /// Reset `Parser` to its initial state.
242    ///
243    /// After each call to `reset()`, don't forget to also set the multipart boundary, or URL
244    /// encoded data length using `set_boundary()` or `set_length()`.
245    pub fn reset(&mut self) {
246        self.bit_data = 0;
247        self.boundary = None;
248        self.length   = 0;
249
250        match self.parser_type {
251            ParserType::Chunked => {
252                self.state          = ParserState::ChunkLength1;
253                self.state_function = Parser::chunk_length1;
254            },
255            ParserType::Head => {
256                self.state          = ParserState::StripDetect;
257                self.state_function = Parser::strip_detect;
258            },
259            ParserType::Multipart => {
260                self.state          = ParserState::MultipartHyphen1;
261                self.state_function = Parser::multipart_hyphen1;
262
263                // lower14 == 1 when we expect a boundary, which is only the first boundary
264                set_lower14!(self, 1);
265            },
266            ParserType::UrlEncoded => {
267                self.state          = ParserState::FirstUrlEncodedName;
268                self.state_function = Parser::first_url_encoded_name;
269            }
270        }
271    }
272
273    /// Resume parsing an additional slice of data.
274    ///
275    /// # Arguments
276    ///
277    /// **`handler`**
278    ///
279    /// The handler implementation.
280    ///
281    /// **`stream`**
282    ///
283    /// The stream of data to be parsed.
284    #[inline]
285    pub fn resume(&mut self, mut handler: &mut T, mut stream: &[u8])
286    -> Result<Success, ParserError> {
287        if let ParserType::UrlEncoded = self.parser_type {
288            if self.length < stream.len() {
289                // amount of data to process is less than the stream length
290                stream = &stream[0..self.length];
291            }
292
293            let mut context = ByteStream::new(stream);
294
295            match self.parse(&mut handler, &mut context) {
296                Ok(Success::Eos(length)) => {
297                    if self.length - length == 0 {
298                        self.state          = ParserState::BodyFinished;
299                        self.state_function = Parser::body_finished;
300
301                        self.parse(&mut handler, &mut context)
302                    } else {
303                        self.length -= length;
304
305                        Ok(Success::Eos(length))
306                    }
307                },
308                Ok(Success::Callback(length)) => {
309                    self.length -= length;
310
311                    Ok(Success::Callback(length))
312                },
313                other => {
314                    other
315                }
316            }
317        } else {
318            self.parse(&mut handler, &mut ByteStream::new(stream))
319        }
320    }
321
322    /// Set the multipart boundary.
323    pub fn set_boundary(&mut self, boundary: &'a [u8]) {
324        self.boundary = Some(boundary);
325    }
326
327    /// Set the URL encoded length.
328    pub fn set_length(&mut self, length: usize) {
329        self.length = length;
330    }
331
332    /// Retrieve the current state.
333    pub fn state(&self) -> ParserState {
334        self.state
335    }
336
337    // ---------------------------------------------------------------------------------------------
338    // RFC RULES
339    // ---------------------------------------------------------------------------------------------
340
341    /*
342    The following rules are used throughout this specification to describe basic parsing constructs.
343    The US-ASCII coded character set is defined by ANSI X3.4-1986.
344
345    OCTET   = <any 8-bit sequence of data>
346    CHAR    = <any US-ASCII character (octets 0 - 127)>
347    UPALPHA = <any US-ASCII uppercase letter "A".."Z">
348    LOALPHA = <any US-ASCII lowercase letter "a".."z">
349    ALPHA   = UPALPHA | LOALPHA
350    DIGIT   = <any US-ASCII digit "0".."9">
351    CTL     = <any US-ASCII control character
352              (octets 0 - 31) and DEL (127)>
353    CR      = <US-ASCII CR, carriage return (13)>
354    LF      = <US-ASCII LF, linefeed (10)>
355    SP      = <US-ASCII SP, space (32)>
356    HT      = <US-ASCII HT, horizontal-tab (9)>
357    <">     = <US-ASCII double-quote mark (34)>
358
359    HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all protocol elements except
360    the entity-body (see appendix 19.3 for tolerant applications). The end-of-line marker within an
361    entity-body is defined by its associated media type, as described in section 3.7.
362
363    CRLF = CR LF
364
365    HTTP/1.1 header field values can be folded onto multiple lines if the continuation line begins
366    with a space or horizontal tab. All linear white space, including folding, has the same
367    semantics as SP. A recipient MAY replace any linear white space with a single SP before
368    interpreting the field value or forwarding the message downstream.
369
370    LWS  = [CRLF] 1*( SP | HT )
371
372    The TEXT rule is only used for descriptive field contents and values that are not intended to be
373    interpreted by the message parser. Words of *TEXT MAY contain characters from character sets
374    other than ISO- 8859-1 [22] only when encoded according to the rules of RFC 2047.
375
376    TEXT = <any OCTET except CTLs, but including LWS>
377
378    A CRLF is allowed in the definition of TEXT only as part of a header field continuation. It is
379    expected that the folding LWS will be replaced with a single SP before interpretation of the
380    TEXT value.
381
382    Hexadecimal numeric characters are used in several protocol elements.
383
384    HEX  = "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
385
386    Many HTTP/1.1 header field values consist of words separated by LWS or special characters. These
387    special characters MUST be in a quoted string to be used within a parameter value.
388
389    token      = 1*<any CHAR except CTLs or separators>
390    separators = "(" | ")" | "<" | ">" | "@"
391               | "," | ";" | ":" | "\" | <">
392               | "/" | "[" | "]" | "?" | "="
393               | "{" | "}" | SP | HT
394
395    Comments can be included in some HTTP header fields by surrounding the comment text with
396    parentheses. Comments are only allowed in fields containing "comment" as part of their field
397    value definition. In all other fields, parentheses are considered part of the field value.
398
399    comment = "(" *( ctext | quoted-pair | comment ) ")"
400    ctext   = <any TEXT excluding "(" and ")">
401
402    A string of text is parsed as a single word if it is quoted using double-quote marks.
403
404    quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
405    qdtext        = <any TEXT except <">>
406
407    The backslash character ("\") MAY be used as a single-character quoting mechanism only within
408    quoted-string and comment constructs.
409
410    quoted-pair = "\" CHAR
411    */
412
413    // ---------------------------------------------------------------------------------------------
414    // DETECTION STATES
415    // ---------------------------------------------------------------------------------------------
416
417    #[inline]
418    fn strip_detect(&mut self, _handler: &mut T, context: &mut ByteStream)
419    -> Result<ParserValue, ParserError> {
420        bs_available!(context) > 0 || exit_eos!(self, context);
421        bs_next!(context);
422
423        if context.byte == b'\r' || context.byte == b'\n'
424        || context.byte == b'\t' || context.byte == b' ' {
425            loop {
426                bs_available!(context) > 0 || exit_eos!(self, context);
427
428                bs_next!(context);
429
430                if context.byte == b'\r' || context.byte == b'\n'
431                || context.byte == b'\t' || context.byte == b' ' {
432                    continue;
433                }
434
435                break;
436            }
437        }
438
439        bs_replay!(context);
440
441        transition!(
442            self,
443            context,
444            Detect1,
445            detect1
446        );
447    }
448
449    #[inline]
450    fn detect1(&mut self, handler: &mut T, context: &mut ByteStream)
451    -> Result<ParserValue, ParserError> {
452        macro_rules! method {
453            ($method:expr, $length:expr) => (
454                bs_jump!(context, $length);
455
456                callback_transition!(
457                    self,
458                    handler,
459                    context,
460                    on_method,
461                    $method,
462                    RequestUrl1,
463                    request_url1
464                );
465            );
466        }
467
468        macro_rules! version {
469            ($major:expr, $minor:expr, $length:expr) => ({
470                bs_jump!(context, $length);
471                set_state!(
472                    self,
473                    ResponseStatusCode1,
474                    response_status_code1
475                );
476
477                if handler.on_version($major, $minor) {
478                    transition!(self, context);
479                }
480
481                exit_callback!(self, context);
482            });
483        }
484
485        unsafe {
486            if bs_starts_with1!(context, b"H") {
487                if bs_has_bytes!(context, 9) {
488                    if bs_starts_with9!(context, b"HTTP/1.1 ") {
489                        version!(1, 1, 9);
490                    } else if bs_starts_with9!(context, b"HTTP/2.0 ") {
491                        version!(2, 0, 9);
492                    } else if bs_starts_with9!(context, b"HTTP/1.0 ") {
493                        version!(1, 0, 9);
494                    } else if bs_starts_with5!(context, b"HTTP/") {
495                        bs_jump!(context, 5);
496
497                        transition!(
498                            self,
499                            context,
500                            ResponseVersionMajor1,
501                            response_version_major1
502                        );
503                    }
504                } else {
505                    bs_jump!(context, 1);
506
507                    transition!(
508                        self,
509                        context,
510                        Detect2,
511                        detect2
512                    );
513                }
514            }
515
516            if bs_has_bytes!(context, 8) {
517                // have enough bytes to compare all known methods immediately, without collecting
518                // individual tokens
519                if bs_starts_with4!(context, b"GET ") {
520                    method!(b"GET", 4);
521                } else if context.byte == b'P' {
522                    if bs_starts_with5!(context, b"POST ") {
523                        method!(b"POST", 5);
524                    } else if bs_starts_with4!(context, b"PUT ") {
525                        method!(b"PUT", 4);
526                    }
527                } else if bs_starts_with7!(context, b"DELETE ") {
528                    method!(b"DELETE", 7);
529                } else if bs_starts_with8!(context, b"CONNECT ") {
530                    method!(b"CONNECT", 8);
531                } else if bs_starts_with8!(context, b"OPTIONS ") {
532                    method!(b"OPTIONS", 8);
533                } else if bs_starts_with5!(context, b"HEAD ") {
534                    method!(b"HEAD", 5);
535                } else if bs_starts_with6!(context, b"TRACE ") {
536                    method!(b"TRACE", 6);
537                } else if bs_starts_with4!(context, b"PRI ") {
538                    method!(b"PRI", 4);
539                }
540            }
541        }
542
543        exit_if_eos!(self, context);
544        bs_next!(context);
545
546        // make sure we have an upper-cased alphabetical character
547        if context.byte > 0x40 && context.byte < 0x5B {
548            // this is a request
549            transition_no_remark!(
550                self,
551                context,
552                RequestMethod,
553                request_method
554            );
555        }
556
557        Err(ParserError::Method(context.byte))
558    }
559
560    #[inline]
561    fn detect2(&mut self, _handler: &mut T, context: &mut ByteStream)
562    -> Result<ParserValue, ParserError> {
563        exit_if_eos!(self, context);
564        bs_next!(context);
565
566        if context.byte == b'T' {
567            transition!(
568                self,
569                context,
570                Detect3,
571                detect3
572            );
573        }
574
575        // make sure we have an upper-cased alphabetical character
576        if context.byte > 0x40 && context.byte < 0x5B {
577            transition_no_remark!(
578                self,
579                context,
580                RequestMethod,
581                request_method
582            );
583        }
584
585        Err(ParserError::Method(context.byte))
586    }
587
588    #[inline]
589    fn detect3(&mut self, _handler: &mut T, context: &mut ByteStream)
590    -> Result<ParserValue, ParserError> {
591        exit_if_eos!(self, context);
592        bs_next!(context);
593
594        if context.byte == b'T' {
595            transition!(
596                self,
597                context,
598                Detect4,
599                detect4
600            );
601        }
602
603        // make sure we have an upper-cased alphabetical character
604        if context.byte > 0x40 && context.byte < 0x5B {
605            transition_no_remark!(
606                self,
607                context,
608                RequestMethod,
609                request_method
610            );
611        }
612
613        Err(ParserError::Method(context.byte))
614    }
615
616    #[inline]
617    fn detect4(&mut self, _handler: &mut T, context: &mut ByteStream)
618    -> Result<ParserValue, ParserError> {
619        exit_if_eos!(self, context);
620        bs_next!(context);
621
622        if context.byte == b'P' {
623            transition!(
624                self,
625                context,
626                Detect5,
627                detect5
628            );
629        }
630
631        // make sure we have an upper-cased alphabetical character
632        if context.byte > 0x40 && context.byte < 0x5B {
633            transition_no_remark!(
634                self,
635                context,
636                RequestMethod,
637                request_method
638            );
639        }
640
641        Err(ParserError::Method(context.byte))
642    }
643
644    #[inline]
645    fn detect5(&mut self, _handler: &mut T, context: &mut ByteStream)
646    -> Result<ParserValue, ParserError> {
647        exit_if_eos!(self, context);
648        bs_next!(context);
649
650        if context.byte == b'/' {
651            transition!(
652                self,
653                context,
654                ResponseVersionMajor1,
655                response_version_major1
656            );
657        }
658
659        // make sure we have an upper-cased alphabetical character
660        if context.byte > 0x40 && context.byte < 0x5B {
661            transition_no_remark!(
662                self,
663                context,
664                RequestMethod,
665                request_method
666            );
667        }
668
669        Err(ParserError::Method(context.byte))
670    }
671
672    // ---------------------------------------------------------------------------------------------
673    // REQUEST STATES
674    // ---------------------------------------------------------------------------------------------
675
676    #[inline]
677    fn request_method(&mut self, handler: &mut T, context: &mut ByteStream)
678    -> Result<ParserValue, ParserError> {
679        bs_collect!(
680            context,
681
682            // break when non-upper-case is found
683            if context.byte < 0x41 || context.byte > 0x5A {
684                break;
685            },
686
687            // on end-of-stream
688            callback_eos_expr!(self, handler, context, on_method)
689        );
690
691        if context.byte == b' ' {
692            callback_ignore_transition!(
693                self,
694                handler,
695                context,
696                on_method,
697                RequestUrl1,
698                request_url1
699            );
700        }
701
702        Err(ParserError::Method(context.byte))
703    }
704
705    #[inline]
706    fn request_url1(&mut self, _handler: &mut T, context: &mut ByteStream)
707    -> Result<ParserValue, ParserError> {
708        exit_if_eos!(self, context);
709        bs_next!(context);
710
711        if is_visible_7bit!(context.byte) {
712            transition_no_remark!(
713                self,
714                context,
715                RequestUrl2,
716                request_url2
717            );
718        }
719
720        Err(ParserError::Url(context.byte))
721    }
722
723    #[inline]
724    fn request_url2(&mut self, handler: &mut T, context: &mut ByteStream)
725    -> Result<ParserValue, ParserError> {
726        collect_visible_7bit!(
727            context,
728
729            // on end-of-stream
730            callback_eos_expr!(self, handler, context, on_url)
731        );
732
733        if context.byte == b' ' {
734            callback_ignore_transition!(
735                self,
736                handler,
737                context,
738                on_url,
739                RequestHttp1,
740                request_http1
741            );
742        }
743
744        Err(ParserError::Url(context.byte))
745    }
746
747    #[inline]
748    fn request_http1(&mut self, handler: &mut T, context: &mut ByteStream)
749    -> Result<ParserValue, ParserError> {
750        macro_rules! version {
751            ($major:expr, $minor:expr, $length:expr) => (
752                bs_jump!(context, $length);
753                set_state!(self, InitialEnd, initial_end);
754
755                if handler.on_version($major, $minor) {
756                    transition!(self, context);
757                }
758
759                exit_callback!(self, context);
760            );
761        }
762
763        if bs_has_bytes!(context, 9) {
764            // have enough bytes to compare all known versions immediately, without collecting
765            // individual tokens
766            unsafe {
767                if bs_starts_with9!(context, b"HTTP/1.1\r") {
768                    version!(1, 1, 9);
769                } else if bs_starts_with9!(context, b"HTTP/2.0\r") {
770                    version!(2, 0, 9);
771                } else if bs_starts_with9!(context, b"HTTP/1.0\r") {
772                    version!(1, 0, 9);
773                }
774            }
775        }
776
777        exit_if_eos!(self, context);
778        bs_next!(context);
779
780        if context.byte == b'H' {
781            transition!(
782                self,
783                context,
784                RequestHttp2,
785                request_http2
786            );
787        }
788
789        Err(ParserError::Version(context.byte))
790    }
791
792    #[inline]
793    fn request_http2(&mut self, _handler: &mut T, context: &mut ByteStream)
794    -> Result<ParserValue, ParserError> {
795        exit_if_eos!(self, context);
796        bs_next!(context);
797
798        if context.byte == b'T' {
799            transition!(
800                self,
801                context,
802                RequestHttp3,
803                request_http3
804            );
805        }
806
807        Err(ParserError::Version(context.byte))
808    }
809
810    #[inline]
811    fn request_http3(&mut self, _handler: &mut T, context: &mut ByteStream)
812    -> Result<ParserValue, ParserError> {
813        exit_if_eos!(self, context);
814        bs_next!(context);
815
816        if context.byte == b'T' {
817            transition!(
818                self,
819                context,
820                RequestHttp4,
821                request_http4
822            );
823        }
824
825        Err(ParserError::Version(context.byte))
826    }
827
828    #[inline]
829    fn request_http4(&mut self, _handler: &mut T, context: &mut ByteStream)
830    -> Result<ParserValue, ParserError> {
831        exit_if_eos!(self, context);
832        bs_next!(context);
833
834        if context.byte == b'P' {
835            transition!(
836                self,
837                context,
838                RequestHttp5,
839                request_http5
840            );
841        }
842
843        Err(ParserError::Version(context.byte))
844    }
845
846    #[inline]
847    fn request_http5(&mut self, _handler: &mut T, context: &mut ByteStream)
848    -> Result<ParserValue, ParserError> {
849        exit_if_eos!(self, context);
850        bs_next!(context);
851
852        if context.byte == b'/' {
853            transition!(
854                self,
855                context,
856                RequestVersionMajor1,
857                request_version_major1
858            );
859        }
860
861        Err(ParserError::Version(context.byte))
862    }
863
864    #[inline]
865    fn request_version_major1(&mut self, _handler: &mut T, context: &mut ByteStream)
866    -> Result<ParserValue, ParserError> {
867        exit_if_eos!(self, context);
868        bs_next!(context);
869
870        set_lower14!(self, 0);
871        set_upper14!(self, 0);
872
873        if is_digit!(context.byte) {
874            set_lower14!(self, (context.byte - b'0') as u32);
875
876            transition!(
877                self,
878                context,
879                RequestVersionMajor2,
880                request_version_major2
881            );
882        }
883
884        Err(ParserError::Version(context.byte))
885    }
886
887    #[inline]
888    fn request_version_major2(&mut self, _handler: &mut T, context: &mut ByteStream)
889    -> Result<ParserValue, ParserError> {
890        exit_if_eos!(self, context);
891        bs_next!(context);
892
893        if context.byte == b'.' {
894            transition!(
895                self,
896                context,
897                RequestVersionMinor1,
898                request_version_minor1
899            );
900        } else if is_digit!(context.byte) {
901            set_lower14!(self, (get_lower14!(self) * 10) + (context.byte - b'0') as u32);
902
903            transition!(
904                self,
905                context,
906                RequestVersionMajor3,
907                request_version_major3
908            );
909        }
910
911        Err(ParserError::Version(context.byte))
912    }
913
914    #[inline]
915    fn request_version_major3(&mut self, _handler: &mut T, context: &mut ByteStream)
916    -> Result<ParserValue, ParserError> {
917        exit_if_eos!(self, context);
918        bs_next!(context);
919
920        if context.byte == b'.' {
921            transition!(
922                self,
923                context,
924                RequestVersionMinor1,
925                request_version_minor1
926            );
927        } else if is_digit!(context.byte) {
928            set_lower14!(self, (get_lower14!(self) * 10) + (context.byte - b'0') as u32);
929
930            transition!(
931                self,
932                context,
933                RequestVersionPeriod,
934                request_version_period
935            );
936        }
937
938        Err(ParserError::Version(context.byte))
939    }
940
941    #[inline]
942    fn request_version_period(&mut self, _handler: &mut T, context: &mut ByteStream)
943    -> Result<ParserValue, ParserError> {
944        exit_if_eos!(self, context);
945        bs_next!(context);
946
947        if context.byte == b'.' {
948            transition!(
949                self,
950                context,
951                RequestVersionMinor1,
952                request_version_minor1
953            );
954        }
955
956        Err(ParserError::Version(context.byte))
957    }
958
959    #[inline]
960    fn request_version_minor1(&mut self, _handler: &mut T, context: &mut ByteStream)
961    -> Result<ParserValue, ParserError> {
962        exit_if_eos!(self, context);
963        bs_next!(context);
964
965        if is_digit!(context.byte) {
966            set_upper14!(self, (context.byte - b'0') as u32);
967
968            transition!(
969                self,
970                context,
971                RequestVersionMinor2,
972                request_version_minor2
973            );
974        }
975
976        Err(ParserError::Version(context.byte))
977    }
978
979    #[inline]
980    fn request_version_minor2(&mut self, _handler: &mut T, context: &mut ByteStream)
981    -> Result<ParserValue, ParserError> {
982        exit_if_eos!(self, context);
983        bs_next!(context);
984
985        if context.byte == b'\r' {
986            bs_replay!(context);
987
988            transition!(
989                self,
990                context,
991                RequestVersionCr,
992                request_version_cr
993            );
994        } else if is_digit!(context.byte) {
995            set_upper14!(self, (get_upper14!(self) * 10) + (context.byte - b'0') as u32);
996
997            transition!(
998                self,
999                context,
1000                RequestVersionMinor3,
1001                request_version_minor3
1002            );
1003        }
1004
1005        Err(ParserError::Version(context.byte))
1006    }
1007
1008    #[inline]
1009    fn request_version_minor3(&mut self, _handler: &mut T, context: &mut ByteStream)
1010    -> Result<ParserValue, ParserError> {
1011        exit_if_eos!(self, context);
1012        bs_next!(context);
1013
1014        if context.byte == b'\r' {
1015            bs_replay!(context);
1016
1017            transition!(
1018                self,
1019                context,
1020                RequestVersionCr,
1021                request_version_cr
1022            );
1023        } else if is_digit!(context.byte) {
1024            set_upper14!(self, (get_upper14!(self) * 10) + (context.byte - b'0') as u32);
1025
1026            transition!(
1027                self,
1028                context,
1029                RequestVersionCr,
1030                request_version_cr
1031            );
1032        }
1033
1034        Err(ParserError::Version(context.byte))
1035    }
1036
1037    #[inline]
1038    fn request_version_cr(&mut self, handler: &mut T, context: &mut ByteStream)
1039    -> Result<ParserValue, ParserError> {
1040        exit_if_eos!(self, context);
1041        bs_next!(context);
1042
1043        if context.byte == b'\r' {
1044            set_state!(self, InitialEnd, initial_end);
1045
1046            if handler.on_version(get_lower14!(self) as u16, get_upper14!(self) as u16) {
1047                transition!(
1048                    self,
1049                    context
1050                );
1051            }
1052
1053            exit_callback!(self, context);
1054        }
1055
1056        Err(ParserError::Version(context.byte))
1057    }
1058
1059    // ---------------------------------------------------------------------------------------------
1060    // RESPONSE STATES
1061    // ---------------------------------------------------------------------------------------------
1062
1063    #[inline]
1064    fn response_version_major1(&mut self, _handler: &mut T, context: &mut ByteStream)
1065    -> Result<ParserValue, ParserError> {
1066        exit_if_eos!(self, context);
1067        bs_next!(context);
1068
1069        set_lower14!(self, 0);
1070        set_upper14!(self, 0);
1071
1072        if is_digit!(context.byte) {
1073            set_lower14!(self, (context.byte - b'0') as u32);
1074
1075            transition!(
1076                self,
1077                context,
1078                ResponseVersionMajor2,
1079                response_version_major2
1080            );
1081        }
1082
1083        Err(ParserError::Version(context.byte))
1084    }
1085
1086    #[inline]
1087    fn response_version_major2(&mut self, _handler: &mut T, context: &mut ByteStream)
1088    -> Result<ParserValue, ParserError> {
1089        exit_if_eos!(self, context);
1090        bs_next!(context);
1091
1092        if context.byte == b'.' {
1093            transition!(
1094                self,
1095                context,
1096                ResponseVersionMinor1,
1097                response_version_minor1
1098            );
1099        } else if is_digit!(context.byte) {
1100            set_lower14!(self, (get_lower14!(self) * 10) + (context.byte - b'0') as u32);
1101
1102            transition!(
1103                self,
1104                context,
1105                ResponseVersionMajor3,
1106                response_version_major3
1107            );
1108        }
1109
1110        Err(ParserError::Version(context.byte))
1111    }
1112
1113    #[inline]
1114    fn response_version_major3(&mut self, _handler: &mut T, context: &mut ByteStream)
1115    -> Result<ParserValue, ParserError> {
1116        exit_if_eos!(self, context);
1117        bs_next!(context);
1118
1119        if context.byte == b'.' {
1120            transition!(
1121                self,
1122                context,
1123                ResponseVersionMinor1,
1124                response_version_minor1
1125            );
1126        } else if is_digit!(context.byte) {
1127            set_lower14!(self, (get_lower14!(self) * 10) + (context.byte - b'0') as u32);
1128
1129            transition!(
1130                self,
1131                context,
1132                ResponseVersionPeriod,
1133                response_version_period
1134            );
1135        }
1136
1137        Err(ParserError::Version(context.byte))
1138    }
1139
1140    #[inline]
1141    fn response_version_period(&mut self, _handler: &mut T, context: &mut ByteStream)
1142    -> Result<ParserValue, ParserError> {
1143        exit_if_eos!(self, context);
1144        bs_next!(context);
1145
1146        if context.byte == b'.' {
1147            transition!(
1148                self,
1149                context,
1150                ResponseVersionMinor1,
1151                response_version_minor1
1152            );
1153        }
1154
1155        Err(ParserError::Version(context.byte))
1156    }
1157
1158    #[inline]
1159    fn response_version_minor1(&mut self, _handler: &mut T, context: &mut ByteStream)
1160    -> Result<ParserValue, ParserError> {
1161        exit_if_eos!(self, context);
1162        bs_next!(context);
1163
1164        if is_digit!(context.byte) {
1165            set_upper14!(self, (context.byte - b'0') as u32);
1166
1167            transition!(
1168                self,
1169                context,
1170                ResponseVersionMinor2,
1171                response_version_minor2
1172            );
1173        }
1174
1175        Err(ParserError::Version(context.byte))
1176    }
1177
1178    #[inline]
1179    fn response_version_minor2(&mut self, _handler: &mut T, context: &mut ByteStream)
1180    -> Result<ParserValue, ParserError> {
1181        exit_if_eos!(self, context);
1182        bs_next!(context);
1183
1184        if context.byte == b' ' {
1185            bs_replay!(context);
1186
1187            transition!(
1188                self,
1189                context,
1190                ResponseVersionSpace,
1191                response_version_space
1192            );
1193        } else if is_digit!(context.byte) {
1194            set_upper14!(self, (get_upper14!(self) * 10) + (context.byte - b'0') as u32);
1195
1196            transition!(
1197                self,
1198                context,
1199                ResponseVersionMinor3,
1200                response_version_minor3
1201            );
1202        }
1203
1204        Err(ParserError::Version(context.byte))
1205    }
1206
1207    #[inline]
1208    fn response_version_minor3(&mut self, _handler: &mut T, context: &mut ByteStream)
1209    -> Result<ParserValue, ParserError> {
1210        exit_if_eos!(self, context);
1211        bs_next!(context);
1212
1213        if context.byte == b' ' {
1214            bs_replay!(context);
1215
1216            transition!(
1217                self,
1218                context,
1219                ResponseVersionSpace,
1220                response_version_space
1221            );
1222        } else if is_digit!(context.byte) {
1223            set_upper14!(self, (get_upper14!(self) * 10) + (context.byte - b'0') as u32);
1224
1225            transition!(
1226                self,
1227                context,
1228                ResponseVersionSpace,
1229                response_version_space
1230            );
1231        }
1232
1233        Err(ParserError::Version(context.byte))
1234    }
1235
1236    #[inline]
1237    fn response_version_space(&mut self, handler: &mut T, context: &mut ByteStream)
1238    -> Result<ParserValue, ParserError> {
1239        exit_if_eos!(self, context);
1240        bs_next!(context);
1241
1242        if context.byte == b' ' {
1243            set_state!(
1244                self,
1245                ResponseStatusCode1,
1246                response_status_code1
1247            );
1248
1249            if handler.on_version(get_lower14!(self) as u16, get_upper14!(self) as u16) {
1250                transition!(
1251                    self,
1252                    context
1253                );
1254            }
1255
1256            exit_callback!(self, context);
1257        }
1258
1259        Err(ParserError::Version(context.byte))
1260    }
1261
1262    #[inline]
1263    fn response_status_code1(&mut self, _handler: &mut T, context: &mut ByteStream)
1264    -> Result<ParserValue, ParserError> {
1265        exit_if_eos!(self, context);
1266
1267        if bs_available!(context) > 2 {
1268            // have enough bytes to compare the entire status code
1269            bs_next!(context);
1270
1271            if !is_digit!(context.byte) {
1272                exit_error!(StatusCode, context.byte);
1273            }
1274
1275            set_lower14!(self, (context.byte - b'0') as u32 * 100);
1276
1277            bs_next!(context);
1278
1279            if !is_digit!(context.byte) {
1280                exit_error!(StatusCode, context.byte);
1281            }
1282
1283            set_lower14!(self, get_lower14!(self) + (context.byte - b'0') as u32 * 10);
1284
1285            bs_next!(context);
1286
1287            if !is_digit!(context.byte) {
1288                exit_error!(StatusCode, context.byte);
1289            }
1290
1291            set_lower14!(self, get_lower14!(self) + (context.byte - b'0') as u32);
1292
1293            transition!(
1294                self,
1295                context,
1296                ResponseStatusCodeSpace,
1297                response_status_code_space
1298            );
1299        }
1300
1301        bs_next!(context);
1302
1303        if is_digit!(context.byte) {
1304            set_lower14!(self, (context.byte - b'0') as u32 * 100);
1305
1306            transition!(
1307                self,
1308                context,
1309                ResponseStatusCode2,
1310                response_status_code2
1311            );
1312        }
1313
1314        Err(ParserError::StatusCode(context.byte))
1315    }
1316
1317    #[inline]
1318    fn response_status_code2(&mut self, _handler: &mut T, context: &mut ByteStream)
1319    -> Result<ParserValue, ParserError> {
1320        exit_if_eos!(self, context);
1321        bs_next!(context);
1322
1323        if is_digit!(context.byte) {
1324            set_lower14!(self, get_lower14!(self) + (context.byte - b'0') as u32 * 10);
1325
1326            transition!(
1327                self,
1328                context,
1329                ResponseStatusCode3,
1330                response_status_code3
1331            );
1332        }
1333
1334        Err(ParserError::StatusCode(context.byte))
1335    }
1336
1337    #[inline]
1338    fn response_status_code3(&mut self, _handler: &mut T, context: &mut ByteStream)
1339    -> Result<ParserValue, ParserError> {
1340        exit_if_eos!(self, context);
1341        bs_next!(context);
1342
1343        if is_digit!(context.byte) {
1344            set_lower14!(self, get_lower14!(self) + (context.byte - b'0') as u32);
1345
1346            transition!(
1347                self,
1348                context,
1349                ResponseStatusCodeSpace,
1350                response_status_code_space
1351            );
1352        }
1353
1354        Err(ParserError::StatusCode(context.byte))
1355    }
1356
1357    #[inline]
1358    fn response_status_code_space(&mut self, handler: &mut T, context: &mut ByteStream)
1359    -> Result<ParserValue, ParserError> {
1360        exit_if_eos!(self, context);
1361        bs_next!(context);
1362
1363        if context.byte == b' ' {
1364            set_state!(
1365                self,
1366                ResponseStatus1,
1367                response_status1
1368            );
1369
1370            if handler.on_status_code(get_lower14!(self) as u16) {
1371                transition!(
1372                    self,
1373                    context
1374                );
1375            }
1376
1377            exit_callback!(self, context);
1378        }
1379
1380        Err(ParserError::StatusCode(context.byte))
1381    }
1382
1383    #[inline]
1384    fn response_status1(&mut self, _handler: &mut T, context: &mut ByteStream)
1385    -> Result<ParserValue, ParserError> {
1386        exit_if_eos!(self, context);
1387        bs_next!(context);
1388
1389        // status is any 8bit non-control byte
1390        if context.byte > 0x1F && context.byte != 0x7F {
1391            bs_replay!(context);
1392
1393            transition!(
1394                self,
1395                context,
1396                ResponseStatus2,
1397                response_status2
1398            );
1399        }
1400
1401        Err(ParserError::Status(context.byte))
1402    }
1403
1404    #[inline]
1405    fn response_status2(&mut self, handler: &mut T, context: &mut ByteStream)
1406    -> Result<ParserValue, ParserError> {
1407        bs_collect!(
1408            context,
1409
1410            // collect loop
1411            if context.byte > 0x1F && context.byte != 0x7F {
1412                continue;
1413            } else if context.byte == b'\r' {
1414                break;
1415            } else {
1416                exit_error!(Status, context.byte);
1417            },
1418
1419            // on end-of-stream
1420            callback!(self, handler, context, on_status, {
1421                exit_eos!(self, context);
1422            })
1423        );
1424
1425        callback_ignore_transition!(
1426            self,
1427            handler,
1428            context,
1429            on_status,
1430            InitialEnd,
1431            initial_end
1432        );
1433    }
1434
1435    // ---------------------------------------------------------------------------------------------
1436    // HEADER STATES
1437    // ---------------------------------------------------------------------------------------------
1438
1439    #[inline]
1440    fn initial_end(&mut self, handler: &mut T, context: &mut ByteStream)
1441    -> Result<ParserValue, ParserError> {
1442        set_state!(self, InitialLf, initial_lf);
1443
1444        if handler.on_initial_finished() {
1445            transition!(self, context);
1446        }
1447
1448        exit_callback!(self, context);
1449    }
1450
1451    #[inline]
1452    fn initial_lf(&mut self, _handler: &mut T, context: &mut ByteStream)
1453    -> Result<ParserValue, ParserError> {
1454        exit_if_eos!(self, context);
1455        bs_next!(context);
1456
1457        if context.byte == b'\n' {
1458            transition!(
1459                self,
1460                context,
1461                HeaderCr2,
1462                header_cr2
1463            );
1464        }
1465
1466        Err(ParserError::CrlfSequence(context.byte))
1467    }
1468
1469    #[inline]
1470    fn check_header_name(&mut self, _handler: &mut T, context: &mut ByteStream)
1471    -> Result<ParserValue, ParserError> {
1472        exit_if_eos!(self, context);
1473        bs_next!(context);
1474
1475        if context.byte == b' ' || context.byte == b'\t' {
1476            // multiline value
1477            transition!(
1478                self,
1479                context,
1480                HeaderValue,
1481                header_value
1482            );
1483        }
1484
1485        bs_replay!(context);
1486
1487        transition!(
1488            self,
1489            context,
1490            FirstHeaderName,
1491            first_header_name
1492        );
1493    }
1494
1495    #[inline]
1496    fn first_header_name(&mut self, handler: &mut T, context: &mut ByteStream)
1497    -> Result<ParserValue, ParserError> {
1498        macro_rules! name {
1499            ($header:expr, $length:expr) => ({
1500                bs_jump!(context, $length);
1501
1502                callback_transition!(
1503                    self,
1504                    handler,
1505                    context,
1506                    on_header_name,
1507                    $header,
1508                    StripHeaderValue,
1509                    strip_header_value
1510                );
1511            });
1512        }
1513
1514        if bs_has_bytes!(context, 24) {
1515            // have enough bytes to compare common header names immediately
1516            unsafe {
1517                if context.byte == b'A' {
1518                    if bs_starts_with7!(context, b"Accept:") {
1519                        name!(b"accept", 7);
1520                    } else if bs_starts_with15!(context, b"Accept-Charset:") {
1521                        name!(b"accept-charset", 15);
1522                    } else if bs_starts_with16!(context, b"Accept-Encoding:") {
1523                        name!(b"accept-encoding", 16);
1524                    } else if bs_starts_with16!(context, b"Accept-Language:") {
1525                        name!(b"accept-language", 16);
1526                    } else if bs_starts_with14!(context, b"Authorization:") {
1527                        name!(b"authorization", 14);
1528                    }
1529                } else if bs_starts_with5!(context, b"Host:") {
1530                    name!(b"host", 5);
1531                } else if context.byte == b'U' {
1532                    if bs_starts_with11!(context, b"User-Agent:") {
1533                        name!(b"user-agent", 11);
1534                    } else if bs_starts_with8!(context, b"Upgrade:") {
1535                        name!(b"upgrade", 8);
1536                    }
1537                } else if context.byte == b'C' {
1538                    if bs_starts_with11!(context, b"Connection:") {
1539                        name!(b"connection", 11);
1540                    } else if bs_starts_with13!(context, b"Content-Type:") {
1541                        name!(b"content-type", 13);
1542                    } else if bs_starts_with15!(context, b"Content-Length:") {
1543                        name!(b"content-length", 15);
1544                    } else if bs_starts_with7!(context, b"Cookie:") {
1545                        name!(b"cookie", 7);
1546                    } else if bs_starts_with14!(context, b"Cache-Control:") {
1547                        name!(b"cache-control", 14);
1548                    } else if bs_starts_with24!(context, b"Content-Security-Policy:") {
1549                        name!(b"content-security-policy", 24);
1550                    }
1551                } else if context.byte == b'L' {
1552                    if bs_starts_with9!(context, b"Location:") {
1553                        name!(b"location", 9);
1554                    } else if bs_starts_with14!(context, b"Last-Modified:") {
1555                        name!(b"last-modified", 14);
1556                    }
1557                } else if bs_starts_with7!(context, b"Pragma:") {
1558                    name!(b"pragma", 7);
1559                } else if bs_starts_with11!(context, b"Set-Cookie:") {
1560                    name!(b"set-cookie", 11);
1561                } else if bs_starts_with18!(context, b"Transfer-Encoding:") {
1562                    name!(b"transfer-encoding", 18);
1563                } else if context.byte == b'X' {
1564                    if bs_starts_with13!(context, b"X-Powered-By:") {
1565                        name!(b"x-powered-by", 13);
1566                    } else if bs_starts_with16!(context, b"X-Forwarded-For:") {
1567                        name!(b"x-forwarded-for", 16);
1568                    } else if bs_starts_with17!(context, b"X-Forwarded-Host:") {
1569                        name!(b"x-forwarded-host", 17);
1570                    } else if bs_starts_with17!(context, b"X-XSS-Protection:") {
1571                        name!(b"x-xss-protection", 17);
1572                    } else if bs_starts_with13!(context, b"X-WebKit-CSP:") {
1573                        name!(b"x-webkit-csp", 13);
1574                    }
1575                } else if bs_starts_with17!(context, b"WWW-Authenticate:") {
1576                    name!(b"www-authenticate", 17);
1577                }
1578            }
1579        }
1580
1581        exit_if_eos!(self, context);
1582        bs_next!(context);
1583
1584        // make sure we have something visible to collect in next state
1585        if is_visible_7bit!(context.byte) {
1586            bs_replay!(context);
1587
1588            transition!(
1589                self,
1590                context,
1591                UpperHeaderName,
1592                upper_header_name
1593            );
1594        }
1595
1596        Err(ParserError::HeaderName(context.byte))
1597    }
1598
1599    #[inline]
1600    fn upper_header_name(&mut self, handler: &mut T, context: &mut ByteStream)
1601    -> Result<ParserValue, ParserError> {
1602        exit_if_eos!(self, context);
1603        bs_next!(context);
1604
1605        if context.byte > 0x40 && context.byte < 0x5B {
1606            // upper-cased byte, let's lower-case it
1607            callback_transition!(
1608                self,
1609                handler,
1610                context,
1611                on_header_name,
1612                &[context.byte + 0x20],
1613                LowerHeaderName,
1614                lower_header_name
1615            );
1616        }
1617
1618        bs_replay!(context);
1619
1620        transition!(
1621            self,
1622            context,
1623            LowerHeaderName,
1624            lower_header_name
1625        );
1626    }
1627
1628    #[inline]
1629    fn lower_header_name(&mut self, handler: &mut T, context: &mut ByteStream)
1630    -> Result<ParserValue, ParserError> {
1631        collect_tokens!(
1632            context,
1633
1634            // stop on these bytes
1635            context.byte > 0x40 && context.byte < 0x5B,
1636
1637            // on end-of-stream
1638            callback_eos_expr!(self, handler, context, on_header_name)
1639        );
1640
1641        if context.byte > 0x40 && context.byte < 0x5B {
1642            // upper-cased byte
1643            bs_replay!(context);
1644
1645            callback_transition!(
1646                self,
1647                handler,
1648                context,
1649                on_header_name,
1650                UpperHeaderName,
1651                upper_header_name
1652            );
1653        } else if context.byte == b':' {
1654            callback_ignore_transition!(
1655                self,
1656                handler,
1657                context,
1658                on_header_name,
1659                StripHeaderValue,
1660                strip_header_value
1661            );
1662        }
1663
1664        Err(ParserError::HeaderName(context.byte))
1665    }
1666
1667    #[inline]
1668    fn strip_header_value(&mut self, _handler: &mut T, context: &mut ByteStream)
1669    -> Result<ParserValue, ParserError> {
1670        consume_linear_space!(
1671            context,
1672
1673            // on end-of-stream
1674            exit_eos!(self, context)
1675        );
1676
1677        // make sure we have something visible to collect in next state
1678        if is_visible_7bit!(context.byte) {
1679            bs_replay!(context);
1680
1681            transition!(
1682                self,
1683                context,
1684                HeaderValue,
1685                header_value
1686            );
1687        }
1688
1689        Err(ParserError::HeaderValue(context.byte))
1690    }
1691
1692    #[inline]
1693    fn header_value(&mut self, handler: &mut T, context: &mut ByteStream)
1694    -> Result<ParserValue, ParserError> {
1695        collect_field!(
1696            context,
1697
1698            // on end-of-stream
1699            callback_eos_expr!(self, handler, context, on_header_value)
1700        );
1701
1702        if context.byte == b'\r' {
1703            callback_ignore_transition!(
1704                self,
1705                handler,
1706                context,
1707                on_header_value,
1708                HeaderLf1,
1709                header_lf1
1710            );
1711        } else if context.byte == b'"' {
1712            transition_no_remark!(
1713                self,
1714                context,
1715                HeaderQuotedValue,
1716                header_quoted_value
1717            );
1718        }
1719
1720        Err(ParserError::HeaderValue(context.byte))
1721    }
1722
1723    #[inline]
1724    fn header_quoted_value(&mut self, handler: &mut T, context: &mut ByteStream)
1725    -> Result<ParserValue, ParserError> {
1726        collect_quoted_field!(
1727            context,
1728
1729            // on end-of-stream
1730            callback_eos_expr!(self, handler, context, on_header_value)
1731        );
1732
1733        if context.byte == b'"' {
1734            transition_no_remark!(
1735                self,
1736                context,
1737                HeaderValue,
1738                header_value
1739            );
1740        } else if context.byte == b'\\' {
1741            transition_no_remark!(
1742                self,
1743                context,
1744                HeaderEscapedValue,
1745                header_escaped_value
1746            );
1747        }
1748
1749        Err(ParserError::HeaderValue(context.byte))
1750    }
1751
1752    #[inline]
1753    fn header_escaped_value(&mut self, handler: &mut T, context: &mut ByteStream)
1754    -> Result<ParserValue, ParserError> {
1755        // since we're not collecting, and because it's EOS, we must execute the callback
1756        // manually
1757        if bs_available!(context) == 0 {
1758            callback_eos_expr!(self, handler, context, on_header_value);
1759        }
1760
1761        bs_next!(context);
1762
1763        // escaped bytes must be 7bit, and cannot be control characters
1764        if context.byte > 0x1F && context.byte < 0x7B {
1765            callback_transition!(
1766                self,
1767                handler,
1768                context,
1769                on_header_value,
1770                HeaderQuotedValue,
1771                header_quoted_value
1772            );
1773        }
1774
1775        Err(ParserError::HeaderValue(context.byte))
1776    }
1777
1778    #[inline]
1779    fn header_cr1(&mut self, _handler: &mut T, context: &mut ByteStream)
1780    -> Result<ParserValue, ParserError> {
1781        unsafe {
1782            if bs_has_bytes!(context, 2) && bs_starts_with2!(context, b"\r\n") {
1783                bs_jump!(context, 2);
1784
1785                transition!(
1786                    self,
1787                    context,
1788                    HeaderCr2,
1789                    header_cr2
1790                );
1791            }
1792        }
1793
1794        exit_if_eos!(self, context);
1795        bs_next!(context);
1796
1797        if context.byte == b'\r' {
1798            transition!(
1799                self,
1800                context,
1801                HeaderLf1,
1802                header_lf1
1803            );
1804        }
1805
1806        Err(ParserError::CrlfSequence(context.byte))
1807    }
1808
1809    #[inline]
1810    fn header_lf1(&mut self, _handler: &mut T, context: &mut ByteStream)
1811    -> Result<ParserValue, ParserError> {
1812        exit_if_eos!(self, context);
1813        bs_next!(context);
1814
1815        if context.byte == b'\n' {
1816            transition!(
1817                self,
1818                context,
1819                HeaderCr2,
1820                header_cr2
1821            );
1822        }
1823
1824        Err(ParserError::CrlfSequence(context.byte))
1825    }
1826
1827    #[inline]
1828    fn header_cr2(&mut self, _handler: &mut T, context: &mut ByteStream)
1829    -> Result<ParserValue, ParserError> {
1830        unsafe {
1831            if bs_has_bytes!(context, 2) && bs_starts_with2!(context, b"\r\n") {
1832                bs_jump!(context, 2);
1833
1834                transition!(
1835                    self,
1836                    context,
1837                    HeaderEnd,
1838                    header_end
1839                );
1840            }
1841        }
1842
1843        exit_if_eos!(self, context);
1844        bs_next!(context);
1845
1846        if context.byte == b'\r' {
1847            transition!(
1848                self,
1849                context,
1850                HeaderLf2,
1851                header_lf2
1852            );
1853        }
1854
1855        bs_replay!(context);
1856
1857        transition!(
1858            self,
1859            context,
1860            CheckHeaderName,
1861            check_header_name
1862        );
1863    }
1864
1865    #[inline]
1866    fn header_lf2(&mut self, _handler: &mut T, context: &mut ByteStream)
1867    -> Result<ParserValue, ParserError> {
1868        exit_if_eos!(self, context);
1869        bs_next!(context);
1870
1871        if context.byte == b'\n' {
1872            transition!(
1873                self,
1874                context,
1875                HeaderEnd,
1876                header_end
1877            );
1878        }
1879
1880        Err(ParserError::CrlfSequence(context.byte))
1881    }
1882
1883    #[inline]
1884    fn header_end(&mut self, handler: &mut T, context: &mut ByteStream)
1885    -> Result<ParserValue, ParserError> {
1886        if let ParserType::Chunked = self.parser_type {
1887            set_state!(self, BodyFinished, body_finished);
1888        } else if let ParserType::Multipart = self.parser_type {
1889            set_state!(self, MultipartDetectData, multipart_detect_data);
1890        } else {
1891            set_state!(self, Finished, finished);
1892        }
1893
1894        if handler.on_headers_finished() {
1895            transition!(self, context);
1896        }
1897
1898        exit_callback!(self, context);
1899    }
1900
1901    // ---------------------------------------------------------------------------------------------
1902    // CHUNK STATES
1903    // ---------------------------------------------------------------------------------------------
1904
1905    #[inline]
1906    fn chunk_length1(&mut self, handler: &mut T, context: &mut ByteStream)
1907    -> Result<ParserValue, ParserError> {
1908        exit_if_eos!(self, context);
1909        bs_next!(context);
1910
1911        if context.byte == b'0' {
1912            set_state!(self, ChunkLengthCr, chunk_length_cr);
1913        } else if is_hex!(context.byte) {
1914            self.length = hex_to_byte!(context.byte) as usize;
1915
1916            set_state!(self, ChunkLength2, chunk_length2);
1917        } else {
1918            exit_error!(ChunkLength, context.byte);
1919        }
1920
1921        if handler.on_chunk_begin() {
1922            transition!(self, context);
1923        }
1924
1925        exit_callback!(self, context);
1926    }
1927
1928    #[inline]
1929    fn chunk_length2(&mut self, _handler: &mut T, context: &mut ByteStream)
1930    -> Result<ParserValue, ParserError> {
1931        exit_if_eos!(self, context);
1932        bs_next!(context);
1933
1934        if is_hex!(context.byte) {
1935            self.length <<= 4;
1936            self.length  |= hex_to_byte!(context.byte) as usize;
1937
1938            transition!(
1939                self,
1940                context,
1941                ChunkLength3,
1942                chunk_length3
1943            );
1944        }
1945
1946        bs_replay!(context);
1947
1948        transition!(
1949            self,
1950            context,
1951            ChunkLengthCr,
1952            chunk_length_cr
1953        );
1954    }
1955
1956    #[inline]
1957    fn chunk_length3(&mut self, _handler: &mut T, context: &mut ByteStream)
1958    -> Result<ParserValue, ParserError> {
1959        exit_if_eos!(self, context);
1960        bs_next!(context);
1961
1962        if is_hex!(context.byte) {
1963            self.length <<= 4;
1964            self.length  |= hex_to_byte!(context.byte) as usize;
1965
1966            transition!(
1967                self,
1968                context,
1969                ChunkLength4,
1970                chunk_length4
1971            );
1972        }
1973
1974        bs_replay!(context);
1975
1976        transition!(
1977            self,
1978            context,
1979            ChunkLengthCr,
1980            chunk_length_cr
1981        );
1982    }
1983
1984    #[inline]
1985    fn chunk_length4(&mut self, _handler: &mut T, context: &mut ByteStream)
1986    -> Result<ParserValue, ParserError> {
1987        exit_if_eos!(self, context);
1988        bs_next!(context);
1989
1990        if is_hex!(context.byte) {
1991            self.length <<= 4;
1992            self.length  |= hex_to_byte!(context.byte) as usize;
1993
1994            transition!(
1995                self,
1996                context,
1997                ChunkLength5,
1998                chunk_length5
1999            );
2000        }
2001
2002        bs_replay!(context);
2003
2004        transition!(
2005            self,
2006            context,
2007            ChunkLengthCr,
2008            chunk_length_cr
2009        );
2010    }
2011
2012    #[inline]
2013    fn chunk_length5(&mut self, _handler: &mut T, context: &mut ByteStream)
2014    -> Result<ParserValue, ParserError> {
2015        exit_if_eos!(self, context);
2016        bs_next!(context);
2017
2018        if is_hex!(context.byte) {
2019            self.length <<= 4;
2020            self.length  |= hex_to_byte!(context.byte) as usize;
2021
2022            transition!(
2023                self,
2024                context,
2025                ChunkLength6,
2026                chunk_length6
2027            );
2028        }
2029
2030        bs_replay!(context);
2031
2032        transition!(
2033            self,
2034            context,
2035            ChunkLengthCr,
2036            chunk_length_cr
2037        );
2038    }
2039
2040    #[inline]
2041    fn chunk_length6(&mut self, _handler: &mut T, context: &mut ByteStream)
2042    -> Result<ParserValue, ParserError> {
2043        exit_if_eos!(self, context);
2044        bs_next!(context);
2045
2046        if is_hex!(context.byte) {
2047            self.length <<= 4;
2048            self.length  |= hex_to_byte!(context.byte) as usize;
2049
2050            transition!(
2051                self,
2052                context,
2053                ChunkLength7,
2054                chunk_length7
2055            );
2056        }
2057
2058        bs_replay!(context);
2059
2060        transition!(
2061            self,
2062            context,
2063            ChunkLengthCr,
2064            chunk_length_cr
2065        );
2066    }
2067
2068    #[inline]
2069    fn chunk_length7(&mut self, _handler: &mut T, context: &mut ByteStream)
2070    -> Result<ParserValue, ParserError> {
2071        exit_if_eos!(self, context);
2072        bs_next!(context);
2073
2074        if is_hex!(context.byte) {
2075            self.length <<= 4;
2076            self.length  |= hex_to_byte!(context.byte) as usize;
2077
2078            transition!(
2079                self,
2080                context,
2081                ChunkLength8,
2082                chunk_length8
2083            );
2084        }
2085
2086        bs_replay!(context);
2087
2088        transition!(
2089            self,
2090            context,
2091            ChunkLengthCr,
2092            chunk_length_cr
2093        );
2094    }
2095
2096    #[inline]
2097    fn chunk_length8(&mut self, _handler: &mut T, context: &mut ByteStream)
2098    -> Result<ParserValue, ParserError> {
2099        exit_if_eos!(self, context);
2100        bs_next!(context);
2101
2102        if is_hex!(context.byte) {
2103            self.length <<= 4;
2104            self.length  |= hex_to_byte!(context.byte) as usize;
2105        } else {
2106            bs_replay!(context);
2107        }
2108
2109        transition!(
2110            self,
2111            context,
2112            ChunkLengthCr,
2113            chunk_length_cr
2114        );
2115    }
2116
2117    #[inline]
2118    fn chunk_length_cr(&mut self, handler: &mut T, context: &mut ByteStream)
2119    -> Result<ParserValue, ParserError> {
2120        exit_if_eos!(self, context);
2121        bs_next!(context);
2122
2123        if context.byte == b'\r' {
2124            if self.length == 0 {
2125                callback_transition!(
2126                    self,
2127                    handler,
2128                    context,
2129                    on_chunk_length,
2130                    self.length,
2131                    HeaderLf1,
2132                    header_lf1
2133                );
2134            }
2135
2136            callback_transition!(
2137                self,
2138                handler,
2139                context,
2140                on_chunk_length,
2141                self.length,
2142                ChunkExtensionsFinished,
2143                chunk_extensions_finished
2144            );
2145        } else if context.byte == b';' {
2146            callback_transition!(
2147                self,
2148                handler,
2149                context,
2150                on_chunk_length,
2151                self.length,
2152                StripChunkExtensionName,
2153                strip_chunk_extension_name
2154            );
2155        }
2156
2157        Err(ParserError::ChunkLength(context.byte))
2158    }
2159
2160    #[inline]
2161    fn chunk_length_lf(&mut self, _handler: &mut T, context: &mut ByteStream)
2162    -> Result<ParserValue, ParserError> {
2163        exit_if_eos!(self, context);
2164        bs_next!(context);
2165
2166        if context.byte == b'\n' {
2167            transition!(
2168                self,
2169                context,
2170                ChunkData,
2171                chunk_data
2172            );
2173        }
2174
2175        Err(ParserError::CrlfSequence(context.byte))
2176    }
2177
2178    #[inline]
2179    fn strip_chunk_extension_name(&mut self, _handler: &mut T, context: &mut ByteStream)
2180    -> Result<ParserValue, ParserError> {
2181        consume_linear_space!(
2182            context,
2183
2184            // on end-of-stream
2185            exit_eos!(self, context)
2186        );
2187
2188        // make sure we have something visible to collect in next state
2189        if is_visible_7bit!(context.byte) {
2190            bs_replay!(context);
2191
2192            transition!(
2193                self,
2194                context,
2195                LowerChunkExtensionName,
2196                lower_chunk_extension_name
2197            );
2198        }
2199
2200        Err(ParserError::ChunkExtensionName(context.byte))
2201    }
2202
2203    #[inline]
2204    fn lower_chunk_extension_name(&mut self, handler: &mut T, context: &mut ByteStream)
2205    -> Result<ParserValue, ParserError> {
2206        collect_tokens!(
2207            context,
2208
2209            // stop on these bytes
2210            context.byte > 0x40 && context.byte < 0x5B,
2211
2212            // on end-of-stream
2213            callback_eos_expr!(self, handler, context, on_chunk_extension_name)
2214        );
2215
2216        if context.byte == b'=' {
2217            callback_ignore_transition!(
2218                self,
2219                handler,
2220                context,
2221                on_chunk_extension_name,
2222                StripChunkExtensionValue,
2223                strip_chunk_extension_value
2224            );
2225        } else if context.byte == b'\r' || context.byte == b';' {
2226            // extension name without a value
2227            bs_replay!(context);
2228
2229            callback_transition!(
2230                self,
2231                handler,
2232                context,
2233                on_chunk_extension_name,
2234                ChunkExtensionFinished,
2235                chunk_extension_finished
2236            );
2237        } else if context.byte > 0x40 && context.byte < 0x5B {
2238            // upper-cased byte
2239            bs_replay!(context);
2240
2241            callback_transition!(
2242                self,
2243                handler,
2244                context,
2245                on_chunk_extension_name,
2246                UpperChunkExtensionName,
2247                upper_chunk_extension_name
2248            );
2249        }
2250
2251        Err(ParserError::ChunkExtensionName(context.byte))
2252    }
2253
2254    #[inline]
2255    fn upper_chunk_extension_name(&mut self, handler: &mut T, context: &mut ByteStream)
2256    -> Result<ParserValue, ParserError> {
2257        exit_if_eos!(self, context);
2258        bs_next!(context);
2259
2260        if context.byte > 0x40 && context.byte < 0x5B {
2261            callback_transition!(
2262                self,
2263                handler,
2264                context,
2265                on_chunk_extension_name,
2266                &[context.byte + 0x20],
2267                LowerChunkExtensionName,
2268                lower_chunk_extension_name
2269            );
2270        }
2271
2272        bs_replay!(context);
2273
2274        transition!(
2275            self,
2276            context,
2277            LowerChunkExtensionName,
2278            lower_chunk_extension_name
2279        );
2280    }
2281
2282    #[inline]
2283    fn strip_chunk_extension_value(&mut self, _handler: &mut T, context: &mut ByteStream)
2284    -> Result<ParserValue, ParserError> {
2285        consume_linear_space!(
2286            context,
2287
2288            // on end-of-stream
2289            exit_eos!(self, context)
2290        );
2291
2292        // make sure we have something visible to collect in next state
2293        if is_visible_7bit!(context.byte) {
2294            bs_replay!(context);
2295
2296            transition!(
2297                self,
2298                context,
2299                ChunkExtensionValue,
2300                chunk_extension_value
2301            );
2302        }
2303
2304        Err(ParserError::ChunkExtensionValue(context.byte))
2305    }
2306
2307    #[inline]
2308    fn chunk_extension_value(&mut self, handler: &mut T, context: &mut ByteStream)
2309    -> Result<ParserValue, ParserError> {
2310        collect_field!(
2311            context,
2312
2313            // stop on these bytes
2314            context.byte == b';',
2315
2316            // on end-of-stream
2317            callback_eos_expr!(self, handler, context, on_chunk_extension_value)
2318        );
2319
2320        if context.byte == b'\r' || context.byte == b';' {
2321            bs_replay!(context);
2322
2323            callback_transition!(
2324                self,
2325                handler,
2326                context,
2327                on_chunk_extension_value,
2328                ChunkExtensionFinished,
2329                chunk_extension_finished
2330            );
2331        } else if context.byte == b'"' {
2332            callback_ignore_transition!(
2333                self,
2334                handler,
2335                context,
2336                on_chunk_extension_value,
2337                ChunkExtensionQuotedValue,
2338                chunk_extension_quoted_value
2339            );
2340        }
2341
2342        Err(ParserError::ChunkExtensionValue(context.byte))
2343    }
2344
2345    #[inline]
2346    fn chunk_extension_quoted_value(&mut self, handler: &mut T, context: &mut ByteStream)
2347    -> Result<ParserValue, ParserError> {
2348        collect_quoted_field!(
2349            context,
2350
2351            // on end-of-stream
2352            callback_eos_expr!(self, handler, context, on_chunk_extension_value)
2353        );
2354
2355        if context.byte == b'"' {
2356            callback_ignore_transition!(
2357                self,
2358                handler,
2359                context,
2360                on_chunk_extension_value,
2361                ChunkExtensionValue,
2362                chunk_extension_value
2363            );
2364        } else if context.byte == b'\\' {
2365            callback_ignore_transition!(
2366                self,
2367                handler,
2368                context,
2369                on_chunk_extension_value,
2370                ChunkExtensionEscapedValue,
2371                chunk_extension_escaped_value
2372            );
2373        }
2374
2375        Err(ParserError::ChunkExtensionValue(context.byte))
2376    }
2377
2378    #[inline]
2379    fn chunk_extension_escaped_value(&mut self, handler: &mut T, context: &mut ByteStream)
2380    -> Result<ParserValue, ParserError> {
2381        exit_if_eos!(self, context);
2382        bs_next!(context);
2383
2384        // escaped bytes must be 7bit, and cannot be control characters
2385        if context.byte > 0x1F && context.byte < 0x7B {
2386            callback_transition!(
2387                self,
2388                handler,
2389                context,
2390                on_chunk_extension_value,
2391                &[context.byte],
2392                ChunkExtensionQuotedValue,
2393                chunk_extension_quoted_value
2394            );
2395        }
2396
2397        Err(ParserError::ChunkExtensionValue(context.byte))
2398    }
2399
2400    #[inline]
2401    fn chunk_extension_finished(&mut self, handler: &mut T, context: &mut ByteStream)
2402    -> Result<ParserValue, ParserError> {
2403        exit_if_eos!(self, context);
2404        bs_next!(context);
2405
2406        if context.byte == b'\r' {
2407            set_state!(self, ChunkExtensionsFinished, chunk_extensions_finished);
2408        } else {
2409            set_state!(self, StripChunkExtensionName, strip_chunk_extension_name);
2410        }
2411
2412        if handler.on_chunk_extension_finished() {
2413            transition!(self, context);
2414        }
2415
2416        exit_callback!(self, context);
2417    }
2418
2419    #[inline]
2420    fn chunk_extensions_finished(&mut self, handler: &mut T, context: &mut ByteStream)
2421    -> Result<ParserValue, ParserError> {
2422        set_state!(self, ChunkLengthLf, chunk_length_lf);
2423
2424        if handler.on_chunk_extensions_finished() {
2425            transition!(
2426                self,
2427                context
2428            );
2429        }
2430
2431        exit_callback!(self, context);
2432    }
2433
2434    #[inline]
2435    fn chunk_data(&mut self, handler: &mut T, context: &mut ByteStream)
2436    -> Result<ParserValue, ParserError> {
2437        exit_if_eos!(self, context);
2438
2439        if bs_available!(context) >= self.length {
2440            // collect remaining chunk data
2441            bs_collect_length!(context, self.length);
2442
2443            self.length = 0;
2444
2445            callback_transition!(
2446                self,
2447                handler,
2448                context,
2449                on_chunk_data,
2450                ChunkDataCr,
2451                chunk_data_cr
2452            );
2453        }
2454
2455        // collect remaining stream data
2456        self.length -= bs_available!(context);
2457
2458        bs_collect_length!(context, bs_available!(context));
2459
2460        callback_transition!(
2461            self,
2462            handler,
2463            context,
2464            on_chunk_data,
2465            ChunkData,
2466            chunk_data
2467        );
2468    }
2469
2470    #[inline]
2471    fn chunk_data_cr(&mut self, _handler: &mut T, context: &mut ByteStream)
2472    -> Result<ParserValue, ParserError> {
2473        exit_if_eos!(self, context);
2474        bs_next!(context);
2475
2476        if context.byte == b'\r' {
2477            transition!(
2478                self,
2479                context,
2480                ChunkDataLf,
2481                chunk_data_lf
2482            );
2483        }
2484
2485        Err(ParserError::CrlfSequence(context.byte))
2486    }
2487
2488    #[inline]
2489    fn chunk_data_lf(&mut self, _handler: &mut T, context: &mut ByteStream)
2490    -> Result<ParserValue, ParserError> {
2491        exit_if_eos!(self, context);
2492        bs_next!(context);
2493
2494        if context.byte == b'\n' {
2495            transition!(
2496                self,
2497                context,
2498                ChunkLength1,
2499                chunk_length1
2500            );
2501        }
2502
2503        Err(ParserError::CrlfSequence(context.byte))
2504    }
2505
2506    // ---------------------------------------------------------------------------------------------
2507    // MULTIPART STATES
2508    // ---------------------------------------------------------------------------------------------
2509
2510    #[inline]
2511    fn multipart_hyphen1(&mut self, handler: &mut T, context: &mut ByteStream)
2512    -> Result<ParserValue, ParserError> {
2513        exit_if_eos!(self, context);
2514        bs_next!(context);
2515
2516        if context.byte == b'-' {
2517            transition!(
2518                self,
2519                context,
2520                MultipartHyphen2,
2521                multipart_hyphen2
2522            );
2523        } else if get_lower14!(self) == 0 {
2524            // we're checking for the boundary within multipart data, but it's not the boundary,
2525            // so let's send the data to the callback and get back to parsing
2526            callback_transition!(
2527                self,
2528                handler,
2529                context,
2530                on_multipart_data,
2531                &[b'\r', b'\n', context.byte],
2532                MultipartDataByByte,
2533                multipart_data_by_byte
2534            );
2535        }
2536
2537        Err(ParserError::MultipartBoundary(context.byte))
2538    }
2539
2540    #[inline]
2541    fn multipart_hyphen2(&mut self, handler: &mut T, context: &mut ByteStream)
2542    -> Result<ParserValue, ParserError> {
2543        exit_if_eos!(self, context);
2544        bs_next!(context);
2545
2546        if context.byte == b'-' {
2547            transition!(
2548                self,
2549                context,
2550                MultipartBoundary,
2551                multipart_boundary
2552            );
2553        } else if get_lower14!(self) == 0 {
2554            // we're checking for the boundary within multipart data, but it's not the boundary,
2555            // so let's send the data to the callback and get back to parsing
2556            callback_transition!(
2557                self,
2558                handler,
2559                context,
2560                on_multipart_data,
2561                &[b'\r', b'\n', b'-', context.byte],
2562                MultipartDataByByte,
2563                multipart_data_by_byte
2564            );
2565        }
2566
2567        Err(ParserError::MultipartBoundary(context.byte))
2568    }
2569
2570    #[inline]
2571    fn multipart_boundary(&mut self, handler: &mut T, context: &mut ByteStream)
2572    -> Result<ParserValue, ParserError> {
2573        exit_if_eos!(self, context);
2574
2575        let (length, callback_data, finished) = {
2576            let boundary = self.boundary.unwrap();
2577
2578            let slice =
2579                if boundary.len() - get_upper14!(self) as usize <= bs_available!(context) {
2580                    // compare remainder of boundary
2581                    &boundary[get_upper14!(self) as usize..]
2582                } else {
2583                    // compare remainder of stream
2584                    &boundary[
2585                        get_upper14!(self) as usize..
2586                        get_upper14!(self) as usize + bs_available!(context)
2587                    ]
2588                };
2589
2590            if bs_starts_with!(context, slice) {
2591                // matches
2592                (slice.len(),
2593                 None,
2594                 get_upper14!(self) as usize + slice.len() == boundary.len())
2595            } else {
2596                // does not match, so we need to provide all the data that has been
2597                // compared as the boundary up to this point
2598                let mut v = Vec::with_capacity(// \r\n--
2599                                               4 as usize +
2600
2601                                               // old boundary data
2602                                               get_upper14!(self) as usize);
2603
2604                v.extend_from_slice(b"\r\n--");
2605                v.extend_from_slice(&boundary[..get_upper14!(self) as usize]);
2606
2607                (0, Some(v), false)
2608            }
2609        };
2610
2611        // due to the borrow checker holding 'boundary', we must transition down here
2612        bs_jump!(context, length);
2613
2614        if let Some(v) = callback_data {
2615            // boundary did not match
2616            if get_lower14!(self) == 0 {
2617                // reset boundary comparison index
2618                set_upper14!(self, 0);
2619
2620                callback_transition!(
2621                    self,
2622                    handler,
2623                    context,
2624                    on_multipart_data,
2625                    &v,
2626                    MultipartDataByByte,
2627                    multipart_data_by_byte
2628                );
2629            }
2630
2631            // we're parsing the initial boundary, and it's invalid
2632            //
2633            // there is one caveat to this error:
2634            //     it will always report the first byte being invalid, even if
2635            //     it's another byte that did not match, because we're using
2636            //     bs_starts_with!() vs an individual byte check
2637            bs_next!(context);
2638
2639            exit_error!(MultipartBoundary, context.byte);
2640        } else if finished {
2641            // boundary comparison finished
2642
2643            // reset boundary comparison index
2644            set_upper14!(self, 0);
2645
2646            transition!(
2647                self,
2648                context,
2649                MultipartBoundaryCr,
2650                multipart_boundary_cr
2651            );
2652        }
2653
2654        // boundary comparison not finished
2655        inc_upper14!(self, length);
2656
2657        exit_eos!(self, context);
2658    }
2659
2660    #[inline]
2661    fn multipart_boundary_cr(&mut self, handler: &mut T, context: &mut ByteStream)
2662    -> Result<ParserValue, ParserError> {
2663        exit_if_eos!(self, context);
2664        bs_next!(context);
2665
2666        if context.byte == b'\r' {
2667            set_state!(self, InitialLf, initial_lf);
2668
2669            if handler.on_multipart_begin() {
2670                transition!(self, context);
2671            }
2672
2673            exit_callback!(self, context);
2674        } else if context.byte == b'-' {
2675            transition!(
2676                self,
2677                context,
2678                MultipartEnd,
2679                multipart_end
2680            );
2681        }
2682
2683        Err(ParserError::MultipartBoundary(context.byte))
2684    }
2685
2686    #[inline]
2687    fn multipart_boundary_lf(&mut self, _handler: &mut T, context: &mut ByteStream)
2688    -> Result<ParserValue, ParserError> {
2689        exit_if_eos!(self, context);
2690        bs_next!(context);
2691
2692        if context.byte == b'\n' {
2693            transition!(
2694                self,
2695                context,
2696                CheckHeaderName,
2697                check_header_name
2698            );
2699        }
2700
2701        Err(ParserError::MultipartBoundary(context.byte))
2702    }
2703
2704    #[inline]
2705    fn multipart_detect_data(&mut self, handler: &mut T, context: &mut ByteStream)
2706    -> Result<ParserValue, ParserError> {
2707        if let Some(length) = handler.content_length() {
2708            self.length = length;
2709
2710            // expect boundary after data
2711            set_lower14!(self, 1);
2712
2713            transition!(
2714                self,
2715                context,
2716                MultipartDataByLength,
2717                multipart_data_by_length
2718            );
2719        }
2720
2721        // do not expect boundary since it can be part of the data itself
2722        set_lower14!(self, 0);
2723
2724        transition!(
2725            self,
2726            context,
2727            MultipartDataByByte,
2728            multipart_data_by_byte
2729        );
2730    }
2731
2732    #[inline]
2733    fn multipart_data_by_length(&mut self, handler: &mut T, context: &mut ByteStream)
2734    -> Result<ParserValue, ParserError> {
2735        exit_if_eos!(self, context);
2736
2737        if bs_available!(context) >= self.length {
2738            // collect remaining multipart data
2739            bs_collect_length!(context, self.length);
2740
2741            self.length = 0;
2742
2743            callback_transition!(
2744                self,
2745                handler,
2746                context,
2747                on_multipart_data,
2748                MultipartDataByLengthCr,
2749                multipart_data_by_length_cr
2750            );
2751        }
2752
2753        // collect remaining stream data
2754        self.length -= bs_available!(context);
2755
2756        bs_collect_length!(context, bs_available!(context));
2757
2758        callback_transition!(
2759            self,
2760            handler,
2761            context,
2762            on_multipart_data,
2763            MultipartDataByLength,
2764            multipart_data_by_length
2765        );
2766    }
2767
2768    #[inline]
2769    fn multipart_data_by_length_cr(&mut self, _handler: &mut T, context: &mut ByteStream)
2770    -> Result<ParserValue, ParserError> {
2771        exit_if_eos!(self, context);
2772        bs_next!(context);
2773
2774        if context.byte == b'\r' {
2775            transition!(
2776                self,
2777                context,
2778                MultipartDataByLengthLf,
2779                multipart_data_by_length_lf
2780            );
2781        }
2782
2783        // this state is only used after multipart_data_by_length, so we can error if we don't
2784        // find the carriage return
2785        Err(ParserError::MultipartBoundary(context.byte))
2786    }
2787
2788    #[inline]
2789    fn multipart_data_by_length_lf(&mut self, _handler: &mut T, context: &mut ByteStream)
2790    -> Result<ParserValue, ParserError> {
2791        exit_if_eos!(self, context);
2792        bs_next!(context);
2793
2794        if context.byte == b'\n' {
2795            transition!(
2796                self,
2797                context,
2798                MultipartHyphen1,
2799                multipart_hyphen1
2800            );
2801        }
2802
2803        // this state is only used after multipart_data_by_length, so we can error if we don't
2804        // find the carriage return
2805        Err(ParserError::MultipartBoundary(context.byte))
2806    }
2807
2808    #[inline]
2809    fn multipart_data_by_byte(&mut self, handler: &mut T, context: &mut ByteStream)
2810    -> Result<ParserValue, ParserError> {
2811        bs_collect_until!(
2812            context,
2813
2814            // collect bytes until
2815            context.byte == b'\r',
2816
2817            // on end-of-stream
2818            callback_eos_expr!(self, handler, context, on_multipart_data)
2819        );
2820
2821        callback_ignore_transition!(
2822            self,
2823            handler,
2824            context,
2825            on_multipart_data,
2826            MultipartDataByByteLf,
2827            multipart_data_by_byte_lf
2828        );
2829    }
2830
2831    #[inline]
2832    fn multipart_data_by_byte_lf(&mut self, handler: &mut T, context: &mut ByteStream)
2833    -> Result<ParserValue, ParserError> {
2834        exit_if_eos!(self, context);
2835        bs_next!(context);
2836
2837        if context.byte == b'\n' {
2838            transition!(
2839                self,
2840                context,
2841                MultipartHyphen1,
2842                multipart_hyphen1
2843            );
2844        }
2845
2846        callback_transition!(
2847            self,
2848            handler,
2849            context,
2850            on_multipart_data,
2851            &[b'\r', context.byte],
2852            MultipartDataByByte,
2853            multipart_data_by_byte
2854        );
2855    }
2856
2857    #[inline]
2858    fn multipart_end(&mut self, _handler: &mut T, context: &mut ByteStream)
2859    -> Result<ParserValue, ParserError> {
2860        exit_if_eos!(self, context);
2861        bs_next!(context);
2862
2863        if context.byte == b'-' {
2864            transition!(
2865                self,
2866                context,
2867                BodyFinished,
2868                body_finished
2869            );
2870        }
2871
2872        Err(ParserError::MultipartBoundary(context.byte))
2873    }
2874
2875    // ---------------------------------------------------------------------------------------------
2876    // URL ENCODED STATES
2877    // ---------------------------------------------------------------------------------------------
2878
2879    #[inline]
2880    fn first_url_encoded_name(&mut self, handler: &mut T, context: &mut ByteStream)
2881    -> Result<ParserValue, ParserError> {
2882        bs_available!(context) > 0 || exit_eos!(self, context);
2883
2884        set_state!(self, UrlEncodedName, url_encoded_name);
2885
2886        if handler.on_url_encoded_begin() {
2887            transition!(
2888                self,
2889                context,
2890                UrlEncodedName,
2891                url_encoded_name
2892            )
2893        }
2894
2895        exit_callback!(self, context);
2896    }
2897
2898    #[inline]
2899    fn url_encoded_name(&mut self, handler: &mut T, context: &mut ByteStream)
2900    -> Result<ParserValue, ParserError> {
2901        collect_visible_7bit!(
2902            context,
2903
2904            // stop on these bytes
2905               context.byte == b'%'
2906            || context.byte == b'+'
2907            || context.byte == b'='
2908            || context.byte == b'&'
2909            || context.byte == b';',
2910
2911            // on end-of-stream
2912            callback_eos_expr!(self, handler, context, on_url_encoded_name)
2913        );
2914
2915        match context.byte {
2916            b'%' => {
2917                callback_ignore_transition!(
2918                    self,
2919                    handler,
2920                    context,
2921                    on_url_encoded_name,
2922                    UrlEncodedNameHex1,
2923                    url_encoded_name_hex1
2924                );
2925            },
2926            b'+' => {
2927                callback_ignore_transition!(
2928                    self,
2929                    handler,
2930                    context,
2931                    on_url_encoded_name,
2932                    UrlEncodedNamePlus,
2933                    url_encoded_name_plus
2934                );
2935            },
2936            b'=' => {
2937                callback_ignore_transition!(
2938                    self,
2939                    handler,
2940                    context,
2941                    on_url_encoded_name,
2942                    UrlEncodedValue,
2943                    url_encoded_value
2944                );
2945            },
2946            b'&' | b';' => {
2947                callback_ignore_transition!(
2948                    self,
2949                    handler,
2950                    context,
2951                    on_url_encoded_name,
2952                    FirstUrlEncodedName,
2953                    first_url_encoded_name
2954                );
2955            },
2956            _ => {
2957                Err(ParserError::UrlEncodedName(context.byte))
2958            }
2959        }
2960    }
2961
2962    #[inline]
2963    fn url_encoded_name_hex1(&mut self, handler: &mut T, context: &mut ByteStream)
2964    -> Result<ParserValue, ParserError> {
2965        exit_if_eos!(self, context);
2966        bs_next!(context);
2967
2968        set_upper14!(
2969            self,
2970            if is_digit!(context.byte) {
2971                (context.byte - b'0') << 4
2972            } else if b'@' < context.byte && context.byte < b'G' {
2973                (context.byte - 0x37) << 4
2974            } else if b'`' < context.byte && context.byte < b'g' {
2975                (context.byte - 0x57) << 4
2976            } else {
2977                exit_error!(UrlEncodedName, context.byte);
2978            }
2979        );
2980
2981        transition!(
2982            self,
2983            context,
2984            UrlEncodedNameHex2,
2985            url_encoded_name_hex2
2986        );
2987    }
2988
2989    #[inline]
2990    fn url_encoded_name_hex2(&mut self, handler: &mut T, context: &mut ByteStream)
2991    -> Result<ParserValue, ParserError> {
2992        exit_if_eos!(self, context);
2993        bs_next!(context);
2994
2995        set_lower14!(
2996            self,
2997            if is_digit!(context.byte) {
2998                context.byte - b'0'
2999            } else if b'@' < context.byte && context.byte < b'G' {
3000                context.byte - 0x37
3001            } else if b'`' < context.byte && context.byte < b'g' {
3002                context.byte - 0x57
3003            } else {
3004                exit_error!(UrlEncodedName, context.byte);
3005            }
3006        );
3007
3008        callback_transition!(
3009            self,
3010            handler,
3011            context,
3012            on_url_encoded_name,
3013            &[(get_upper14!(self) | get_lower14!(self)) as u8],
3014            UrlEncodedName,
3015            url_encoded_name
3016        );
3017    }
3018
3019    #[inline]
3020    fn url_encoded_name_plus(&mut self, handler: &mut T, context: &mut ByteStream)
3021    -> Result<ParserValue, ParserError> {
3022        callback_transition!(
3023            self,
3024            handler,
3025            context,
3026            on_url_encoded_name,
3027            b" ",
3028            UrlEncodedName,
3029            url_encoded_name
3030        );
3031    }
3032
3033    #[inline]
3034    fn url_encoded_value(&mut self, handler: &mut T, context: &mut ByteStream)
3035    -> Result<ParserValue, ParserError> {
3036        collect_visible_7bit!(
3037            context,
3038
3039            // stop on these bytes
3040               context.byte == b'%'
3041            || context.byte == b'+'
3042            || context.byte == b'&'
3043            || context.byte == b';',
3044
3045            // on end-of-stream
3046            callback_eos_expr!(self, handler, context, on_url_encoded_value)
3047        );
3048
3049        match context.byte {
3050            b'%' => {
3051                callback_ignore_transition!(
3052                    self,
3053                    handler,
3054                    context,
3055                    on_url_encoded_value,
3056                    UrlEncodedValueHex1,
3057                    url_encoded_value_hex1
3058                );
3059            },
3060            b'&' | b';' => {
3061                callback_ignore_transition!(
3062                    self,
3063                    handler,
3064                    context,
3065                    on_url_encoded_value,
3066                    FirstUrlEncodedName,
3067                    first_url_encoded_name
3068                );
3069            },
3070            b'+' => {
3071                callback_ignore_transition!(
3072                    self,
3073                    handler,
3074                    context,
3075                    on_url_encoded_value,
3076                    UrlEncodedValuePlus,
3077                    url_encoded_value_plus
3078                );
3079            },
3080            _ => {
3081                Err(ParserError::UrlEncodedValue(context.byte))
3082            }
3083        }
3084    }
3085
3086    #[inline]
3087    fn url_encoded_value_hex1(&mut self, _handler: &mut T, context: &mut ByteStream)
3088    -> Result<ParserValue, ParserError> {
3089        exit_if_eos!(self, context);
3090        bs_next!(context);
3091
3092        set_upper14!(
3093            self,
3094            if is_digit!(context.byte) {
3095                (context.byte - b'0') << 4
3096            } else if b'@' < context.byte && context.byte < b'G' {
3097                (context.byte - 0x37) << 4
3098            } else if b'`' < context.byte && context.byte < b'g' {
3099                (context.byte - 0x57) << 4
3100            } else {
3101                exit_error!(UrlEncodedValue, context.byte);
3102            }
3103        );
3104
3105        transition!(
3106            self,
3107            context,
3108            UrlEncodedValueHex2,
3109            url_encoded_value_hex2
3110        );
3111    }
3112
3113    #[inline]
3114    fn url_encoded_value_hex2(&mut self, handler: &mut T, context: &mut ByteStream)
3115    -> Result<ParserValue, ParserError> {
3116        exit_if_eos!(self, context);
3117        bs_next!(context);
3118
3119        set_lower14!(
3120            self,
3121            if is_digit!(context.byte) {
3122                context.byte - b'0'
3123            } else if b'@' < context.byte && context.byte < b'G' {
3124                context.byte - 0x37
3125            } else if b'`' < context.byte && context.byte < b'g' {
3126                context.byte - 0x57
3127            } else {
3128                exit_error!(UrlEncodedValue, context.byte);
3129            }
3130        );
3131
3132        callback_transition!(
3133            self,
3134            handler,
3135            context,
3136            on_url_encoded_value,
3137            &[(get_upper14!(self) | get_lower14!(self)) as u8],
3138            UrlEncodedValue,
3139            url_encoded_value
3140        );
3141    }
3142
3143    #[inline]
3144    fn url_encoded_value_plus(&mut self, handler: &mut T, context: &mut ByteStream)
3145    -> Result<ParserValue, ParserError> {
3146        callback_transition!(
3147            self,
3148            handler,
3149            context,
3150            on_url_encoded_value,
3151            b" ",
3152            UrlEncodedValue,
3153            url_encoded_value
3154        );
3155    }
3156
3157    // ---------------------------------------------------------------------------------------------
3158    // DEAD & FINISHED STATES
3159    // ---------------------------------------------------------------------------------------------
3160
3161    #[inline]
3162    fn dead(&mut self, _handler: &mut T, _context: &mut ByteStream)
3163    -> Result<ParserValue, ParserError> {
3164        exit_error!(Dead);
3165    }
3166
3167    #[inline]
3168    fn body_finished(&mut self, handler: &mut T, context: &mut ByteStream)
3169    -> Result<ParserValue, ParserError> {
3170        set_state!(self, Finished, finished);
3171
3172        if handler.on_body_finished() {
3173            transition!(self, context);
3174        }
3175
3176        exit_callback!(self, context);
3177    }
3178
3179    #[inline]
3180    fn finished(&mut self, _handler: &mut T, context: &mut ByteStream)
3181    -> Result<ParserValue, ParserError> {
3182        exit_finished!(self, context);
3183    }
3184}