* issue between rainbows/unicorn 5.0.0 and rack on ruby >= 1.9.1 @ 2016-07-13 19:51 Kevin Mullican 2016-07-13 20:24 ` Eric Wong 0 siblings, 1 reply; 4+ messages in thread From: Kevin Mullican @ 2016-07-13 19:51 UTC (permalink / raw) To: rainbows-public Greetings, We have run into a problem while trying to use rainbows/unicorn 5.0.0 on ruby >= 1.9.1. The issue is with rack. As of ruby 1.9.1, String no longer responds to #each, however it seems that rainbows is still sending a string body through rack. See: rainbows-5.0.0/lib/rainbows/process_client.rb:51: in `write_response` which enters rack at: rainbows-5.0.0/lib/rainbows/response.rb:85:in `write_body_each' Note that the rack spec specifically requires that body respond to #each and yield a set of strings: https://github.com/rack/rack/blob/25a549883b85fb33970b4a1530a365c0c9e51f95/SPEC#L245-L248 So, it seems that the onus is likely on rainbows to conform to the rack spec in order to require it's use. One solution would be to wrap the bare string in an array before it descends into rack. Sincerely, Kevin Mullican ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: issue between rainbows/unicorn 5.0.0 and rack on ruby >= 1.9.1 2016-07-13 19:51 issue between rainbows/unicorn 5.0.0 and rack on ruby >= 1.9.1 Kevin Mullican @ 2016-07-13 20:24 ` Eric Wong 2016-07-14 16:13 ` Dan Kegel 0 siblings, 1 reply; 4+ messages in thread From: Eric Wong @ 2016-07-13 20:24 UTC (permalink / raw) To: Kevin Mullican; +Cc: rainbows-public Kevin Mullican <kmullican@oblong.com> wrote: > Greetings, > > We have run into a problem while trying to use rainbows/unicorn 5.0.0 > on ruby >= 1.9.1. The issue is with rack. As of ruby 1.9.1, String no > longer responds to #each, however it seems that rainbows is still > sending a string body through rack. See: > > rainbows-5.0.0/lib/rainbows/process_client.rb:51: in `write_response` > > which enters rack at: > > rainbows-5.0.0/lib/rainbows/response.rb:85:in `write_body_each' That is all correct. > Note that the rack spec specifically requires that body respond to > #each and yield a set of strings: > > https://github.com/rack/rack/blob/25a549883b85fb33970b4a1530a365c0c9e51f95/SPEC#L245-L248 Also correct. > So, it seems that the onus is likely on rainbows to conform to the > rack spec in order to require it's use. One solution would be to wrap > the bare string in an array before it descends into rack. Actually, I believe the onus is on the application to produce a correct response body for the application server to use. Testing your application with the Rack::Lint middleware enabled should've detected such an error. Application frameworks (e.g. Sinatra, Rails, etc) already produce a response body which responds to #each out-of-the-box. A brief scan of lib/rack/handlers/*.rb in rack.git reveals the server handlers bundled with rack itself expect the body to respond to #each, too. ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: issue between rainbows/unicorn 5.0.0 and rack on ruby >= 1.9.1 2016-07-13 20:24 ` Eric Wong @ 2016-07-14 16:13 ` Dan Kegel 2016-07-14 22:17 ` Eric Wong 0 siblings, 1 reply; 4+ messages in thread From: Dan Kegel @ 2016-07-14 16:13 UTC (permalink / raw) To: Eric Wong; +Cc: Kevin Mullican, rainbows-public On Wed, Jul 13, 2016 at 1:24 PM, Eric Wong <e@80x24.org> wrote: > Actually, I believe the onus is on the application to produce a > correct response body for the application server to use. I work with Kevin, and helped track this down. Neither of us use Ruby much, hence our difficulty. I'm posting a followup here in case others in a similar spot happen across this thread. One problem was in our rackup.ru (I'll show a bit more code than needed, to be kind to newbies): class AppendSlash def initialize(app, options={}) @app = app @base = options[:base] end def call(env) if env['REQUEST_URI'] == @base [301, { 'Content-Type' => 'text/html', 'Location' => @base + '/' }, ''] else @app.call(env) end end end The fix was to change }, ''] to }, ['']] Likewise, in a few of our apps, we had to change [200, { 'Content-Type' => 'text/plain', 'Content-Length' => data.length.to_s }, data ] to [200, { 'Content-Type' => 'text/plain', 'Content-Length' => data.length.to_s }, [data] ] The question was also asked at https://github.com/rack/rack/issues/1096 so I'll follow up there, too. Thanks! - Dan ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: issue between rainbows/unicorn 5.0.0 and rack on ruby >= 1.9.1 2016-07-14 16:13 ` Dan Kegel @ 2016-07-14 22:17 ` Eric Wong 0 siblings, 0 replies; 4+ messages in thread From: Eric Wong @ 2016-07-14 22:17 UTC (permalink / raw) To: Dan Kegel; +Cc: Kevin Mullican, rainbows-public Dan Kegel <dank@kegel.com> wrote: > On Wed, Jul 13, 2016 at 1:24 PM, Eric Wong <e@80x24.org> wrote: > > Actually, I believe the onus is on the application to produce a > > correct response body for the application server to use. > > I work with Kevin, and helped track this down. Neither of us use Ruby > much, hence our difficulty. > I'm posting a followup here in case others in a similar spot happen > across this thread. Thanks for the followup! > One problem was in our rackup.ru (I'll show a bit more code than > needed, to be kind to newbies): > > class AppendSlash > def initialize(app, options={}) > @app = app > @base = options[:base] > end > def call(env) > if env['REQUEST_URI'] == @base > [301, { > 'Content-Type' => 'text/html', > 'Location' => @base + '/' > }, ''] Also in the interest of being kind to newbies; some minor problems in the above example unrelated to your original problem: * REQUEST_URI isn't actually part of the Rack spec, but many servers include it, so I guess it's fine in practice. * Content-Length isn't specified for your 301 response; which might cause redirects to not terminate properly. This could confuse clients and/or cause Rainbows! to hit the keepalive_timeout (default 5s) and delay redirects by that time[*] According to Rack::Utils::STATUS_WITH_NO_ENTITY_BODY, only 100-199, 204, 205, 304 response codes can get away without a Content-Length or "Transfer-Encoding: chunked" header Of course, you may be using the Rack::ContentLength/Rack::Chunked middlewares to generate the appropriate headers, but the code below indicates not... > [200, { > 'Content-Type' => 'text/plain', > 'Content-Length' => data.length.to_s > }, [data] > ] If you're unsure about the encoding of `data', 'Content-Length' => data.bytesize.to_s would be safer for multi-byte responses. String#bytesize is available from 1.8.7 onwards. However, if you're certain `data' is already a single-byte encoding (binary/us-ascii) String#size could be a hair faster since it's one of the few optimized dispatch instructions in the mainline VM. [*] in retrospect, this is probably major barrier to adoption of Rainbows! and yahns, since they take a stricter interpretation of Rack SPEC than most other servers. There've been several reports in the past of users forgetting to set content-length/chunked in responses and wondering why some responses take so long. ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-07-14 22:17 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-07-13 19:51 issue between rainbows/unicorn 5.0.0 and rack on ruby >= 1.9.1 Kevin Mullican 2016-07-13 20:24 ` Eric Wong 2016-07-14 16:13 ` Dan Kegel 2016-07-14 22:17 ` Eric Wong
Code repositories for project(s) associated with this public inbox https://yhbt.net/rainbows.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).