0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-15 20:50:24 +00:00
Commit graph

76 commits

Author SHA1 Message Date
Magnus Klaar
c747efbd75 replace quoted:from_url with cowboy_http:urldecode
This change makes the dependency on quoted optional
by adding a minimal urldecode function to cowboy.

A protocol option for setting the urldecoding function
has been added to the cowboy_http_protocol module.
The default value for this option is set to be
equivalent to the default settings for quoted.

{fun cowboy_http:urldecode/2, crash}

A note has been added in the README to document
how to use quoted instead of this function.

A field to store this option value has been added
to the state record in the cowboy_http_protocol
module and the http_req record in include/http.hrl

Functions that previously used quoted:from_url/1
has been updated to require an equivalent function
in addition to the previously required arguments.

This change removes a C compiler from the build
requirements of cowboy. It also removes the requirement
to cross compile the code if the target arch/OS
is different from the arch/OS used to build it.
2011-12-07 19:02:10 +01:00
Loïc Hoguin
0201f7f2b2 cowboy_http_protocol shouldn't crash if the client sends HTTP responses
It was replying back the correct error, but with a crash message in
the console. This patch prevents it from crashing.

Fixes issue #94 reported by oribrost.
2011-12-06 12:22:36 +01:00
Loïc Hoguin
c605c4fa40 Add 'Accept' header parsing
Rework the cowboy_http_req:parse_header/2 function while I was at it.
2011-10-26 04:07:08 +02:00
Loïc Hoguin
fe5f0ca539 Add a max_line_length to the HTTP protocol
Allows to limit the size of request and header lines, thus preventing
Cowboy from infinitely reading from the socket and never finding an
end of line.

Defaults to 4096 bytes.
2011-10-19 20:35:55 +02:00
Loïc Hoguin
bf1b84eb83 Fix a misnamed variable for {loop, ...} returns in init/3 2011-10-11 18:12:50 +02:00
Loïc Hoguin
691b7c4518 Fix specs after erlang:hibernate/3 calls were added
This however does not fix the related Dialyzer warnings.
I have no idea what the warnings are about nor how to fix them,
so feel free to work on it and submit a patch!
2011-10-11 01:49:13 +02:00
Loïc Hoguin
5e006be01f Add support for loops in standard HTTP handlers
Now init/3 can return one of the following values to enable loops:
 - {loop, Req, State}
 - {loop, Req, State, hibernate}
 - {loop, Req, State, Timeout}
 - {loop, Req, State, Timeout, hibernate}

Returning one of these tuples will activate looping in the HTTP handler.
When looping, handle/2 is never called. Instead, Cowboy will listen
for Erlang messages and forward them to the info/3 function of the
handler. If a timeout is defined, Cowboy will also close the connection
when no message has been received for Timeout milliseconds.

The info/3 function is defined as info(Msg, Req, State). It can return
either of the following tuples:
 - {ok, Req, State}
 - {loop, Req, State}
 - {loop, Req, State, hibernate}

The first one ends the connection, calling terminate/2 before closing.
The others continue the loop.

Loops are useful when writing long-polling handlers that need to wait
and don't expect to receive anything. Therefore it is recommended to
set a timeout to close the connection if nothing arrives after a while
and to enable hibernate everywhere.

Normal HTTP handlers shouldn't need to use this and as such info/3
was made optional.
2011-10-10 17:27:52 +02:00
Loïc Hoguin
138cccb4f9 Allow HTTP handlers to skip the handle/2 step in init/3
You can now return {shutdown, Req, State} from Handler:init/3
to skip the handle/2 step.

Also allow init/3 function to send responses.
2011-10-06 15:54:37 +02:00
Loïc Hoguin
c2be0f2073 Remove the 'HEAD' chunked_reply/3 clause
From the RFC:
  The HEAD method is identical to GET except that the server MUST NOT
  return a message-body in the response. The metainformation contained
  in the HTTP headers in response to a HEAD request SHOULD be identical
  to the information sent in response to a GET request.
2011-10-05 18:30:23 +02:00
Loïc Hoguin
bf5c2717bc Parse 'Connection' headers as a list of tokens
Replaces the 'Connection' interpretation in cowboy_http_protocol
from raw value to the parsed value, looking for a single token
matching close/keep-alive instead of the whole raw value (which
could contain more than one token, for example with Firefox 6+
using websocket).

