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

137 commits

Author SHA1 Message Date
Loïc Hoguin
3da9a6eef9
Add a test for early errors that occur on the request-line 2017-11-20 16:26:37 +01:00
Loïc Hoguin
ecb2a735ef
Remove a useless todo 2017-11-20 11:28:22 +01:00
Loïc Hoguin
62bf505d33
Add more rfc7230 tests
Also fixes the handling of the max_headers option for HTTP/1.1.
It is now a strict limit and not dependent on whether data is
already in the buffer.
2017-11-20 00:23:27 +01:00
Loïc Hoguin
39baed6c80
Add preliminary support for trailers in responses
This depends on changes in Cowlib that are only available on
master.
2017-11-15 14:58:49 +01:00
Loïc Hoguin
6a8f9ebbb2
Fix packet being dropped when using switch_protocol
This only happens if the switch takes too long, and should not
happen unless a spawned process refuses to shut down immediately.
2017-11-13 18:03:25 +01:00
Loïc Hoguin
83bd8bc935
Fix two edge cases for cowboy_req:stream_body
Sending data of size 0 with the fin flag set resulted in nothing
being sent to the client and still considering the response to
be finished for HTTP/1.1.

For both HTTP/1.1 and HTTP/2, the final chunk of body that is
sent automatically by Cowboy at the end of a response that the
user did not properly terminate was not passing through stream
handlers. This resulted in issues like compression being incorrect.

Some tests still fail under 20.1.3. They are due to recent zlib
changes and should be fixed in a future patch release. Unfortunately
it does not seem to be any 20.1 version that is safe to use for
Cowboy, although some will work better than others.
2017-11-01 15:33:10 +00:00
Loïc Hoguin
774824cd0f
Fix another warning 2017-10-31 22:36:37 +00:00
Loïc Hoguin
a97640d56d
Add informational responses to metrics 2017-10-31 15:04:00 +00:00
Loïc Hoguin
ef58e15547
Introduce cowboy_req:sock/1 and cowboy_req:cert/1
To obtain the local socket ip/port and the client TLS
certificate, respectively.
2017-10-25 21:03:26 +01:00
Loïc Hoguin
4bebe39975
Ensure stream terminate is called when switching protocols 2017-10-22 14:53:04 +01:00
Loïc Hoguin
76f4db863e
Fix sending of final chunk in HTTP/1.1
I broke this when fixing stream handlers earlier.
2017-10-21 21:01:40 +01:00
Loïc Hoguin
c62ce1c63e
Fix stream handler state being discarded on terminate
When we have to send a response before terminating a stream,
we call info. The state returned by this info call was
discarded when we called terminate after that. This commit
fixes it.

There are no tests for this, however the new metrics test
in the next commit requires the correct behavior so this
is ultimately covered.
2017-10-21 13:09:20 +01:00
Loïc Hoguin
c602871f86
Fix HTTP/1.1 stopping streams too early
It is possible in some cases to move on to the next request
without waiting, but that can be done as an optimization
later on if necessary.
2017-10-20 13:16:04 +01:00
Loïc Hoguin
11ae407eed
Ensure the behavior on stream handler crash is consistent
Also corrects the lack of error response when HTTP/1.1 is used.
2017-09-27 14:17:27 +02:00
Loïc Hoguin
d47e22edaa
Cleanup various comments 2017-09-25 13:52:58 +02:00
Loïc Hoguin
c09b10190b
Move body length count to cowboy_stream_h instead of protocols
The documentation was correct, the code was not.

This should make it easier to implement new protocols. Note that
for HTTP/2 we will need to add some form of counting later on to
check for malformed requests, but we can do simpler and just
reduce from the expected length and then check if that's 0 when
IsFin=fin.
2017-09-25 12:48:47 +02:00
Loïc Hoguin
a6126306a2
Centralize stream handler error reporting in cowboy_stream 2017-09-21 12:53:21 +02:00
Loïc Hoguin
3cbf885961
Improve how we detect request errors
When the request process exits with a {request_error, Reason, Human}
exit reason, Cowboy will return a 400 status code instead of 500.
Cowboy may also return a more specific status code depending on
the error. Currently it may also return 408 or 413.

This should prove to be more solid that looking inside the stack
trace.
2017-09-14 13:42:17 +02:00
Loïc Hoguin
45ddcd8c67
Implement the shutdown timeout for request processes
This should work very similar to normal supervisors,
in particular during the shutdown sequence when the
connection process goes down or switches to Websocket.

