lib/async/http/protocol/http1/server.rb in async-http-0.78.0 vs lib/async/http/protocol/http1/server.rb in async-http-0.79.0
- old
+ new
@@ -20,11 +20,11 @@
super
@ready = Async::Notification.new
end
- def closed!
+ def closed(error = nil)
super
@ready.signal
end
@@ -36,18 +36,16 @@
# At this point, there is very little we can do to recover:
Console::Event::Failure.for(error).emit(self, "Failed to write failure response!", severity: :debug)
end
def next_request
- # Wait for the connection to become idle before reading the next request:
- unless idle?
+ if closed?
+ return nil
+ elsif !idle?
@ready.wait
end
- # The default is true.
- return unless @persistent
-
# Read an incoming request:
return unless request = Request.read(self)
unless persistent?(request.version, request.method, request.headers)
@persistent = false
@@ -88,42 +86,45 @@
if body and protocol = response.protocol
# We force a 101 response if the protocol is upgraded - HTTP/2 CONNECT will return 200 for success, but this won't be understood by HTTP/1 clients:
write_response(@version, 101, response.headers)
- stream = write_upgrade_body(protocol)
-
# At this point, the request body is hijacked, so we don't want to call #finish below.
request = nil
response = nil
- # We must return here as no further request processing can be done:
- return body.call(stream)
+ if body.stream?
+ return body.call(write_upgrade_body(protocol))
+ else
+ write_upgrade_body(protocol, body)
+ end
elsif response.status == 101
# This code path is to support legacy behavior where the response status is set to 101, but the protocol is not upgraded. This may not be a valid use case, but it is supported for compatibility. We expect the response headers to contain the `upgrade` header.
write_response(@version, response.status, response.headers)
- stream = write_tunnel_body(version)
-
# Same as above:
request = nil
response = nil
- # We must return here as no further request processing can be done:
- return body&.call(stream)
+ if body.stream?
+ return body.call(write_tunnel_body(version))
+ else
+ write_tunnel_body(version, body)
+ end
else
write_response(@version, response.status, response.headers)
if request.connect? and response.success?
- stream = write_tunnel_body(version)
-
# Same as above:
request = nil
response = nil
- # We must return here as no further request processing can be done:
- return body.call(stream)
+ if body.stream?
+ return body.call(write_tunnel_body(version))
+ else
+ write_tunnel_body(version, body)
+ end
else
head = request.head?
# Same as above:
request = nil
@@ -141,11 +142,15 @@
write_body(version, nil)
request&.finish
end
- # Discard or wait for the input body to be consumed:
- finishable&.wait
+ if finishable
+ finishable.wait(@persistent)
+ else
+ # Do not remove this line or you will unleash the gods of concurrency hell.
+ task.yield
+ end
rescue => error
raise
ensure
body&.close(error)
end