Introduce the functions cowboy_http_req:parse_header/2 and /3
to semantically parse the header values and return a proper
Erlang term.
2011-10-05 13:32:20 +02:00
Loïc Hoguin
9a775cce3c Move a few binary string handling functions to cowboy_bstr 2011-10-04 18:34:14 +02:00
Loïc Hoguin
ee77ecec92 Remove the connection information from the HTTP protocol state
Use the Req connection information instead.
2011-10-04 13:09:57 +02:00
Loïc Hoguin
547107cfb9 Close connection on all errors
And use a proper cowboy_http_req:reply/4 call for the 204 response.
2011-10-04 12:37:19 +02:00
Loïc Hoguin
148fb949c5 Small doc clarification 2011-10-04 11:27:04 +02:00
Loïc Hoguin
d25c30790c Do not send a 408 response if the Request-Line wasn't fully received
The server should not send a response if there wasn't at least
the beginning of a request sent (the Request-Line).
2011-10-04 10:54:30 +02:00
Michiel Hakvoort
d8e841c8a2 Add cowboy_protocol behaviour 2011-09-30 08:49:58 +02:00
Loïc Hoguin
eff9477201 Improve the error message for HTTP handlers
Making it look more like the websocket handler error messages.
2011-09-28 18:01:35 +02:00
Loïc Hoguin
89ae3c8cad 'Host' header is optional in HTTP/1.0
Krishnamurthy, Kristol, Mogul: "Key Differences between HTTP/1.0
and HTTP/1.1", "Internet address conservation".
http://www8.org/w8-papers/5c-protocols/key/key.html

Fixes issue #35 reported by Alex Kropivny.
2011-09-14 01:45:12 +02:00
Loïc Hoguin
b669b1b5a3 Reset the max number of empty lines between keepalive requests
Fixes issue #47.
2011-09-13 23:41:34 +02:00
Loïc Hoguin
24bf2c54d0 Ensure header names are handled in a case insensitive manner
To this end we are formatting the header names just like OTP does
except we do it for names of up to 32 characters, as there are
widely used header names of more than 20 characters, the limit that
OTP follows currently. An example of such header name would be
Sec-Websocket-Version.

The formatting itself is fairly simple: an uppercase character at
the start and after dashes, everything else lowercase.
2011-08-23 16:20:53 +02:00
Loïc Hoguin
43d14b52cd Give the ListenerPid to the protocol on startup
Also sends a message 'shoot' that can be received by the protocol
to make sure Cowboy has had enough time to fully initialize the
socket. This message should be received before any socket-related
operations are performed.

WebSocket request connections are now moved from the pool 'default'
to the pool 'websocket', meaning we can have a lot of running
WebSockets despite having a low 'max_connections' setting.
2011-08-10 20:28:30 +02:00
Loïc Hoguin
474f4e0bfa Call Handler:terminate/2 even on error in Handler:handle/2
This ensures we can cleanup what we did in Handler:init/3.
2011-07-07 17:45:28 +02:00
Loïc Hoguin
aa0a66749e Move recursion out of a try .. catch block.
Fixes issue #31.

Recursion shouldn't happen in a single catch statement or inside
a try .. catch statement. The only safe construct for catching
exceptions and perform recursion when everything goes well is
to put the recursive call inside a try .. of .. catch construct
in the of .. catch block.

Otherwise the stack gets filled with exception-related information
since they can still be caught if we were to send them and unfold
the whole thing.

Thanks go to lpgauth for reporting the issue and people on IRC
for explaining the hows and whys.
2011-07-06 20:00:08 +02:00
Loïc Hoguin
108a491f55 Add documentation for the public interface.
This is probably not perfect yet but it should be better than
nothing. We'll improve things with feedback received from the
many users.
2011-07-06 17:42:20 +02:00
Loïc Hoguin
3e55cb62c9 Refresh the type specifications.
Following discussions on #erlounge.

Also fixes compilation in R14B03 and fixes a few underspecs
dialyzer warnings.
2011-05-25 23:02:40 +02:00
Loïc Hoguin
4c4030a792 Send a meaningful error to error_logger on handler crashes.
Inspired by gen_server and friends. Should fix issue #13.
2011-05-20 01:28:55 +02:00
Anthony Ramine
0ca8f1364b Implement path_info feature
The dispatcher now accepts '...' as the leading segment of Host and the
trailing segment of Path, this special atom matches any remaining path tail.

When given "cowboy.bugs.dev-extend.eu", host rule ['...', <<"dev-extend">>,
<<"eu">>] matches and fills host_info with [<<"cowboy">>, <<"bugs">>].

When given "/a/b/c/d", path rule [<<"a">>, <<"b">>, '...'] matches and fills
path_info with [<<"c">>, <<"d">>].
2011-05-09 15:14:38 +02:00
Loïc Hoguin
420f5baf98 Add chunked reply support.
Send the status line and headers using
cowboy_http_req:chunked_reply/3, and
individual chunks with cowboy_http_req:chunk/2.
2011-05-08 17:26:21 +02:00
Loïc Hoguin
29e71cf4da Switch the HTTP protocol to use binary packets instead of lists.
The server now does a single recv (or more, but only if needed)
which is then sent to erlang:decode_packet/3 multiple times. Since
most requests are smaller than the default MTU on many platforms,
we benefit from this greatly.

