Date | Commit message (Collapse) |
|
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.
|
|
|
|
Explicitly track if our request will need Content-Length
or chunked body decoding.
|
|
The macro version lets us painlessly compare Ruby strings
against constant C strings. It wraps a C version of the
function which is necessary to avoid double evaluation while
preventing the user from having to type sizeof or strlen.
|
|
We'll need to keep track of a few more things to account
for content/chunk length and the temporary file descriptor
we'll need to use.
|
|
|
|
It's easy enough to just check a single equality without having
extra functions obscuring what's actually going on.
|
|
We'll need to be defining g_http_transfer_encoding and
g_content_length in the near future.
|
|
Just extra noise we don't care about. This also allows us to
undef the DEF_GLOBAL macro to avoid polluting the main
namespace.
|
|
It's mostly uninteresting code.
|
|
Create a Ruby string object before jumping into the function
to reduce the number of parameters passed and to take advantage
of our STR_NEW macro to reduce noise.
|
|
|
|
It doesn't conflict with any any common variables, tokens or
documentation pieces in the code.
|
|
Eliminate unnecessary jumping around in the source code to find
actions that lead to other actions and making it harder to
notice side effects when dealing with data we're sharing anyways.
|
|
There's also no point in validating field hits if our field is a
common field; so only do the validation for field length if we
need to allocate memory for a new field.
|
|
The "_value" suffix was used to denote the return type, which is
redundandant as it is already known at compile time (being that
this is C and functions have explicit return types). Furthurmore,
the "_value" is confusing since we're actually returning a "key"
when "value" is used in the context of "key-value" pairs.
|
|
More tightly integrate the C/Ruby portions with C/Ragel to avoid
the confusing the flow. Split out some files into hopefully
logical areas so it's easier to focus on more
interesting/volatile code.
|
|
Only fallback to check_sizeof() if it is not. check_sizeof() is
broken in Ruby 1.9.2preview1 (but fixed in trunk).
|
|
We'll be needing the UH_OFF_T_MAX define for the chunked
body handling and rb_str_set_len may be needed as well.
|
|
It's too annoying to have to deal with long prefixes that all
look alike. "g_" is fairly standard in C programs so I'm
keeping it (even though eliminating the prefix entirely is
preferable, but there'd be name conflicts I don't feel like
resolving).
|
|
So that blame falls on Eric if stuff breaks.
|
|
typedefs can be misleading for aggregate types, a struct is a
struct.
|
|
But keep it in the Manifest
|
|
Use Data_Make_Struct instead of Data_Wrap_Struct to avoid extra
steps/code in object allocation. The GC will also free()
implicitly if no free callback is passed to Data_Make_Struct,
and we don't need an extra method here...
Since we're more comfortable with object management nowadays,
just make the data_get() fail with an assertion failure if it
somehow (very unlikely) ends up getting a NULL parser object.
Unicorn itself has no way of recovering other than throwing
errors to clients anyways and we have bigger problems if there's
a GC bug causing this.
Then, finally, reduce the size of our http_parser struct even
more (we'll add an int back later) since we know it's safe to
do so...
|
|
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.
|
|
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.
|
|
They aren't common, but apparently there exist
URLs with them, so we'll support them.
|
|
We now parse the scheme, host and port from Absolute URIs and
ignore them if the equivalents are specified in the other
headers.
|
|
Use the "do {} while (0)" idiom to wrap the macros we can
wrap to avoid having to worry about semi-colons when using
them.
Unfortunately DEF_MAX_LENGTH can't be wrapped with "do {} while
(0)". But we do now correctly constify the strings
DEF_MAX_LENGTH creates and also make them static to reduce
visibility.
|
|
This means "Host: foo-bar:" (trailing colon) will assume
server_port is 80, not a blank string.
|
|
While we're at it, replace a bunch of zero assignments
with a memset to avoid forgetting a struct element in
case we change the struct.
|
|
I don't see the point of using a macro here as it's never called
in a hot path. It's a very minor size reduction in the binary,
but also makes the rest of the code less noisy/screamy.
|
|
There's no point in having redefinable callbacks if they're
always going to be pointed to the same function. This reduces
the size of the http_parser structure to half its original size.
This change may actually make more sense in servers Mongrel/Thin
than Unicorn since Unicorn only has one parser per-process while
other servers can have hundreds or even thousands.
|
|
|
|
|
|
We don't do anything special with content length in the parser
other than forcing the headers without the "HTTP_" prefix for
Rack-compliance.
|
|
It's part of the HTTP/1.1 (rfc2616), so we might as well
handle it in there and set PATH_INFO while we're at it.
Also, make "OPTIONS *" test not fail Rack::Lint
|
|
Remove ctype.h and stdio.h #includes. We avoid ctype.h
functions since it is locale-dependent and HTTP itself is
locale-independent.
Also, regenerate http11_parser.c against Ragel 6.4
|
|
Also, some minor cleanups and branch refactoring.
|
|
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.
|
|
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.
|
|
The build-time complexity was not worth the minor
performance improvement we could get for the average
case (and we can cut down the amount of comparisons
by putting frequent/required headers first).
|
|
"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.
|
|
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/
|
|
Fix the logic in HttpParser up front so we don't have
to mess around with the following convoluted steps:
1. setting the HTTP_CONTENT_{LENGTH,TYPE} headers
2. reading the HTTP_CONTENT_{LENGTH,TYPE} headers again
3. setting the CONTENT_{LENGTH,TYPE} based on the
HTTP_-prefixed one
4. deleting the HTTP_CONTENT_{LENGTH,TYPE} headers
(since Rack doesn't like them)
1, 2, 3 were in the C code, 4 was in Ruby.
Now the logic is:
1. if CONTENT_{LENGTH,TYPE} headers are seen, don't prefix
with "HTTP_".
All the branch logic for the new code is done at init time, too
so there's no additional overhead in the HTTP parsing phase.
There's also no additional overhead of hash lookups in the extra
steps.
|
|
It's a CGI-ism and is not in the Rack spec, so don't bother.
|
|
There's no point in increasing method visibility since
it can cause conflicts with other libraries and reduces
the inlining opportunities the compiler can make.
|
|
|
|
Also, update the Manifest
|