Created
June 9, 2021 17:04
-
-
Save Dan-Do/48fa159b814fef6821b38c5fe54345cf to your computer and use it in GitHub Desktop.
patch core crystal code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class HTTP::Server::RequestProcessor | |
def process(input, output) : Nil | |
response = Response.new(output) | |
begin | |
until @wants_close | |
request = HTTP::Request.from_io( | |
input, | |
max_request_line_size: max_request_line_size, | |
max_headers_size: max_headers_size, | |
) | |
# EOF | |
break unless request | |
response.reset | |
if request.is_a?(HTTP::Status) | |
response.respond_with_status(request) | |
return | |
end | |
response.version = request.version | |
response.headers["Connection"] = "keep-alive" if request.keep_alive? | |
context = Context.new(request, response) | |
Log.with_context do | |
done = Channel(Nil).new | |
spawn do | |
@handler.call(context) | |
ensure | |
done.send nil | |
end | |
select | |
when done.receive | |
when timeout(9.seconds) | |
raise "Could not process @handler.call(context) in 9 seconds" | |
end | |
exit if context.get?("exit") | |
rescue ex : ClientError | |
Log.debug(exception: ex.cause) { ex.message } | |
ensure | |
response.output.close | |
end | |
output.flush | |
# If there is an upgrade handler, hand over | |
# the connection to it and return | |
if upgrade_handler = response.upgrade_handler | |
upgrade_handler.call(output) | |
return | |
end | |
break unless request.keep_alive? | |
# Don't continue if the handler set `Connection` header to `close` | |
break unless HTTP.keep_alive?(response) | |
# The request body is either FixedLengthContent or ChunkedContent. | |
# In case it has not entirely been consumed by the handler, the connection is | |
# closed the connection even if keep alive was requested. | |
case body = request.body | |
when FixedLengthContent | |
if body.read_remaining > 0 | |
# Close the connection if there are bytes remaining | |
break | |
end | |
when ChunkedContent | |
# Close the connection if the IO has still bytes to read. | |
break unless body.closed? | |
end | |
end | |
rescue IO::Error | |
# IO-related error, nothing to do | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment