summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/en/cowboy/2.0/guide/constraints.asciidoc101
-rw-r--r--docs/en/cowboy/2.0/guide/constraints/index.html100
-rw-r--r--docs/en/cowboy/2.0/guide/static_files.asciidoc40
-rw-r--r--docs/en/cowboy/2.0/guide/static_files/index.html39
-rw-r--r--docs/index.xml104
5 files changed, 239 insertions, 145 deletions
diff --git a/docs/en/cowboy/2.0/guide/constraints.asciidoc b/docs/en/cowboy/2.0/guide/constraints.asciidoc
index 0ae01d59..822962d2 100644
--- a/docs/en/cowboy/2.0/guide/constraints.asciidoc
+++ b/docs/en/cowboy/2.0/guide/constraints.asciidoc
@@ -1,54 +1,91 @@
[[constraints]]
== Constraints
-Cowboy provides an optional constraints based validation feature
-when interacting with user input.
+Constraints are validation and conversion functions applied
+to user input.
-Constraints are first used during routing. The router uses
-constraints to more accurately match bound values, allowing
-to create routes where a segment is an integer for example,
-and rejecting the others.
+They are used in various places in Cowboy, including the
+router and the request match functions.
-Constraints are also used when performing a match operation
-on input data, like the query string or cookies. There, a
-default value can also be provided for optional values.
+=== Syntax
-Finally, constraints can be used to not only validate input,
-but also convert said input into proper Erlang terms, all in
-one step.
+Constraints are provided as a list of fields. For each field
+in the list, specific constraints can be applied, as well as
+a default value if the field is missing.
-=== Structure
+A field can take the form of an atom `field`, a tuple with
+constraints `{field, Constraints}` or a tuple with constraints
+and a default value `{field, Constraints, Default}`.
+The `field` form indicates the field is mandatory.
-Constraints are provided as a list of fields and for each
-field a list of constraints for that field can be provided.
+Note that when used with the router, only the second form
+makes sense, as it does not use the default and the field
+is always defined.
-Fields are either the name of the field; the name and
-one or more constraints; or the name, one or more constraints
-and a default value.
+Constraints for each field are provided as an ordered list
+of atoms or funs to apply. Built-in constraints are provided
+as atoms, while custom constraints are provided as funs.
-When no default value is provided then the field is required.
-Otherwise the default value is used.
+When multiple constraints are provided, they are applied in
+the order given. If the value has been modified by a constraint
+then the next one receives the new value.
-All constraints for a field will be used to match its value
-in the order they are given. If the value is modified by a
-constraint, the next constraint receives the updated value.
+For example, the following constraints will first validate
+and convert the field `my_value` to an integer, and then
+check that the integer is positive:
+
+[source,erlang]
+----
+PositiveFun = fun(V) when V > 0 -> true; (_) -> false end,
+{my_value, [int, PositiveFun]}.
+----
+
+When there's only one constraint, it can be provided directly
+without wrapping it into a list:
+
+[source,erlang]
+----
+{my_value, int}
+----
=== Built-in constraints
+Built-in constraints are specified as an atom:
+
[cols="<,<",options="header"]
|===
| Constraint | Description
-| int | Convert binary value to integer.
+| int | Converts binary value to integer.
| nonempty | Ensures the binary value is non-empty.
|===
-=== Custom constraint
+=== Custom constraints
+
+Custom constraints are specified as a fun. This fun takes
+a single argument and must return one of `true`, `{true, NewValue}`
+or `false`.
+
+`true` indicates the input is valid, `false` otherwise.
+The `{true, NewValue}` tuple is returned when the input
+is valid and the value has been converted. For example,
+the following constraint will convert the binary input
+to an integer:
+
+[source,erlang]
+----
+fun (Value0) when is_binary(Value0) ->
+ try binary_to_integer(Value0) of
+ Value -> {true, Value}
+ catch _:_ ->
+ false
+ end.
+----
-In addition to the predefined constraints, Cowboy will accept
-a fun. This fun must accept one argument and return one of
-`true`, `{true, NewValue}` or `false`. The result indicates
-whether the value matches the constraint, and if it does it
-can optionally be modified. This allows converting the value
-to a more appropriate Erlang term.
+Constraint functions should only crash because the programmer
+made an error when chaining constraints incorrectly (for example
+if the constraints were `[int, int]`, and not because of input.
+If the input is invalid then `false` must be returned.
-Note that constraint functions SHOULD be pure and MUST NOT crash.
+In our snippet, the `is_binary/1` guard will crash only
+because of a programmer error, and the try block is there
+to ensure that we do not crash when the input is invalid.
diff --git a/docs/en/cowboy/2.0/guide/constraints/index.html b/docs/en/cowboy/2.0/guide/constraints/index.html
index 2428e8d4..f2904152 100644
--- a/docs/en/cowboy/2.0/guide/constraints/index.html
+++ b/docs/en/cowboy/2.0/guide/constraints/index.html
@@ -69,36 +69,53 @@
<h1 class="lined-header"><span>Constraints</span></h1>
-<div class="paragraph"><p>Cowboy provides an optional constraints based validation feature
-when interacting with user input.</p></div>
-<div class="paragraph"><p>Constraints are first used during routing. The router uses
-constraints to more accurately match bound values, allowing
-to create routes where a segment is an integer for example,
-and rejecting the others.</p></div>
-<div class="paragraph"><p>Constraints are also used when performing a match operation
-on input data, like the query string or cookies. There, a
-default value can also be provided for optional values.</p></div>
-<div class="paragraph"><p>Finally, constraints can be used to not only validate input,
-but also convert said input into proper Erlang terms, all in
-one step.</p></div>
+<div class="paragraph"><p>Constraints are validation and conversion functions applied
+to user input.</p></div>
+<div class="paragraph"><p>They are used in various places in Cowboy, including the
+router and the request match functions.</p></div>
<div class="sect1">
-<h2 id="_structure">Structure</h2>
+<h2 id="_syntax">Syntax</h2>
<div class="sectionbody">
-<div class="paragraph"><p>Constraints are provided as a list of fields and for each
-field a list of constraints for that field can be provided.</p></div>
-<div class="paragraph"><p>Fields are either the name of the field; the name and
-one or more constraints; or the name, one or more constraints
-and a default value.</p></div>
-<div class="paragraph"><p>When no default value is provided then the field is required.
-Otherwise the default value is used.</p></div>
-<div class="paragraph"><p>All constraints for a field will be used to match its value
-in the order they are given. If the value is modified by a
-constraint, the next constraint receives the updated value.</p></div>
+<div class="paragraph"><p>Constraints are provided as a list of fields. For each field
+in the list, specific constraints can be applied, as well as
+a default value if the field is missing.</p></div>
+<div class="paragraph"><p>A field can take the form of an atom <code>field</code>, a tuple with
+constraints <code>{field, Constraints}</code> or a tuple with constraints
+and a default value <code>{field, Constraints, Default}</code>.
+The <code>field</code> form indicates the field is mandatory.</p></div>
+<div class="paragraph"><p>Note that when used with the router, only the second form
+makes sense, as it does not use the default and the field
+is always defined.</p></div>
+<div class="paragraph"><p>Constraints for each field are provided as an ordered list
+of atoms or funs to apply. Built-in constraints are provided
+as atoms, while custom constraints are provided as funs.</p></div>
+<div class="paragraph"><p>When multiple constraints are provided, they are applied in
+the order given. If the value has been modified by a constraint
+then the next one receives the new value.</p></div>
+<div class="paragraph"><p>For example, the following constraints will first validate
+and convert the field <code>my_value</code> to an integer, and then
+check that the integer is positive:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 3.1.8
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="color: #009900">PositiveFun</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">fun</span></span>(<span style="color: #009900">V</span>) <span style="font-weight: bold"><span style="color: #0000FF">when</span></span> <span style="color: #009900">V</span> <span style="color: #990000">&gt;</span> <span style="color: #993399">0</span> <span style="color: #990000">-&gt;</span> <span style="color: #000080">true</span>; (<span style="color: #990000">_</span>) <span style="color: #990000">-&gt;</span> <span style="color: #000080">false</span> <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>,
+{<span style="color: #FF6600">my_value</span>, [<span style="color: #FF6600">int</span>, <span style="color: #009900">PositiveFun</span>]}<span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>When there&#8217;s only one constraint, it can be provided directly
+without wrapping it into a list:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 3.1.8
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt>{<span style="color: #FF6600">my_value</span>, <span style="color: #FF6600">int</span>}</tt></pre></div></div>
</div>
</div>
<div class="sect1">
<h2 id="_built_in_constraints">Built-in constraints</h2>
<div class="sectionbody">
+<div class="paragraph"><p>Built-in constraints are specified as an atom:</p></div>
<div class="tableblock">
<table rules="all"
width="100%"
@@ -115,7 +132,7 @@ cellspacing="0" cellpadding="4">
<tbody>
<tr>
<td align="left" valign="top"><p class="table">int</p></td>
-<td align="left" valign="top"><p class="table">Convert binary value to integer.</p></td>
+<td align="left" valign="top"><p class="table">Converts binary value to integer.</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">nonempty</p></td>
@@ -127,15 +144,34 @@ cellspacing="0" cellpadding="4">
</div>
</div>
<div class="sect1">
-<h2 id="_custom_constraint">Custom constraint</h2>
+<h2 id="_custom_constraints">Custom constraints</h2>
<div class="sectionbody">
-<div class="paragraph"><p>In addition to the predefined constraints, Cowboy will accept
-a fun. This fun must accept one argument and return one of
-<code>true</code>, <code>{true, NewValue}</code> or <code>false</code>. The result indicates
-whether the value matches the constraint, and if it does it
-can optionally be modified. This allows converting the value
-to a more appropriate Erlang term.</p></div>
-<div class="paragraph"><p>Note that constraint functions SHOULD be pure and MUST NOT crash.</p></div>
+<div class="paragraph"><p>Custom constraints are specified as a fun. This fun takes
+a single argument and must return one of <code>true</code>, <code>{true, NewValue}</code>
+or <code>false</code>.</p></div>
+<div class="paragraph"><p><code>true</code> indicates the input is valid, <code>false</code> otherwise.
+The <code>{true, NewValue}</code> tuple is returned when the input
+is valid and the value has been converted. For example,
+the following constraint will convert the binary input
+to an integer:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 3.1.8
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">fun</span></span> (<span style="color: #009900">Value0</span>) <span style="font-weight: bold"><span style="color: #0000FF">when</span></span> <span style="font-weight: bold"><span style="color: #000080">is_binary</span></span>(<span style="color: #009900">Value0</span>) <span style="color: #990000">-&gt;</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">try</span></span> <span style="font-weight: bold"><span style="color: #000000">binary_to_integer</span></span>(<span style="color: #009900">Value0</span>) <span style="font-weight: bold"><span style="color: #0000FF">of</span></span>
+ <span style="color: #009900">Value</span> <span style="color: #990000">-&gt;</span> {<span style="color: #000080">true</span>, <span style="color: #009900">Value</span>}
+ <span style="font-weight: bold"><span style="color: #0000FF">catch</span></span> <span style="color: #990000">_:_</span> <span style="color: #990000">-&gt;</span>
+ <span style="color: #000080">false</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span><span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>Constraint functions should only crash because the programmer
+made an error when chaining constraints incorrectly (for example
+if the constraints were <code>[int, int]</code>, and not because of input.
+If the input is invalid then <code>false</code> must be returned.</p></div>
+<div class="paragraph"><p>In our snippet, the <code>is_binary/1</code> guard will crash only
+because of a programmer error, and the try block is there
+to ensure that we do not crash when the input is invalid.</p></div>
</div>
</div>
diff --git a/docs/en/cowboy/2.0/guide/static_files.asciidoc b/docs/en/cowboy/2.0/guide/static_files.asciidoc
index ef271198..9d9b8cc2 100644
--- a/docs/en/cowboy/2.0/guide/static_files.asciidoc
+++ b/docs/en/cowboy/2.0/guide/static_files.asciidoc
@@ -1,25 +1,17 @@
[[static_files]]
== Static files
-Cowboy comes with a special handler built as a REST handler
-and designed specifically for serving static files. It is
-provided as a convenience and provides a quick solution for
-serving files during development.
+Cowboy comes with a ready to use handler for serving static
+files. It is provided as a convenience for serving files
+during development.
For systems in production, consider using one of the many
Content Distribution Network (CDN) available on the market,
-as they are the best solution for serving files. They are
-covered in the next chapter. If you decide against using a
-CDN solution, then please look at the chapter after that,
-as it explains how to efficiently serve static files on
-your own.
+as they are the best solution for serving files.
The static handler can serve either one file or all files
-from a given directory. It can also send etag headers for
-client-side caching.
-
-To use the static file handler, simply add routes for it
-with the appropriate options.
+from a given directory. The etag generation and mime types
+can be configured.
=== Serve one file
@@ -31,13 +23,13 @@ to the given application's private directory.
The following rule will serve the file 'static/index.html'
from the application `my_app`'s priv directory whenever the
-path `/` is accessed.
+path `/` is accessed:
[source,erlang]
{"/", cowboy_static, {priv_file, my_app, "static/index.html"}}
You can also specify the absolute path to a file, or the
-path to the file relative to the current directory.
+path to the file relative to the current directory:
[source,erlang]
{"/", cowboy_static, {file, "/var/www/index.html"}}
@@ -56,13 +48,13 @@ private directory.
The following rule will serve any file found in the application
`my_app`'s priv directory inside the `static/assets` folder
-whenever the requested path begins with `/assets/`.
+whenever the requested path begins with `/assets/`:
[source,erlang]
{"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets"}}
You can also specify the absolute path to the directory or
-set it relative to the current directory.
+set it relative to the current directory:
[source,erlang]
{"/assets/[...]", cowboy_static, {dir, "/var/www/assets"}}
@@ -86,7 +78,7 @@ you may have. You can of course create your own function.
To use the default function, you should not have to configure
anything, as it is the default. If you insist, though, the
-following will do the job.
+following will do the job:
[source,erlang]
----
@@ -99,7 +91,7 @@ a list of less used options, like mimetypes or etag. All option
types have this optional field.
To use the function that will detect almost any mimetype,
-the following configuration will do.
+the following configuration will do:
[source,erlang]
----
@@ -109,7 +101,7 @@ the following configuration will do.
You probably noticed the pattern by now. The configuration
expects a module and a function name, so you can use any
-of your own functions instead.
+of your own functions instead:
[source,erlang]
----
@@ -131,7 +123,7 @@ directly to disk.
Finally, the mimetype can be hard-coded for all files.
This is especially useful in combination with the `file`
-and `priv_file` options as it avoids needless computation.
+and `priv_file` options as it avoids needless computation:
[source,erlang]
----
@@ -148,7 +140,7 @@ rather poorly over a cluster of nodes, for example, as the
file metadata will vary from server to server, giving a
different etag on each server.
-You can however change the way the etag is calculated.
+You can however change the way the etag is calculated:
[source,erlang]
----
@@ -162,7 +154,7 @@ time. In a distributed setup, you would typically use the
file path to retrieve an etag value that is identical across
all your servers.
-You can also completely disable etag handling.
+You can also completely disable etag handling:
[source,erlang]
----
diff --git a/docs/en/cowboy/2.0/guide/static_files/index.html b/docs/en/cowboy/2.0/guide/static_files/index.html
index f7ea1472..62067b96 100644
--- a/docs/en/cowboy/2.0/guide/static_files/index.html
+++ b/docs/en/cowboy/2.0/guide/static_files/index.html
@@ -69,22 +69,15 @@
<h1 class="lined-header"><span>Static files</span></h1>
-<div class="paragraph"><p>Cowboy comes with a special handler built as a REST handler
-and designed specifically for serving static files. It is
-provided as a convenience and provides a quick solution for
-serving files during development.</p></div>
+<div class="paragraph"><p>Cowboy comes with a ready to use handler for serving static
+files. It is provided as a convenience for serving files
+during development.</p></div>
<div class="paragraph"><p>For systems in production, consider using one of the many
Content Distribution Network (CDN) available on the market,
-as they are the best solution for serving files. They are
-covered in the next chapter. If you decide against using a
-CDN solution, then please look at the chapter after that,
-as it explains how to efficiently serve static files on
-your own.</p></div>
+as they are the best solution for serving files.</p></div>
<div class="paragraph"><p>The static handler can serve either one file or all files
-from a given directory. It can also send etag headers for
-client-side caching.</p></div>
-<div class="paragraph"><p>To use the static file handler, simply add routes for it
-with the appropriate options.</p></div>
+from a given directory. The etag generation and mime types
+can be configured.</p></div>
<div class="sect1">
<h2 id="_serve_one_file">Serve one file</h2>
<div class="sectionbody">
@@ -95,7 +88,7 @@ the <code>/</code> path, for example. The path configured is relative
to the given application&#8217;s private directory.</p></div>
<div class="paragraph"><p>The following rule will serve the file <em>static/index.html</em>
from the application <code>my_app</code>'s priv directory whenever the
-path <code>/</code> is accessed.</p></div>
+path <code>/</code> is accessed:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
@@ -103,7 +96,7 @@ http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt>{<span style="color: #FF0000">"/"</span>, <span style="color: #FF6600">cowboy_static</span>, {<span style="color: #FF6600">priv_file</span>, <span style="color: #FF6600">my_app</span>, <span style="color: #FF0000">"static/index.html"</span>}}</tt></pre></div></div>
<div class="paragraph"><p>You can also specify the absolute path to a file, or the
-path to the file relative to the current directory.</p></div>
+path to the file relative to the current directory:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
@@ -125,7 +118,7 @@ may be found in subfolders.</p></div>
private directory.</p></div>
<div class="paragraph"><p>The following rule will serve any file found in the application
<code>my_app</code>'s priv directory inside the <code>static/assets</code> folder
-whenever the requested path begins with <code>/assets/</code>.</p></div>
+whenever the requested path begins with <code>/assets/</code>:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
@@ -133,7 +126,7 @@ http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt>{<span style="color: #FF0000">"/assets/[...]"</span>, <span style="color: #FF6600">cowboy_static</span>, {<span style="color: #FF6600">priv_dir</span>, <span style="color: #FF6600">my_app</span>, <span style="color: #FF0000">"static/assets"</span>}}</tt></pre></div></div>
<div class="paragraph"><p>You can also specify the absolute path to the directory or
-set it relative to the current directory.</p></div>
+set it relative to the current directory:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
@@ -159,7 +152,7 @@ of hundreds of mimetypes that should cover almost any need
you may have. You can of course create your own function.</p></div>
<div class="paragraph"><p>To use the default function, you should not have to configure
anything, as it is the default. If you insist, though, the
-following will do the job.</p></div>
+following will do the job:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
@@ -171,7 +164,7 @@ http://www.gnu.org/software/src-highlite -->
a list of less used options, like mimetypes or etag. All option
types have this optional field.</p></div>
<div class="paragraph"><p>To use the function that will detect almost any mimetype,
-the following configuration will do.</p></div>
+the following configuration will do:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
@@ -181,7 +174,7 @@ http://www.gnu.org/software/src-highlite -->
[{<span style="color: #FF6600">mimetypes</span>, <span style="color: #FF6600">cow_mimetypes</span>, <span style="color: #FF6600">all</span>}]}}</tt></pre></div></div>
<div class="paragraph"><p>You probably noticed the pattern by now. The configuration
expects a module and a function name, so you can use any
-of your own functions instead.</p></div>
+of your own functions instead:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
@@ -201,7 +194,7 @@ A browser receiving such file will attempt to download it
directly to disk.</p></div>
<div class="paragraph"><p>Finally, the mimetype can be hard-coded for all files.
This is especially useful in combination with the <code>file</code>
-and <code>priv_file</code> options as it avoids needless computation.</p></div>
+and <code>priv_file</code> options as it avoids needless computation:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
@@ -220,7 +213,7 @@ can not be applied to all systems though. It would perform
rather poorly over a cluster of nodes, for example, as the
file metadata will vary from server to server, giving a
different etag on each server.</p></div>
-<div class="paragraph"><p>You can however change the way the etag is calculated.</p></div>
+<div class="paragraph"><p>You can however change the way the etag is calculated:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
@@ -233,7 +226,7 @@ file on disk, the size of the file and the last modification
time. In a distributed setup, you would typically use the
file path to retrieve an etag value that is identical across
all your servers.</p></div>
-<div class="paragraph"><p>You can also completely disable etag handling.</p></div>
+<div class="paragraph"><p>You can also completely disable etag handling:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
diff --git a/docs/index.xml b/docs/index.xml
index 8e02388c..56e19789 100644
--- a/docs/index.xml
+++ b/docs/index.xml
@@ -1083,36 +1083,53 @@ when the connection has been closed.&lt;/p&gt;&lt;/div&gt;
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://ninenines.eu/docs/en/cowboy/2.0/guide/constraints/</guid>
- <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Cowboy provides an optional constraints based validation feature
-when interacting with user input.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Constraints are first used during routing. The router uses
-constraints to more accurately match bound values, allowing
-to create routes where a segment is an integer for example,
-and rejecting the others.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Constraints are also used when performing a match operation
-on input data, like the query string or cookies. There, a
-default value can also be provided for optional values.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Finally, constraints can be used to not only validate input,
-but also convert said input into proper Erlang terms, all in
-one step.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;sect1&#34;&gt;
-&lt;h2 id=&#34;_structure&#34;&gt;Structure&lt;/h2&gt;
-&lt;div class=&#34;sectionbody&#34;&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Constraints are provided as a list of fields and for each
-field a list of constraints for that field can be provided.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Fields are either the name of the field; the name and
-one or more constraints; or the name, one or more constraints
-and a default value.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;When no default value is provided then the field is required.
-Otherwise the default value is used.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;All constraints for a field will be used to match its value
-in the order they are given. If the value is modified by a
-constraint, the next constraint receives the updated value.&lt;/p&gt;&lt;/div&gt;
+ <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Constraints are validation and conversion functions applied
+to user input.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;They are used in various places in Cowboy, including the
+router and the request match functions.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;sect1&#34;&gt;
+&lt;h2 id=&#34;_syntax&#34;&gt;Syntax&lt;/h2&gt;
+&lt;div class=&#34;sectionbody&#34;&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Constraints are provided as a list of fields. For each field
+in the list, specific constraints can be applied, as well as
+a default value if the field is missing.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;A field can take the form of an atom &lt;code&gt;field&lt;/code&gt;, a tuple with
+constraints &lt;code&gt;{field, Constraints}&lt;/code&gt; or a tuple with constraints
+and a default value &lt;code&gt;{field, Constraints, Default}&lt;/code&gt;.
+The &lt;code&gt;field&lt;/code&gt; form indicates the field is mandatory.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Note that when used with the router, only the second form
+makes sense, as it does not use the default and the field
+is always defined.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Constraints for each field are provided as an ordered list
+of atoms or funs to apply. Built-in constraints are provided
+as atoms, while custom constraints are provided as funs.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;When multiple constraints are provided, they are applied in
+the order given. If the value has been modified by a constraint
+then the next one receives the new value.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;For example, the following constraints will first validate
+and convert the field &lt;code&gt;my_value&lt;/code&gt; to an integer, and then
+check that the integer is positive:&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;listingblock&#34;&gt;
+&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite --&gt;
+&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #009900&#34;&gt;PositiveFun&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;fun&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;V&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;V&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #000080&#34;&gt;true&lt;/span&gt;; (&lt;span style=&#34;color: #990000&#34;&gt;_&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #000080&#34;&gt;false&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;end&lt;/span&gt;&lt;/span&gt;,
+{&lt;span style=&#34;color: #FF6600&#34;&gt;my_value&lt;/span&gt;, [&lt;span style=&#34;color: #FF6600&#34;&gt;int&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;PositiveFun&lt;/span&gt;]}&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;When there&amp;#8217;s only one constraint, it can be provided directly
+without wrapping it into a list:&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;listingblock&#34;&gt;
+&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite --&gt;
+&lt;pre&gt;&lt;tt&gt;{&lt;span style=&#34;color: #FF6600&#34;&gt;my_value&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;int&lt;/span&gt;}&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_built_in_constraints&#34;&gt;Built-in constraints&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Built-in constraints are specified as an atom:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;tableblock&#34;&gt;
&lt;table rules=&#34;all&#34;
width=&#34;100%&#34;
@@ -1129,7 +1146,7 @@ cellspacing=&#34;0&#34; cellpadding=&#34;4&#34;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34; valign=&#34;top&#34;&gt;&lt;p class=&#34;table&#34;&gt;int&lt;/p&gt;&lt;/td&gt;
-&lt;td align=&#34;left&#34; valign=&#34;top&#34;&gt;&lt;p class=&#34;table&#34;&gt;Convert binary value to integer.&lt;/p&gt;&lt;/td&gt;
+&lt;td align=&#34;left&#34; valign=&#34;top&#34;&gt;&lt;p class=&#34;table&#34;&gt;Converts binary value to integer.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34; valign=&#34;top&#34;&gt;&lt;p class=&#34;table&#34;&gt;nonempty&lt;/p&gt;&lt;/td&gt;
@@ -1141,15 +1158,34 @@ cellspacing=&#34;0&#34; cellpadding=&#34;4&#34;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
-&lt;h2 id=&#34;_custom_constraint&#34;&gt;Custom constraint&lt;/h2&gt;
+&lt;h2 id=&#34;_custom_constraints&#34;&gt;Custom constraints&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;In addition to the predefined constraints, Cowboy will accept
-a fun. This fun must accept one argument and return one of
-&lt;code&gt;true&lt;/code&gt;, &lt;code&gt;{true, NewValue}&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;. The result indicates
-whether the value matches the constraint, and if it does it
-can optionally be modified. This allows converting the value
-to a more appropriate Erlang term.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Note that constraint functions SHOULD be pure and MUST NOT crash.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Custom constraints are specified as a fun. This fun takes
+a single argument and must return one of &lt;code&gt;true&lt;/code&gt;, &lt;code&gt;{true, NewValue}&lt;/code&gt;
+or &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;&lt;code&gt;true&lt;/code&gt; indicates the input is valid, &lt;code&gt;false&lt;/code&gt; otherwise.
+The &lt;code&gt;{true, NewValue}&lt;/code&gt; tuple is returned when the input
+is valid and the value has been converted. For example,
+the following constraint will convert the binary input
+to an integer:&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;listingblock&#34;&gt;
+&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite --&gt;
+&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;fun&lt;/span&gt;&lt;/span&gt; (&lt;span style=&#34;color: #009900&#34;&gt;Value0&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;is_binary&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Value0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
+ &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;try&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;binary_to_integer&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Value0&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;of&lt;/span&gt;&lt;/span&gt;
+ &lt;span style=&#34;color: #009900&#34;&gt;Value&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; {&lt;span style=&#34;color: #000080&#34;&gt;true&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Value&lt;/span&gt;}
+ &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;catch&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;_:_&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
+ &lt;span style=&#34;color: #000080&#34;&gt;false&lt;/span&gt;
+ &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Constraint functions should only crash because the programmer
+made an error when chaining constraints incorrectly (for example
+if the constraints were &lt;code&gt;[int, int]&lt;/code&gt;, and not because of input.
+If the input is invalid then &lt;code&gt;false&lt;/code&gt; must be returned.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;In our snippet, the &lt;code&gt;is_binary/1&lt;/code&gt; guard will crash only
+because of a programmer error, and the try block is there
+to ensure that we do not crash when the input is invalid.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>