aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/guide/book.asciidoc2
-rw-r--r--doc/src/guide/loop_handlers.asciidoc2
-rw-r--r--doc/src/guide/modern_web.asciidoc25
-rw-r--r--doc/src/guide/ws_handlers.asciidoc6
-rw-r--r--doc/src/manual/cowboy.start_clear.asciidoc10
-rw-r--r--doc/src/manual/cowboy.start_tls.asciidoc10
-rw-r--r--doc/src/manual/cowboy_app.asciidoc6
-rw-r--r--doc/src/manual/cowboy_constraints.asciidoc60
-rw-r--r--doc/src/manual/cowboy_constraints.int.asciidoc63
-rw-r--r--doc/src/manual/cowboy_constraints.nonempty.asciidoc62
-rw-r--r--doc/src/manual/cowboy_handler.terminate.asciidoc18
-rw-r--r--doc/src/manual/cowboy_websocket.asciidoc8
-rw-r--r--src/cowboy_constraints.erl6
-rw-r--r--src/cowboy_handler.erl2
14 files changed, 225 insertions, 55 deletions
diff --git a/doc/src/guide/book.asciidoc b/doc/src/guide/book.asciidoc
index 98e2d83..39e70d2 100644
--- a/doc/src/guide/book.asciidoc
+++ b/doc/src/guide/book.asciidoc
@@ -75,6 +75,4 @@ include::middlewares.asciidoc[Middlewares]
include::migrating_from_1.0.asciidoc[Migrating from Cowboy 1.0 to 2.0]
-// @todo Maybe history? Could take info from architecture also.
-
include::specs.asciidoc[HTTP and other specifications]
diff --git a/doc/src/guide/loop_handlers.asciidoc b/doc/src/guide/loop_handlers.asciidoc
index 80bc484..21bf842 100644
--- a/doc/src/guide/loop_handlers.asciidoc
+++ b/doc/src/guide/loop_handlers.asciidoc
@@ -1,8 +1,6 @@
[[loop_handlers]]
== Loop handlers
-// @todo This description needs to be updated.
-
Loop handlers are a special kind of HTTP handlers used when the
response can not be sent right away. The handler enters instead
a receive loop waiting for the right message before it can send
diff --git a/doc/src/guide/modern_web.asciidoc b/doc/src/guide/modern_web.asciidoc
index 6c43adb..4852573 100644
--- a/doc/src/guide/modern_web.asciidoc
+++ b/doc/src/guide/modern_web.asciidoc
@@ -1,8 +1,6 @@
[[modern_web]]
== The modern Web
-// @todo Link to related xrefs.
-
Cowboy is a server for the modern Web. This chapter explains
what it means and details all the standards involved.
@@ -56,9 +54,9 @@ methods, status codes, headers or semantics.
=== Websocket
-Websocket is a protocol built on top of HTTP/1.1 that provides
-a two-ways communication channel between the client and the
-server. Communication is asynchronous and can occur concurrently.
+xref:ws_protocol[Websocket] is a protocol built on top of HTTP/1.1
+that provides a two-ways communication channel between the client and
+the server. Communication is asynchronous and can occur concurrently.
It consists of a Javascript object allowing setting up a
Websocket connection to the server, and a binary based
@@ -79,6 +77,9 @@ is closer to TCP in that aspect, and requires you to design
and implement your own protocol on top of it; or adapt an
existing protocol to Websocket.
+Cowboy provides an interface known as xref:ws_handlers[Websocket handlers]
+that gives complete control over a Websocket connection.
+
The Websocket protocol is defined by RFC 6455.
=== Long-lived requests
@@ -101,21 +102,21 @@ type, `text/event-stream`, along with a new HTTP header,
`Last-Event-ID`. It is defined in the EventSource W3C
specification.
-Cowboy provides an interface known as loop handlers that
-facilitates the implementation of long-polling or stream
+Cowboy provides an interface known as xref:loop_handlers[loop handlers]
+that facilitates the implementation of long-polling or stream
mechanisms. It works regardless of the underlying protocol.
=== REST
-REST, or REpresentational State Transfer, is a style of
-architecture for loosely connected distributed systems.
-It can easily be implemented on top of HTTP.
+xref:rest_principles[REST, or REpresentational State Transfer],
+is a style of architecture for loosely connected distributed
+systems. It can easily be implemented on top of HTTP.
REST is essentially a set of constraints to be followed.
Many of these constraints are purely architectural and
solved by simply using HTTP. Some constraints must be
explicitly followed by the developer.
-Cowboy provides an interface known as REST handlers that
-simplifies the implementation of a REST API on top of
+Cowboy provides an interface known as xref:rest_handlers[REST handlers]
+that simplifies the implementation of a REST API on top of
the HTTP protocol.
diff --git a/doc/src/guide/ws_handlers.asciidoc b/doc/src/guide/ws_handlers.asciidoc
index 61a523b..84dfb9b 100644
--- a/doc/src/guide/ws_handlers.asciidoc
+++ b/doc/src/guide/ws_handlers.asciidoc
@@ -151,7 +151,9 @@ websocket_info(_Info, State) ->
=== Sending frames
-// @todo So yeah, reply makes no sense. Maybe change it to send. Sigh.
+// @todo This will be deprecated and eventually replaced with a
+// {Commands, State} interface that allows providing more
+// functionality easily.
All `websocket_` callbacks share return values. They may
send zero, one or many frames to the client.
@@ -222,8 +224,6 @@ init(Req, State) ->
This value cannot be changed once it is set. It defaults to
`60000`.
-// @todo Perhaps the default should be changed.
-
=== Saving memory
The Websocket connection process can be set to hibernate
diff --git a/doc/src/manual/cowboy.start_clear.asciidoc b/doc/src/manual/cowboy.start_clear.asciidoc
index 7a12a58..3d09935 100644
--- a/doc/src/manual/cowboy.start_clear.asciidoc
+++ b/doc/src/manual/cowboy.start_clear.asciidoc
@@ -47,16 +47,12 @@ ProtocolOpts::
The protocol options are in a map containing all the options for
the different protocols that may be involved when connecting
-to the listener, including HTTP/1.1 and HTTP/2 but also
-subprotocols like Websocket.
-// @todo For Websocket this might change in the future.
+to the listener, including HTTP/1.1 and HTTP/2.
+
The HTTP/1.1 options are documented in the
link:man:cowboy_http(3)[cowboy_http(3)] manual;
-the HTTP/2 options in
-link:man:cowboy_http2(3)[cowboy_http2(3)];
-and the Websocket options in
-link:man:cowboy_websocket(3)[cowboy_websocket(3)].
+and the HTTP/2 options in
+link:man:cowboy_http2(3)[cowboy_http2(3)].
== Return value
diff --git a/doc/src/manual/cowboy.start_tls.asciidoc b/doc/src/manual/cowboy.start_tls.asciidoc
index 1cf87c9..8d2131a 100644
--- a/doc/src/manual/cowboy.start_tls.asciidoc
+++ b/doc/src/manual/cowboy.start_tls.asciidoc
@@ -47,16 +47,12 @@ ProtocolOpts::
The protocol options are in a map containing all the options for
the different protocols that may be involved when connecting
-to the listener, including HTTP/1.1 and HTTP/2 but also
-subprotocols like Websocket.
-// @todo For Websocket this might change in the future.
+to the listener, including HTTP/1.1 and HTTP/2.
+
The HTTP/1.1 options are documented in the
link:man:cowboy_http(3)[cowboy_http(3)] manual;
-the HTTP/2 options in
-link:man:cowboy_http2(3)[cowboy_http2(3)];
-and the Websocket options in
-link:man:cowboy_websocket(3)[cowboy_websocket(3)].
+and the HTTP/2 options in
+link:man:cowboy_http2(3)[cowboy_http2(3)].
== Return value
diff --git a/doc/src/manual/cowboy_app.asciidoc b/doc/src/manual/cowboy_app.asciidoc
index bc67959..5825cf9 100644
--- a/doc/src/manual/cowboy_app.asciidoc
+++ b/doc/src/manual/cowboy_app.asciidoc
@@ -20,8 +20,7 @@ Functions:
* link:man:cowboy(3)[cowboy(3)] - Listener management
* link:man:cowboy_req(3)[cowboy_req(3)] - Request and response
* link:man:cowboy_router(3)[cowboy_router(3)] - Router
-
-// @todo What about cowboy_constraints?
+* link:man:cowboy_constraints(3)[cowboy_constraints(3)] - Constraints
Protocols:
@@ -33,9 +32,6 @@ Handlers:
* link:man:cowboy_static(3)[cowboy_static(3)] - Static file handler
-// @todo What about cowboy_stream_h?
-// @todo cowboy_compress_h
-
Behaviors:
* link:man:cowboy_handler(3)[cowboy_handler(3)] - Plain HTTP handlers
diff --git a/doc/src/manual/cowboy_constraints.asciidoc b/doc/src/manual/cowboy_constraints.asciidoc
new file mode 100644
index 0000000..52ee664
--- /dev/null
+++ b/doc/src/manual/cowboy_constraints.asciidoc
@@ -0,0 +1,60 @@
+= cowboy_constraints(3)
+
+== Name
+
+cowboy_constraints - Constraints
+
+== Description
+
+The module `cowboy_constraints` defines the built-in
+constraints in Cowboy and provides an interface for
+manipulating these constraints.
+
+Constraints are functions that define what type of
+input is allowed. They are used throughout Cowboy,
+from the router to query strings to cookies.
+
+== Exports
+
+Built-in constraints:
+
+* link:man:cowboy_constraints:int(3)[cowboy_constraints:int(3)] - Integer constraint
+* link:man:cowboy_constraints:nonempty(3)[cowboy_constraints:nonempty(3)] - Non-empty constraint
+
+== Types
+
+=== constraint()
+
+[source,erlang]
+----
+constraint() :: int | nonempty | fun()
+----
+
+A constraint function.
+
+The atom constraints are built-in, see the corresponding
+function in the exports list above.
+
+=== reason()
+
+[source,erlang]
+----
+reason() :: {constraint(), Reason, Value}
+
+Reason :: any()
+Value :: any()
+----
+
+Reason for the constraint failure.
+
+It includes the constraint function in question,
+a machine-readable error reason and the value that
+made the constraint fail.
+
+== See also
+
+link:man:cowboy(7)[cowboy(7)],
+link:man:cowboy(3)[cowboy(3)],
+link:man:cowboy_router(3)[cowboy_router(3)],
+link:man:cowboy_req:match_cookies(3)[cowboy_req:match_cookies(3)],
+link:man:cowboy_req:match_qs(3)[cowboy_req:match_qs(3)]
diff --git a/doc/src/manual/cowboy_constraints.int.asciidoc b/doc/src/manual/cowboy_constraints.int.asciidoc
new file mode 100644
index 0000000..28855a4
--- /dev/null
+++ b/doc/src/manual/cowboy_constraints.int.asciidoc
@@ -0,0 +1,63 @@
+= cowboy_constraints:int(3)
+
+== Name
+
+cowboy_constraints:int - Integer constraint
+
+== Description
+
+Constraint functions implement a number of different operations.
+
+[source,erlang]
+----
+int(forward, Bin) -> {ok, Int} | {error, not_an_integer}
+
+Bin :: binary()
+Int :: integer()
+----
+
+Validate and convert the text representation of an integer.
+
+[source,erlang]
+----
+int(reverse, Int) -> {ok, Bin} | {error, not_an_integer}
+----
+
+Convert an integer back to its text representation.
+
+[source,erlang]
+----
+int(format_error, Error) -> HumanReadable
+
+Error :: {not_an_integer, Bin | Int}
+HumanReadable :: iolist()
+----
+
+Generate a human-readable error message.
+
+== Arguments
+
+Arguments vary depending on the operation. Constraint
+functions always take the operation type as first argument,
+and the value as second argument.
+
+== Return value
+
+The return value varies depending on the operation.
+
+== Changelog
+
+* *2.0*: Interface modified to allow for a variety of operations.
+* *1.0*: Constraint introduced.
+
+== Examples
+
+This function is not meant to be called directly.
+
+== See also
+
+link:man:cowboy_constraints(3)[cowboy_constraints(3)],
+link:man:cowboy_constraints:nonempty(3)[cowboy_constraints:nonempty(3)],
+link:man:cowboy_router(3)[cowboy_router(3)],
+link:man:cowboy_req:match_cookies(3)[cowboy_req:match_cookies(3)],
+link:man:cowboy_req:match_qs(3)[cowboy_req:match_qs(3)]
diff --git a/doc/src/manual/cowboy_constraints.nonempty.asciidoc b/doc/src/manual/cowboy_constraints.nonempty.asciidoc
new file mode 100644
index 0000000..0c25b4b
--- /dev/null
+++ b/doc/src/manual/cowboy_constraints.nonempty.asciidoc
@@ -0,0 +1,62 @@
+= cowboy_constraints:nonempty(3)
+
+== Name
+
+cowboy_constraints:nonempty - Non-empty constraint
+
+== Description
+
+Constraint functions implement a number of different operations.
+
+[source,erlang]
+----
+nonempty(forward | reverse, <<>>) -> {error, empty}
+----
+
+Reject empty values.
+
+[source,erlang]
+----
+nonempty(forward | reverse, Bin) -> {ok, Bin}
+
+Bin :: binary()
+----
+
+Accept any other binary values.
+
+[source,erlang]
+----
+nonempty(format_error, Error) -> HumanReadable
+
+Error :: {empty, Bin}
+HumanReadable :: iolist()
+----
+
+Generate a human-readable error message.
+
+== Arguments
+
+Arguments vary depending on the operation. Constraint
+functions always take the operation type as first argument,
+and the value as second argument.
+
+== Return value
+
+The return value varies depending on the operation.
+
+== Changelog
+
+* *2.0*: Interface modified to allow for a variety of operations.
+* *1.0*: Constraint introduced.
+
+== Examples
+
+This function is not meant to be called directly.
+
+== See also
+
+link:man:cowboy_constraints(3)[cowboy_constraints(3)],
+link:man:cowboy_constraints:int(3)[cowboy_constraints:int(3)],
+link:man:cowboy_router(3)[cowboy_router(3)],
+link:man:cowboy_req:match_cookies(3)[cowboy_req:match_cookies(3)],
+link:man:cowboy_req:match_qs(3)[cowboy_req:match_qs(3)]
diff --git a/doc/src/manual/cowboy_handler.terminate.asciidoc b/doc/src/manual/cowboy_handler.terminate.asciidoc
index f10d945..c995ba3 100644
--- a/doc/src/manual/cowboy_handler.terminate.asciidoc
+++ b/doc/src/manual/cowboy_handler.terminate.asciidoc
@@ -8,12 +8,12 @@ cowboy_handler:terminate - Terminate the handler
[source,erlang]
----
-terminate(Reason, Req | undefined, State, Handler) -> ok
+terminate(Reason, PartialReq, State, Handler) -> ok
-Reason :: any()
-Req :: cowboy_req:req()
-State :: any()
-Handler :: module()
+Reason :: any()
+PartialReq :: map()
+State :: any()
+Handler :: module()
----
Call the optional terminate callback if it is defined.
@@ -27,13 +27,13 @@ Reason::
Reason for termination.
-Req::
+PartialReq::
The Req object.
+
-It is possible to pass `undefined` if the handler has no concept
-of requests/responses and discarded the Req object before calling
-this function.
+It is possible to remove fields from the Req object to save memory
+when the handler has no concept of requests/responses. The only
+requirement is that a map is provided.
State::
diff --git a/doc/src/manual/cowboy_websocket.asciidoc b/doc/src/manual/cowboy_websocket.asciidoc
index 7979b97..2421ae8 100644
--- a/doc/src/manual/cowboy_websocket.asciidoc
+++ b/doc/src/manual/cowboy_websocket.asciidoc
@@ -25,9 +25,10 @@ websocket_init(State) -> CallResult %% optional
websocket_handle(InFrame, State) -> CallResult
websocket_info(Info, State) -> CallResult
-terminate(Reason, undefined, State) -> ok %% optional
+terminate(Reason, PartialReq, State) -> ok %% optional
Req :: cowboy_req:req()
+PartialReq :: map()
State :: any()
Opts :: cowboy_websocket:opts()
InFrame :: {text | binary | ping | pong, binary()}
@@ -74,9 +75,8 @@ tuple).
The optional `terminate/3` callback will ultimately be called
with the reason for the termination of the connection. This
-callback is common to all handlers. Note that Websocket has
-no concept of requests so it sets the second argument to
-undefined.
+callback is common to all handlers. Note that Websocket will
+not provide the full Req object by default, to save memory.
Cowboy will terminate the process right after closing the
Websocket connection. This means that there is no need to
diff --git a/src/cowboy_constraints.erl b/src/cowboy_constraints.erl
index 6b468fe..6509c4b 100644
--- a/src/cowboy_constraints.erl
+++ b/src/cowboy_constraints.erl
@@ -78,11 +78,11 @@ int(format_error, {not_an_integer, Value}) ->
io_lib:format("The value ~p is not an integer.", [Value]).
nonempty(Type, <<>>) when Type =/= format_error ->
- {error, not_empty};
+ {error, empty};
nonempty(Type, Value) when Type =/= format_error, is_binary(Value) ->
{ok, Value};
-nonempty(format_error, {not_empty, Value}) ->
- io_lib:format("The value ~p is not empty.", [Value]).
+nonempty(format_error, {empty, Value}) ->
+ io_lib:format("The value ~p is empty.", [Value]).
-ifdef(TEST).
diff --git a/src/cowboy_handler.erl b/src/cowboy_handler.erl
index 3249f76..3d509b6 100644
--- a/src/cowboy_handler.erl
+++ b/src/cowboy_handler.erl
@@ -28,7 +28,7 @@
| {module(), Req, any(), any()}
when Req::cowboy_req:req().
--callback terminate(any(), cowboy_req:req(), any()) -> ok.
+-callback terminate(any(), map(), any()) -> ok.
-optional_callbacks([terminate/3]).
-spec execute(Req, Env) -> {ok, Req, Env}