Date | Commit message (Collapse) |
|
Ruby 1.8.* users should get the latest Ruby 1.8.7 anyways since
they contain critical bugfixes. We don't keep workarounds
forever since the root problem is fixed/worked-around in
upstream and people have had more than a year to upgrade Ruby.
|
|
for i in `git ls-files '*.rb'`; do ruby -w -c $i; done
|
|
Since modern machines have more memory these days and
clients are sending more data, avoiding potentially slow
filesystem operations for larger uploads can be useful
for some applications.
|
|
In case a request sends the header and buffer as one packet,
TeeInput relying on accounting info from StreamInput is harmful
as StreamInput will buffer in memory outside of TeeInput's
control.
This bug is triggered by calling env["rack.input"].size or
env["rack.input"].rewind before to read.
|
|
It's possible for an application to call size after it has read
a few bytes/lines, so do not screw up a user's read offset when
consuming input.
|
|
Avoid having specific knowledge of internals in TeeInput
and instead move that to StreamInput when dealing with
byte counts. This makes things easier for Rainbows! which
will need to extends these classes.
|
|
We will eventually expose a Unicorn::StreamInput object as
"rack.input" for Rack 2.x applications. StreamInput allows
applications to avoid buffering input to disk, removing the
(potentially expensive) rewindability requirement of Rack 1.x.
TeeInput is also rewritten to build off StreamInput for
simplicity. The only regression is that TeeInput#rewind forces
us to consume an unconsumed stream before returning, a
negligible price to pay for decreased complexity.
|
|
Not that anybody uses trailers extensively, but it's
good to know it's there.
|
|
This should be easier for Rainbows! to use
|
|
TeeInput methods may be invoked deep in the stack, so
avoid giving them more work to do if a client disconnects
due to a bad upload.
|
|
This is slightly shorter and hopefully easier to find.
|
|
This should ensure we have less typing to do.
|
|
Noticed while hacking on a Zbatery-using application
|
|
"stringio" is part of the Ruby distro and we use it in multiple
places, so avoid re-requiring it.
|
|
Different threads may change $/ during execution, so cache it at
function entry to a local variable for safety. $/ may also be
of a non-binary encoding, so rely on Rack::Utils.bytesize to
portably capture the correct size.
Our string slicing is always safe from 1.9 encoding: both our
socket and backing temporary file are opened in binary mode,
so we'll always be dealing with binary strings in this class
(in accordance to the Rack spec).
|
|
It makes RDoc look better and cleaner, since we don't
do anything in the Unicorn namespace.
|
|
Some folks may require more fine-grained control of buffering
and I/O chunk sizes, so we'll support them (unofficially, for
now).
|
|
no need to pass an extra argument
|
|
Rack 1.2 removed the +size+ method requirement, but we'll
still support it since Rack 1.2 doesn't _prohibit_ it, and
Rack 1.[01] applications will continue to exist for a while.
|
|
It's a waste of memory bandwidth to do memcpy() when we know
Unicorn::HttpParser (via rb_str_resize()) will allocate new
memory for the string for us. An empty String is "free",
as we've already paid the Object cost regardless.
|
|
We'll use struct members exclusively from now on instead of
throwing ivars into the mix. This allows us to _unofficially_
support direct access to more members easily. Unofficial
extensions may include the ability to splice(2)/tee(2) for
better performance.
This also makes our object size smaller across all Ruby
implementations as well, too (helps Rainbows! out).
|
|
|
|
We do not hide unforseen exceptions, as that could cause us to
waste precious time attempting to continue processing after
errors.
|
|
First move it to a separate method, this allows subclasses to
reuse our error handler. Additionally, capture HttpParserError
as well since backtraces are worthless when a client sends us
a bad request, too.
|
|
|
|
Leaving the EOFError exception as-is bad because most
applications/frameworks run an application-wide exception
handler to pretty-print and/or log the exception with a huge
backtrace.
Since there's absolutely nothing we can do in the server-side
app to deal with clients prematurely shutting down, having a
backtrace does not make sense. Having a backtrace can even be
harmful since it creates unnecessary noise for application
engineers monitoring or tracking down real bugs.
|
|
It's confusing when a local variable reuses the same name
as a struct member.
|
|
Just let the error bubble all the way up to where Unicorn calls
process_client where it'll be appropriately handled.
Additionally, we'l just check the return value of tee() in
ensure_length and avoid it if it nils on us.
|
|
|
|
Subclass off the core File class so we don't have to
worry about #size being defined. This will mainly
be useful to Rainbows! but allows us to simplify
our TeeInput implementation a little, too.
|
|
Found in Rainbows! testing. Reusing the buffer when finalizing
input for headers could be problematic because it would lead
to the @buf2 instance variable being clobbered; allowing the
trailers to "leak" into the body.
|
|
Under FreeBSD writing to the file in sync mode does not change current
position, so change position to the end of the file. Without this patch
multipart post requests with large data (image uploading) does not work
correctly:
Status: 500 Internal Server Error
bad content body
/usr/local/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/utils.rb:347:in `parse_multipart'
/usr/local/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/utils.rb:319:in `loop'
/usr/local/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/utils.rb:319:in `parse_multipart'
File position behavior under FreeBSD :
ruby -v
ruby 1.8.7 (2009-04-08 patchlevel 160) [i386-freebsd7]
irb(main):001:0> b = File.new("abc", "w+")
=> #<File:abc>
irb(main):002:0> b.sync = true
=> true
irb(main):004:0> b.write("abc")
=> 3
irb(main):005:0> b.pos
=> 0
Acked-by: Eric Wong <normalperson@yhbt.net>
|
|
There are existing applications and libraries that don't check
the return value of env['rack.input'].read(length) (like Rails
:x). Those applications became broken under the IO#readpartial
semantics of TeeInput#read when handling larger request bodies.
We'll preserve the IO#readpartial semantics _only_ when handling
chunked requests (as long as Rack allows it, it's useful for
real-time processing of audio/video streaming uploads,
especially with Rainbows! and mobile clients) but use
read-in-full semantics for TeeInput#read on requests with a
known Content-Length.
|
|
We've started using magic comments to ensure any strings we
create are binary instead. Additionally, ensure we create any
StringIO objects with an explicit string (which default to
binary) to ensure the StringIO object is binary. This is
because StringIO.new (with no arguments) will always use the
process-wide default encoding since it does not know about
magic comments (and couldn't, really...)
|
|
This ensures any string literals that pop up in *our* code will
just be a bag of bytes. This shouldn't affect/fix/break
existing apps in most cases, but most constants will always have
the "correct" encoding (none!) to be consistent with HTTP/socket
expectations. Since this comment affects things only on a
per-source basis, it won't affect existing apps with the
exception of strings we pass to the Rack application.
This will eventually allow us to get rid of that Unicorn::Z
constant, too.
|
|
the docs for the TeeInput class was clobbering the Unicorn
module documentation instead.
|
|
TeeInput being needed is now (once again) an uncommon code path
so there's no point in relying on global constants. While we're
at it, allow StringIO to be used in the presence of small
inputs; too.
|
|
This method is strictly a filter, it does no I/O so "read"
is not an appropriate name to give it.
|
|
This should be more robust, faster and easier to deal
with than the ugly proof-of-concept regexp-based ones.
|
|
With the 1.9.2preview1 release (and presumably 1.9.1 p243), the
Ruby core team has decided that bending over backwards to
support crippled operating/file systems was necessary and that
files must be closed before unlinking.
Regardless, this is more efficient than using Tempfile because:
1) no delegation is necessary, this is a real File object
2) no mkdir is necessary for locking, we can trust O_EXCL
to work properly without unnecessary FS activity
3) no finalizer is needed to unlink the file, we unlink
it as soon as possible after creation.
|
|
This simplifies chunked_reader substantially with a slight
increase in tee_input complexity. This is beneficial because
chunked_reader is more complex to begin with and more likely
to experience correctness issues.
|
|
This change gives applications full control to deny clients
from uploading unwanted message bodies. This also paves the
way for doing things like upload progress notification within
applications in a Rack::Lint-compatible manner.
Since we don't support HTTP keepalive, so we have more freedom
here by being able to close TCP connections and deny clients the
ability to write to us (and thus wasting our bandwidth).
While I could've left this feature off by default indefinitely
for maximum backwards compatibility (for arguably broken
applications), Unicorn is not and has never been about
supporting the lowest common denominator.
|
|
This was causing the first part of the body to be missing when
an HTTP client failed to delay between sending the header and
body in the request.
|
|
We can actually just use one IO and file descriptor here and
simplify the code while we're at it.
|
|
Oops!
|
|
The complexity of making the object persistent isn't worth the
potential performance gain here.
|
|
We don't ever expose the @rd object to the public so
Rack-applications won't ever call size() on it.
|
|
Pay a performance penalty and always proxy reads through our
TeeInput object to ensure nobody closes our internal reader.
|
|
Trying not to repeat ourselves. Unfortunately, Ruby 1.9 forces
us to actually care about encodings of arbitrary byte sequences.
|
|
Just clarifying the license terms of the new code. Other files
should really have this notice in there as well.
|