Martin Posthumus <[email protected]> wrote:
> Hello,
>
> As of Rack v3, the internal representation of headers containing multiple
> values appears to have been changed to use an array of strings rather than a
> newline-separated string. Pull request visible here:
> https://github.com/rack/rack/pull/1793
>
> The Rack changelog (https://github.com/rack/rack/blob/main/CHANGELOG.md)
> also includes this entry under 3.0.0:
> "Response header values can be an Array to handle multiple values (and no
> longer supports \n encoded headers)."
OK. unicorn has no choice to support all Rack as long as Rack <= 2
applications exist...
> I'm running into some serialization issues with this sort of header when
> trying to run an application on Unicorn that makes use of multiple cookies.
> The `set-cookie` header is returning what appears to be a stringified array:
>
> set-cookie: ["my.cookie=.....; domain=......; path=/", "rack.session=......;
> path=/; httponly"]
>
> Which in turn results in cookies getting registered with names like
> `["rack.session` rather than `rack.session`.
>
> I'm not especially familiar with Unicorn's internals, but poking around a
> little bit, it looks like this might be related to the definition of
> `http_response_write` in lib/unicorn/http_response.rb, where it handles
> newline-separated strings, but not arrays. I can confirm that the set-cookie
> header value appears to be an array in this method, not a string.
Does this work for you?
diff --git a/lib/unicorn/http_response.rb b/lib/unicorn/http_response.rb
index b23e521..3308c9b 100644
--- a/lib/unicorn/http_response.rb
+++ b/lib/unicorn/http_response.rb
@@ -40,7 +40,10 @@ def http_response_write(socket, status, headers, body,
# key in Rack < 1.5
hijack = value
else
- if value =~ /\n/
+ 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
> At present I'm only seeing this issue when running on a Unicorn server. When
> I swap out something like webrick, it appears the array values are handled
> as expected.
Yeah, I haven't looked deeply at Rack 3 support and hate dealing
with the culture of breaking changes prevalent in the Ruby world :<