summaryrefslogtreecommitdiffstats
path: root/docs/en/cowboy/1.0/guide/broken_clients/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/en/cowboy/1.0/guide/broken_clients/index.html')
-rw-r--r--docs/en/cowboy/1.0/guide/broken_clients/index.html212
1 files changed, 212 insertions, 0 deletions
diff --git a/docs/en/cowboy/1.0/guide/broken_clients/index.html b/docs/en/cowboy/1.0/guide/broken_clients/index.html
new file mode 100644
index 00000000..d0046439
--- /dev/null
+++ b/docs/en/cowboy/1.0/guide/broken_clients/index.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Nine Nines Support: Cowboy User Guide</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <!-- Change them or set them up as you like -->
+ <meta name="description" content="">
+ <meta name="author" content="(Soft10) Pol Cámara">
+
+ <!-- Stylesheets -->
+ <link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic' rel='stylesheet' type='text/css'>
+ <link href="/css/bootstrap.min.css" rel="stylesheet">
+ <link href="/css/99s.css" rel="stylesheet">
+<!-- <link href="js/google-code-prettify/prettify.css" rel="stylesheet"> -->
+ <link href="/css/sh99s.css" rel="stylesheet"/>
+
+ <!-- Enables html5 support on older browsers, other js is placed at the end of the page to speed up loading -->
+ <!--[if lt IE 9]>
+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+
+ <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">
+ <link rel="alternate" href="/feeds/atom.xml" type="application/atom+xml" title="Nine Nines Atom Feed">
+ </head>
+
+ <body class="big_text docs">
+ <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">
+ <!-- Top navigation and social icons-->
+ <div id="side-header">
+ <nav>
+ <ul>
+ <li><a title="Erlang training" href="/training">Training</a></li>
+ <li><a title="Technical publications" href="/articles">Articles</a></li>
+ <li><a title="Our talks" href="/talks">Talks</a></li>
+ <li class="active"><a title="Our services" href="/support">Pricing &amp; Sponsoring</a></li>
+ <li><a title="Community support" href="http://lists.ninenines.eu">Mailing Lists</a></li>
+ <li><a title="Contact us" href="mailto:[email protected]">Contact</a></li>
+ </ul>
+ </nav>
+ <ul id="social">
+ <li>
+ <a href="https://github.com/ninenines" title="Check our Github repositories"><img src="/img/ico_github.png" data-hover="/img/ico_github_alt.png" alt="Github"></a>
+ </li>
+ <li class="dropdown" id="twitter-links">
+ <a href="#twitter-links" class="dropdown-toggle" data-toggle="dropdown" title="Follow us on Twitter">
+ <img src="/img/ico_twitter.png" data-hover="/img/ico_twitter_alt.png" alt="Twitter">
+ </a>
+ <ul class="dropdown-menu">
+ <li><a title="Visit Loïc Hoguin's Twitter Account" href="http://twitter.com/lhoguin">@lhoguin</a></li>
+ <!-- <li class="divider"></li>
+ <li><a title="Visit our official Twitter account" href="#">@99s</a></li> -->
+ </ul>
+ </li>
+ <!-- <li>
+ <a href="/css/" title="Add us on Linkedin"><img src="/img/ico_linkedin.png" data-hover="img/ico_linkedin_alt.png" alt="Linkedin"></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>Dealing with broken clients</span></h1>
+
+<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>
+
+<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>
+
+<p>That means clients that ignore the HTTP standard completely may fail to understand Cowboy's responses. There are of course workarounds. This chapter aims to cover them.</p>
+
+<h2 id="lowercase_headers">Lowercase headers</h2>
+
+<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>
+
+<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>
+
+<script type="syntaxhighlighter" class="brush: erlang"><![CDATA[
+capitalize_hook(Status, Headers, Body, Req) ->
+ Headers2 = [{cowboy_bstr:capitalize_token(N), V}
+ || {N, V} <- Headers],
+ {ok, Req2} = cowboy_req:reply(Status, Headers2, Body, Req),
+ Req2.
+]]></script>
+
+<p>Note that SPDY 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>
+
+<h2 id="camel-case_headers">Camel-case headers</h2>
+
+<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>
+
+<h2 id="chunked_transfer-encoding">Chunked transfer-encoding</h2>
+
+<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>
+
+<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>
+
+<script type="syntaxhighlighter" class="brush: erlang"><![CDATA[
+Req2 = cowboy_req:set(resp_state, waiting_stream).
+]]></script>
+
+
+<!-- a.code -->
+</div>
+
+<div class="span3 sidecol">
+<div class="input-append">
+<form id="form-search" class="form-search" action="#">
+ <input id="input-search" type="text" placeholder="Function search" autocomplete="off" autofocus class="input-medium search-query span2">
+ <button type="submit" class="btn btn-success">Go</button>
+</form>
+</div>
+
+<h3 id="docs-nav">Navigation</h3>
+
+<h3>See also</h3><ul><li><a href="/docs/en/cowboy/1.0/manual/">Function Reference</a></li><li><a href="/docs/en/cowboy/1.0/index.html">README</a></li></ul>
+
+<h3>Version select</h3>
+<ul>
+
+ <li><a href="/docs/en/cowboy/1.0/guide/"><strong>1.0</strong></a></li>
+
+ <li><a href="/docs/en/cowboy/HEAD/guide/"><strong>HEAD</strong></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 &copy; Nine Nines 2012-2014</p>
+ </div>
+ </div>
+ </div>
+ </footer>
+
+ <!-- Javascript -->
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
+ <script src="/js/bootstrap-carousel.js"></script>
+ <script src="/js/bootstrap-dropdown.js"></script>
+ <script src="/js/custom.js"></script>
+
+
+<script type="text/javascript" src="/js/shCore.js"></script>
+<script type="text/javascript" src="/js/shlang/shBrushBash.js"></script>
+<script type="text/javascript" src="/js/shlang/shBrushErlang.js"></script>
+<script type="text/javascript" src="/js/shlang/shBrushJScript.js"></script>
+<script type="text/javascript" src="/js/shlang/shBrushPlain.js"></script>
+<script type="text/javascript">SyntaxHighlighter.all();</script>
+
+<script type="text/javascript" src="/js/fuse.min.js"></script>
+<script type="text/javascript">
+$(document).ready(function(){
+ var f;
+
+ $.getJSON("/docs/db.json", function(data){
+ f = new Fuse(data, {keys: ["n"], threshold: 0.3});
+ $("<ul id=\"search-results\">").insertAfter("#form-search");
+ });
+
+ $("#input-search").keyup(function(e){if(f){if (e.which != 13 ){
+ var results = f.search($(this).val());
+ if (results.length == 0){
+ $("#form-search").attr("action", "#");
+ }else{
+ $("#form-search").attr("action", results[0].l);
+ }
+
+ $("#search-results").empty();
+ for (var i = 0; i < 10 && i < results.length; i++){
+ $("<li><a href=\"" + results[i].l + "\">" + results[i].n + "</a></li>")
+ .appendTo("#search-results");
+ }
+ }}});
+});
+</script>
+
+ </body>
+</html>