Date | Commit message (Collapse) |
|
With sendfile enabled, we must avoid writing headers (or normal,
non-file responses) while a file is deferred for sending. This
means we must disable processing of new requests while a file
is deferred for sending and use the on_write_complete callback
less aggressively.
|
|
It's a destructive method, and it does more than just parsing.
|
|
Those are entirely single-threaded during the application
dispatch phase.
|
|
While gawk can handle binary data, other awks cannot, so
use tr(1) to filter out non-printable characters from the
WebSocket message. We need to send a bigger message, too,
since tr(1) output is buffered and there's no portable way
to unbuffer it :<
|
|
|
|
We don't send headers with HTTP/0.9 connections, so the IO write
watchers in Rev are never enabled if we're proxying IO objects
as the response body.
|
|
This was always an issue, but not noticed until
0cd65fa1e01be369b270c72053cf21a3d6bcb45f ...
|
|
The FileStreamer class of EventMachine (and by extension
NeverBlock) unfortunately doesn't handle this. It's possible
to do with Revactor (since it uses Rev under the covers),
but we'll support what we can easily for now.
|
|
This is cheaper for serving static files and only
slightly more expensive for pipes and sockets (extra
path lookup for File.stat).
|
|
Its conceivable that we can avoid loading TeeInput for
EventMachine and Rev concurrency models in the future
since it's unused there.
|
|
We need to remember to close response bodies even if
a client aborts the connection, since body.close can
trigger interesting things like logging and such...
|
|
EM::FileStreamer must be passed a path, so should release
our newly opened descriptor first :<
|
|
Middlewares like Clogger may wrap Rack::File responses
with another body that responds to to_path and still
rely on #close to trigger an action (writing out the log
file).
|
|
Some middlewares such as Clogger rely on wrapping the body
having the close method called on it for logging.
|
|
Similar to what we do in EM, this avoid unnecessary
conditional logic inside more frequently used code paths.
|
|
Remove unnecessary include and also remove unnecessary
nesting.
|
|
Some apps never serve static files nor proxy pipes/sockets,
so they'll never need to deal with deferred responses.
|
|
It's slightly faster as theres no string to parse and also
no garbage format string to be discarded.
|
|
We also properly fail on EM::FileStreamer responses, too
|
|
Extraneous returns are harder to follow.
|
|
Some applications may not use Response*Pipe and TryDefer at all,
so there's no reason to pollute the runtime with extra nodes to
mark during GC.
|
|
This makes it easier to write proxies for slow clients that
benefit from keep-alive. We also need to be careful about
non-HTTP/1.1 connections that can't do keepalive, now.
|
|
If a response proxying a pipe (or socket) includes a
Content-Length, do not attempt to outsmart the application
and just use the given Content-Length.
This helps avoid exposing applications to weird internals such
as env["rainbows.autochunk"] and X-Rainbows-* response headers.
|
|
No need to double up on begin blocks since we know @client.write
won't raise exceptions @io.read_nonblock does. Also prefer
@client.write to @client.send_data since it looks more in
line with other IO interfaces.
|
|
Since the EM loop runs entirely in one thread, we can get away
with using a single buffer across all pipe/socket responses.
|
|
Using EM.enable_proxy with EM.attach seems to cause
EM::Connection#receive_data callbacks to be fired before the
proxy has a chance to act, leading the first few chunks of data
being lost in the default receive_data handler. Instead
just rely on EM.watch like the chunked pipe.
|
|
Rack::File already sets the Content-Length header for us,
so there's no reason to ever set this ourselves.
|
|
|
|
IO#read always returns a binary string buffer if passed an
explicit length to read, and we always do that. This is
a small garbage reduction.
|
|
Favor constants over literal strings for a small garbage
reduction.
|
|
This will give each concurrency model more control over
particular code paths and serving static files.
|
|
Eric Wong (3):
test_isolate: document why we test with Rack 1.1.0
doc: make RDoc skip private methods
bump Unicorn dependency to 1.1.1
|
|
This avoids costant resolution problems on client EOF
during input processing.
|
|
|
|
|
|
In addition to the 1.9-only IO.copy_stream, the new sendfile
1.0.0 gem may optionally be used with most concurrency models
(even under 1.8).
See http://rainbows.rubyforge.org/Static_Files.html for more info
Other changes:
* 1.9 encoding bugfix for (Rev)FiberSpawn and FiberPool
* fixed potential rack.input corruption with Revactor
* ThreadPool graceful shutdown no longer blocks until timeout
* optional ServerToken middleware for to display Server: header
* Dependencies bumped to Rack 1.1+ and Unicorn 1.1.0+
* numerous internal cleanups, small bugfixes and speedups
* more concise website oriented at users
|
|
Since we suck at building websites, we just rely on RDoc as a
website builder. And since Rainbows! is an application server
(and not a programming library), our internal API should be of
little interest to end users.
Anybody interested in Rainbows! (or any other project) internals
should be reading the source.
|
|
Some folks may be interested in setting up Rainbows!
as a static file server.
|
|
For consistency with rev_write_response (and the existing
"write_response").
|
|
Cramp needs to override our normal header sending for
(old) WebSockets connections.
|
|
Cramp monkey patches Rainbows internals for WebSockets
support and we forgot about it. Add a new integration
test to ensure this continues to work in the future
(and force us to update the test for newer Cramp).
|
|
|
|
|
|
Unicorn 1.1.0 lets us change this default, and we need it higher
to avoid wasting workers against stupidly (or maliciously) slow
clients.
|
|
|
|
Other concurrency models will eventually be able to use it, too.
|
|
rb_str_slice_bang() allocates a new string internally and calls
rb_str_aref_m() AND rb_str_aset_m(), too. String#[] just
calls rb_str_aref_m() directly, so it's a much quicker code
path. Also, "[]" methods dispatch faster under 1.9, too.
|
|
|
|
Fortunately this only affects the hardly-used FiberSpawn and
FiberPool concurrency models, and also unreleased revisions of
Rev. 1.9 encoding is tricky to handle right when doing I/O in
Ruby...
|
|
non-blocking write() may cause kernel buffers to be allocated
behind the scenes, so retry the write() even if it's short
because it may succeed the next time around.
|