Date | Commit message (Collapse) |
|
This was back when I did s/mongrel/Unicorn/g
on the sources.
|
|
We need to ensure children are spawned by waiting
until the master is ready.
|
|
Avoid using strcmp() since it could break badly if
Ruby ever stopped null-terminating strings C-style.
We're also freezing "http" as a global. Rack does not
explicitly permit nor deny this, and Mongrel has always
used frozen strings as hash values in other places.
|
|
Apparently I was smoking crack and thought they weren't
changeable. Additionally, SO_REUSEADDR is set by TCPServer.new,
so there's no need to set it ourselves; so avoid putting
extra items in the purgatory.
This allows SIGHUP to change listen options.
|
|
Sockets may be unintentionally unlinked on the filesystem.
When reloading our config, ensure that the socket exists
on the filesystem. If not, close the listener (since it's
unusable by outside apps) and reopen it.
|
|
Rather than blindly appending to our listener set
with every "listen" directive read in the config
file, reset our internal array.
Listeners specified on the command-line are always
preserved between config reloads.
|
|
This fixes a long-standing bug where listeners would be removed
from the known listener set during a reload but never correctly
shut down (until reexec).
Additionally, test_server was working around this bug (my fault,
subconciously) as teardown did not unbind the socket, requiring
the tests to grab a new port.
|
|
Pass "https" to "rack.url_scheme" if the X-Forwarded-Proto
header matches "https". X-Forwarded-Proto is a semi-standard
header that Ruby frameworks seem to respect; so we use that.
We won't support ENV['HTTPS'] since that can only be set at
start time and some app servers supporting https also support
http.
Currently, "rack.url_scheme" only allows "http" and "https",
so we won't set anything else to avoid breaking Rack::Lint.
|
|
* Test for '*' in "OPTIONS * HTTP/1.1" for now (even though
Rack doesn't like it).
* Some clients can send absolute URIs, too
|
|
Run tests with warnings so we detect stupid things like this.
|
|
|
|
I can't think of a good reason to ever use restrictive
permissions with UNIX domain sockets for an HTTP server.
Since some folks run their nginx on port 80 and then
have it drop permissions, we need to ensure our socket
is readable and writable across the board.
The reason I'm respecting the existing umask at all (instead of
using 0000 across the board like most daemonizers) is because
the admin may want to restrict access (especially write access)
to log files.
|
|
I/O on slow descriptors can be interrupted so make sure we
(and Ruby itself) are handling EINTR correctly.
|
|
Premade lambda/proc/Proc objects may all be passed, to the
hooks, not just anonymous blocks.
|
|
In case redirect_io is called multiple times,
we don't want to lose debugging output.
|
|
Not sure if unicorn_rails should create them since the builtin
Rails server only creates things under tmp/*.
|
|
Recent changes made to the unicorn_rails loader were needed to
get ActiveRecordStore to load correctly.
|
|
We need to ensure the next request has started
processing before we can guarantee a temp file
has been unlinked.
|
|
We'll allow before_exec to override that setting, however.
There are cases where someone setting
Logger.new("/path/to/file") will create new file descriptors in
the master process. This will prevent FD leakage
and a test case (for Linux only) proves it.
|
|
|
|
Loading Rails takes a very long time, so consolidate most of the
tests into one big test that allows us to avoid loading Rails.
It makes the test less like unit tests, but they could still
be split up into private functions if one wants to run them
individually.
|
|
Additional tests for Rails have been added
* cookies and sessions
* POST requests
* POST requests with multipart uploads
* 404 handling
* static file serving
* cached static file serving
(resources with ";" caching in some old 1.2.x version
not yet tested)
|
|
|
|
Very preliminary for now. Basically just sets up a basic
controller and response. Requires git to clone the official
Rails repository.
|
|
* Expand addresses like "1:8080" to "127.0.0.1:8080"
beforehand so sock_name() in SocketHelper will
always return consistent results.
* Add support for "unix:/path/to/foo" paths for easier
synchronization with nginx config files.
|
|
|
|
They were non-conformant for the longest time
|
|
We need to ensure the QUIT signal to the old processes
are processed when fixing the config.
Additionally, the log rotation checker was not reliable
because the master log emitted a similar message to
the workers and we were not distinguishing between
them. Check for all 5 logs (1 master + 4 workers)
to be rotated.
|
|
"HTTP_BODY" could conflict with a "Body:" HTTP header if there
ever is one. Also, try to hide this body from the Rack
environment before @app is called since it is only used by
Unicorn internally.
|
|
We still need to support "listeners" for easy use of
command-line options, but folks using the config file should use
"listen" as it is more flexible.
|
|
Instead of having global options for all listeners,
make all socket options per-listener. This allows
reverse-proxies to pick different listeners to get
different options on different sockets.
Given a cluster of machines (10.0.0.1, 10.0.0.2, 10.0.0.3)
running Unicorn with the following config:
------------------ 8< ----------------
listen "/tmp/local.sock", :backlog => 1
listen "*:8080" # use the backlog=1024 default
------------------ 8< ----------------
It is possible to configure a reverse proxy to try to use
"/tmp/local.sock" first and then fall back to using the
TCP listener on port 8080 in a failover configuration.
Thus the nginx upstream configuration on 10.0.0.1 to
compliment this would be:
------------------ 8< ----------------
upstream unicorn_cluster {
# reject connections ASAP if we are overloaded
server unix:/tmp/local.sock;
# fall back to other machines in the cluster via "backup"
# listeners which have a large backlog queue.
server 10.0.0.2:8080 backup;
server 10.0.0.3:8080 backup;
}
------------------ 8< ----------------
This removes the global "backlog" config option which
was inflexible with multiple machines in a cluster
and exposes the ability to change SO_SNDBUF/SO_RCVBUF
via setsockopt(2) for the first time.
|
|
This is in the Rack specification and a good idea. Remind
ourselves to prevent file descriptor or other resource leaks in
case the body is not an Array.
|
|
We always close the socket immediately after a
successful write for two reasons:
1) To prevent error responses from being rewritten.
If we throw an exception in our request/app/response
chain, we'll attempt to write an HTTP 400/500 response
out if the socket is open. No way to write to
an open socket.
2) To uncork the socket if TCP_CORK is enabled (Linux)
ASAP. This should be a tick faster than waiting
to go back up the stack and close it there.
|
|
This reworks error handling throughout the entire stack to be
more Ruby-ish. Exceptions are raised instead of forcing the
us to check return values.
If a client is sending us a bad request, we send a 400.
If unicorn or app breaks in an unexpected way, we'll
send a 500.
Both of these last-resort error responses are sent using
IO#write_nonblock to avoid tying Unicorn up longer than
necessary and all exceptions raised are ignored.
Sending a valid HTTP response back should reduce the chance of
us from being marked as down or broken by a load balancer.
Previously, some load balancers would mark us as down if we close
a socket without sending back a valid response; so make a best
effort to send one. If for some reason we cannot write a valid
response, we're still susceptible to being marked as down.
A successful HttpResponse.write() call will now close the socket
immediately (instead of doing it higher up the stack). This
ensures the errors will never get written to the socket on a
successful response.
|
|
|
|
They're easier for me to type and read and just barely faster
when doing comparisons on.
|
|
Instead of rotating logs immediately when SIGUSR1 is caught,
defer it until the current client is processing is complete.
This allows multi-line log messages generated by apps to not be
broken up if SIGUSR1 is received while the app is running.
If we're sleeping inside IO.select, we close a pipe in the
exceptfds set to cause EBADF to be raised.
This also adds a small reliability improvement to test_exec
so we wait until signals are ready before sending USR1
to rotate logs.
|
|
* commit 'v0.2.3':
unicorn 0.2.3
Ensure Tempfiles are unlinked after every request
Don't bother unlinking UNIX sockets
Conflicts:
lib/unicorn/socket.rb
|
|
Otherwise we bloat TMPDIR and run the host out of space, oops!
|
|
bind_listen takes a hash as its second parameter now, allowing
the addition of :sndbuf and :rcvbuf options to specify the size
of the buffers in bytes. These correspond to the SO_SNDBUF and
SO_RCVBUF options via setsockopt(2) respectively.
This also adds support for per-listener backlogs to be used.
However, this is only an internal API change and the changes
have not yet been exposed to the user via Unicorn::Configurator,
yet.
Also add a bunch of SocketHelper tests
|
|
This cuts the HttpParser interface down to #execute and #reset
method. HttpParser#execute will return true if it completes and
false if it is not. http->nread state is kept internally so we
don't have to keep track of it in Ruby; removing one parameter
from #execute.
HttpParser#reset is unchanged.
All errors are handled through exceptions anyways, so the
HttpParser#error? method stopped being useful.
Also added some more unit tests to the HttpParser since I know
some folks are (rightfully) uncomfortable with changing stable C
code. We now have tests for incremental parsing.
In summary, we have:
* more test cases
* less C code
* simpler interfaces
* small performance improvement
=> win \o/
|
|
* commit 'origin/benchmark':
benchmark: header values must be strings
All new benchmarks, old ones removed
|
|
Newer versions of Unicorn "enforce" this by splitting on "\n" to
handle Rack-style multi-value headers.
|
|
dd.ru is a rackup file is intended as a dd(1)-like test for I/O
performance.
There are also individual request, response, and big_request
benchmarks for micro benchmarking some parts of Unicorn.
The rest of the benchmarks are gone: I am not interested in
performance comparisons (and pissing matches) with other web
servers (or their fanboys/girls).
I will _NEVER_ publically publish benchmarks comparing Unicorn
against other web servers. I will only compare Unicorn against
other versions of Unicorn, possibly on different platforms.
Neutral third-parties are invited to publish their own
benchmarks (along with detailed procedures, version numbers and
other details) comparing Unicorn to other servers.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
|
|
Rack uses a single newline character to represent multi-value
headers. Thus { 'Set-Cookie' => "foo=bar\nbar=foo" }
will get you:
Set-Cookie: foo=bar
Set-Cookie: bar=foo
While RFC2616 says you can combine headers as:
Set-Cookie: foo=bar,bar=foo
There are probably HTTP clients out there that don't handle
things correctly so don't bother...
Additionally, don't bother doing duplicate suppression anymore.
Just assume Rack or a higher layer knows what it's doing
regarding duplicates and we'll get a Hash most of the time
anyways.
|
|
The master _may_ run with different user/group/umask than the
workers. Since the logs were always created by the master
process, the master should rotate them first to ensure correct
ownership and permissions.
This way if the workers fail log rotation and die, they'll
be automatically respawned with the new logs in place.
|
|
This test requires Rack to be loaded and will not
run without it. This also seems broken on 1.9 still
with Rack 0.9.1...
|
|
It's a CGI-ism and is not in the Rack spec, so don't bother.
|
|
Although I didn't like the idea initially, signal queueing
allows test_exec to run more reliably and the limited signal
queue size will prevent scary queued signal behavior.
Also, always wakeup the master immediately when CHLD is trapped
to reduce the performance impact of SIGHUP-based config
reloading. Combined with an extra check in test_exec, this
should make test_exec run much more reliably than before.
|
|
Despite reading numerous articles and inspecting the 1.9.1-p0 C
source, I will never trust that we're always handling
encoding-aware IO objects correctly. Thus this new test uses
UNIX shell utilities that should always operate on files/sockets
on a byte-level.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
|