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.
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.
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.
This is a workaround for an issue in the hipe compiler where
compilation of code matching on binaries using patterns of the
form Data = <<Char, _Ignore/bits>> fails because _Ignore is
expected to be used. Using /binary instead of /bits resolves
the issue.
We're applying this change to all binary expressions in cowboy_http
because all functions in this module process human readable text
formats which are always expected to be bytestrings.
Two uses of /bits has been changed to /binary in cowboy_http_websocket
in two clauses of a single function, websocket_data/4. This is safe
to change because the data is later passed to binary:match/2 which
will always fail with a badarg error if the input is a bitstring
instead of a bytestring.
This function doesn't try to add any additional header besides the
Connection: Upgrade header. It also doesn't accept a body.
It should be used for the intermediate reply to an upgrade process,
before the real reply is sent (if any, for example when using TLS).
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!
This change allows application developers to refuse websocket upgrades
by returning {shutdown, Req}. The application can also send a reply
with a custom error before returning from websocket_init/3, otherwise
an error 400 is sent.
Note that right now Cowboy closes the connection immediately. Also note
that neither terminate/3 nor websocket_terminate/3 will be called when
the connection is shutdown by websocket_init/3.
I know it is unlikely to use plain TCP on port 443, where SSL is
usually used, but a bug is still a bug, and as such it should be fixed.
Now the port will be probably appended to the location when port 443
is used without SSL.
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.
If the websocket frame handling code in cowboy_http_websocket receives
only 1 byte at a time, it fails with a badmatch in
cowboy_http_websocket:websocket_data/4. This commit fixes the problem
and introduces a test of the correct behaviour.
The issue was that we were calling erlang:hibernate before a
receive .. after .. end call. Erlang hibernates the process before
reaching the receive instruction and we therefore couldn't enter
the after clause when hibernating.
This is now fixed by using erlang:send_after instead and receiving
that message instead of using an after clause.
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.
Improves the readability of websocket handler code by having
two functions: websocket_handle/3 handles the packets received
from the socket, removing the tuple construct that was otherwise
needed, so only websocket_handle(Data, Req, State) is needed now;
websocket_info/3 handles the messages that the websocket handler
process received, as websocket_info(Info, Req, State).
Both functions return values are handled identically by Cowboy
so nothing changes on that end.
This ensures that an error thrown in handler_terminate/4 will be
shown after the error from handler_call/6, in the expected order.
As we already call WebSocketHandler:terminate/3, this should
fix issue #23.
Browsers get mad that the returned location address is not the same
as what they sent, since the :(80|443) is stripped.
Add a simple eunit test due to existing ct websockets tests not
covering this case.
Return {ok, Req, State, hibernate}
or {reply, Data, Req, State, hibernate} to hibernate the websocket
process and save up memory and CPU. You should hibernate processes
that will receive few messages. So probably most of them.