diff options
author | Jean Boussier <jean.boussier@gmail.com> | 2020-07-16 11:39:30 +0200 |
---|---|---|
committer | Eric Wong <bofh@yhbt.net> | 2020-07-16 11:57:22 +0000 |
commit | 92f587c191c96e201984d47ccdaf43a1bff2fc17 (patch) | |
tree | f4de27b542a7fa9f72ae002636b11b0c680debdf /lib/unicorn/http_server.rb | |
parent | 17de306edbbf4140df7ec49dbb7e26e59d33c0f9 (diff) | |
download | unicorn-92f587c191c96e201984d47ccdaf43a1bff2fc17.tar.gz |
While not part of the rack spec, this API is exposed by both puma and falcon, and Rails use it when available. The 103 Early Hints response code is specified in RFC 8297.
Diffstat (limited to 'lib/unicorn/http_server.rb')
-rw-r--r-- | lib/unicorn/http_server.rb | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb index 45a2e97..05dad99 100644 --- a/lib/unicorn/http_server.rb +++ b/lib/unicorn/http_server.rb @@ -15,7 +15,7 @@ class Unicorn::HttpServer :before_fork, :after_fork, :before_exec, :listener_opts, :preload_app, :orig_app, :config, :ready_pipe, :user, - :default_middleware + :default_middleware, :early_hints attr_writer :after_worker_exit, :after_worker_ready, :worker_exec attr_reader :pid, :logger @@ -588,6 +588,25 @@ class Unicorn::HttpServer rescue end + def e103_response_write(client, headers) + response = if @request.response_start_sent + "103 Early Hints\r\n" + else + "HTTP/1.1 103 Early Hints\r\n" + end + + headers.each_pair do |k, vs| + next if !vs || vs.empty? + values = vs.to_s.split("\n".freeze) + values.each do |v| + response << "#{k}: #{v}\r\n" + end + end + response << "\r\n".freeze + response << "HTTP/1.1 ".freeze if @request.response_start_sent + client.write(response) + end + def e100_response_write(client, env) # We use String#freeze to avoid allocations under Ruby 2.1+ # Not many users hit this code path, so it's better to reduce the @@ -602,7 +621,15 @@ class Unicorn::HttpServer # once a client is accepted, it is processed in its entirety here # in 3 easy steps: read request, call app, write app response def process_client(client) - status, headers, body = @app.call(env = @request.read(client)) + env = @request.read(client) + + if early_hints + env["rack.early_hints"] = lambda do |headers| + e103_response_write(client, headers) + end + end + + status, headers, body = @app.call(env) begin return if @request.hijacked? |