Date | Commit message (Collapse) |
|
Evil clients may be exposed to the Unicorn parser via
Rainbows!, so we'll allow people to turn off blindly
trusting certain X-Forwarded* headers for "rack.url_scheme"
and rely on middleware to handle it.
|
|
The first value of X-Forwarded-Proto in rack.url_scheme should
be used as it can be chained. This header can be set multiple
times via different proxies in the chain, but consider the first
one to be valid.
Additionally, respect X-Forwarded-SSL as it may be passed with
the "on" flag instead of X-Forwarded-Proto.
ref: rack commit 85ca454e6143a3081d90e4546ccad602a4c3ad2e
and 35bb5ba6746b5d346de9202c004cc926039650c7
|
|
This limits the number of keepalive requests of a single
connection to prevent a single client from monopolizing server
resources. On multi-process servers (e.g. Rainbows!) with many
keepalive clients per worker process, this can force a client to
reconnect and increase its chances of being accepted on a
less-busy worker process.
This directive is named after the nginx directive which
is identical in function.
|
|
This allows apps/middlewares on Rainbows! that rely on env in
the response_body#close to hold onto the env.
|
|
Some apps may do them, so make sure we do them correctly.
|
|
No need to accept any number of args, that could hide bugs in
applications that could give three or more arguments. We also
raise ArgumentError when given a negative length argument to
read.
|
|
Any calls to read with an explicit zero length now returns an
empty string. While not explicitly specified by Rack::Lint,
this is for compatibility with StringIO and IO methods which
are common in other web servers.
|
|
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.
|
|
We'll need this in Rainbows!
|
|
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.
|
|
An easy combination of the existing HttpParser#keepalive? and
HttpParser#reset methods, this makes it easier to implement
persistence.
|
|
Yes, this means even POST/PUT bodies may be kept alive,
but only if the body (and trailers) are fully-consumed.
|
|
We cannot clear the buffer between requests because
clients may send multiple requests that get taken in
one read()/recv() call.
|
|
This should be easier for Rainbows! to use
|
|
The parser and request object become one and the
same, since the parser lives for the lifetime
of the request.
|
|
This provides the kgio_read! method which is like readpartial,
only significantly cheaper when a client disconnects on us.
|
|
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.
|
|
It's expensive to generate a backtrace and this exception
is only triggered by bad clients. So make it harder for
them to DoS us by sending bad requests.
|
|
It's a much closer representation of what we'd expect in
the real server than a mono-directional UNIX pipe.
|
|
The bugs from signal handling were fixed in the Rubinius
1.1.0 release.
|
|
This should hopefully make the non-blocking accept()
situation more tolerable under Ruby 1.9.2.
|
|
This should ensure we have less typing to do.
|
|
There's no need for a response class or object since Rack just
uses an array as the response. So use a procedural style which
allows for easier understanding.
We shall also support keepalive/pipelining in the future, too.
|
|
While we've always unlinked dead sockets from nuked/leftover
processes, blindly unlinking them can cause unnecessary failures
when an active process is already listening on them. We now
make a simple connect(2) check to ensure the socket is not in
use before unlinking it.
Thanks to Jordan Ritter for the detailed bug report leading to
this fix.
ref: http://mid.gmane.org/8D95A44B-A098-43BE-B532-7D74BD957F31@darkridge.com
|
|
These nasty hacks were breaking Rubinius compatibility.
This can be further cleaned up, too.
|
|
"stringio" is part of the Ruby distro and we use it in multiple
places, so avoid re-requiring it.
|
|
Under Linux, this allows users to tune the time (in seconds) to
defer connections before allowing them to be accepted. The
behavior of TCP_DEFER_ACCEPT changed with Linux 2.6.32 and idle
connections may still be accept()-ed after the specified value
in seconds. A small value of '1' remains the default for
Unicorn as Unicorn does not worry about slow clients. Higher
values provide better DoS protection for Rainbows! but also
increases kernel memory usage.
Allowing "dataready" for FreeBSD accept filters will allow
SSL sockets to be used in the future for HTTPS, too.
|
|
We do an extra check in the application dispatch to ensure
ENV['PWD'] is set correctly to match Dir.pwd (even if the
string path is different) as this is required for Capistrano
deployments.
These tests should now pass under OSX where /var is apparently
a symlink to /private/var.
|
|
As of rbx commit cf4a5a759234faa3f7d8a92d68fa89d8c5048f72,
most of the issues uncovered in our test suite are fixed.
|
|
It's a good idea to use a caching http_proxy to save bandwidth
when isolating gems for different Ruby versions.
|
|
They cannot be worked around, but tickets have been filed
upstream (I still hate all bug trackers besides Debian's).
TCPServer.for_fd (needed for zero-downtime upgrades):
http://github.com/evanphx/rubinius/issues/354
UnixServer.for_fd (needed for zero-downtime upgrades):
http://github.com/evanphx/rubinius/issues/355
Signal handling behavior seems broken (OOM or segfaults):
http://github.com/evanphx/rubinius/issues/356
|
|
This fails under Rubinius.
ref: http://github.com/evanphx/rubinius/issues/355
|
|
I'm not sure what I was smoking when I originally (and
knowingly) wrote the racy code.
|
|
Non-MRI runtimes (like Rubinius) may implement garbage
collection very differently than MRI.
|
|
IO#reopen in Rubinius seems to munge the O_APPEND flag when passed a
path, however passing an actual IO object. However, at the system call
level, everything is the same.
ref: http://github.com/evanphx/rubinius/issues/347
|
|
When Unicorn receives a request with a "Version" header, the
HttpParser transforms it into "HTTP_VERSION". After that tries to add
it to the request hash which already contains a "HTTP_VERSION" key
with the actual http version of the request. So it tries to append the
new value separated by a comma. But since the http version is a
freezed constant, the TypeError exception is raised.
According to the HTTP RFC
(http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.1) a
"Version" header is valid. However, it's not supported in rack, since
rack has a HTTP_VERSION env variable for the http version. So I think
the easiest way to deal with this problem is to just ignore the header
since it is extremely unusual. We were getting it from a crappy bot.
ref: http://mid.gmane.org/AANLkTimuGgcwNAMcVZdViFWdF-UcW_RGyZAue7phUXps@mail.gmail.com
Acked-by: Eric Wong <normalperson@yhbt.net>
|
|
...than "test ?r" and "test ?w"
Not everybody comes from a Unix shell programming background,
even though they *should* ;)
|
|
They are not compatible, and the Rails 3 tests will
be completely separate.
|
|
This was noticed by running under Ruby 1.9.2-preview3
|
|
This allows us to gets rid of the Rack 1.0.1 dependency when
running Rails tests since previous versions of Rails 2.3.x
needed Rack 1.0.1, where as Rails 2.2.x and below could be used
with any version of Rack (under Unicorn only).
|
|
This is allowed by RFC 2616, section 2.2, where spaces and
horizontal tabs are counted as linear white space and linear
white space (not just regular spaces) may prefix field-values
(section 4.2).
This has _not_ been a real issue in ~4 years of using this
parser (starting with Mongrel) with clients in the wild.
Thanks to IƱaki Baz Castillo for pointing this out.
|
|
This is useful as a :listeners argument when setting up
Raindrops::Middleware (http://raindrops.bogomips.org/),
as it can be done automatically.
|
|
HTTP requests without trailers still need a CRLF after the last
chunk, that is: it must end as: "0\r\n\r\n", not "0\r\n". So
we'll always pretend there are trailers to parse for the
sake of TeeInput.
This is mostly a pedantic fix, as the two bytes in the socket
buffer are unlikely to trigger protocol errors.
|
|
...instead of tripping an assertion.
This fixes a potential denial-of-service for servers exposed directly
to untrusted clients.
This bug does not affect supported Unicorn deployments as Unicorn is
only supported with trusted clients (such as nginx) on a LAN. nginx is
known to reject clients that send invalid Content-Length headers, so any
deployments on a trusted LAN and/or behind nginx are safe.
Servers affected by this bug include (but are not limited to) Rainbows!
and Zbatery. This does not affect Thin nor Mongrel which never got
request body filtering treatment that the Unicorn HTTP parser got in
August 2009.
|
|
Avoid Tempfile.new(nil), which breaks under Ruby 1.9.2
and was probably a bad idea to begin with.
|
|
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).
|
|
The temporary paths we create to mimic script/server-emulation
did not work when working_directory was used. Now we defer
path creation until after working_directory is bound.
|
|
First off, this memory leak DOES NOT affect Unicorn itself.
Unicorn allocates the HttpParser once and always reuses it
in every sequential request.
This leak affects applications which repeatedly allocate a new
HTTP parser. Thus this bug affects _all_ deployments of
Rainbows! and Zbatery. These servers allocate a new parser for
every client connection.
I misread the Data_Make_Struct/Data_Wrap_Struct documentation
and ended up passing NULL as the "free" argument instead of -1,
causing the memory to never be freed.
From README.EXT in the MRI source which I misread:
> The free argument is the function to free the pointer
> allocation. If this is -1, the pointer will be just freed.
> The functions mark and free will be called from garbage
> collector.
|
|
we've already got "-*- encoding: binary -*-" in everything
|
|
This prevents trigger-happy init scripts from reading the pid
file (and thus sending signals) to a not-fully initialized
master process to handle them.
This does NOT fix anything if other processes are sending
signals prematurely without relying on the presence of the pid
file. It's not possible to prevent all cases of this in one
process, even in a purely C application, so we won't bother
trying.
We continue to always defer signal handling to the main loop
anyways, and signals sent to the master process will be
deferred/ignored until Unicorn::HttpServer#join is run.
|