-
-
Notifications
You must be signed in to change notification settings - Fork 16
Ensure 1xx and Remainder responses mark connection as not persistent #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -204,7 +204,9 @@ | |
with '#read_response_body' do | ||
with "GET" do | ||
it "should ignore body for informational responses" do | ||
expect(client.read_response_body("GET", 100, {'content-length' => '10'})).to be_nil | ||
body = client.read_response_body("GET", 100, {'content-length' => '10'}) | ||
expect(body).to be_a(::Protocol::HTTP1::Body::Remainder) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we used this body in any way, wouldn't it corrupt the underlying connection? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes and no. While not a dominant use case, one could read from the Think of |
||
expect(client.persistent).to be == false | ||
end | ||
|
||
it "should ignore body for no content responses" do | ||
|
@@ -214,6 +216,7 @@ | |
it "should handle non-chunked transfer-encoding" do | ||
body = client.read_response_body("GET", 200, {'transfer-encoding' => ['identity']}) | ||
expect(body).to be_a(::Protocol::HTTP1::Body::Remainder) | ||
expect(client.persistent).to be == false | ||
end | ||
|
||
it "should be an error if both transfer-encoding and content-length is set" do | ||
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should handle 101 here explicitly? i.e. I don't think 100 continue should respond with a body, and it's also true that 101 affects connection persistence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of my goals here is to ensure that all 1xx responses are default-safe whether or not 1xx is looped on (via
async-http
'sRequest.read
) and whether or not 101 ends up being used for a websocket connection.The most important part is ensuring
@persistent=false
happens for all 1xx (including 101). That could be done here without theRemainder
. Failing to do at least this much opens up a potential desync.As I tried to mention in the OP, I'm hoping to move toward every
Response
having a body. I've been testing this in my own code with great success as it solves issues likeStatistics
and other wrappers not being able to wrap responses that lack bodies. In my own case, that includes wrapping 101's. Converting non-1xx to all have bodies is obviously a larger discussion and beyond the context here.Returning a
Remainder
here has some benefits:a) For 101 with
Upgrade: websocket
, ifAsync::HTTP::Client
or another non-websocket-aware client is in use, thenRemainder
hints that there is something remaining on the stream (which indeed there is). More, any call toresponse.close
would properly close that stream and not leave it dangling open (which is the case whenresponse.body==nil
).b) For 101 with
Upgrade: <other-than-websocket>
, theRemainder
is directly usable. Depending on the target protocol, that is potentially useful. And, the stream can still be hijacked for more direct access to the underlying socket (and the Remainder simply ignored).c) For all 1xx, the
Remainder
can be thought of as a type of promise on the future data on the socket. Again, this hints to a developer that there's more to come. But it's more than a hint--it also clarifies that this socket is not available to be reused yet because the stream of data is not complete. To me,nil
implies that there is nothing more coming.Helpfully, using a
Remainder
for all 1xx shouldn't be detrimental to existing use since 1xx support is newly added. The only existing usage was viaasync-websocket
, and anything that hijacks the connection was already ignoring thenil
body, so it will simply ignore theRemainder
body now. Barring something pretty weird, I believe this to be a non-breaking change.All that said, if you're really uncomfortable with changing to
Remainder
, I can rework it to maintainnil
and simply set@persistent
instead.