File tree Expand file tree Collapse file tree 2 files changed +41
-3
lines changed
lib/async/http/protocol/http1 Expand file tree Collapse file tree 2 files changed +41
-3
lines changed Original file line number Diff line number Diff line change @@ -83,7 +83,7 @@ def each(task: Task.current)
8383 version = request . version
8484
8585 # Same as above:
86- request = nil unless body
86+ request = nil unless request . body
8787 response = nil
8888
8989 write_body ( version , body , head , trailer )
@@ -97,8 +97,13 @@ def each(task: Task.current)
9797 write_body ( request . version , nil )
9898 end
9999
100- # Gracefully finish reading the request body if it was not already done so.
101- request &.finish
100+ if request &.body
101+ # Read one chunk to allow small or 0-length bodies to identify the body as complete.
102+ request . body . read unless request . body . empty?
103+ # If request body has outstanding data, will close the stream. This avoids wasting cycles if remaining
104+ # body size is large or unknown. If body was already read, leaves stream open for potential keep-alive.
105+ request . close
106+ end
102107
103108 # This ensures we yield at least once every iteration of the loop and allow other fibers to execute.
104109 task . yield
@@ -109,6 +114,7 @@ def each(task: Task.current)
109114 end
110115 end
111116 end
117+
112118 end
113119 end
114120 end
Original file line number Diff line number Diff line change 77
88require 'async/http/protocol/http11'
99require 'async/http/a_protocol'
10+ require 'protocol/http/body/readable'
1011
1112describe Async ::HTTP ::Protocol ::HTTP11 do
1213 it_behaves_like Async ::HTTP ::AProtocol
@@ -32,6 +33,37 @@ def around
3233 end
3334 end
3435
36+ with 'bad request body' do
37+ let ( :app ) do
38+ Protocol ::HTTP ::Middleware . for do |request |
39+ Protocol ::HTTP ::Response [ 400 , { } , [ "Bad request" ] ]
40+ end
41+ end
42+
43+ class EndlessBody < Protocol ::HTTP ::Body ::Readable
44+ attr :chunks_read
45+ def initialize
46+ @chunks_read = 0
47+ end
48+ def read
49+ @chunks_read += 1
50+ Async ::Task . current . yield
51+ 'endless'
52+ end
53+ end
54+
55+ it "should close the connection when request unread" do
56+ body = EndlessBody . new
57+ response = client . post ( '/' , { } , body )
58+
59+ expect ( response ) . to be ( :bad_request? )
60+
61+ response . read
62+ sleep 0.01 # brief window for multiple chunks to be read and avoid Async::Stop
63+ expect ( body . chunks_read ) . to be :< , 5
64+ end
65+ end
66+
3567 with 'head request' do
3668 let ( :app ) do
3769 Protocol ::HTTP ::Middleware . for do |request |
You can’t perform that action at this time.
0 commit comments