Date | Commit message (Collapse) |
|
We don't want to accidentally kill every process in the
process group.
|
|
When SIGHUP reloads the config, we didn't account for the case
where the listen socket was completely unspecified. Thus the
default listener (0.0.0.0:8080), did not get preserved and
re-injected into the config properly.
Note that relying on the default listen or specifying listeners
on the command-line means it's /practically/ impossible to
_unbind_ those listeners with a configuration file reload. We
also need to preserve the (unspecified) default listener across
upgrades that later result in SIGHUP, too; so the easiest way is
to inject the default listener into the command-line for
upgrades.
Many thanks to James Golick for reporting and helping me track
down the bug since this behavior is difficult to write reliable
automated tests for.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
|
|
Just to ensure we handle HUP correctly since preload_app
changes the behavior of HUP handling a bit.
|
|
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.
|
|
This probably doesn't affect anyone with HTTP/1.1, but
future versions of HTTP will use absolute URIs and maybe
we'll eventually get clients that (mistakenly) send us
Host: headers along with absolute URIs.
|
|
HTTP/0.9 GET requests expect responses without headers. Some
weird applications/tools still use the ancient HTTP/0.9
protocol for weird reasons, so we'll support them.
ref: rfc 1945, section 4.1
|
|
This method determines if there are headers in the request.
Simple HTTP/0.9 requests did not have headers in the request
(and our responses we make should not have them, either).
|
|
And it'll default to HTTP/0.9 if HTTP_VERSION is not specified
(as version-less HTTP requests imply HTTP/0.9.
|
|
Followup to commit 7f74a16406c92c4362ac20af4ccb8bc821cf978b,
we want to ensure error messages do not get swallowed up into
/dev/null when daemonizing; so we defer the default redirects
to "/dev/null" to as late as possible.
|
|
SERVER_PROTOCOL is actually defined as "HTTP/1.1 even though it
should not be for HTTP/0.9 responses.
|
|
HTTP/0.9 only supports GET requests and didn't require a
version number in the request line. Additionally, only
a single CRLF was required.
Note: we don't correctly generate HTTP/0.9 responses, yet.
|
|
While I still consider pound to be irrelevant, but I still
sometimes get hand-crafted HTTP requests that come in with
multiline headers. Since these are part of the HTTP specs and
not difficult to support, we might as well support them for
the sake of completeness.
|
|
Rack is autoload-based and so are we.
|
|
ab still sends this with HTTP/1.0 requests, which is
unfortunate, but synthetic benchmarks are good for marketing
purposes!
|
|
This lets clients can pass through newly-invented status codes
that Rack does not know about.
|
|
It's not worth the effort to keep the internal API consistent
between non-bugfix versions.
|
|
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 makes a noticeable difference on light GET/HEAD requests.
Heck, even the tests run a few seconds faster.
|
|
This should be used to detect if a request can really handle
keepalives and pipelining. Currently, the rules are:
1. MUST be a GET or HEAD request
2. MUST be HTTP/1.1
3. MUST NOT have "Connection: close" set
This also reduces the amount of garbage we create by
globalizing constants and using them whenever possible.
|
|
This method is strictly a filter, it does no I/O so "read"
is not an appropriate name to give it.
|
|
The normal at_exit handlers can't work here
|
|
Otherwise Ruby could get confused and not be able to reap the
process correctly (and thus wait a long time for timeout).
|
|
Otherwise they might be picked up by the GC during the
other tests (exposed by Ruby 1.9.1-p243).
|
|
Since Rack requires a Hash object, this is joined in in
accordance with rfc2616, section 4.2[1]. Of course, it's up to
the framework or application to handle such requests.
I could optimize this to avoid creating a single garbage
String object, but I don't think it's common enough to
worry about...
[1] - http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
|
|
Just in case clients decide to get cute.
|
|
We're bound by the maximum value of off_t when handling
input bodies (we need to buffer to disk). Also ensure
we stop bad clients that send us unparseable lengths.
|
|
This should be more robust, faster and easier to deal
with than the ugly proof-of-concept regexp-based ones.
|
|
Our current TrailerParser is liberal and does not require it,
but the to-be-activated Ragel one is not.
|
|
|
|
|
|
test/test_helper doesn't seem to be required correctly anymore,
since we know our own module/test names don't conflict, just
fix RUBYLIB to include $(test_prefix)
With test_util.rb, using #reopen with Tempfile objects seems
prone to the objects being closed. Not completely sure what is
going on but I'll just sidestep around it since I've stopped
trusting Tempfile by now...
|
|
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.
|
|
We couldn't do proper namespacing for the C module so there was
a potential conflict with Init_http11() in Mongrel. This was
needed because Mongrel's HTTP parser could be used in some
applications and we may be unfortunate enough need to support
them.
|
|
There's a small memory reduction to be had when forking
oodles of processes and the Perl hacker in me still
gets confused into thinking those are arrays...
|
|
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.
|
|
Support for the "Trailer:" header and associated Trailer
lines should be reasonably well supported now
|
|
|
|
I'd honestly be more comfortable doing this in C (and possibly
adapting the code from the libcurl internals since that code has
been very well-tested).
|
|
Eventually this (and ChunkedReader) may be done in C/Ragel
along with the existing HttpParser.
|
|
This won't be heavily used enough to make preallocation worth
the effort. While we're at it, don't enforce policy by forcing
the readpartial buffer to be Encoding::BINARY (even though it
/should/ be :), it's up to the user of the interface to decide.
|
|
The default is false because some applications were not
written to handle partial reads (even though IO#read allows
it, not just IO#readpartial).
|
|
|
|
Now that I've beefed out my Makefile to detect errors,
I've noticed this test has been failing under 1.9 for
a while now. Currently no released version of Rack(1.0)
or Rails(2.3.2.1) supports this.
|
|
This has been broken since
6945342a1f0a4caaa918f2b0b1efef88824439e0
"Transfer-Encoding: chunked streaming input support" but
somehow never caught by me or anyone else.
|
|
Additionally, provide verifications for sizes after-the-fact
to avoid slamming all of our input into the server.
|
|
No point in making syscalls to deal with empty bodies.
Reinstate usage of the NULL_IO object which allows us
to avoid allocating new objects.
|
|
This adds support for handling POST/PUT request bodies sent with
chunked transfer encodings ("Transfer-Encoding: chunked").
Attention has been paid to ensure that a client cannot OOM us by
sending an extremely large chunk.
This implementation is pure Ruby as the Ragel-based
implementation in rfuzz didn't offer a streaming interface. It
should be reasonably close to RFC-compliant but please test it
in an attempt to break it.
The more interesting part is the ability to stream data to the
hosted Rack application as it is being transferred to the
server. This can be done regardless if the input is chunked or
not, enabling the streaming of POST/PUT bodies can allow the
hosted Rack application to process input as it receives it. See
examples/echo.ru for an example echo server over HTTP.
Enabling streaming also allows Rack applications to support
upload progress monitoring previously supported by Mongrel
handlers.
Since Rack specifies that the input needs to be rewindable, this
input is written to a temporary file (a la tee(1)) as it is
streamed to the application the first time. Subsequent rewinded
reads will read from the temporary file instead of the socket.
Streaming input to the application is disabled by default since
applications may not necessarily read the entire input body
before returning. Since this is a completely new feature we've
never seen in any Ruby HTTP application server before, we're
taking the safe route by leaving it disabled by default.
Enabling this can only be done globally by changing the
Unicorn HttpRequest::DEFAULTS hash:
Unicorn::HttpRequest::DEFAULTS["unicorn.stream_input"] = true
Similarly, a Rack application can check if streaming input
is enabled by checking the value of the "unicorn.stream_input"
key in the environment hashed passed to it.
All of this code has only been lightly tested and test coverage
is lacking at the moment.
[1] - http://tools.ietf.org/html/rfc2616#section-3.6.1
|
|
This should prevent Rack from being required too early
on so "-I" being passed through the unicorn command-line
can modify $LOAD_PATH for Rack
|
|
* benchmark:
Define HttpRequest#reset if missing
|
|
Newer versions of Unicorn do not include a #reset method
|