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