From: Eric Wong <e@80x24.org>
To: Martin Posthumus <martin.posthumus@gmail.com>
Cc: unicorn-public@yhbt.net, Jean Boussier <jean.boussier@shopify.com>
Subject: Re: Support for Rack 3 headers formatted as arrays
Date: Sun, 25 Dec 2022 22:56:58 +0000 [thread overview]
Message-ID: <20221225225658.M711750@dcvr> (raw)
In-Reply-To: <7c851d8a-bc57-7df8-3240-2f5ab831c47c@gmail.com>
Martin Posthumus <martin.posthumus@gmail.com> wrote:
> > OK. unicorn has no choice to support all Rack as long as Rack <= 2
> > applications exist...
>
> Understood, I just wanted to show that I'm reasonably confident this isn't
> due to something weird I was doing in application code, and that ultimately
> I couldn't find any workaround that didn't involve monkeypatching either
> Rack or Unicorn.
>
> > Does this work for you?
>
> Indeed it does!
Thanks for the confirmation and good to know.
> > Yeah, I haven't looked deeply at Rack 3 support and hate dealing
> > with the culture of breaking changes prevalent in the Ruby world :<
>
> Yeah, I get it. To be fair the array representation probably makes more
> sense for a header with multiple values, but downstream in practice it means
> you have to deal with both.
Yes, and Rack 3 also breaks the array of arrays `[ [ k, v1 ], [ k, v2 ] ]'
representation I was relying on :<
In any case, I'm thinking about hoisting out append_header()
into its own method to reuse between normal responses and
rack.early_hints 103 responses.
Cc-ing Jean to see if anything is amiss with the following
since they wrote the original code.
Original Rack 3 headers patch at:
https://yhbt.net/unicorn-public/20221210024246.GA8584@dcvr/
diff --git a/lib/unicorn/http_response.rb b/lib/unicorn/http_response.rb
index 3308c9be..19469b47 100644
--- a/lib/unicorn/http_response.rb
+++ b/lib/unicorn/http_response.rb
@@ -19,6 +19,18 @@ def err_response(code, response_start_sent)
"#{code} #{STATUS_CODES[code]}\r\n\r\n"
end
+ def append_header(buf, key, value)
+ case value
+ when Array # Rack 3
+ value.each { |v| buf << "#{key}: #{v}\r\n" }
+ when /\n/ # Rack 2
+ # avoiding blank, key-only cookies with /\n+/
+ value.split(/\n+/).each { |v| buf << "#{key}: #{v}\r\n" }
+ else
+ buf << "#{key}: #{value}\r\n"
+ end
+ end
+
# writes the rack_response to socket as an HTTP response
def http_response_write(socket, status, headers, body,
req = Unicorn::HttpRequest.new)
@@ -40,15 +52,7 @@ def http_response_write(socket, status, headers, body,
# key in Rack < 1.5
hijack = value
else
- case value
- when Array # Rack 3
- value.each { |v| buf << "#{key}: #{v}\r\n" }
- when /\n/ # Rack 2
- # avoiding blank, key-only cookies with /\n+/
- value.split(/\n+/).each { |v| buf << "#{key}: #{v}\r\n" }
- else
- buf << "#{key}: #{value}\r\n"
- end
+ append_header(buf, key, value)
end
end
socket.write(buf << "\r\n".freeze)
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 3416808f..cad515b9 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -589,22 +589,11 @@ def handle_error(client, e)
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)
+ rss = @request.response_start_sent
+ buf = rss ? "103 Early Hints\r\n" : "HTTP/1.1 103 Early Hints\r\n"
+ headers.each { |key, value| append_header(buf, key, value) }
+ buf << (rss ? "\r\nHTTP/1.1 ".freeze : "\r\n".freeze)
+ client.write(buf)
end
def e100_response_write(client, env)
next prev parent reply other threads:[~2022-12-25 22:56 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-09 21:52 Support for Rack 3 headers formatted as arrays Martin Posthumus
2022-12-10 2:42 ` Eric Wong
2022-12-12 15:52 ` Martin Posthumus
2022-12-25 22:56 ` Eric Wong [this message]
2022-12-27 8:17 ` Jean Boussier
2023-01-11 11:12 ` Jean Boussier
2023-01-11 11:40 ` Eric Wong
2023-01-11 11:44 ` Jean Boussier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://yhbt.net/unicorn/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221225225658.M711750@dcvr \
--to=e@80x24.org \
--cc=jean.boussier@shopify.com \
--cc=martin.posthumus@gmail.com \
--cc=unicorn-public@yhbt.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhbt.net/unicorn.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).