From fe3492a98de29942477b061cd02c92246f4bf85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 28 Mar 2016 15:36:42 +0200 Subject: Initial commit, new website system --- docs/index.xml | 2001 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2001 insertions(+) create mode 100644 docs/index.xml (limited to 'docs/index.xml') diff --git a/docs/index.xml b/docs/index.xml new file mode 100644 index 00000000..b62edf2e --- /dev/null +++ b/docs/index.xml @@ -0,0 +1,2001 @@ + + + + Docs on Nine Nines + http://ninenines.eu/docs/ + Recent content in Docs on Nine Nines + Hugo -- gohugo.io + en-us + + + + Architecture + http://ninenines.eu/docs/en/cowboy/2.0/guide/architecture/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/cowboy/2.0/guide/architecture/ + <div class="paragraph"><p>Cowboy is a lightweight HTTP server.</p></div> +<div class="paragraph"><p>It is built on top of Ranch. Please see the Ranch guide for more +information.</p></div> +<div class="sect1"> +<h2 id="_one_process_per_connection">One process per connection</h2> +<div class="sectionbody"> +<div class="paragraph"><p>It uses only one process per connection. The process where your +code runs is the process controlling the socket. Using one process +instead of two allows for lower memory usage.</p></div> +<div class="paragraph"><p>Because there can be more than one request per connection with the +keepalive feature of HTTP/1.1, that means the same process will be +used to handle many requests.</p></div> +<div class="paragraph"><p>Because of this, you are expected to make sure your process cleans +up before terminating the handling of the current request. This may +include cleaning up the process dictionary, timers, monitoring and +more.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_binaries">Binaries</h2> +<div class="sectionbody"> +<div class="paragraph"><p>It uses binaries. Binaries are more efficient than lists for +representing strings because they take less memory space. Processing +performance can vary depending on the operation. Binaries are known +for generally getting a great boost if the code is compiled natively. +Please see the HiPE documentation for more details.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_date_header">Date header</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Because querying for the current date and time can be expensive, +Cowboy generates one <code>Date</code> header value every second, shares it +to all other processes, which then simply copy it in the response. +This allows compliance with HTTP/1.1 with no actual performance loss.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_max_connections">Max connections</h2> +<div class="sectionbody"> +<div class="paragraph"><p>By default the maximum number of active connections is set to a +generally accepted big enough number. This is meant to prevent having +too many processes performing potentially heavy work and slowing +everything else down, or taking up all the memory.</p></div> +<div class="paragraph"><p>Disabling this feature, by setting the <code>{max_connections, infinity}</code> +protocol option, would give you greater performance when you are +only processing short-lived requests.</p></div> +</div> +</div> + + + + + AsciiDoc documentation + http://ninenines.eu/docs/en/erlang.mk/1/guide/asciidoc/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/erlang.mk/1/guide/asciidoc/ + <div class="paragraph"><p>Erlang.mk provides rules for generating documentation from +AsciiDoc files. It can automatically build a user guide PDF, +chunked HTML documentation and Unix manual pages.</p></div> +<div class="sect1"> +<h2 id="_requirements">Requirements</h2> +<div class="sectionbody"> +<div class="paragraph"><p>It is necessary to have <a href="http://asciidoc.org/">AsciiDoc</a>, +<a href="http://xmlsoft.org/XSLT/xsltproc2.html">xsltproc</a> and +<a href="http://dblatex.sourceforge.net/">dblatex</a> installed on your +system for Erlang.mk to generate documentation from AsciiDoc sources.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_writing_asciidoc_documentation">Writing AsciiDoc documentation</h2> +<div class="sectionbody"> +<div class="paragraph"><p><a href="http://asciidoc.org/">AsciiDoc</a> is a text document format for +writing notes, documentation, articles, books, ebooks, slideshows, +web pages, man pages and blogs. AsciiDoc files can be translated +to many formats including HTML, PDF, EPUB, man page.</p></div> +<div class="paragraph"><p>The <a href="http://asciidoc.org/userguide.html">AsciiDoc user guide</a> +describes the AsciiDoc syntax.</p></div> +<div class="paragraph"><p>The <a href="https://github.com/ninenines/erlang.mk/tree/master/doc/src/guide">Erlang.mk user guide</a> +is written in AsciiDoc and can be used as an example. The entry +file is <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">book.asciidoc</a>.</p></div> +<div class="paragraph"><p>Erlang.mk expects you to put your documentation in a specific +location. This is <em>doc/src/guide/</em> for the user guide, and +<em>doc/src/manual/</em> for the function reference. In the case of +the user guide, the entry point is always <em>doc/src/guide/book.asciidoc</em>.</p></div> +<div class="paragraph"><p>For manual pages, it is good practice to use section 3 for +modules, and section 7 for the application itself.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_configuration">Configuration</h2> +<div class="sectionbody"> +<div class="paragraph"><p>All of the AsciiDoc related configuration can be done directly +inside the files themselves.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_usage">Usage</h2> +<div class="sectionbody"> +<div class="paragraph"><p>To build all documentation:</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>$ make docs</tt></pre></div></div> +<div class="paragraph"><p>To build only the AsciiDoc documentation:</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>$ make asciidoc</tt></pre></div></div> +<div class="paragraph"><p>To build only the user guide:</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>$ make asciidoc-guide</tt></pre></div></div> +<div class="paragraph"><p>To build only the manual:</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>$ make asciidoc-manual</tt></pre></div></div> +<div class="paragraph"><p>To install man pages on Unix:</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>$ make install-docs</tt></pre></div></div> +<div class="paragraph"><p>Erlang.mk allows customizing the installation path and sections +of the man pages to be installed. The <code>MAN_INSTALL_PATH</code> variable +defines where man pages will be installed. It defaults to +<em>/usr/local/share/man</em>. The <code>MAN_SECTIONS</code> variable defines +which manual sections are to be installed. It defaults to <code>3 7</code>.</p></div> +<div class="paragraph"><p>To install man pages to a custom location:</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>$ make install-docs <span style="color: #009900">MAN_INSTALL_PATH</span><span style="color: #990000">=</span>/opt/share/man</tt></pre></div></div> +<div class="paragraph"><p>Note that you may need to run the install commands using +<code>sudo</code> or equivalent if the location is not writeable by +your user.</p></div> +</div> +</div> + + + + + Building + http://ninenines.eu/docs/en/erlang.mk/1/guide/app/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/erlang.mk/1/guide/app/ + <div class="paragraph"><p>Erlang.mk can do a lot of things, but it is, first and +foremost, a build tool. In this chapter we will cover +the basics of building a project with Erlang.mk.</p></div> +<div class="paragraph"><p>For most of this chapter, we will assume that you are +using a project <a href="../getting_started">generated by Erlang.mk</a>.</p></div> +<div class="sect1"> +<h2 id="_how_to_build">How to build</h2> +<div class="sectionbody"> +<div class="paragraph"><p>To build a project, all you have to do is type <code>make</code>:</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>$ make</tt></pre></div></div> +<div class="paragraph"><p>It will work regardless of your project: OTP applications, +library applications, NIFs, port drivers or even releases. +Erlang.mk also automatically downloads and compiles the +dependencies for your project.</p></div> +<div class="paragraph"><p>All this is possible thanks to a combination of configuration +and conventions. Most of the conventions come from Erlang/OTP +itself so any seasoned Erlang developers should feel right at +home.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_what_to_build">What to build</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Erlang.mk gives you control over three steps of the build +process, allowing you to do a partial build if needed.</p></div> +<div class="paragraph"><p>A build has three phases: first any dependency is fetched +and built, then the project itself is built and finally a +release may be generated when applicable. A release is only +generated for projects specifically configured to do so.</p></div> +<div class="paragraph"><p>Erlang.mk handles those three phases automatically when you +type <code>make</code>. But sometimes you just want to repeat one or +two of them.</p></div> +<div class="paragraph"><p>The commands detailed in this section are most useful after +you have a successful build as they allow you to quickly +redo a step instead of going through everything. This is +especially useful for large projects or projects that end +up generating releases.</p></div> +<div class="sect3"> +<h4 id="_application">Application</h4> +<div class="paragraph"><p>You can build your application and dependencies without +generating a release by running the following command:</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>$ make app</tt></pre></div></div> +<div class="paragraph"><p>To build your application without touching dependencies +at all, you can use the <code>SKIP_DEPS</code> variable:</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>$ make app <span style="color: #009900">SKIP_DEPS</span><span style="color: #990000">=</span><span style="color: #993399">1</span></tt></pre></div></div> +<div class="paragraph"><p>This command is very useful if you have a lot of dependencies +and develop on a machine with slow file access, like the +Raspberry Pi and many other embedded devices.</p></div> +<div class="paragraph"><p>Note that this command may fail if a required dependency +is missing.</p></div> +</div> +<div class="sect3"> +<h4 id="_dependencies">Dependencies</h4> +<div class="paragraph"><p>You can build all dependencies, and nothing else, by +running the following command:</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>$ make deps</tt></pre></div></div> +<div class="paragraph"><p>This will fetch and compile all dependencies and their +dependencies, recursively.</p></div> +<div class="paragraph"><p><a href="../deps">Packages and dependencies</a> are covered +in the next chapter.</p></div> +</div> +<div class="sect3"> +<h4 id="_release">Release</h4> +<div class="paragraph"><p>It is not possible to build the release without at least +building the application itself, unless of course if there&#8217;s +no application to begin with.</p></div> +<div class="paragraph"><p>To generate the release, <code>make</code> will generally suffice with +a normal Erlang.mk. A separate target is however available, +and will take care of building the release, after building +the application and all dependencies:</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>$ make rel</tt></pre></div></div> +<div class="paragraph"><p>Consult the <a href="../relx">Releases</a> chapter for more +information about what releases are and how they are generated.</p></div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_application_resource_file">Application resource file</h2> +<div class="sectionbody"> +<div class="paragraph"><p>When building your application, Erlang.mk will generate the +<a href="http://www.erlang.org/doc/man/app.html">application resource file</a>. +This file is mandatory for all Erlang applications and is +found in <em>ebin/$(PROJECT).app</em>.</p></div> +<div class="paragraph"><p><code>PROJECT</code> is a variable defined in your Makefile and taken +from the name of the directory when Erlang.mk bootstraps +your project.</p></div> +<div class="paragraph"><p>Erlang.mk can build the <em>ebin/$(PROJECT).app</em> in two different +ways: from the configuration found in the Makefile, or from +the <em>src/$(PROJECT).app.src</em> file.</p></div> +<div class="sect3"> +<h4 id="_application_configuration">Application configuration</h4> +<div class="paragraph"><p>Erlang.mk automatically fills the <code>PROJECT</code> variable when +bootstrapping a new project, but everything else is up to +you. None of the values are required to build your project, +although it is recommended to fill everything relevant to +your situation.</p></div> +<div class="dlist"><dl> +<dt class="hdlist1"> +<code>PROJECT</code> +</dt> +<dd> +<p> + The name of the OTP application or library. +</p> +</dd> +<dt class="hdlist1"> +<code>PROJECT_DESCRIPTION</code> +</dt> +<dd> +<p> + Short description of the project. +</p> +</dd> +<dt class="hdlist1"> +<code>PROJECT_VERSION</code> +</dt> +<dd> +<p> + Current version of the project. +</p> +</dd> +<dt class="hdlist1"> +<code>PROJECT_REGISTERED</code> +</dt> +<dd> +<p> + List of the names of all registered processes. +</p> +</dd> +<dt class="hdlist1"> +<code>LOCAL_DEPS</code> +</dt> +<dd> +<p> + List of Erlang/OTP applications this project depends on, + excluding <code>erts</code>, <code>kernel</code> and <code>stdlib</code>, or list of + dependencies local to this repository (in <code>APPS_DIR</code>). +</p> +</dd> +<dt class="hdlist1"> +<code>DEPS</code> +</dt> +<dd> +<p> + List of applications this project depends on that need + to be fetched by Erlang.mk. +</p> +</dd> +</dl></div> +<div class="paragraph"><p>There&#8217;s no need for quotes or anything. The relevant part of +the Cowboy Makefile follows, if you need an example:</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">PROJECT =</span> cowboy +<span style="color: #009900">PROJECT_DESCRIPTION =</span> Small<span style="color: #990000">,</span> fast<span style="color: #990000">,</span> modular HTTP server<span style="color: #990000">.</span> +<span style="color: #009900">PROJECT_VERSION =</span> 2.0.0-pre.2 +<span style="color: #009900">PROJECT_REGISTERED =</span> cowboy_clock + +<span style="color: #009900">LOCAL_DEPS =</span> crypto +<span style="color: #009900">DEPS =</span> cowlib ranch</tt></pre></div></div> +<div class="paragraph"><p>Any space before and after the value is dropped.</p></div> +<div class="paragraph"><p><a href="../deps">Dependencies</a> are covered in details in +the next chapter.</p></div> +</div> +<div class="sect3"> +<h4 id="_legacy_method">Legacy method</h4> +<div class="paragraph"><p>The <em>src/$(PROJECT).app.src</em> file is a legacy method of +building Erlang applications. It was introduced by the original +<code>rebar</code> build tool, of which Erlang.mk owes a great deal as it +is its main inspiration.</p></div> +<div class="paragraph"><p>The <em>.app.src</em> file serves as a template to generate the <em>.app</em> +file. Erlang.mk will take it, fill in the <code>modules</code> value +dynamically, and save the result in <em>ebin/$(PROJECT).app</em>.</p></div> +<div class="paragraph"><p>When using this method, Erlang.mk cannot fill the <code>applications</code> +key from dependencies automatically, which means you need to +add them to Erlang.mk and to the <em>.app.src</em> at the same time, +duplicating the work.</p></div> +<div class="paragraph"><p>If you really can&#8217;t live without the legacy method, for one +reason or another, worry not; Erlang.mk will support it. And +if you need to create a new project that uses this method, you +just have to say so when bootstrapping:</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>$ make -f erlang<span style="color: #990000">.</span>mk bootstrap-lib <span style="color: #009900">LEGACY</span><span style="color: #990000">=</span><span style="color: #993399">1</span></tt></pre></div></div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_automatic_application_resource_file_values">Automatic application resource file values</h2> +<div class="sectionbody"> +<div class="paragraph"><p>When building the application resource file, Erlang.mk may +automatically add an <code>id</code> key with information about the +Git commit (if using Git), or an empty string otherwise. +It will only do this under specific conditions:</p></div> +<div class="ulist"><ul> +<li> +<p> +The application was built as a dependency of another, or +</p> +</li> +<li> +<p> +The legacy method was used, and the <em>.app.src</em> file contained <code>{id, "git"}</code> +</p> +</li> +</ul></div> +<div class="paragraph"><p>This value is most useful when you need to help your users, +as it allows you to know which version they run exactly by +asking them to look in the file, or by running a simple +command on their production server:</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: #993399">1</span><span style="color: #990000">&gt;</span> <span style="font-weight: bold"><span style="color: #000000">application:get_all_key</span></span>(<span style="color: #FF6600">cowboy</span>)<span style="color: #990000">.</span> +{<span style="color: #FF6600">ok</span>,[{<span style="color: #FF6600">description</span>,<span style="color: #FF0000">"Small, fast, modular HTTP server."</span>}, + {<span style="color: #FF6600">id</span>,<span style="color: #FF0000">"2.0.0-pre.2-25-g0ffde50-dirty"</span>},</tt></pre></div></div> +</div> +</div> +<div class="sect1"> +<h2 id="_file_formats">File formats</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Erlang.mk supports a variety of different source file formats. +The following formats are supported natively:</p></div> +<div class="tableblock"> +<table rules="all" +width="100%" +frame="border" +cellspacing="0" cellpadding="4"> +<col width="25%" /> +<col width="25%" /> +<col width="25%" /> +<col width="25%" /> +<thead> +<tr> +<th align="left" valign="top"> Extension </th> +<th align="center" valign="top"> Location </th> +<th align="center" valign="top"> Description </th> +<th align="center" valign="top"> Output</th> +</tr> +</thead> +<tbody> +<tr> +<td align="left" valign="top"><p class="table">.erl</p></td> +<td align="center" valign="top"><p class="table">src/</p></td> +<td align="center" valign="top"><p class="table">Erlang source</p></td> +<td align="center" valign="top"><p class="table">ebin/*.beam</p></td> +</tr> +<tr> +<td align="left" valign="top"><p class="table">.core</p></td> +<td align="center" valign="top"><p class="table">src/</p></td> +<td align="center" valign="top"><p class="table">Core Erlang source</p></td> +<td align="center" valign="top"><p class="table">ebin/*.beam</p></td> +</tr> +<tr> +<td align="left" valign="top"><p class="table">.xrl</p></td> +<td align="center" valign="top"><p class="table">src/</p></td> +<td align="center" valign="top"><p class="table">Leex source</p></td> +<td align="center" valign="top"><p class="table">src/*.erl</p></td> +</tr> +<tr> +<td align="left" valign="top"><p class="table">.yrl</p></td> +<td align="center" valign="top"><p class="table">src/</p></td> +<td align="center" valign="top"><p class="table">Yecc source</p></td> +<td align="center" valign="top"><p class="table">src/*.erl</p></td> +</tr> +<tr> +<td align="left" valign="top"><p class="table">.asn1</p></td> +<td align="center" valign="top"><p class="table">asn1/</p></td> +<td align="center" valign="top"><p class="table">ASN.1 files</p></td> +<td align="center" valign="top"><p class="table">include/<strong>.hrl include/</strong>.asn1db src/*.erl</p></td> +</tr> +<tr> +<td align="left" valign="top"><p class="table">.mib</p></td> +<td align="center" valign="top"><p class="table">mibs/</p></td> +<td align="center" valign="top"><p class="table">SNMP MIB files</p></td> +<td align="center" valign="top"><p class="table">include/<strong>.hrl priv/mibs/</strong>.bin</p></td> +</tr> +</tbody> +</table> +</div> +<div class="paragraph"><p>Files are always searched recursively.</p></div> +<div class="paragraph"><p>The build is ordered, so that files that generate Erlang source +files are run before, and the resulting Erlang source files are +then built normally.</p></div> +<div class="paragraph"><p>In addition, Erlang.mk keeps track of header files (<code>.hrl</code>) +as described at the end of this chapter. It can also compile +C code, as described in the <a href="../ports">NIFs and port drivers</a> +chapter.</p></div> +<div class="paragraph"><p>Erlang.mk also comes with plugins for the following formats:</p></div> +<div class="tableblock"> +<table rules="all" +width="100%" +frame="border" +cellspacing="0" cellpadding="4"> +<col width="25%" /> +<col width="25%" /> +<col width="25%" /> +<col width="25%" /> +<thead> +<tr> +<th align="left" valign="top"> Extension </th> +<th align="center" valign="top"> Location </th> +<th align="center" valign="top"> Description </th> +<th align="center" valign="top"> Output</th> +</tr> +</thead> +<tbody> +<tr> +<td align="left" valign="top"><p class="table">.dtl</p></td> +<td align="center" valign="top"><p class="table">templates/</p></td> +<td align="center" valign="top"><p class="table">Django templates</p></td> +<td align="center" valign="top"><p class="table">ebin/*.beam</p></td> +</tr> +<tr> +<td align="left" valign="top"><p class="table">.proto</p></td> +<td align="center" valign="top"><p class="table">src/</p></td> +<td align="center" valign="top"><p class="table">Protocol buffers</p></td> +<td align="center" valign="top"><p class="table">ebin/*.beam</p></td> +</tr> +</tbody> +</table> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_compilation_options">Compilation options</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Erlang.mk provides a few variables that you can use to customize +the build process and the resulting files.</p></div> +<div class="sect3"> +<h4 id="_erlc_opts">ERLC_OPTS</h4> +<div class="paragraph"><p><code>ERLC_OPTS</code> can be used to pass some options to <code>erlc</code>, the Erlang +compiler. Erlang.mk does not restrict any option. Please refer to +the <a href="http://www.erlang.org/doc/man/erlc.html">erlc Manual</a> for the +full list.</p></div> +<div class="paragraph"><p>By default, Erlang.mk will set the following options:</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">ERLC_OPTS =</span> -Werror <span style="color: #990000">+</span>debug_info <span style="color: #990000">+</span>warn_export_vars <span style="color: #990000">+</span>warn_shadow_vars <span style="color: #990000">+</span>warn_obsolete_guard</tt></pre></div></div> +<div class="paragraph"><p>In other words: warnings as errors, debug info (recommended) and +enable warnings for exported variables, shadow variables and +obsolete guard functions.</p></div> +<div class="paragraph"><p>You can redefine this variable in your Makefile to change it +completely, either before or after including Erlang.mk:</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">ERLC_OPTS =</span> <span style="color: #990000">+</span>debug_info</tt></pre></div></div> +<div class="paragraph"><p>You can also filter out some options from the defaults Erlang.mk +sets, by defining ERLC_OPTS after including Erlang.mk using the +<code>:=</code> operator.</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>include erlang.mk + +<span style="color: #990000">ERLC_OPTS :=</span> <span style="color: #009900">$(</span>filter-out -Werror<span style="color: #990000">,</span><span style="color: #009900">$(ERLC_OPTS))</span></tt></pre></div></div> +</div> +<div class="sect3"> +<h4 id="_erlc_exclude">ERLC_EXCLUDE</h4> +<div class="paragraph"><p><code>ERLC_EXCLUDE</code> can be used to exclude some modules from the +compilation. It&#8217;s there for handling special cases, you should +not normally need it.</p></div> +<div class="paragraph"><p>To exclude a module, simply list it in the variable, either +before or after including Erlang.mk:</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">ERLC_EXCLUDE =</span> cowboy_http2</tt></pre></div></div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_cold_and_hot_builds">Cold and hot builds</h2> +<div class="sectionbody"> +<div class="paragraph"><p>The first time you run <code>make</code>, Erlang.mk will build everything.</p></div> +<div class="paragraph"><p>The second time you run <code>make</code>, and all subsequent times, Erlang.mk +will only rebuild what changed. Erlang.mk has been optimized for +this use case, as it is the most common during development.</p></div> +<div class="paragraph"><p>Erlang.mk figures out what changed by using the dependency tracking +feature of Make. Make automatically rebuilds a target if one of its +dependency has changed (for example if a header file has changed, +all the source files that include it will be rebuilt), and Erlang.mk +leverages this feature to cut down on rebuild times.</p></div> +<div class="paragraph"><p>Note that this applies only to building; some other features of +Erlang.mk will run every time they are called regardless of files +changed.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_dependency_tracking">Dependency tracking</h2> +<div class="sectionbody"> +<div class="admonitionblock"> +<table><tr> +<td class="icon"> +<div class="title">Note</div> +</td> +<td class="content">This section is about the dependency tracking between files +inside your project, not application dependencies.</td> +</tr></table> +</div> +<div class="paragraph"><p>Erlang.mk keeps track of the dependencies between the different +files in your project. This information is kept in the <em>$(PROJECT).d</em> +file in your directory. It is generated if missing, and will be +generated again after every file change, by default.</p></div> +<div class="paragraph"><p>Dependency tracking is what allows Erlang.mk to know when to +rebuild Erlang files when header files, behaviors or parse +transforms have changed. Erlang.mk also automatically keeps +track of which files should be compiled first, for example +when you have behaviors used by other modules in your project.</p></div> +<div class="paragraph"><p>If your project is stable, you may want to disable generating +the dependency tracking file every time you compile. You can +do this by adding the following line to your <em>Makefile</em>:</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>NO_MAKEDEP <span style="color: #990000">?=</span> <span style="color: #993399">1</span></tt></pre></div></div> +<div class="paragraph"><p>As you can see, the snippet above uses <code>?=</code> instead of a +simple equal sign. This is to allow you to temporarily override +this value when you do make substantial changes to your project +(including a new header file, new module with dependencies, etc.) +and want to rebuild the dependency tracking file. You&#8217;ll be +able to use the following command:</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">NO_MAKEDEP</span><span style="color: #990000">=</span> make</tt></pre></div></div> +<div class="paragraph"><p>Otherwise, <code>make clean app</code> will of course force the +recompilation of your project.</p></div> +<div class="paragraph"><p>Erlang.mk can also keep track of the source files generated +by other means, for example if you generate code from a data +file in your repository.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_generating_erlang_source">Generating Erlang source</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Erlang.mk provides hooks at different stages of the build process. +When your goal is to generate Erlang source files, you can +add your own rules before or after the dependency tracking +file is generated. To do this, you would add your hook before +or after including the <em>erlang.mk</em> file.</p></div> +<div class="paragraph"><p>The easiest way is after:</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">PROJECT =</span> example + +include erlang.mk + +<span style="color: #009900">$(PROJECT)</span>.d<span style="color: #990000">::</span> src/generated_mod.erl + +src/generated_mod.erl<span style="color: #990000">::</span> gen-mod.sh + <span style="color: #009900">$(gen_verbose)</span> <span style="color: #990000">.</span>/gen-mod.sh <span style="color: #009900">$@</span></tt></pre></div></div> +<div class="paragraph"><p>In this case we use <code>$(gen_verbose)</code> to hide the details of +the build by default. Erlang.mk will simply say what file +is it currently generating.</p></div> +<div class="paragraph"><p>When using an external script to generate the Erlang source +file, it is recommended to depend on that script, so that +the source file gets generated again when the script gets +modified.</p></div> +<div class="paragraph"><p>If for whatever reason you prefer to hook before including +Erlang.mk, don&#8217;t forget to set the <code>.DEFAULT_GOAL</code> variable, +otherwise nothing will get built:</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">PROJECT =</span> example + +.DEFAULT_GOAL <span style="color: #990000">=</span> all + +<span style="color: #009900">$(PROJECT)</span>.d<span style="color: #990000">::</span> src/generated_mod.erl + +include erlang.mk + +src/generated_mod.erl<span style="color: #990000">::</span> gen-mod.sh + <span style="color: #009900">$(gen_verbose)</span> <span style="color: #990000">.</span>/gen-mod.sh <span style="color: #009900">$@</span></tt></pre></div></div> +</div> +</div> +<div class="sect1"> +<h2 id="_cleaning">Cleaning</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Building typically involves creating a lot of new files. Some +are reused in rebuilds, some are simply replaced. All can be +removed safely.</p></div> +<div class="paragraph"><p>Erlang.mk provides two commands to remove them: <code>clean</code> and +<code>distclean</code>. <code>clean</code> removes all the intermediate files that +were created as a result of building, including the BEAM files, +the dependency tracking file and the generated documentation. +<code>distclean</code> removes these and more, including the downloaded +dependencies, Dialyzer&#8217;s PLT file and the generated release, +putting your directory back to the state it was before you +started working on it.</p></div> +<div class="paragraph"><p>To clean:</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>$ make clean</tt></pre></div></div> +<div class="paragraph"><p>Or distclean:</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>$ make distclean</tt></pre></div></div> +<div class="paragraph"><p>That is the question.</p></div> +<div class="paragraph"><p>Note that Erlang.mk will automatically clean some files as +part of other targets, but it will never run <code>distclean</code> if +you don&#8217;t explicitly use it.</p></div> +</div> +</div> + + + + + Code coverage + http://ninenines.eu/docs/en/erlang.mk/1/guide/coverage/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/erlang.mk/1/guide/coverage/ + <div class="paragraph"><p>Placeholder chapter.</p></div> + + + + + Common Test + http://ninenines.eu/docs/en/erlang.mk/1/guide/common_test/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/erlang.mk/1/guide/common_test/ + <div class="paragraph"><p>Common Test is Erlang&#8217;s functional testing framework. +Erlang.mk automates the discovery and running of Common +Test suites.</p></div> +<div class="sect1"> +<h2 id="_writing_tests">Writing tests</h2> +<div class="sectionbody"> +<div class="paragraph"><p>The <a href="http://www.erlang.org/doc/apps/common_test/write_test_chapter.html">Common Test user guide</a> +is the best place to learn how to write tests. Erlang.mk +requires that file names for test suites end with <em>_SUITE.erl</em> +and that the files be located in the <em>$(TEST_DIR)</em> directory. +This defaults to <em>test/</em>.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_configuration">Configuration</h2> +<div class="sectionbody"> +<div class="paragraph"><p>The <code>CT_OPTS</code> variable allows you to set extra Common Test +options. Options are documented in the +<a href="http://www.erlang.org/doc/apps/common_test/run_test_chapter.html">Common Test user guide</a>. +You can use it to set Common Test hooks, for example:</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">CT_OPTS =</span> -ct_hooks cowboy_ct_hook</tt></pre></div></div> +<div class="paragraph"><p>The <code>CT_SUITES</code> variable can be used to override what +Common Test suites Erlang.mk will be aware of. It does +not normally need to be set as Erlang.mk will find the +test suites automatically.</p></div> +<div class="paragraph"><p>The name of the suite is the part before <code>_SUITE.erl</code>. +If the file is named <em>http_SUITE.erl</em>, the test suite +is <code>http</code>:</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">CT_SUITES =</span> http ws</tt></pre></div></div> +</div> +</div> +<div class="sect1"> +<h2 id="_usage">Usage</h2> +<div class="sectionbody"> +<div class="paragraph"><p>To run all tests (including Common Test):</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>$ make tests</tt></pre></div></div> +<div class="paragraph"><p>To run all tests and static checks (including Common Test):</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>$ make check</tt></pre></div></div> +<div class="paragraph"><p>You can also run Common Test separately:</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>$ make ct</tt></pre></div></div> +<div class="paragraph"><p>Erlang.mk will create targets for all test suites it finds. +If you have a file named <em>test/http_SUITE.erl</em>, then the +target <code>ct-http</code> will run that specific test suite:</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>$ make ct-http</tt></pre></div></div> +<div class="paragraph"><p>Erlang.mk provides a convenient way to run a specific +group or a specific test case within a specific group, +using the variable <code>t</code>. Note that this only applies to +suite-specific targets, like the <code>ct-http</code> example above.</p></div> +<div class="paragraph"><p>To run all tests from the <code>http_compress</code> group in the +<code>http_SUITE</code> test suite, write:</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>$ make ct-http <span style="color: #009900">t</span><span style="color: #990000">=</span>http_compress</tt></pre></div></div> +<div class="paragraph"><p>Similarly, to run a specific test case in that group:</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>$ make ct-http <span style="color: #009900">t</span><span style="color: #990000">=</span>http_compress<span style="color: #990000">:</span>headers_dupe</tt></pre></div></div> +<div class="paragraph"><p>To do the same against a multi-application repository, +you can use the <code>-C</code> option:</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>$ make -C apps/my_app ct-http <span style="color: #009900">t</span><span style="color: #990000">=</span>my_group<span style="color: #990000">:</span>my_case</tt></pre></div></div> +<div class="paragraph"><p>Note that this also applies to dependencies. When using Cowboy +as a dependency, you can run the following directly:</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>$ make -C deps/cowboy ct-http <span style="color: #009900">t</span><span style="color: #990000">=</span>http_compress</tt></pre></div></div> +<div class="paragraph"><p>Finally, <a href="../coverage">code coverage</a> is available, +but covered in its own chapter.</p></div> +</div> +</div> + + + + + Compatibility with other build tools + http://ninenines.eu/docs/en/erlang.mk/1/guide/compat/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/erlang.mk/1/guide/compat/ + <div class="paragraph"><p>Erlang.mk tries its best to be compatible with the other Erlang +build tools. It can use dependencies written with other build +tools in mind, and can also make your projects usable by those +build tools as well. Erlang.mk is like the cool kid that gets +along with everybody.</p></div> +<div class="paragraph"><p>In this chapter I will use the term <em>Rebar project</em> to refer +to a project built using Rebar 2, Rebar 3 or Mad. These three +build tools are very similar and share the same configuration +file.</p></div> +<div class="sect1"> +<h2 id="_rebar_projects_as_erlang_mk_dependencies">Rebar projects as Erlang.mk dependencies</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Erlang.mk comes with a feature called <em>Autoload</em> which will +use Rebar 2 to patch any Rebar project and make it compatible +with Erlang.mk. This feature essentially patches Rebar out +and adds a Makefile to the project that Erlang.mk can then +use for building:</p></div> +<div class="paragraph"><p><em>Autoload</em> is documented in more details in the +<a href="../deps">Packages and dependencies</a> chapter.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_erlang_mk_projects_as_rebar_dependencies">Erlang.mk projects as Rebar dependencies</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Erlang.mk projects can be made compatible with the Rebar family +of build tools pretty easily, as Erlang.mk will generate +all the files they require for building.</p></div> +<div class="paragraph"><p>The Rebar family requires two files: a <em>rebar.config</em> file +containing compilation options and the list of dependencies, +and the application resource file, found either at +<em>ebin/$(PROJECT).app</em> or at <em>src/$(PROJECT).app.src</em>.</p></div> +<div class="sect3"> +<h4 id="_rebar_configuration">Rebar configuration</h4> +<div class="paragraph"><p>Erlang.mk comes with a target that generates a <em>rebar.config</em> +file when invoked:</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>$ make rebar<span style="color: #990000">.</span>config</tt></pre></div></div> +<div class="paragraph"><p>Careful! This will build the file even if it already existed +before.</p></div> +<div class="paragraph"><p>To build this file, Erlang.mk uses information it finds in +the <code>DEPS</code> and <code>ERLC_OPTS</code> variables, among others. This +means that the Rebar family builds your project much the +same way as Erlang.mk.</p></div> +<div class="paragraph"><p>Careful though! Different build tools have different fetching +strategies. If some applications provide differing dependencies, +they might be fetched differently by other build tools. Check +the upcoming Sanity check chapter to find out how to detect such +issues.</p></div> +<div class="paragraph"><p>You can automatically generate this file when you build +your application, by making it a dependency of the <code>app</code> +target:</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: #990000">app::</span> rebar.config</tt></pre></div></div> +<div class="paragraph"><p>Don&#8217;t forget to commit the file when it changes!</p></div> +<div class="paragraph"><p>If you run into other issues, it&#8217;s probably because you use a +feature specific to Erlang.mk, like the <code>cp</code> fetch method. +It could also be that we forgot to handle something! Sorry. +We are of course interested to hear about any compatibility +problems you may have, just open a ticket!</p></div> +</div> +<div class="sect3"> +<h4 id="_application_resource_file">Application resource file</h4> +<div class="paragraph"><p>Erlang.mk has two ways to generate an application resource +file: from the information found in the Makefile, or from +the information found in the <em>src/$(PROJECT).app.src</em> file. +Needless to say, if you have this file in your repository, +then you don&#8217;t need to worry about compatibility with other +build tools.</p></div> +<div class="paragraph"><p>If you don&#8217;t, however, it&#8217;s not much harder. Every time +Erlang.mk will compile your application, it will produce +a new <em>ebin/$(PROJECT).app</em> file. Simply commit this file +when it changes. It will only change when you modify the +configuration, add or remove modules.</p></div> +</div> +</div> +</div> + + + + + Connection + http://ninenines.eu/docs/en/gun/1.0/guide/connect/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/gun/1.0/guide/connect/ + <div class="paragraph"><p>This chapter describes how to open, monitor and close +a connection using the Gun client.</p></div> +<div class="sect1"> +<h2 id="_gun_connections">Gun connections</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Gun is designed with the SPDY and Websocket protocols in mind. +They are built for long-running connections that allow concurrent +exchange of data, either in the form of request/responses for +SPDY or in the form of messages for Websocket.</p></div> +<div class="paragraph"><p>A Gun connection is an Erlang process that manages a socket to +a remote endpoint. This Gun connection is owned by a user +process that is called the <em>owner</em> of the connection, and is +managed by the supervision tree of the <code>gun</code> application.</p></div> +<div class="paragraph"><p>The owner process communicates with the Gun connection +by calling functions from the module <code>gun</code>. All functions +perform their respective operations asynchronously. The Gun +connection will send Erlang messages to the owner process +whenever needed.</p></div> +<div class="paragraph"><p>When the remote endpoint closes the connection, Gun attempts +to reconnect automatically.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_opening_a_new_connection">Opening a new connection</h2> +<div class="sectionbody"> +<div class="paragraph"><p>The <code>gun:open/{2,3}</code> function must be used to open a connection.</p></div> +<div class="listingblock"> +<div class="title">Opening a connection to example.org on port 443</div> +<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">ok</span>, <span style="color: #009900">ConnPid</span>} <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">gun:open</span></span>(<span style="color: #FF0000">"example.org"</span>, <span style="color: #993399">443</span>)<span style="color: #990000">.</span></tt></pre></div></div> +<div class="paragraph"><p>If the port given is 443, Gun will attempt to connect using +SSL. The protocol will be selected automatically using the +NPN extension for TLS. By default Gun supports SPDY/3.1, +SPDY/3 and HTTP/1.1 when connecting using SSL.</p></div> +<div class="paragraph"><p>For any other port, Gun will attempt to connect using TCP +and will use the HTTP/1.1 protocol.</p></div> +<div class="paragraph"><p>The transport and protocol used can be overriden using +options. The manual documents all available options.</p></div> +<div class="paragraph"><p>Options can be provided as a third argument, and take the +form of a map.</p></div> +<div class="listingblock"> +<div class="title">Opening an SSL connection to example.org on port 8443</div> +<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">ok</span>, <span style="color: #009900">ConnPid</span>} <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">gun:open</span></span>(<span style="color: #FF0000">"example.org"</span>, <span style="color: #993399">8443</span>, #{<span style="color: #0000FF">transport</span><span style="color: #990000">=&gt;</span><span style="color: #FF6600">ssl</span>})<span style="color: #990000">.</span></tt></pre></div></div> +</div> +</div> +<div class="sect1"> +<h2 id="_waiting_for_the_connection_to_be_established">Waiting for the connection to be established</h2> +<div class="sectionbody"> +<div class="paragraph"><p>When Gun successfully connects to the server, it sends a +<code>gun_up</code> message with the protocol that has been selected +for the connection.</p></div> +<div class="paragraph"><p>Gun provides the functions <code>gun:await_up/{1,2,3}</code> that wait +for the <code>gun_up</code> message. They can optionally take a monitor +reference and/or timeout value. If no monitor is provided, +one will be created for the duration of the function call.</p></div> +<div class="listingblock"> +<div class="title">Synchronous opening of a connection</div> +<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">ok</span>, <span style="color: #009900">ConnPid</span>} <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">gun:open</span></span>(<span style="color: #FF0000">"example.org"</span>, <span style="color: #993399">443</span>), +{<span style="color: #FF6600">ok</span>, <span style="color: #009900">Protocol</span>} <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">gun:await_up</span></span>(<span style="color: #009900">ConnPid</span>)<span style="color: #990000">.</span></tt></pre></div></div> +</div> +</div> +<div class="sect1"> +<h2 id="_handling_connection_loss">Handling connection loss</h2> +<div class="sectionbody"> +<div class="paragraph"><p>When the connection is lost, Gun will send a <code>gun_down</code> +message indicating the current protocol, the reason the +connection was lost and two list of stream references.</p></div> +<div class="paragraph"><p>The first list indicates open streams that <em>may</em> have been +processed by the server. The second list indicates open +streams that the server did not process.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_monitoring_the_connection_process">Monitoring the connection process</h2> +<div class="sectionbody"> +<div class="paragraph"><p>@todo Gun should detect the owner process being killed</p></div> +<div class="paragraph"><p>Because software errors are unavoidable, it is important to +detect when the Gun process crashes. It is also important +to detect when it exits normally. Erlang provides two ways +to do that: links and monitors.</p></div> +<div class="paragraph"><p>Gun leaves you the choice as to which one will be used. +However, if you use the <code>gun:await/{2,3}</code> or <code>gun:await_body/{2,3}</code> +functions, a monitor may be used for you to avoid getting +stuck waiting for a message that will never come.</p></div> +<div class="paragraph"><p>If you choose to monitor yourself you can do it on a permanent +basis rather than on every message you will receive, saving +resources. Indeed, the <code>gun:await/{3,4}</code> and <code>gun:await_body/{3,4}</code> +functions both accept a monitor argument if you have one already.</p></div> +<div class="listingblock"> +<div class="title">Monitoring the connection process</div> +<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">ok</span>, <span style="color: #009900">ConnPid</span>} <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">gun:open</span></span>(<span style="color: #FF0000">"example.org"</span>, <span style="color: #993399">443</span>)<span style="color: #990000">.</span> +<span style="color: #009900">MRef</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">monitor</span></span>(<span style="font-weight: bold"><span style="color: #000080">process</span></span>, <span style="color: #009900">ConnPid</span>)<span style="color: #990000">.</span></tt></pre></div></div> +<div class="paragraph"><p>This monitor reference can be kept and used until the connection +process exits.</p></div> +<div class="listingblock"> +<div class="title">Handling <code>DOWN</code> messages</div> +<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">receive</span></span> + <span style="font-style: italic"><span style="color: #9A1900">%% Receive Gun messages here...</span></span> + {<span style="color: #FF6600">'DOWN'</span>, <span style="color: #009900">Mref</span>, <span style="font-weight: bold"><span style="color: #000080">process</span></span>, <span style="color: #009900">ConnPid</span>, <span style="color: #009900">Reason</span>} <span style="color: #990000">-&gt;</span> + <span style="font-weight: bold"><span style="color: #000000">error_logger:error_msg</span></span>(<span style="color: #FF0000">"Oops!"</span>), + <span style="font-weight: bold"><span style="color: #000080">exit</span></span>(<span style="color: #009900">Reason</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>What to do when you receive a <code>DOWN</code> message is entirely up to you.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_closing_the_connection_abruptly">Closing the connection abruptly</h2> +<div class="sectionbody"> +<div class="paragraph"><p>The connection can be stopped abruptly at any time by calling +the <code>gun:close/1</code> function.</p></div> +<div class="listingblock"> +<div class="title">Immediate closing of the connection</div> +<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: #000000">gun:close</span></span>(<span style="color: #009900">ConnPid</span>)<span style="color: #990000">.</span></tt></pre></div></div> +<div class="paragraph"><p>The process is stopped immediately without having a chance to +perform the protocol&#8217;s closing handshake, if any.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_closing_the_connection_gracefully">Closing the connection gracefully</h2> +<div class="sectionbody"> +<div class="paragraph"><p>The connection can also be stopped gracefully by calling the +<code>gun:shutdown/1</code> function.</p></div> +<div class="listingblock"> +<div class="title">Graceful shutdown of the connection</div> +<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: #000000">gun:shutdown</span></span>(<span style="color: #009900">ConnPid</span>)<span style="color: #990000">.</span></tt></pre></div></div> +<div class="paragraph"><p>Gun will refuse any new requests or messages after you call +this function. It will however continue to send you messages +for existing streams until they are all completed.</p></div> +<div class="paragraph"><p>For example if you performed a GET request just before calling +<code>gun:shutdown/1</code>, you will still receive the response before +Gun closes the connection.</p></div> +<div class="paragraph"><p>If you set a monitor beforehand, you will receive a message +when the connection has been closed.</p></div> +</div> +</div> + + + + + Constraints + http://ninenines.eu/docs/en/cowboy/2.0/guide/constraints/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/cowboy/2.0/guide/constraints/ + <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="sect1"> +<h2 id="_structure">Structure</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> +</div> +<div class="sect1"> +<h2 id="_built_in_constraints">Built-in constraints</h2> +<div class="sectionbody"> +<div class="tableblock"> +<table rules="all" +width="100%" +frame="border" +cellspacing="0" cellpadding="4"> +<col width="50%" /> +<col width="50%" /> +<thead> +<tr> +<th align="left" valign="top"> Constraint </th> +<th align="left" valign="top"> Description</th> +</tr> +</thead> +<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> +</tr> +<tr> +<td align="left" valign="top"><p class="table">nonempty</p></td> +<td align="left" valign="top"><p class="table">Ensures the binary value is non-empty.</p></td> +</tr> +</tbody> +</table> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_custom_constraint">Custom constraint</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> +</div> + + + + + Continuous integration + http://ninenines.eu/docs/en/erlang.mk/1/guide/ci/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/erlang.mk/1/guide/ci/ + <div class="paragraph"><p>Placeholder chapter.</p></div> + + + + + Contributing + http://ninenines.eu/docs/en/erlang.mk/1/guide/contributing/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/erlang.mk/1/guide/contributing/ + <div class="paragraph"><p>You are welcome and encouraged to contribute.</p></div> +<div class="paragraph"><p>This is how.</p></div> +<div class="sect1"> +<h2 id="_priorities">Priorities</h2> +<div class="sectionbody"> +<div class="paragraph"><p>From the most important to the least important:</p></div> +<div class="ulist"><ul> +<li> +<p> +Bugs +</p> +</li> +<li> +<p> +Package issues/additions +</p> +</li> +<li> +<p> +Refactoring +</p> +</li> +<li> +<p> +Features +</p> +</li> +</ul></div> +</div> +</div> +<div class="sect1"> +<h2 id="_bugs">Bugs</h2> +<div class="sectionbody"> +<div class="paragraph"><p>If you have found a bug, you should open a ticket. Include +everything relevant including the command you used, output, +a link to the code that triggers the issue, why you think +this is a bug, etc.</p></div> +<div class="paragraph"><p>If you think you have found a bug but you are not sure, you +should open a ticket as previously explained.</p></div> +<div class="paragraph"><p>If you have found a bug and you need it to be solved RIGHT +NOW, open a ticket as previously explained.</p></div> +<div class="paragraph"><p>Once you have opened a ticket, be patient, try to answer +questions in a timely manner and confirm that the bug was +indeed fixed when it is.</p></div> +<div class="paragraph"><p>If you can&#8217;t be patient, either try to solve the bug and +contribute the fix back or become a paying customer.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_code">Code</h2> +<div class="sectionbody"> +<div class="paragraph"><p>The code is located in the <em>core/*.mk</em> and <em>plugins/*.mk</em> files. +The tests are located in the <em>test/Makefile</em> and <em>test/*.mk</em> files.</p></div> +<div class="paragraph"><p>If you have a fix or a hack for a bug, you should open a +pull request. Any fix should include a test case that fails +before the fix and is working after.</p></div> +<div class="paragraph"><p>If you have a test case that reproduces a bug, but no fix for +it, you should open a pull request.</p></div> +<div class="paragraph"><p>Changes need to be tested with at least the <code>make check</code> +command. A specific test case can be tested using <code>make check c=CASE</code> +with <code>CASE</code> the name of the target to run. Output can be +modulated using the <code>V</code> variable, which is an integer +from 0 to 4. A typical use would be <code>make check c=dialyzer V=3</code>. +The value 4 is particular and shows expanded commands right +before they are executed.</p></div> +<div class="paragraph"><p>To run tests in parallel, use the <code>-j</code> option. It is generally +a good idea to also use the <code>-k</code> option to run all tests even +if one fails. For example: <code>make check -j 32 -k</code>.</p></div> +<div class="paragraph"><p>Some changes should be tested against all packages. Continue +reading for more details on testing them.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_packages">Packages</h2> +<div class="sectionbody"> +<div class="paragraph"><p>You can search existing packages using the <code>make search q=STRING</code> +command. This can be done both from an Erlang.mk project or +directly from the Erlang.mk repository.</p></div> +<div class="paragraph"><p>Packages can be added to the index using the <code>pkg_add.sh</code> script.</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>$ git clone https<span style="color: #990000">:</span>//github<span style="color: #990000">.</span>com<span style="color: #990000">/</span><span style="color: #009900">$YOURUSERNAME</span>/erlang<span style="color: #990000">.</span>mk +$ cd erlang<span style="color: #990000">.</span>mk +$ <span style="color: #990000">.</span>/pkg_add<span style="color: #990000">.</span>sh cowboy git https<span style="color: #990000">:</span>//github<span style="color: #990000">.</span>com/ninenines/cowboy <span style="color: #993399">1.0</span><span style="color: #990000">.</span><span style="color: #993399">0</span> + http<span style="color: #990000">:</span>//ninenines<span style="color: #990000">.</span>eu <span style="color: #FF0000">"Small, fast and modular HTTP server."</span> +$ git push origin master</tt></pre></div></div> +<div class="paragraph"><p>Before sending a pull request, you should test your package. +You can use the following command: <code>make check p=PACKAGE</code>, +where <code>PACKAGE</code> is the name of the package, for example +<code>cowboy</code>.</p></div> +<div class="paragraph"><p>To test all packages, the <code>make packages</code> command can be used. +This can take a long time. Some packages will fail with certain +versions of Erlang, or if a prerequisite is missing from your system. +You can of course speed things up using the <code>-j</code> and <code>-k</code> flags.</p></div> +<div class="paragraph"><p>After all packages have been tested, you can run the command +<code>make summary</code> to know what changed since the previous run.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_documentation">Documentation</h2> +<div class="sectionbody"> +<div class="paragraph"><p>The documentation is always right.</p></div> +<div class="paragraph"><p>If you think you have found a mistake in the documentation, +this is a bug. You can either open a ticket or send a pull +request.</p></div> +<div class="paragraph"><p>To make sure that the documentation changes work, install +the listed <a href="../asciidoc">Requirements</a> on your system and +run <code>make docs</code>.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_feature_requests">Feature requests</h2> +<div class="sectionbody"> +<div class="paragraph"><p>If you have an awesome idea or need something that Erlang.mk +doesn&#8217;t provide yet, open a ticket. Provide as much detail as +possible.</p></div> +<div class="paragraph"><p>If you have code, great! Open a pull request as previously +explained.</p></div> +<div class="paragraph"><p>If not, you can still improve your feature request by writing +the related documentation.</p></div> +</div> +</div> + + + + + Cowboy Function Reference + http://ninenines.eu/docs/en/cowboy/2.0/manual/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/cowboy/2.0/manual/ + <div class="ulist"><ul> +<li> +<p> +<a href="cowboy_app">cowboy(7)</a> +</p> +</li> +<li> +<p> +<a href="cowboy">cowboy(3)</a> +</p> +</li> +<li> +<p> +<a href="cowboy_handler">cowboy_handler(3)</a> +</p> +</li> +<li> +<p> +<a href="cowboy_loop">cowboy_loop(3)</a> +</p> +</li> +<li> +<p> +<a href="cowboy_middleware">cowboy_middleware(3)</a> +</p> +</li> +<li> +<p> +<a href="cowboy_protocol">cowboy_protocol(3)</a> +</p> +</li> +<li> +<p> +<a href="cowboy_req">cowboy_req(3)</a> +</p> +</li> +<li> +<p> +<a href="cowboy_rest">cowboy_rest(3)</a> +</p> +</li> +<li> +<p> +<a href="cowboy_router">cowboy_router(3)</a> +</p> +</li> +<li> +<p> +<a href="cowboy_static">cowboy_static(3)</a> +</p> +</li> +<li> +<p> +<a href="cowboy_sub_protocol">cowboy_sub_protocol(3)</a> +</p> +</li> +<li> +<p> +<a href="cowboy_websocket">cowboy_websocket(3)</a> +</p> +</li> +<li> +<p> +<a href="http_status_codes">HTTP status codes(7)</a> +</p> +</li> +</ul></div> + + + + + Cowboy User Guide + http://ninenines.eu/docs/en/cowboy/2.0/guide/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/cowboy/2.0/guide/ + <div class="sect1"> +<h2 id="_rationale">Rationale</h2> +<div class="sectionbody"> +<div class="ulist"><ul> +<li> +<p> +<a href="modern_web/">The modern Web</a> +</p> +</li> +<li> +<p> +<a href="erlang_web/">Erlang and the Web</a> +</p> +</li> +</ul></div> +</div> +</div> +<div class="sect1"> +<h2 id="_introduction">Introduction</h2> +<div class="sectionbody"> +<div class="ulist"><ul> +<li> +<p> +<a href="introduction/">Introduction</a> +</p> +</li> +<li> +<p> +<a href="getting_started/">Getting started</a> +</p> +</li> +<li> +<p> +<a href="overview/">Request overview</a> +</p> +</li> +<li> +<p> +<a href="erlang_beginners/">Erlang for beginners</a> +</p> +</li> +</ul></div> +</div> +</div> +<div class="sect1"> +<h2 id="_configuration">Configuration</h2> +<div class="sectionbody"> +<div class="ulist"><ul> +<li> +<p> +<a href="routing/">routing</a> +</p> +</li> +<li> +<p> +<a href="constraints/">Constraints</a> +</p> +</li> +<li> +<p> +<a href="static_files/">Static files</a> +</p> +</li> +</ul></div> +</div> +</div> +<div class="sect1"> +<h2 id="_request_and_response">Request and response</h2> +<div class="sectionbody"> +<div class="ulist"><ul> +<li> +<p> +<a href="handlers/">Handlers</a> +</p> +</li> +<li> +<p> +<a href="loop_handlers/">Loop handlers</a> +</p> +</li> +<li> +<p> +<a href="req/">The Req object</a> +</p> +</li> +<li> +<p> +<a href="req_body/">Reading the request body</a> +</p> +</li> +<li> +<p> +<a href="resp/">Sending a response</a> +</p> +</li> +<li> +<p> +<a href="cookies/">Using cookies</a> +</p> +</li> +<li> +<p> +<a href="multipart/">Multipart</a> +</p> +</li> +</ul></div> +</div> +</div> +<div class="sect1"> +<h2 id="_rest">REST</h2> +<div class="sectionbody"> +<div class="ulist"><ul> +<li> +<p> +<a href="rest_principles/">REST principles</a> +</p> +</li> +<li> +<p> +<a href="rest_handlers/">Handling REST requests</a> +</p> +</li> +<li> +<p> +<a href="rest_flowcharts/">REST flowcharts</a> +</p> +</li> +<li> +<p> +<a href="resource_design/">Designing a resource handler</a> +</p> +</li> +</ul></div> +</div> +</div> +<div class="sect1"> +<h2 id="_websocket">Websocket</h2> +<div class="sectionbody"> +<div class="ulist"><ul> +<li> +<p> +<a href="ws_protocol/">The Websocket protocol</a> +</p> +</li> +<li> +<p> +<a href="ws_handlers/">Handling Websocket connections</a> +</p> +</li> +</ul></div> +</div> +</div> +<div class="sect1"> +<h2 id="_internals">Internals</h2> +<div class="sectionbody"> +<div class="ulist"><ul> +<li> +<p> +<a href="architecture/">Architecture</a> +</p> +</li> +<li> +<p> +<a href="broken_clients/">Dealing with broken clients</a> +</p> +</li> +<li> +<p> +<a href="middlewares/">Middlewares</a> +</p> +</li> +<li> +<p> +<a href="sub_protocols/">Sub protocols</a> +</p> +</li> +<li> +<p> +<a href="hooks/">Hooks</a> +</p> +</li> +</ul></div> +</div> +</div> + + + + + Dealing with broken clients + http://ninenines.eu/docs/en/cowboy/2.0/guide/broken_clients/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/cowboy/2.0/guide/broken_clients/ + <div class="paragraph"><p>There exists a very large number of implementations for the +HTTP protocol. Most widely used clients, like browsers, +follow the standard quite well, but others may not. In +particular custom enterprise clients tend to be very badly +written.</p></div> +<div class="paragraph"><p>Cowboy tries to follow the standard as much as possible, +but is not trying to handle every possible special cases. +Instead Cowboy focuses on the cases reported in the wild, +on the public Web.</p></div> +<div class="paragraph"><p>That means clients that ignore the HTTP standard completely +may fail to understand Cowboy&#8217;s responses. There are of +course workarounds. This chapter aims to cover them.</p></div> +<div class="sect1"> +<h2 id="_lowercase_headers">Lowercase headers</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Cowboy converts all headers it receives to lowercase, and +similarly sends back headers all in lowercase. Some broken +HTTP clients have issues with that.</p></div> +<div class="paragraph"><p>A simple way to solve this is to create an <code>onresponse</code> hook +that will format the header names with the expected case.</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: #000000">capitalize_hook</span></span>(<span style="color: #009900">Status</span>, <span style="color: #009900">Headers</span>, <span style="color: #009900">Body</span>, <span style="color: #009900">Req</span>) <span style="color: #990000">-&gt;</span> + <span style="color: #009900">Headers2</span> <span style="color: #990000">=</span> [{<span style="font-weight: bold"><span style="color: #000000">cowboy_bstr:capitalize_token</span></span>(<span style="color: #009900">N</span>), <span style="color: #009900">V</span>} + || {<span style="color: #009900">N</span>, <span style="color: #009900">V</span>} <span style="color: #990000">&lt;-</span> <span style="color: #009900">Headers</span>], + <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #009900">Status</span>, <span style="color: #009900">Headers2</span>, <span style="color: #009900">Body</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div> +<div class="paragraph"><p>Note that HTTP/2 clients do not have that particular issue +because the specification explicitly says all headers are +lowercase, unlike HTTP which allows any case but treats +them as case insensitive.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_camel_case_headers">Camel-case headers</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Sometimes it is desirable to keep the actual case used by +clients, for example when acting as a proxy between two broken +implementations. There is no easy solution for this other than +forking the project and editing the <code>cowboy_protocol</code> file +directly.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_chunked_transfer_encoding">Chunked transfer-encoding</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Sometimes an HTTP client advertises itself as HTTP/1.1 but +does not support chunked transfer-encoding. This is invalid +behavior, as HTTP/1.1 clients are required to support it.</p></div> +<div class="paragraph"><p>A simple workaround exists in these cases. By changing the +Req object response state to <code>waiting_stream</code>, Cowboy will +understand that it must use the identity transfer-encoding +when replying, just like if it was an HTTP/1.0 client.</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">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:set</span></span>(<span style="color: #FF6600">resp_state</span>, <span style="color: #FF6600">waiting_stream</span>)<span style="color: #990000">.</span></tt></pre></div></div> +</div> +</div> + + + + + Designing a resource handler + http://ninenines.eu/docs/en/cowboy/2.0/guide/resource_design/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/cowboy/2.0/guide/resource_design/ + <div class="paragraph"><p>This chapter aims to provide you with a list of questions +you must answer in order to write a good resource handler. +It is meant to be usable as a step by step guide.</p></div> +<div class="sect1"> +<h2 id="_the_service">The service</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Can the service become unavailable, and when it does, can +we detect it? For example, database connectivity problems +may be detected early. We may also have planned outages +of all or parts of the system. Implement the +<code>service_available</code> callback.</p></div> +<div class="paragraph"><p>What HTTP methods does the service implement? Do we need +more than the standard OPTIONS, HEAD, GET, PUT, POST, +PATCH and DELETE? Are we not using one of those at all? +Implement the <code>known_methods</code> callback.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_type_of_resource_handler">Type of resource handler</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Am I writing a handler for a collection of resources, +or for a single resource?</p></div> +<div class="paragraph"><p>The semantics for each of these are quite different. +You should not mix collection and single resource in +the same handler.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_collection_handler">Collection handler</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Skip this section if you are not doing a collection.</p></div> +<div class="paragraph"><p>Is the collection hardcoded or dynamic? For example, +if you use the route <code>/users</code> for the collection of +users then the collection is hardcoded; if you use +<code>/forums/:category</code> for the collection of threads +then it isn&#8217;t. When the collection is hardcoded you +can safely assume the resource always exists.</p></div> +<div class="paragraph"><p>What methods should I implement?</p></div> +<div class="paragraph"><p>OPTIONS is used to get some information about the +collection. It is recommended to allow it even if you +do not implement it, as Cowboy has a default +implementation built-in.</p></div> +<div class="paragraph"><p>HEAD and GET are used to retrieve the collection. +If you allow GET, also allow HEAD as there&#8217;s no extra +work required to make it work.</p></div> +<div class="paragraph"><p>POST is used to create a new resource inside the +collection. Creating a resource by using POST on +the collection is useful when resources may be +created before knowing their URI, usually because +parts of it are generated dynamically. A common +case is some kind of auto incremented integer +identifier.</p></div> +<div class="paragraph"><p>The next methods are more rarely allowed.</p></div> +<div class="paragraph"><p>PUT is used to create a new collection (when +the collection isn&#8217;t hardcoded), or replace +the entire collection.</p></div> +<div class="paragraph"><p>DELETE is used to delete the entire collection.</p></div> +<div class="paragraph"><p>PATCH is used to modify the collection using +instructions given in the request body. A PATCH +operation is atomic. The PATCH operation may +be used for such things as reordering; adding, +modifying or deleting parts of the collection.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_single_resource_handler">Single resource handler</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Skip this section if you are doing a collection.</p></div> +<div class="paragraph"><p>What methods should I implement?</p></div> +<div class="paragraph"><p>OPTIONS is used to get some information about the +resource. It is recommended to allow it even if you +do not implement it, as Cowboy has a default +implementation built-in.</p></div> +<div class="paragraph"><p>HEAD and GET are used to retrieve the resource. +If you allow GET, also allow HEAD as there&#8217;s no extra +work required to make it work.</p></div> +<div class="paragraph"><p>POST is used to update the resource.</p></div> +<div class="paragraph"><p>PUT is used to create a new resource (when it doesn&#8217;t +already exist) or replace the resource.</p></div> +<div class="paragraph"><p>DELETE is used to delete the resource.</p></div> +<div class="paragraph"><p>PATCH is used to modify the resource using +instructions given in the request body. A PATCH +operation is atomic. The PATCH operation may +be used for adding, removing or modifying specific +values in the resource.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_the_resource">The resource</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Following the above discussion, implement the +<code>allowed_methods</code> callback.</p></div> +<div class="paragraph"><p>Does the resource always exist? If it may not, implement +the <code>resource_exists</code> callback.</p></div> +<div class="paragraph"><p>Do I need to authenticate the client before they can +access the resource? What authentication mechanisms +should I provide? This may include form-based, token-based +(in the URL or a cookie), HTTP basic, HTTP digest, +SSL certificate or any other form of authentication. +Implement the <code>is_authorized</code> callback.</p></div> +<div class="paragraph"><p>Do I need fine-grained access control? How do I determine +that they are authorized access? Handle that in your +<code>is_authorized</code> callback.</p></div> +<div class="paragraph"><p>Can access to a resource be forbidden regardless of access +being authorized? A simple example of that is censorship +of a resource. Implement the <code>forbidden</code> callback.</p></div> +<div class="paragraph"><p>Are there any constraints on the length of the resource URI? +For example, the URI may be used as a key in storage and may +have a limit in length. Implement <code>uri_too_long</code>.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_representations">Representations</h2> +<div class="sectionbody"> +<div class="paragraph"><p>What media types do I provide? If text based, what charsets +are provided? What languages do I provide?</p></div> +<div class="paragraph"><p>Implement the mandatory <code>content_types_provided</code>. Prefix +the callbacks with <code>to_</code> for clarity. For example, <code>to_html</code> +or <code>to_text</code>.</p></div> +<div class="paragraph"><p>Implement the <code>languages_provided</code> or <code>charsets_provided</code> +callbacks if applicable.</p></div> +<div class="paragraph"><p>Is there any other header that may make the representation +of the resource vary? Implement the <code>variances</code> callback.</p></div> +<div class="paragraph"><p>Depending on your choices for caching content, you may +want to implement one or more of the <code>generate_etag</code>, +<code>last_modified</code> and <code>expires</code> callbacks.</p></div> +<div class="paragraph"><p>Do I want the user or user agent to actively choose a +representation available? Send a list of available +representations in the response body and implement +the <code>multiple_choices</code> callback.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_redirections">Redirections</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Do I need to keep track of what resources were deleted? +For example, you may have a mechanism where moving a +resource leaves a redirect link to its new location. +Implement the <code>previously_existed</code> callback.</p></div> +<div class="paragraph"><p>Was the resource moved, and is the move temporary? If +it is explicitly temporary, for example due to maintenance, +implement the <code>moved_temporarily</code> callback. Otherwise, +implement the <code>moved_permanently</code> callback.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_the_request">The request</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Do we need to perform extra checks to make sure the request +is valid? Cowboy will do many checks when receiving the +request already, do we need more? Note that this only +applies to the request-line and headers of the request, +and not the body. Implement <code>malformed_request</code>.</p></div> +<div class="paragraph"><p>May there be a request body? Will I know its size? +What&#8217;s the maximum size of the request body I&#8217;m willing +to accept? Implement <code>valid_entity_length</code>.</p></div> +<div class="paragraph"><p>Finally, take a look at the sections corresponding to the +methods you are implementing.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_options_method">OPTIONS method</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Cowboy by default will send back a list of allowed methods. +Do I need to add more information to the response? Implement +the <code>options</code> method.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_get_and_head_methods">GET and HEAD methods</h2> +<div class="sectionbody"> +<div class="paragraph"><p>If you implement the methods GET and/or HEAD, you must +implement one <code>ProvideResource</code> callback for each +content-type returned by the <code>content_types_provided</code> +callback.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_put_post_and_patch_methods">PUT, POST and PATCH methods</h2> +<div class="sectionbody"> +<div class="paragraph"><p>If you implement the methods PUT, POST and/or PATCH, +you must implement the <code>content_types_accepted</code> callback, +and one <code>AcceptResource</code> callback for each content-type +it returns. Prefix the <code>AcceptResource</code> callback names +with <code>from_</code> for clarity. For example, <code>from_html</code> or +<code>from_json</code>.</p></div> +<div class="paragraph"><p>Do we want to allow the POST method to create individual +resources directly through their URI (like PUT)? Implement +the <code>allow_missing_post</code> callback. It is recommended to +explicitly use PUT in these cases instead.</p></div> +<div class="paragraph"><p>May there be conflicts when using PUT to create or replace +a resource? Do we want to make sure that two updates around +the same time are not cancelling one another? Implement the +<code>is_conflict</code> callback.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_delete_methods">DELETE methods</h2> +<div class="sectionbody"> +<div class="paragraph"><p>If you implement the method DELETE, you must implement +the <code>delete_resource</code> callback.</p></div> +<div class="paragraph"><p>When <code>delete_resource</code> returns, is the resource completely +removed from the server, including from any caching service? +If not, and/or if the deletion is asynchronous and we have +no way of knowing it has been completed yet, implement the +<code>delete_completed</code> callback.</p></div> +</div> +</div> + + + + + Dialyzer + http://ninenines.eu/docs/en/erlang.mk/1/guide/dialyzer/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://ninenines.eu/docs/en/erlang.mk/1/guide/dialyzer/ + <div class="paragraph"><p>Dialyzer is a tool that will detect discrepancies in your +program. It does so using a technique known as success +typing analysis which has the advantage of providing no +false positives. Dialyzer is able to detect type errors, +dead code and more.</p></div> +<div class="paragraph"><p>Erlang.mk provides a wrapper around Dialyzer.</p></div> +<div class="sect1"> +<h2 id="_how_it_works">How it works</h2> +<div class="sectionbody"> +<div class="paragraph"><p>Dialyzer requires a PLT file to work. The PLT file contains +the analysis information from all applications which are not +expected to change, or rarely do. These would be all the +dependencies of the application or applications you are +currently working on, including standard applications in +Erlang/OTP itself.</p></div> +<div class="paragraph"><p>Dialyzer can generate this PLT file. Erlang.mk includes rules +to automatically generate the PLT file when it is missing.</p></div> +<div class="paragraph"><p>Once the PLT file is generated, Dialyzer can perform the +analysis in record time.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_configuration">Configuration</h2> +<div class="sectionbody"> +<div class="paragraph"><p>In a typical usage scenario, no variable needs to be set. +The defaults should be enough. Do note however that the +dependencies need to be set properly using the <code>DEPS</code> and +<code>LOCAL_DEPS</code> variables.</p></div> +<div class="paragraph"><p>The <code>DIALYZER_PLT</code> file indicates where the PLT file will +be written to (and read from). By default this is +<em>$(PROJECT).plt</em> in the project&#8217;s directory. Note that +the <code>DIALYZER_PLT</code> variable is exported and is understood +by Dialyzer directly.</p></div> +<div class="paragraph"><p>The <code>PLT_APPS</code> variable can be used to add additional +applications to the PLT. You can either list application +names or paths to these applications.</p></div> +<div class="paragraph"><p>Erlang.mk defines two variables for specifying options +for the analysis: <code>DIALYZER_DIRS</code> and <code>DIALYZER_OPTS</code>. +The former one defines which directories should be part +of the analysis. The latter defines what extra warnings +Dialyzer should report.</p></div> +<div class="paragraph"><p>Note that Erlang.mk enables the race condition warnings +by default. As it can take considerably large resources +to run, you may want to disable it on larger projects.</p></div> +</div> +</div> +<div class="sect1"> +<h2 id="_usage">Usage</h2> +<div class="sectionbody"> +<div class="paragraph"><p>To perform an analysis, run the following command:</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>$ make dialyze</tt></pre></div></div> +<div class="paragraph"><p>This will create the PLT file if it doesn&#8217;t exist.</p></div> +<div class="paragraph"><p>The analysis will also be performed when you run the +following command, alongside tests:</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>$ make check</tt></pre></div></div> +<div class="paragraph"><p>You can use the <code>plt</code> target to create the PLT file if +it doesn&#8217;t exist. This is normally not necessary as +Dialyzer creates it automatically.</p></div> +<div class="paragraph"><p>The PLT file will be removed when you run <code>make distclean</code>.</p></div> +</div> +</div> + + + + + \ No newline at end of file -- cgit v1.2.3