@@ -244,20 +244,18 @@ struct RequestHeader:
244244 return String(self .raw_headers)
245245
246246 fn parse_raw (inout self , inout r : Reader) raises -> Int:
247- var n = 1
248- # while True:
249- var first_byte = r.peek(n)
247+ var first_byte = r.peek(1 )
250248 if len (first_byte) == 0 :
251- raise Error(" Failed to read first byte from header" )
249+ raise Error(" Failed to read first byte from request header" )
252250
253251 var buf : Bytes
254252 var e : Error
255253
256254 buf, e = r.peek(r.buffered())
257255 if e:
258- raise Error(" Failed to read header: " + e.__str__ ())
256+ raise Error(" Failed to read request header: " + e.__str__ ())
259257 if len (buf) == 0 :
260- raise Error(" Failed to read header" )
258+ raise Error(" Failed to read request header, empty buffer " )
261259
262260 var end_of_first_line = self .parse_first_line(buf)
263261
@@ -278,14 +276,14 @@ struct RequestHeader:
278276
279277 var first_whitespace = index_byte(b, bytes (whitespace, pop = False )[0 ])
280278 if first_whitespace <= 0 :
281- raise Error(" Could not find HTTP request method in the request: " + String(b))
279+ raise Error(" Could not find HTTP request method in request line : " + String(b))
282280
283281 _ = self .set_method_bytes(b[:first_whitespace])
284282
285283 var last_whitespace = last_index_byte(b, bytes (whitespace, pop = False )[0 ]) + 1
286284
287285 if last_whitespace < 0 :
288- raise Error(" Could not find last whitespace in request line: " + String(b))
286+ raise Error(" Could not find request target or HTTP version in request line: " + String(b))
289287 elif last_whitespace == 0 :
290288 raise Error(" Request URI is empty: " + String(b))
291289
@@ -629,47 +627,78 @@ struct ResponseHeader:
629627 fn headers (self ) -> String:
630628 return String(self .raw_headers)
631629
632- fn parse_first_line (inout self , first_line : String) raises -> None :
633- var n = first_line.find(" " )
634-
635- var proto = first_line[:n + 1 ]
630+ # fn parse_from_list(inout self, headers: List[String], first_line: String) raises -> None:
631+ # _ = self.parse_first_line(first_line)
632+
633+ # for header in headers:
634+ # var header_str = header[]
635+ # var separator = header_str.find(":")
636+ # if separator == -1:
637+ # raise Error("Invalid header")
636638
637- _ = self .set_protocol(proto)
639+ # var key = String(header_str)[:separator]
640+ # var value = String(header_str)[separator + 1 :]
638641
639- var rest_of_response_line = first_line[n + 1 :]
642+ # if len(key) > 0:
643+ # self.parse_header(key, value)
640644
641- var status_code = atol(rest_of_response_line[:3 ])
642- _ = self .set_status_code(status_code)
643-
644- var message = rest_of_response_line[4 :]
645- if len (message) > 1 :
646- _ = self .set_status_message(bytes ((message), pop = False ))
645+ fn parse_raw (inout self , inout r : Reader) raises -> Int:
646+ var first_byte = r.peek(1 )
647+ if len (first_byte) == 0 :
648+ raise Error(" Failed to read first byte from response header" )
647649
648- _ = self .set_content_length(- 2 )
650+ var buf : Bytes
651+ var e : Error
652+
653+ buf, e = r.peek(r.buffered())
654+ if e:
655+ raise Error(" Failed to read response header: " + e.__str__ ())
656+ if len (buf) == 0 :
657+ raise Error(" Failed to read response header, empty buffer" )
649658
650- fn parse_from_list (inout self , headers : List[String], first_line : String) raises -> None :
651- _ = self .parse_first_line(first_line)
659+ var end_of_first_line = self .parse_first_line(buf)
660+
661+ var header_len = self .read_raw_headers(buf[end_of_first_line:])
652662
653- for header in headers:
654- var header_str = header[]
655- var separator = header_str.find(" :" )
656- if separator == - 1 :
657- raise Error(" Invalid header" )
663+ self .parse_headers(buf[end_of_first_line:])
664+
665+ return end_of_first_line + header_len
666+
667+ fn parse_first_line (inout self , buf : Bytes) raises -> Int:
668+ var b_next = buf
669+ var b = Bytes()
670+ while len (b) == 0 :
671+ try :
672+ b, b_next = next_line(b_next)
673+ except e:
674+ raise Error(" Failed to read first line from response, " + e.__str__ ())
675+
676+ var first_whitespace = index_byte(b, bytes (whitespace, pop = False )[0 ])
677+ if first_whitespace <= 0 :
678+ raise Error(" Could not find HTTP version in response line: " + String(b))
658679
659- var key = String(header_str)[:separator]
660- var value = String(header_str)[separator + 1 :]
680+ _ = self .set_protocol(b[:first_whitespace])
661681
662- if len (key) > 0 :
663- self .parse_header(key, value)
682+ var last_whitespace = last_index_byte(b, bytes (whitespace, pop = False )[0 ]) + 1
664683
665- fn parse_raw ( inout self , first_line : String) raises -> None :
666- var headers = self .raw_headers
667-
668- _ = self .parse_first_line(first_line )
684+ if last_whitespace < 0 :
685+ raise Error( " Could not find status code or in response line: " + String(b))
686+ elif last_whitespace == 0 :
687+ raise Error( " Response URI is empty: " + String(b) )
669688
689+ var status_text = b[last_whitespace :]
690+ if len (status_text) > 1 :
691+ _ = self .set_status_message(status_text)
692+
693+ var status_code = atol(b[first_whitespace+ 1 :last_whitespace])
694+ _ = self .set_status_code(status_code)
695+
696+ return len (buf) - len (b_next)
697+
698+ fn parse_headers (inout self , buf : Bytes) raises -> None :
699+ _ = self .set_content_length(- 2 )
670700 var s = headerScanner()
671- s.set_b(headers)
672- s.disable_normalization = self .disable_normalization
701+ s.set_b(buf)
673702
674703 while s.next():
675704 if len (s.key()) > 0 :
@@ -710,6 +739,31 @@ struct ResponseHeader:
710739 return
711740 if key.lower() == " trailer" :
712741 _ = self .set_trailer_bytes(bytes (value, pop = False ))
742+
743+ fn read_raw_headers (inout self , buf : Bytes) raises -> Int:
744+ var n = index_byte(buf, bytes (nChar, pop = False )[0 ])
745+
746+ if n == - 1 :
747+ self .raw_headers = self .raw_headers[:0 ]
748+ raise Error(" Failed to find a newline in headers" )
749+
750+ if n == 0 or (n == 1 and (buf[0 ] == bytes (rChar, pop = False )[0 ])):
751+ # empty line -> end of headers
752+ return n + 1
753+
754+ n += 1
755+ var b = buf
756+ var m = n
757+ while True :
758+ b = b[m:]
759+ m = index_byte(b, bytes (nChar, pop = False )[0 ])
760+ if m == - 1 :
761+ raise Error(" Failed to find a newline in headers" )
762+ m += 1
763+ n += m
764+ if m == 2 and (b[0 ] == bytes (rChar, pop = False )[0 ]) or m == 1 :
765+ self .raw_headers = self .raw_headers + buf[:n]
766+ return n
713767
714768struct headerScanner :
715769 var __b : Bytes
0 commit comments