Processes that need to enforce the shutdown timeout
will be required to trap exits, just like in a supervisor.
In a vanilla Cowboy, this only matters at connection
shutdown, as Cowboy will otherwise wait for the request
process to be down before stopping the stream.

Tests are currently missing.
2017-08-08 16:59:33 +02:00
Loïc Hoguin
767da623f1
Fix terminate not being called on connection close in HTTP/1.1
Introduces the new stream_handler_SUITE test suite. More cases
will be added later on.
2017-06-02 12:31:00 +02:00
Loïc Hoguin
96bbf6752f
Properly handle 101 upgrade responses for Websocket 2017-05-05 16:10:15 +02:00
Loïc Hoguin
7db724f04a
Add inactivity_timeout and other options improvements 2017-05-05 13:48:25 +02:00
Loïc Hoguin
6100470c90
Kill all children processes when terminating the connection
This is a more or less temporary solution to an existing problem.
In the future we will need to enforce a shutdown timeout for
these processes.
2017-05-03 18:31:28 +02:00
Loïc Hoguin
95d2855f62
Add the idle_timeout HTTP/1.1 protocol option
This fixes the connection being dropped because of request_timeout
despite there being some active streams.
2017-05-03 17:44:00 +02:00
Loïc Hoguin
061cc227b1
Make the default 204 response go through stream handlers 2017-04-18 16:07:01 +02:00
Loïc Hoguin
6e8b907ae2
Pass the HTTP/2 switch_protocol event to stream handlers
To accomplish this the code for sending the 101 response was
moved to the cowboy_http2 module.
2017-04-18 14:06:34 +02:00
Loïc Hoguin
10dfd8c910
Add the early_error cowboy_stream callback
This callback is called when an error occurs before the request
(including headers, excluding body) was fully received. The
init/3 callback will not be called. The callback receives the
partial Req object (possibly empty), the reason for the error
and the response command that the server will send. It allows
you to be aware of the error and possibly modify the response
before it is sent.
2017-03-27 10:26:13 +02:00
Loïc Hoguin
a45813c60f
Allow passing options to sub protocols
Before this commit we had an issue where configuring a
Websocket connection was simply not possible without
doing magic, adding callbacks or extra return values.
The init/2 function only allowed setting hibernate
and timeout options.

After this commit, when switching to a different
type of handler you can either return

  {module, Req, State}

or

  {module, Req, State, Opts}

where Opts is any value (as far as the sub protocol
interface is concerned) and is ultimately checked
by the custom handlers.

A large protocol like Websocket would accept only
a map there, with many different options, while a
small interface like loop handlers would allow
passing hibernate and nothing else.

For Websocket, hibernate must be set from the
websocket_init/1 callback, because init/2 executes
in a separate process.

Sub protocols now have two callbacks: one with the
Opts value, one without.

The loop handler code was largely reworked and
simplified. It does not need to manage a timeout
or read from the socket anymore, it's the job of
the protocol code. A lot of unnecessary stuff was
therefore removed.

Websocket compression must now be enabled from
the handler options instead of per listener. This
means that a project can have two separate Websocket
handlers with different options. Compression is
still disabled by default, and the idle_timeout
value was changed from inifnity to 60000 (60 seconds),
as that's safer and is also a good value for mobile
devices.
2017-02-18 18:26:20 +01:00
Loïc Hoguin
80f8cda7ff
Remove or fix a small number of todo comments
One had the todo text fixed, another had the task to do done.
2017-02-05 20:45:36 +01:00
Loïc Hoguin
98c614ee0b
Add missing human-readable errors for HTTP/1.1 2017-02-05 15:10:00 +01:00
Loïc Hoguin
353dc29d8f
Fix protocol breaking when user tries to send empty chunk
The {data, IsFin, Data} uses IsFin to indicate whether this
is the last chunk, while chunked transfer-encoding uses the
length of Data, and ends when it is 0. We must therefore not
send chunks with empty data.
2017-01-20 15:16:50 +01:00
Loïc Hoguin
0f8452cafa
Add support for multiple stream handlers
The stream handlers can be specified using the protocol
option 'stream_handlers'. It defaults to [cowboy_stream_h].

The cowboy_stream_h module currently does not forward the
calls to further stream handlers. It feels like an edge
case; usually we'd want to put our own handlers between
the protocol code and the request process. I am therefore
going to focus on other things for now.

The various types and specifications for stream handlers
have been updated and the cowboy_stream module can now
be safely used as a behavior. The interface might change
a little more, though.