In the case of requests with a body, the server usually read at
least part of the body on the first recv. This is bufferized
properly and used when later retrieving the body.

In the case of pipelined requests, we can end up reading many
requests in a single recv, which are then handled properly using
only the buffer containing the received data.
2011-05-05 14:03:39 +02:00
Loïc Hoguin
6c1f73c53c Add cowboy_http_req:port/1.
Returns the port given in the Host header if present,
otherwise the default port of 443 for HTTPS and 80 for HTTP
is returned.
2011-05-04 12:52:13 +02:00
Loïc Hoguin
c044fa9602 Remove the next_request function always matching its first clause. 2011-04-30 01:14:57 +02:00
Loïc Hoguin
e8286e18e6 Remove the include/types.hrl file. 2011-04-18 13:56:38 +02:00
Loïc Hoguin
2beb5c8206 Move the dispatcher related types into cowboy_dispatcher. 2011-04-18 13:24:27 +02:00
Loïc Hoguin
ef2673b61e Rename dispatch() into dispatch_rules(). 2011-04-18 12:14:13 +02:00
Loïc Hoguin
15dc645596 Use the inet:socket() type instead of the user-defined one. 2011-04-18 00:06:26 +02:00
Loïc Hoguin
73b120b68e Fix a pattern matching bug in cowboy_http_protocol:handler_init/2. 2011-04-12 16:22:46 +02:00
Loïc Hoguin
6ec20b736e Limit the number of empty lines to allow before the request-line.
Defaults to 5. Prevents someone from indefinitely sending empty lines.
2011-04-09 15:28:41 +02:00
Loïc Hoguin
0fad6c6fde Don't crash on errors while receiving headers; throw an error 500 instead.
The server shouldn't crash the request process when we have an error
while receiving headers. A case where this could happen is if the header
line is too long.

See also bfrog's report on ticket #3 on github.
2011-04-07 00:54:32 +02:00
Loïc Hoguin
d8a2fcf258 Don't automatically retrieve the peer information for the 'OPTIONS' method. 2011-04-05 20:09:49 +02:00
Loïc Hoguin
44e6f60b91 Handle properly the default Connection value for HTTP/1.0.
Fixes a bug reported by evaxsoftware on IRC.
2011-04-05 20:07:52 +02:00
Loïc Hoguin
d0d9b0e8b3 Use a more efficient variant of string:to_lower to improve performance.
After much testing and experimentation of all kinds I find lists to be both
faster and using less memory than binaries for request-line and headers
handling. This is more than likely due to the fact that headers are very
short and thus do not benefit from the advantages of refc binaries, meaning
they're copied, just like lists. The memory usage discrepancy is still a
mystery for the most part, although the hoops needed to perform operations
on the binaries are probably responsible for the extra memory use.

I'm thus giving up on trying to use binaries for request-line and headers.
Instead, this commit improves performances even more to the lists code,
making lists 5% faster than binaries. Lists are easier to work with too,
so I guess it's all a big win for everyone.

Of course the request body is still read as a binary, we're using the
binary type where it performs best.
2011-03-27 01:16:11 +01:00
Loïc Hoguin
5726aa3d85 Match early in connection_to_atom for a small performance improvement. 2011-03-27 01:11:33 +01:00
Loïc Hoguin
9fe8141d2a Allow Handler:init/3 to request a protocol upgrade. 2011-03-22 23:03:43 +01:00
Loïc Hoguin
7888be00d2 Forward transport and protocol name to Handler:init. 2011-03-22 19:50:02 +01:00
Loïc Hoguin
c3a36246b5 Explicitly ignore the return value of cowboy_http_req:reply in error_response. 2011-03-22 12:27:34 +01:00
Loïc Hoguin
c366343ac6 Fix spec for cowboy_http_protocol:init/3. 2011-03-21 22:22:30 +01:00
Loïc Hoguin
7cacb88fec Introduce cowboy_http_req:body/1 to read the full request body. 2011-03-21 22:08:27 +01:00
Loïc Hoguin
e9781e77f1 Make sure error_response always returns ok. 2011-03-21 17:52:27 +01:00
Loïc Hoguin
e3dc9b2694 Add specs to ensure_response and change the clauses order. 2011-03-21 17:51:21 +01:00
Loïc Hoguin
8b02992e6a Skip the request body if it hasn't been read by the handler. 2011-03-21 17:47:17 +01:00