@@ -547,6 +547,12 @@ structure Machine (ty : Machine.MachineType) where
547547 -/
548548 keepAlive : Bool := false
549549
550+ /--
551+ If the connection has been closed (no more data will arrive).
552+ When true, EOF during parsing triggers connectionClosed instead of needMoreData.
553+ -/
554+ connectionClosedByPeer : Bool := false
555+
550556namespace Machine
551557
552558private def shouldBreakConnection (c : Status) : Bool :=
@@ -603,14 +609,27 @@ def setFailure (machine : Machine ty) (error : H1.Machine.Error) : Machine ty :=
603609 |>.setReaderState (.failed error)
604610 |>.setError error
605611
612+ /--
613+ Marks that the connection has been closed by the peer.
614+ This should be called when the underlying connection is closed (e.g., socket closed).
615+ After calling this, any parsing that requires more data will fail with connectionClosed
616+ instead of emitting needMoreData events.
617+ -/
618+ @[inline]
619+ public def closePeerConnection (machine : Machine ty) : Machine ty :=
620+ { machine with connectionClosedByPeer := true }
621+
606622private def parseWith (machine : Machine ty) (parser : Parser α) (limit : Option Nat) (expect : Option Nat := none) : (Machine ty × Option α) :=
607623 let remaining := machine.reader.input.remainingBytes
608624 match parser machine.reader.input with
609625 | .success buffer result => ({ machine with reader := machine.reader.setInput buffer }, some result)
610626 | .error it .eof =>
611627 let usedBytesUntilFailure := remaining - it.remainingBytes
612628
613- if let some limit := limit then
629+ -- If connection is closed by peer, trigger connectionClosed error instead of needMoreData
630+ if machine.connectionClosedByPeer then
631+ (machine.setFailure .connectionClosed, none)
632+ else if let some limit := limit then
614633 if usedBytesUntilFailure ≥ limit
615634 then (machine.setFailure .badMessage, none)
616635 else (machine.addEvent (.needMoreData expect), none)
0 commit comments