Просмотр исходного кода

Document 2.2 changes and the new stream_trailers function

Loïc Hoguin 7 лет назад
Родитель
Сommit
4c22bdbcb7

+ 2 - 0
doc/src/guide/book.asciidoc

@@ -73,6 +73,8 @@ include::middlewares.asciidoc[Middlewares]
 
 = Additional information
 
+include::migrating_from_2.1.asciidoc[Migrating from Cowboy 2.1 to 2.2]
+
 include::migrating_from_2.0.asciidoc[Migrating from Cowboy 2.0 to 2.1]
 
 include::migrating_from_1.0.asciidoc[Migrating from Cowboy 1.0 to 2.0]

+ 107 - 0
doc/src/guide/migrating_from_2.1.asciidoc

@@ -0,0 +1,107 @@
+[appendix]
+== Migrating from Cowboy 2.1 to 2.2
+
+Cowboy 2.2 focused on adding features required for writing
+gRPC servers and on completing test suites for the core
+HTTP RFCs, fixing many bugs along the way.
+
+=== Features added
+
+* Add support for sending trailers at the end of response bodies.
+  Trailers are additional header fields that may be sent after the
+  body to add more information to the response. Their usage is
+  required in gRPC servers. They are optional and may be discarded
+  in other scenarios (for example if the request goes through an
+  HTTP/1.0 proxy, as HTTP/1.0 does not support trailers).
+
+* The `max_skip_body_length` option was added to `cowboy_http`.
+  It controls how much of a request body Cowboy is willing to skip
+  when the handler did not touch it. If the remaining body size is
+  too large Cowboy instead closes the connection. It defaults to 1MB.
+
+* The CONNECT and TRACE methods are now rejected as they are
+  currently not implemented and must be handled differently than
+  other methods. They will be implemented in a future release.
+
+=== New functions
+
+* The function `stream_trailers/2` has been added. It terminates
+  a stream and adds trailer fields at the end of the response. A
+  corresponding stream handler command `{trailers, Trailers}`
+  has also been added.
+
+=== Bugs fixed
+
+* Test suites for the core HTTP RFCs RFC7230, RFC7231 and RFC7540
+  have been completed. Many of the bugs listed here were fixed as
+  a result of this work.
+
+* Many HTTP/2 edge cases when clients are misbehaving have been
+  corrected. This includes many cases where the request is malformed
+  (for example when a pseudo-header is present twice).
+
+* When the HTTP/2 SETTINGS_INITIAL_WINDOW_SIZE value changes,
+  Cowboy now properly updates the flow control windows.
+
+* HTTP/2 could mistakenly log stray messages that actually were
+  expected. This is no longer the case.
+
+* We no longer send a GOAWAY frame when the HTTP/2 preface is invalid.
+
+* Some values in the Req object of pushed requests were in the
+  wrong type. They are now the expected binary instead of iolist.
+
+* A response body was sometimes sent in response to HEAD requests
+  when using HTTP/2. The body is now ignored.
+
+* The `max_headers` option for `cowboy_http` was not always respected
+  depending on the contents of the buffer. The limit is now strict.
+
+* When an early error occurred on the HTTP/1.1 request line, the
+  partial Req given to stream handlers was missing the `ref` and
+  `peer` information. This has been corrected.
+
+* Absolute URIs with a userinfo component, or without an authority
+  component, are now properly rejected for HTTP/1.0 and HTTP/1.1.
+
+* Whitespace is no longer allowed in header lines before the colon.
+
+* 408 responses to HTTP/1.1 requests now properly include a
+  connection: close header indicating that we are going to
+  close the connection. This header will also be sent for
+  other early errors resulting in the closing of the connection.
+
+* When both the transfer-encoding and content-length headers are
+  sent in an HTTP/1.1 request, the transfer-encoding now takes
+  precedence over the content-length header and the latter is
+  removed from the Req object.
+
+* A 400 response is now returned when the transfer-encoding
+  header is invalid or contains any transfer-coding other
+  than chunked.
+
+* Invalid chunk sizes are now rejected immediately.
+
+* Chunk extensions are now limited to 129 characters. They are
+  not used in practice and are still ignored by Cowboy. The limit
+  is not configurable.
+
+* The final chunk was mistakenly sent in responses to HEAD
+  requests. This is now corrected.
+
+* `OPTIONS *` requests were broken in Cowboy 2.0. They are now
+  working again. Both the routing and `cowboy_req:uri/1,2` have
+  been corrected.
+
+* 204 responses no longer include a content-length header.
+
+* A packet could be lost when switching to Websocket or any
+  other protocol via the `switch_protocol` command. This is
+  now fixed.
+
+* A 426 response will now be sent when a handler requires
+  the client to upgrade to Websocket and the request did not
+  include the required headers.
+
+* Both experimental stream handlers `cowboy_metrics_h` and
+  `cowboy_tracer_h` received a number of fixes and improvements.

+ 1 - 0
doc/src/manual/cowboy_req.asciidoc

@@ -84,6 +84,7 @@ Response:
 * link:man:cowboy_req:reply(3)[cowboy_req:reply(3)] - Send the response
 * link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)] - Send the response headers
 * link:man:cowboy_req:stream_body(3)[cowboy_req:stream_body(3)] - Stream the response body
