@@ -43,9 +43,9 @@ structure Config where
4343 maxHeaderSize : Nat := 8192
4444
4545 /--
46- Connection timeout in seconds .
46+ Connection timeout in milliseconds .
4747 -/
48- timeoutSeconds : Time.Second .Offset := 10
48+ timeoutMilliseconds : Time.Millisecond .Offset := 1000
4949
5050 /--
5151 Whether to enable keep-alive connections by default.
@@ -117,6 +117,9 @@ inductive Error
117117 | other (message : String)
118118deriving Repr, BEq
119119
120+ instance : Repr ByteSlice where
121+ reprPrec x := reprPrec x.toByteArray.data
122+
120123/--
121124Events that can occur during HTTP message processing.
122125-/
@@ -156,7 +159,7 @@ inductive Event
156159 Awaiting the next request
157160 -/
158161 | next
159- deriving Inhabited
162+ deriving Inhabited, Repr
160163
161164inductive Reader.State : Type
162165 /--
@@ -502,6 +505,14 @@ structure Machine where
502505
503506namespace Machine
504507
508+ private def shouldBreakConnection (c : Status) : Bool :=
509+ match c with
510+ | .uriTooLong
511+ | .badRequest
512+ | .payloadTooLarge
513+ | .requestHeaderFieldsTooLarge => true
514+ | _ => false
515+
505516-- Additional helper functions for writer manipulation
506517@[inline]
507518private def modifyWriter (machine : Machine) (fn : Writer → Writer) : Machine :=
@@ -557,7 +568,7 @@ private def parseWith (machine : Machine) (parser : Parser α) (limit : Option N
557568
558569 if let some limit := limit then
559570 if usedBytesUntilFailure ≥ limit
560- then (machine.setError .badRequest, none)
571+ then (machine.setFailure .badRequest .badRequest, none)
561572 else (machine.addEvent (.needMoreData expect), none)
562573 else (machine.addEvent (.needMoreData expect), none)
563574 | .error _ _ =>
@@ -666,7 +677,7 @@ def setHeaders (response : Response.Head) (machine : Machine) : Machine :=
666677
667678 let headers := if let some date := machine.instant then headers.insert "Date" (date.format "EEE, dd MMM yyyy HH:mm:ss 'GMT'" ) else headers
668679
669- let headers := if ¬machine.keepAlive ∨ response.status.isClientError ∨ response.status.isServerError then
680+ let headers := if ¬machine.keepAlive ∨ shouldBreakConnection response.status then
670681 headers.insert "Connection" "close"
671682 else
672683 headers
@@ -748,12 +759,14 @@ def sendResponse (machine : Machine) (response : Response.Head) : Machine :=
748759 | .waitingHeaders =>
749760 let machine := machine.modifyWriter ({ · with response, state := .waitingForFlush })
750761 let conn := response.headers.getD "Connection"
751- if response.status.isClientError || response.status.isServerError || conn.contains "close" then
762+
763+ if conn.contains "close" then
752764 machine
753765 |>.closeConnection
754- |>.setReaderState .complete -- Stop receiving data
766+ |>.setReaderState .complete
755767 else
756768 machine
769+
757770 | _ =>
758771 machine
759772
@@ -765,7 +778,7 @@ def isReaderComplete (machine : Machine) : Bool :=
765778/--
766779Advances the state of the reader.
767780-/
768- def processRead (machine : Machine) : Machine :=
781+ partial def processRead (machine : Machine) : Machine :=
769782 match machine.reader.state with
770783 | .needStartLine =>
771784 let (machine, result) := parseWith machine parseRequestLine (limit := some 8192 )
@@ -774,6 +787,7 @@ def processRead (machine : Machine) : Machine :=
774787 machine
775788 |>.modifyReader (.setRequest head)
776789 |>.setReaderState (.needHeader 0 )
790+ |>.processRead
777791 else
778792 machine
779793
@@ -788,6 +802,7 @@ def processRead (machine : Machine) : Machine :=
788802 machine
789803 |>.modifyReader (.addHeader name value)
790804 |>.setReaderState (.needHeader (headerCount + 1 ))
805+ |>.processRead
791806 else
792807 processHeaders machine
793808 else
@@ -804,6 +819,7 @@ def processRead (machine : Machine) : Machine :=
804819 machine
805820 |>.setReaderState (.needChunkedBody size)
806821 |>.setEvent (some ext <&> .chunkExt)
822+ |>.processRead
807823 | none =>
808824 machine
809825
@@ -817,24 +833,34 @@ def processRead (machine : Machine) : Machine :=
817833 machine
818834 |>.setReaderState .needChunkedSize
819835 |>.addEvent (.gotData false body)
836+ |>.processRead
820837 else
821838 machine
822839 |>.setReaderState .complete
823840 |>.addEvent (.gotData true .empty)
841+ |>.processRead
824842 | .incomplete body remaining => machine
825843 |>.setReaderState (.needChunkedBody remaining)
826844 |>.addEvent (.gotData false body)
827845 else
828846 machine
829847
848+ | .needFixedBody 0 =>
849+ machine
850+ |>.setReaderState .complete
851+ |>.addEvent (.gotData true .empty)
852+ |>.processRead
853+
830854 | .needFixedBody size =>
831855 let (machine, result) := parseWith machine (parseFixedSizeData size) (limit := none) (some size)
832856
833857 if let some body := result then
834858 match body with
835- | .complete body => machine
859+ | .complete body =>
860+ machine
836861 |>.setReaderState .complete
837862 |>.addEvent (.gotData true body)
863+ |>.processRead
838864 | .incomplete body remaining =>
839865 machine
840866 |>.setReaderState (.needFixedBody remaining)
@@ -878,31 +904,32 @@ def takeOutput (machine : Machine) (highMark := 0): Option (Machine × BufferBui
878904/--
879905Write response data to the machine
880906-/
881- def processWrite (machine : Machine) : Machine :=
907+ partial def processWrite (machine : Machine) : Machine :=
882908 match machine.writer.state with
883909 | .waitingHeaders =>
884910 machine
885911
886912 | .waitingForFlush =>
887913 if machine.shouldFlush then
888- machine.setHeaders machine.writer.response
914+ machine.setHeaders machine.writer.response |>.processWrite
889915 else
890916 machine
891917
892918 | .writingFixedData =>
893919 if machine.writer.userData.size ≥ machine.config.highMark ∨ machine.writer.closed then
894920 let machine := machine.modifyWriter Writer.writeFixedBody
895921 if machine.writer.closed then
896- machine.setWriterState .complete
922+ machine.setWriterState .complete |>.processWrite
897923 else
898924 machine
899925 else
900926 machine
927+
901928 | .writingChunkedBody =>
902929 if machine.writer.closed then
903- machine.modifyWriter Writer.writeFinalChunk
930+ machine.modifyWriter Writer.writeFinalChunk |>.processWrite
904931 else if machine.writer.userData.size ≥ machine.config.highMark then
905- machine.modifyWriter Writer.writeChunkedBody
932+ machine.modifyWriter Writer.writeChunkedBody |>.processWrite
906933 else
907934 machine
908935
0 commit comments