about summary refs log tree commit homepage
path: root/ext/unicorn_http/unicorn_http.rl
DateCommit message (Collapse)
2011-01-05http_parser: add clear method, deprecate reset
But allows small optimizations to be made to avoid constant/instance variable lookups later :)
2011-01-04http_response: implement httpdate in C
This can return a static string and be significantly faster as it reduces object allocations and Ruby method calls for the fastest websites that serve thousands of requests a second. It assumes the Ruby runtime is single-threaded, but that is the case of Ruby 1.8 and 1.9 and also what Unicorn is all about. This change is safe for Rainbows! under 1.8 and 1.9.
2010-12-26http: #keepalive? and #headers? work after #next?
We need to preserve our internal flags and only clear them on HttpParser#parse. This allows the async concurrency models in Rainbows! to work properly.
2010-12-21http: hook up "trust_x_forwarded" to configurator
More config bloat, sadly this is necessary for Rainbows! :<
2010-12-20http: allow ignoring X-Forwarded-* for url_scheme
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.
2010-12-20http: refactor finalize_header function
rack.url_scheme handling and SERVER_{NAME,PORT} handling each deserve their own functions.
2010-12-20http: update setting of "https" for rack.url_scheme
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
2010-12-20http: support keepalive_requests directive
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.
2010-12-19http: delay clearing env on HttpParser#next?
This allows apps/middlewares on Rainbows! that rely on env in the response_body#close to hold onto the env.
2010-11-07tee_input: switch to simpler API for parsing trailers
Not that anybody uses trailers extensively, but it's good to know it's there.
2010-11-06http_parser: add HttpParser#next? method
An easy combination of the existing HttpParser#keepalive? and HttpParser#reset methods, this makes it easier to implement persistence.
2010-11-06enable HTTP keepalive support for all methods
Yes, this means even POST/PUT bodies may be kept alive, but only if the body (and trailers) are fully-consumed.
2010-10-07http: fix behavior with pipelined requests
We cannot clear the buffer between requests because clients may send multiple requests that get taken in one read()/recv() call.
2010-10-07http: remove unnecessary rb_str_update() calls
Rubinius no longer uses it, and it conflicts with a public method in MRI.
2010-10-07http: allow this to be used as a request object
The parser and request object become one and the same, since the parser lives for the lifetime of the request.
2010-10-05http: raise empty backtrace for HttpParserError
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.
2010-06-24http: avoid (re-)declaring the Unicorn module
It makes for messy documentation.
2010-06-08http: move Version: header check into a less common path
Since the "Version" header is uncommon and never hits our optimized case, we don't need to check for it in the common case.
2010-06-08http: ignore Version: header if explicitly set by client
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>
2010-04-26http: pedantic fix for trailer-less chunked requests
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.
2010-02-18http: const correctness fixes
Not fun, but maybe this can help us spot _real_ problems more easily in the future.
2010-02-18http: cleanup globals and ABI namespace
* init_globals() is a static function, avoid conflicting with any potential libraries out there... * mUnicorn and cHttpParser do not need to be static globals they're not used outside of Init_unicorn_http().
2010-02-18http: avoid signedness warnings
We never come close to the signed limits anywhere, so it should be safe either way, but make paranoid compiler settings less noisy if possible.
2010-02-13http: fix memory leak exposed in concurrent servers
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.
2009-11-04http: allow headers/trailers to be written byte-wise
This allows clients to trickle headers and trailers. While Unicorn itself does not support slow clients for many reasons, this affects servers that depend on our parser like Rainbows!. This actually does affect Unicorn when handling trailers, but HTTP trailers are very ever rarely used in requests. Fortunately this stupid bug does not seem able to trigger out-of-bounds conditions.
2009-09-15http: cleanup assertion for memoized header strings
assert_frozen() should not be checking what type of object it is, instead put an extra assertion in there to ensure we have a string.
2009-09-14http: create a new string buffer on empty values
Since empty values on one line can be a heuristic to determine future lines are continuation lines (and a as a result, a decently long header), pre-allocate a string buffer just in case. This is to workaround what appears to be bug in the Rubinius C API, but it could be considered (intended) DWIM behavior, too...
2009-09-14http: use rb_str_{update,flush} if available
Rubinius supports these functions as of 039091066244cfcf483310b86b5c4989aaa6302b This allows the test_http_parser_ng.rb test to run under Rubinius db612aa62cad9e5cc41a4a4be645642362029d20
2009-09-14http: support Rubies without the OBJ_FROZEN macro
Rubinius does not support frozen objects, maybe other Rubies lack support for it as well.
2009-09-06http: ignore Host: continuation lines with absolute URIs
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.
2009-09-06http: rb_gc_mark already ignores immediates
No need to add an extra check, even if it does avoid a function call.
2009-09-06http: NIL_P(var) instead of var == Qnil
This should be more inline with Ruby standards/coding style and probably more future-proof, as well.
2009-09-06http: verbose assertions
This makes it easier for bug reporters to tell us what's wrong in case line numbers change.
2009-09-06http: extra assertion when advancing p manually
Just in case, it'll be easier to track down if bugs pop up.
2009-09-06http: remove needless goto
There's no need to use a goto here to avoid one level of nesting.
2009-09-06http: use explicit elses for readability
This should make code easier to read and follow.
2009-09-06http: refactor keepalive tracking to functions
In case we modify our struct to not use bitflags, this should make it easier to change the parser code. This also adds extra clarification for how we track keepalive and why we only do it for certain request methods.
2009-09-06http: switch to macros for bitflag handling
These are similar to the macros found in MRI, and can more easily allow us to swap out the bitflags for real struct members...
2009-09-06http: clarify the setting of the actual header in the hash
Avoid a negative conditional in the process and having an explicit else in there makes this piece easier to track. Also explain /why/ the Host: header can get ignored.
2009-09-06http: cleanup and avoid potential signedness warning
Just pass the http_parser struct pointer when checking for invalid headers in the trailer. The compiler should be smart enough to inline and not relookup the flags. This avoids having to worry about the flags being signed or not (they should never be) and also makes it easier to maintain if we move away from using bitfields.
2009-09-03http: add HttpParser#headers? method
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).
2009-09-02http: SERVER_PROTOCOL matches HTTP_VERSION
And it'll default to HTTP/0.9 if HTTP_VERSION is not specified (as version-less HTTP requests imply HTTP/0.9.
2009-08-29unicorn_http: "fix" const warning
neither buffer nor p should be const (since we modify buffer in $snake_upcase_char), but this is a much smaller change _for now_
2009-08-18http: support for multi-line HTTP headers
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.
2009-08-18http: make strings independent before modification
Ruby strings may be copy-on-write (multiple #dup'ed strings can point to the same internal buffers). So since HttpParser#headers modifies its buffer argument, we'll need to make sure the String object we have points to its own private buffer. This doesn't affect Unicorn except in a to-be-written test case that relies on a #dup'ed String.
2009-08-17Documentation updates
* Documented Unicorn::HttpParser API methods * Keep GPL2 (COPYING) as-is without RDoc formatting. * The auto-generated index.html is stupid, replace it with README which looks saner.
2009-08-15http: support for "Connection: keep-alive"
ab still sends this with HTTP/1.0 requests, which is unfortunate, but synthetic benchmarks are good for marketing purposes!
2009-08-11http: add "HttpParser#keepalive?" method
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.
2009-08-10http: rename read_body to filter_body
This method is strictly a filter, it does no I/O so "read" is not an appropriate name to give it.
2009-08-09http: join repeated headers with a comma
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