From: Ryan Tomayko <r@tomayko.com>
To: rack-devel@googlegroups.com
Subject: Re: Threading Bug Patches
Date: Wed, 27 Jan 2010 17:46:22 -0800 [thread overview]
Message-ID: <f732822d1001271746oebbb596lb20884573a126b24@mail.gmail.com> (raw)
In-Reply-To: <9a95538e-c5e6-4e8b-97a0-efda50e7ccc0@n7g2000yqb.googlegroups.com>
On Wed, Jan 27, 2010 at 1:26 PM, Sunny Hirai <thesunny@gmail.com> wrote:
> I'm posting patches for bugs as I find them. I'm trying to
> specifically fix the file response bug at:
>
> http://groups.google.com/group/rack-devel/browse_thread/thread/568f5045d55aa063
>
> I haven't solved it but I have found and am finding other bugs.
>
> In Rack::Chunked
>
> def call(env)
> self.dup._call(env)
> end
>
> def _call(env)
> status, headers, body = @app.call(env)
> headers = HeaderHash.new(headers)
>
> if env['HTTP_VERSION'] == 'HTTP/1.0' ||
> STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
> headers['Content-Length'] ||
> headers['Transfer-Encoding']
> [status, headers, body]
> else
> dup.chunk(status, headers, body)
> end
> end
>
> A new instance is needed because it creates an instance variable @body
> later. The body would end up being the same for requests occurring at
> the same time.
I don't see how. Here's Rack::Chunked in it's entirety:
require 'rack/utils'
module Rack
# Middleware that applies chunked transfer encoding to response bodies
# when the response does not include a Content-Length header.
class Chunked
include Rack::Utils
def initialize(app)
@app = app
end
def call(env)
status, headers, body = @app.call(env)
headers = HeaderHash.new(headers)
if env['HTTP_VERSION'] == 'HTTP/1.0' ||
STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
headers['Content-Length'] ||
headers['Transfer-Encoding']
[status, headers, body]
else
dup.chunk(status, headers, body)
end
end
def chunk(status, headers, body)
@body = body
headers.delete('Content-Length')
headers['Transfer-Encoding'] = 'chunked'
[status, headers, self]
end
def each
term = "\r\n"
@body.each do |chunk|
size = bytesize(chunk)
next if size == 0
yield [size.to_s(16), term, chunk, term].join
end
yield ["0", term, "", term].join
end
def close
@body.close if @body.respond_to?(:close)
end
end
end
That should be fine under multiple concurrent threads of execution.
Thanks,
Ryan
prev parent reply other threads:[~2010-01-28 1:46 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-27 21:26 Threading Bug Patches Sunny Hirai
2010-01-28 1:46 ` Ryan Tomayko [this message]
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-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://groups.google.com/group/rack-devel
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f732822d1001271746oebbb596lb20884573a126b24@mail.gmail.com \
--to=rack-devel@googlegroups.com \
/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.
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).