<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="Loïc Hoguin based on a design from (Soft10) Pol Cámara">
<meta name="generator" content="Hugo 0.17" />
<title>Nine Nines: Migrating from Cowboy 1.0 to 2.0</title>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic' rel='stylesheet' type='text/css'>
<link href="/css/99s.css?r=1" rel="stylesheet">
<link rel="shortcut icon" href="/img/ico/favicon.ico">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/img/ico/apple-touch-icon-114.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/img/ico/apple-touch-icon-72.png">
<link rel="apple-touch-icon-precomposed" href="/img/ico/apple-touch-icon-57.png">
</head>
<body class="">
<header id="page-head">
<div id="topbar" class="container">
<div class="row">
<div class="span2">
<h1 id="logo"><a href="/" title="99s">99s</a></h1>
</div>
<div class="span10">
<div id="side-header">
<nav>
<ul>
<li><a title="Hear my thoughts" href="/articles">Articles</a></li>
<li><a title="Watch my talks" href="/talks">Talks</a></li>
<li class="active"><a title="Read the docs" href="/docs">Documentation</a></li>
<li><a title="Request my services" href="/services">Consulting & Training</a></li>
</ul>
</nav>
<ul id="social">
<li>
<a href="https://github.com/ninenines" title="Check my Github repositories"><img src="/img/ico_github.png" data-hover="/img/ico_github_alt.png" alt="Github"></a>
</li>
<li>
<a title="Keep in touch!" href="http://twitter.com/lhoguin"><img src="/img/ico_microblog.png" data-hover="/img/ico_microblog_alt.png"></a>
</li>
<li>
<a title="Contact me" href="mailto:[email protected]"><img src="/img/ico_mail.png" data-hover="/img/ico_mail_alt.png"></a>
</li>
</ul>
</div>
</div>
</div>
</div>
</header>
<div id="contents" class="two_col">
<div class="container">
<div class="row">
<div id="docs" class="span9 maincol">
<h1 class="lined-header"><span>Migrating from Cowboy 1.0 to 2.0</span></h1>
<div class="paragraph"><p>A lot has changed between Cowboy 1.0 and 2.0. The <code>cowboy_req</code>
interface in particular has seen a massive revamp. Hooks are
gone, their functionality can now be achieved via stream
handlers.</p></div>
<div class="paragraph"><p>The documentation has seen great work, in particular the
manual. Each module and each function now has its own dedicated
manual page with full details and examples.</p></div>
<div class="sect1">
<h2 id="_compatibility">Compatibility</h2>
<div class="sectionbody">
<div class="paragraph"><p>Compatibility with Erlang/OTP R16, 17 and 18 has been dropped.
Erlang/OTP 19.0 or above is required. It is non-trivial to
make Cowboy 2.0 work with older Erlang/OTP versions.</p></div>
<div class="paragraph"><p>Cowboy 2.0 is not compatible with Cowlib versions older than
2.0. It should be compatible with Ranch 1.0 or above, however
it has not been tested with Ranch versions older than 1.4.</p></div>
<div class="paragraph"><p>Cowboy 2.0 is tested on Arch Linux, Ubuntu, FreeBSD, Windows
and OSX. It is tested with every point release (latest patch
release) and also with HiPE on the most recent release.</p></div>
<div class="paragraph"><p>Cowboy 2.0 now comes with Erlang.mk templates.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_features_added">Features added</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
The HTTP/2 protocol is now supported.
</p>
</li>
<li>
<p>
Cowboy no longer uses only one process per connection.
It now uses one process per connection plus one process
per request by default. This is necessary for HTTP/2.
There might be a slight drop in performance for HTTP/1.1
connections due to this change.
</p>
</li>
<li>
<p>
Cowboy internals have largely been reworked in order to
support HTTP/2. This opened the way to stream handlers,
which are a chain of modules that are called whenever
something happens relating to a request/response.
</p>
</li>
<li>
<p>
The <code>cowboy_stream_h</code> stream handler has been added.
It provides most of Cowboy’s default behavior.
</p>
</li>
<li>
<p>
The <code>cowboy_compress_h</code> stream handler has been added.
It compresses responses when possible. It’s worth noting
that it compresses in more cases than Cowboy 1.0 ever did.
</p>
</li>
<li>
<p>
Because of the many changes in the internals of Cowboy,
many options have been added or modified. Of note is that
the Websocket options are now given per handler rather
than for the entire listener.
</p>
</li>
<li>
<p>
Websocket permessage-deflate compression is now supported
via the <code>websocket_compress</code> option.
</p>
</li>
<li>
<p>
Static file handlers will now correctly find files found
in <em>.ez</em> archives.
</p>
</li>
<li>
<p>
Constraints have been generalized and are now used not only
in the router but also in some <code>cowboy_req</code> functions. Their
interface has also been modified to allow for reverse
operations and formatting of errors.
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_features_removed">Features removed</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
SPDY support has been removed. Use HTTP/2 instead.
</p>
</li>
<li>
<p>
Hooks have been removed. Use <a href="../streams">stream handlers</a> instead.
</p>
</li>
<li>
<p>
The undocumented <code>waiting_stream</code> hack has been removed.
It allowed disabling chunked transfer-encoding for HTTP/1.1.
It has no equivalent in Cowboy 2.0. Open a ticket if necessary.
</p>
</li>
<li>
<p>
Sub protocols still exist, but their interface has largely changed
and they are no longer documented for the time being.
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_changed_behaviors">Changed behaviors</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
The handler behaviors have been renamed and are now <code>cowboy_handler</code>,
<code>cowboy_loop</code>, <code>cowboy_rest</code> and <code>cowboy_websocket</code>.
</p>
</li>
<li>
<p>
Plain HTTP, loop, REST and Websocket handlers have had their
init and terminate callbacks unified. They now all use the
<code>init/2</code> and <code>terminate/3</code> callbacks. The latter is now optional.
The terminate reason has now been documented for all handlers.
</p>
</li>
<li>
<p>
The tuple returned to switch to a different handler type has
changed. It now takes the form <code>{Module, Req, State}</code> or
<code>{Module, Req, State, Opts}</code>, where <code>Opts</code> is a map of options
to configure the handler. The timeout and hibernate options
must now be specified using this map, where applicable.
</p>
</li>
<li>
<p>
All behaviors that used to accept <code>halt</code> or <code>shutdown</code> tuples
as a return value no longer do so. The return value is now
a <code>stop</code> tuple, consistent across Cowboy.
</p>
</li>
<li>
<p>
Middlewares can no longer return an <code>error</code> tuple. They have
to send the response and return a <code>stop</code> tuple instead.
</p>
</li>
<li>
<p>
The <code>known_content_type</code> REST handler callback has been removed
as it was found unnecessary.
</p>
</li>
<li>
<p>
Websocket handlers have both the normal <code>init/2</code> and
an optional <code>websocket_init/1</code> function. The reason for
that exception is that the <code>websocket_*</code> callbacks execute
in a separate process from the <code>init/2</code> callback, and it
was therefore not obvious how timers or monitors should
be setup properly. They are effectively initializing the
handler before and after the HTTP/1.1 upgrade.
</p>
</li>
<li>
<p>
Websocket handlers can now send frames directly from
<code>websocket_init/1</code>. The frames will be sent immediately
after the handshake.
</p>
</li>
<li>
<p>
Websocket handler callbacks no longer receive the Req
argument. The <code>init/2</code> callback still receives it and
can be used to extract relevant information. The <code>terminate/3</code>
callback, if implemented, may still receive the Req
(see next bullet point).
</p>
</li>
<li>
<p>
Websocket handlers have a new <code>req_filter</code> option that
can be used to customize how much information should be
discarded from the Req object after the handshake. Note
that the Req object is only available in <code>terminate/3</code>
past that point.
</p>
</li>
<li>
<p>
Websocket handlers have their timeout default changed
from infinity to 60 seconds.
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_new_functions">New functions</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
The <code>cowboy_req:scheme/1</code> function has been added.
</p>
</li>
<li>
<p>
The <code>cowboy_req:uri/1,2</code> function has been added, replacing the
less powerful functions <code>cowboy_req:url/1</code> and <code>cowboy_req:host_url/1</code>.
</p>
</li>
<li>
<p>
The functions <code>cowboy_req:match_qs/2</code> and <code>cowboy_req:match_cookies/2</code>
allow matching query string and cookies against constraints.
</p>
</li>
<li>
<p>
The function <code>cowboy_req:set_resp_cookie/3</code> has been added to
complement <code>cowboy_req:set_resp_cookie/4</code>.
</p>
</li>
<li>
<p>
The functions <code>cowboy_req:resp_header/2,3</code> and <code>cowboy_req:resp_headers/1</code>
have been added. They can be used to retrieve response headers
that were previously set.
</p>
</li>
<li>
<p>
The function <code>cowboy_req:set_resp_headers/2</code> has been added. It
allows setting many response headers at once.
</p>
</li>
<li>
<p>
The functions <code>cowboy_req:push/3,4</code> can be used to push resources
for protocols that support it (by default only HTTP/2).
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_changed_functions">Changed functions</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
The <code>cowboy:start_http/4</code> function was renamed to <code>cowboy:start_clear/3</code>.
</p>
</li>
<li>
<p>
The <code>cowboy:start_https/4</code> function was renamed to <code>cowboy:start_tls/3</code>.
</p>
</li>
<li>
<p>
Most, if not all, functions in the <code>cowboy_req</code> module have been modified.
Please consult the changelog of each individual functions. The changes
are mainly about simplifying and clarifying the interface. The Req is no
longer returned when not necessary, maps are used wherever possible,
and some functions have been renamed.
</p>
</li>
<li>
<p>
The position of the <code>Opts</code> argument for <code>cowboy_req:set_resp_cookie/4</code>
has changed to improve consistency. It is now the last argument.
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_removed_functions">Removed functions</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
The functions <code>cowboy_req:url/1</code> and <code>cowboy_req:host_url/1</code> have been
removed in favor of the new function <code>cowboy_req:uri/1,2</code>.
</p>
</li>
<li>
<p>
The functions <code>cowboy_req:meta/2,3</code> and <code>cowboy_req:set_meta/3</code> have
been removed. The Req object is now a public map, therefore they became
unnecessary.
</p>
</li>
<li>
<p>
The functions <code>cowboy_req:set_resp_body_fun/2,3</code> have been removed.
For sending files, the function <code>cowboy_req:set_resp_body/2</code> can now
take a sendfile tuple.
</p>
</li>
<li>
<p>
Remove many undocumented functions from <code>cowboy_req</code>, including the
functions <code>cowboy_req:get/2</code> and <code>cowboy_req:set/3</code>.
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_other_changes">Other changes</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
The correct percent-decoding algorithm is now used for path elements
during routing. It will no longer decode <code>+</code> characters.
</p>
</li>
<li>
<p>
The router will now properly handle path segments <code>.</code> and <code>..</code>.
</p>
</li>
<li>
<p>
Routing behavior has changed for URIs containing latin1 characters.
They are no longer allowed. URIs are expected to be in UTF-8 once
they are percent-decoded.
</p>
</li>
<li>
<p>
Etag comparison in REST handlers has been fixed. Some requests may
now fail when they succeeded in the past.
</p>
</li>
<li>
<p>
The <code>If-*-Since</code> headers are now ignored in REST handlers if
the corresponding <code>If*-Match</code> header exist. The former is
largely a backward compatible header and this shouldn’t create
any issue. The new behavior follows the current RFCs more closely.
</p>
</li>
<li>
<p>
The static file handler has been improved to handle more special
characters on systems that accept them.
</p>
</li>
</ul></div>
</div>
</div>
<nav style="margin:1em 0">
<a style="float:left" href="https://ninenines.eu/docs/en/cowboy/2.0/guide/sub_protocols/">
Sub protocols
</a>
<a style="float:right" href="https://ninenines.eu/docs/en/cowboy/2.0/guide/specs/">
HTTP and other specifications
</a>
</nav>
</div>
<div class="span3 sidecol">
<h3>
Cowboy
2.0
User Guide
</h3>
<ul>
<li><a href="/docs/en/cowboy/2.0/guide">User Guide</a></li>
<li><a href="/docs/en/cowboy/2.0/manual">Function Reference</a></li>
</ul>
<h4 id="docs-nav">Navigation</h4>
<h4>Version select</h4>
<ul>
<li><a href="/docs/en/cowboy/2.0/guide">2.0</a></li>
<li><a href="/docs/en/cowboy/1.0/guide">1.0</a></li>
</ul>
</div>
</div>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="span6">
<p id="scroll-top"><a href="#">↑ Scroll to top</a></p>
<nav>
<ul>
<li><a href="mailto:[email protected]" title="Contact us">Contact us</a></li><li><a href="https://github.com/ninenines/ninenines.github.io" title="Github repository">Contribute to this site</a></li>
</ul>
</nav>
</div>
<div class="span6 credits">
<p><img src="/img/footer_logo.png"></p>
<p>Copyright © Loïc Hoguin 2012-2016</p>
</div>
</div>
</div>
</footer>
<script src="/js/custom.js"></script>
</body>
</html>