+* link:man:cowboy_req:stream_trailers(3)[cowboy_req:stream_trailers(3)] - Send the response trailers
 * link:man:cowboy_req:push(3)[cowboy_req:push(3)] - Push a resource to the client
 
 == Types

+ 5 - 2
doc/src/manual/cowboy_req.stream_body.asciidoc

@@ -24,7 +24,9 @@ function.
 The second argument indicates if this call is the final
 call. Use the `nofin` value until you know no more data
 will be sent. The final call should use `fin` (possibly
-with an empty data value).
+with an empty data value) or be a call to the
+link:man:cowboy_req:stream_trailers(3)[cowboy_req:stream_trailers(3)]
+function.
 
 Note that not using `fin` for the final call is not an
 error; Cowboy will take care of it when the request
@@ -74,4 +76,5 @@ cowboy_req:stream_body(<<"World!\n">>, fin, Req).
 == See also
 
 link:man:cowboy_req(3)[cowboy_req(3)],
-link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)]
+link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)],
+link:man:cowboy_req:stream_trailers(3)[cowboy_req:stream_trailers(3)]

+ 4 - 1
doc/src/manual/cowboy_req.stream_reply.asciidoc

@@ -34,7 +34,9 @@ If a response body was set before calling this function,
 it will not be sent.
 
 Use link:man:cowboy_req:stream_body(3)[cowboy_req:stream_body(3)]
-to stream the response body.
+to stream the response body and optionally
+link:man:cowboy_req:stream_trailers(3)[cowboy_req:stream_trailers(3)]
+to send response trailer field values.
 
 You may want to set the content-length header when using
 this function, if it is known in advance. This will allow
@@ -106,4 +108,5 @@ link:man:cowboy_req:set_resp_headers(3)[cowboy_req:set_resp_headers(3)],
 link:man:cowboy_req:inform(3)[cowboy_req:inform(3)],
 link:man:cowboy_req:reply(3)[cowboy_req:reply(3)],
 link:man:cowboy_req:stream_body(3)[cowboy_req:stream_body(3)],
+link:man:cowboy_req:stream_trailers(3)[cowboy_req:stream_trailers(3)],
 link:man:cowboy_req:push(3)[cowboy_req:push(3)]

+ 70 - 0
doc/src/manual/cowboy_req.stream_trailers.asciidoc

@@ -0,0 +1,70 @@
+= cowboy_req:stream_trailers(3)
+
+== Name
+
+cowboy_req:stream_trailers - Send the response trailers
+
+== Description
+
+[source,erlang]
+----
+stream_trailers(Trailers, Req :: cowboy_req:req()) -> ok
+
+Trailers :: cowboy:http_headers()
+----
+
+Send the response trailers and terminate the stream.
+
+This function can only be called once, after initiating
+a response using
+link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)]
+and sending zero or more body chunks using
+link:man:cowboy_req:stream_body(3)[cowboy_req:stream_body(3)]
+with the `nofin` argument set. The function `stream_trailers/2`
+implies `fin` and automatically terminate the response.
+
+You must list all field names sent in trailers in the
+trailer header, otherwise they might be dropped by intermediaries
+or clients.
+
+== Arguments
+
+Trailers::
+
+Trailer field values to be sent.
+
+Req::
+
+The Req object.
+
+== Return value
+
+The atom `ok` is always returned. It can be safely ignored.
+
+== Changelog
+
+* *2.2*: Function introduced.
+
+== Examples
+
+.Stream a response body with trailers
+[source,erlang]
+----
+Req = cowboy_req:stream_reply(200, #{
+    <<"content-type">> => <<"text/plain">>,
+    <<"trailer">> => <<"expires, content-md5">>
+}, Req0),
+cowboy_req:stream_body(<<"Hello\n">>, nofin, Req),
+timer:sleep(1000),
+cowboy_req:stream_body(<<"World!\n">>, nofin, Req).
+cowboy_req:stream_trailers(#{
+    <<"expires">> => <<"Sun, 10 Dec 2017 19:13:47 GMT">>,
+    <<"content-md5">> => <<"fbf68a8e34b2ded53bba54e68794b4fe">>
+}, Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)],
+link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_body(3)]

+ 19 - 2
doc/src/manual/cowboy_stream.asciidoc

@@ -114,8 +114,8 @@ Initiate a response to the client.
 ----
 
 This initiates a response to the client. The stream
-will end when a data command with the `fin` flag is
-returned.
+will end when a data command with the `fin` flag or
+a trailer command is returned.
 
 [[data_command]]
 === data
@@ -127,6 +127,16 @@ Send data to the client.
 {data, fin(), iodata()}
 ----
 
+[[trailers_command]]
+=== trailers
+
+Send response trailers to the client.
+
+[source,erlang]
+----
+{trailers, cowboy:http_headers()}
+----
+
 [[push_command]]
 === push
 
@@ -286,6 +296,13 @@ Same as the xref:data_command[data command].
 
 Sent when the request process streams data to the client.
 
+=== trailers
+
+Same as the xref:trailers_command[trailers command].
+
+Sent when the request process sends the trailer field values
+to the client.
+
 === push
 
 Same as the xref:push_command[push command].