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

100 commits

Author SHA1 Message Date
Loïc Hoguin
ee8c50c5ab Fix and rework the HTTP test suite
Use a proper HTTP client to run all tests. This client is currently
undocumented and should not be used.

Includes a few fixes:

* Fix a bug in the max_keepalive test
* Fix a bug with max_keepalive handling
* Fix a bug in stream_body/1 where data was lost under some conditions

The tests now run quite faster than before.

All the tests now run twice: once for TCP, once for SSL.
2012-04-29 15:22:20 +02:00
Loïc Hoguin
95e05d822f Add chunked transfer encoding support and rework the body reading API
Introduces 3 low level functions and updates the existing higher
levels functions. The new primitives are has_body/1, body_length/1
and stream_body/1. In addition to that, a helper function
init_stream/4 has been added.

Streaming a body implies to decode the Transfer-Encoding and
Content-Encoding used for the body. By default, Cowboy will try
to figure out what was used and decode them properly. You can
override this if you want to disable this behavior or simply
support more encodings by calling the init_stream/4 function
before you start streaming the body.
2012-04-01 21:25:55 +02:00
Magnus Klaar
5a7040ee1c Convert request to proplist when logging 2012-04-01 17:57:00 +02:00
Loïc Hoguin
7e74582432 Don't close requests when the replied body is chunked 2012-03-15 23:05:40 +01:00
Loïc Hoguin
8e2cc3d7f1 Add an 'onrequest' hook for HTTP
This new protocol option is a fun.

It expects a single arg, the Req, and should only return a possibly
modified Req. This can be used for many things like URL rewriting,
access logging or listener-wide authentication.

If a reply is sent inside the hook, then Cowboy will consider the
request handled and will move on to the next one.
2012-03-15 22:29:38 +01:00
Loïc Hoguin
36a6823e50 Do not send chunked Transfer-Encoding replies for HTTP/1.0
Fixes compatibility issue #140 reported by @majek.
2012-03-13 03:00:05 +01:00
Loïc Hoguin
d9212c21dd Remove the redundant include/ from -include("http.hrl") 2012-02-27 08:07:03 +01:00
David Kelly
e7b6e2a402 Added absoluteURI support
If requests go through a proxy, they will have the original uri in the
request, i.e. : GET http://proxy.server.uri/some/query/string  HTTP 1.1 ...

That was problematic -- cowboy_http_protocol:request didn't know what to
to with the result of decode_packet applied to this, which would be something
like:

``` erlang
{http_request,'GET',{absoluteURI,http,<<"proxy.server.uri">>,
	undefined,<<"/some/query/string">>},{1,1}}
```

So, I just ignore the host, grab the path and pass into

``` erlang
cowboy_http_protocol:request({http_request, Method, {abs_path, Path},
	Version}, State)
```

Seems to do the trick without much effort.
2012-02-02 20:25:23 +01:00
Loïc Hoguin
062db95653 Apply a trick to the erlang:hibernate calls to suppress dialyzer warnings
Initially recommended by Magnus Klaar, the trick is to add a catch
instruction before the erlang:hibernate/3 call so that Dialyzer
thinks it will return, followed by the expected return value
('ok' for HTTP, 'closed' for websockets).

This should be good enough until a real solution is found.
2012-02-02 20:04:06 +01:00
Loïc Hoguin
4b93c2d19a Fix a case where request body wouldn't get cleaned up on keepalive
The body was still in the buffer that's being used for the next
request and was thus used as a request, causing errors.
2012-01-23 21:57:54 +01:00
Loïc Hoguin
16d3cb76c7 Rename the type http_status/0 to cowboy_http:status/0 2012-01-23 09:43:26 +01:00
Loïc Hoguin
a297d5e42b Rename the type http_header/0 to cowboy_http:header/0
At the same time rename http_headers/0 to cowboy_http:headers/0.
2012-01-23 09:36:59 +01:00
Loïc Hoguin
8622dff906 Rename the type http_version/0 to cowboy_http:version/0 2012-01-23 09:28:29 +01:00
Loïc Hoguin
314483a0b6 Rename the type http_uri/0 to cowboy_http:uri/0 2012-01-23 09:23:58 +01:00
Loïc Hoguin
9f40167487 Rename the type http_method/0 to cowboy_http:method/0
Exported types are much better than include files.
2012-01-23 09:21:33 +01:00
Loïc Hoguin
b650ef8907 Merge branch 'multipart' of https://github.com/nox/cowboy
Conflicts:
	src/cowboy_http_req.erl
	test/http_SUITE.erl
2012-01-23 07:37:49 +01:00
Anthony Ramine
528507c7de Add multipart support 2012-01-23 07:20:35 +01:00
Loïc Hoguin
fd211d3c03 Fix handler crashes handling
We try to send a 500 error only if we didn't send the response
headers yet. If they were, then we have no way to be sure the
response was fully sent, nor should we assume anything about
how this will be handled client-side, so we do nothing more
and in both cases close the connection.
2012-01-06 20:23:59 +01:00
Loïc Hoguin
ba87aa4193 Move the ensure_response call before ensure_body_processed
We want to reply as soon as possible.
2012-01-06 19:20:17 +01:00
Loïc Hoguin
17c9d45786 Remove outdated @todo notes and update another 2011-12-22 21:48:24 +01:00
Loïc Hoguin
72d91583b9 Add a max_keepalive HTTP protocol option
Based on the patch by Louis-Philippe Gauthier.
2011-12-22 21:35:40 +01:00
Loïc Hoguin
f81cb89b54 Reply status 400 if we receive an unexpected value or error for headers 2011-12-15 20:43:15 +01:00
Loïc Hoguin
e550ba7cd3 Add cowboy:accept_ack/1 for a cleaner handling of the shoot message 2011-12-15 20:19:02 +01:00
Loïc Hoguin
8d2102fe11 Allow HTTP protocol upgrades to use keepalive
REST needed this to be allowed to chain requests on the same connection.
2011-12-08 18:30:13 +01:00
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