This commit does not include tests or documentation.
They will follow separately.
2017-01-16 14:36:33 +01:00
José Valim
f59c29dff0
Return status 431 if the request header field is too large
This commit changes Cowboy to follow RFC6585.
2017-01-03 17:47:23 +01:00
Loïc Hoguin
43adacc760
Welcome to 2017 2017-01-02 19:36:36 +01:00
Loïc Hoguin
309780a9fd
Remaining Dialyzer fixes 2017-01-02 18:27:03 +01:00
Loïc Hoguin
e10daf39fa
Numerous Dialyzer fixes 2017-01-02 16:47:16 +01:00
Loïc Hoguin
5cb2b544b7 Use cow_http_hd:parse_host directly
Removes some duplicate code from cowboy_http.
2016-08-11 16:45:52 +02:00
Loïc Hoguin
b75b0a6d4d Use integer_to_binary when possible 2016-08-11 11:53:05 +02:00
Loïc Hoguin
83aa3f1b9c Use binary_to_integer instead of to list and back 2016-08-10 17:50:28 +02:00
Loïc Hoguin
e30d120bd8 Make reply functions return Req 2016-08-10 17:15:02 +02:00
Loïc Hoguin
3a057683af Add a lot of todos 2016-08-10 11:52:41 +02:00
Loïc Hoguin
ae0dd61673 Add tests for responses and request body reading
This is a large commit. The cowboy_req interface has largely
changed, and will change a little more. It's possible that
some examples or tests have not been converted to the new
interface yet. The documentation has not yet been updated.
All of this will be fixed in smaller subsequent commits.

Gotta start somewhere...
2016-08-10 11:49:31 +02:00
Loïc Hoguin
4fed8637b6 Fix cowboy_req:peer/1 2016-06-20 17:28:59 +02:00
Loïc Hoguin
7603518ed0 HTTP/1.1: Don't send 500 errors twice
The stream handler is responsible for sending errors.
The protocol should only send errors when no responses
were sent (this might not work yet).
2016-06-06 17:26:13 +02:00
Loïc Hoguin
2620d65fde Fix more HTTP/2 handshake test cases 2016-03-13 11:26:26 +01:00
Loïc Hoguin
4e6a4ee53f Add initial HTTP/1.1 Upgrade to HTTP/2
The same edge cases that fail with other handshake methods
also fail here (mostly bad preface/timeouts stuff). In
addition, the HTTP2-Settings header contents are currently
not checked and so the related edge case tests also fail.
2016-03-12 18:25:35 +01:00
Loïc Hoguin
92edad53d2 Add the beginning of the rfc7540 test suite
Currently only testing handshake.

Tests that pass currently involve no request/response.
ALPN and prior knowledge support have some edge cases left to fix.
HTTP/1.1 Upgrade has not been implemented yet.
2016-03-10 23:30:49 +01:00
Loïc Hoguin
0193538dba Fix warnings 2016-03-06 18:09:43 +01:00
Loïc Hoguin
b370442a63 Initial commit with connection/streams
Breaking changes with previous commit. This is a very large change,
and I am giving up on making a single commit that fixes everything.
More commits will follow slowly adding back features, introducing
new tests and fixing the documentation.

This change contains most of the work toward unifying the interface
for handling both HTTP/1.1 and HTTP/2. HTTP/1.1 connections are now
no longer 1 process per connection; instead by default 1 process per
request is also created. This has a number of pros and cons.

Because it has cons, we also allow users to use a lower-level API
that acts on "streams" (requests/responses) directly at the connection
process-level. If performance is a concern, one can always write a
stream handler. The performance in this case will be even greater
than with Cowboy 1, although all the special handlers are unavailable.

When switching to Websocket, after the handler returns from init/2,
Cowboy stops the stream and the Websocket protocol takes over the
connection process. Websocket then calls websocket_init/2 for any
additional initialization such as timers, because the process is
different in init/2 and websocket_*/* functions. This however would
allow us to use websocket_init/2 for sending messages on connect,
instead of sending ourselves a message and be subject to races.
Note that websocket_init/2 is optional.

This is all a big change and while most of the tests pass, some
functionality currently doesn't. SPDY is broken and will be removed
soon in favor of HTTP/2. Automatic compression is currently disabled.
The cowboy_req interface probably still have a few functions that
need to be updated. The docs and examples do not refer the current
functionality anymore.

Everything will be fixed over time. Feedback is more than welcome.
Open a ticket!
2016-03-05 20:20:42 +01:00
Loïc Hoguin
89c47d3d6e Use cowlib for parsing headers; remove cowboy_http 2015-02-04 16:18:28 +01:00