You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by wi...@apache.org on 2020/01/10 08:12:57 UTC

[couchdb-mochiweb] branch upstream-2.20.0 created (now cedc22f)

This is an automated email from the ASF dual-hosted git repository.

willholley pushed a change to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git.


      at cedc22f  Merge pull request #226 from mochi/otp-22

This branch includes the following new commits:

     new 985fa8a  Add missing issue URL to CHANGES.md
     new 458eedf  fix cookie value parsing
     new 9a1b109  Use more direct translation of RFC 6265 grammar
     new 7884405  Merge pull request #213 from mochi/lego12239-master
     new 83fdebc  Remove compile(tuple_calls) from mochifmt
     new 2ab10af  Remove compile(tuple_calls) from mochiweb_acceptor
     new dc74151  Remove compile(tuple_calls) from mochiweb_http
     new 6f9452c  Remove compile(tuple_calls) from mochiweb_multipart
     new c3e45be  Remove compile(tuple_calls) from mochiweb_request
     new 763fa52  Remove compile(tuple_calls) from mochiweb_response
     new 5ae2f0a  Remove compile(tuple_calls) from mochiweb_websocket
     new ef4f886  Remove compile(tuple_calls) from the template
     new 1c73aaf  Remove compile(tuple_calls) from examples/hmac_api
     new b6b3ff1  Remove compile(tuple_calls) from examples/https_store
     new 58699cb  Remove compile(tuple_calls) from examples/keepalive
     new 1092472  Remove compile(tuple_calls) from test/mochiweb_http_tests
     new 2cae813  Remove compile(tuple_calls) from test/mochiweb_websocket_tests
     new 1054298  Remove compile(tuple_calls) from test/mochiweb_tests
     new 8892431  Remove compile(tuple_calls) from test/mochiweb_request_tests
     new 69d6df7  Run erl_tidy on modified source files
     new 2cb3104  Merge pull request #215 from mochi/remove-tuple-calls
     new 05d3ceb  Update README.md
     new 9f024df  Update README.md
     new 2b4b272  Debug Travis, it seems like older releases are not working
     new d12ac64  Use a matrix to get an older dist for old releases
     new ec98873  Merge pull request #221 from mochi/fix-travis-build
     new c692fd7  Use https for URLs in README.md
     new ad11980  Merge pull request #220 from penhs/master
     new fc8de2b  add support for SameSite=none in cookies
     new c5e7b83  Merge pull request #225 from djnym/support-samesite-none
     new 0c68ac4  Update CHANGES and add OTP 21.3, 22 to travis matrix
     new cedc22f  Merge pull request #226 from mochi/otp-22

The 32 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[couchdb-mochiweb] 29/32: add support for SameSite=none in cookies

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit fc8de2ba2b313bfbf85c1ec59ecde1ab155922d0
Author: Anthony Molinaro <an...@openx.com>
AuthorDate: Fri Jul 12 22:00:34 2019 +0000

    add support for SameSite=none in cookies
---
 src/mochiweb_cookies.erl | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/mochiweb_cookies.erl b/src/mochiweb_cookies.erl
index c7b0fcf..dd28610 100644
--- a/src/mochiweb_cookies.erl
+++ b/src/mochiweb_cookies.erl
@@ -65,7 +65,7 @@ cookie(Key, Value) ->
 %% where Option = {max_age, int_seconds()} | {local_time, {date(), time()}}
 %%                | {domain, string()} | {path, string()}
 %%                | {secure, true | false} | {http_only, true | false}
-%%                | {same_site, lax | strict}
+%%                | {same_site, lax | strict | none}
 %%
 %% @doc Generate a Set-Cookie header field tuple.
 cookie(Key, Value, Options) ->
@@ -130,7 +130,9 @@ cookie(Key, Value, Options) ->
             lax ->
                 "; SameSite=Lax";
             strict ->
-                "; SameSite=Strict"
+                "; SameSite=Strict";
+            none ->
+                "; SameSite=None"
         end,
     CookieParts = [Cookie, ExpiresPart, SecurePart, DomainPart, PathPart,
         HttpOnlyPart, SameSitePart],
@@ -378,6 +380,18 @@ cookie_test() ->
           "Max-Age=86417"},
     C3 = cookie("Customer", "WILE_E_COYOTE",
                 [{max_age, 86417}, {local_time, LocalTime}]),
+
+    % test various values for SameSite
+    %
+    % unset default to nothing
+    C4 = {"Set-Cookie","i=test123; Version=1"},
+    C4 = cookie("i", "test123", []),
+    C5 = {"Set-Cookie","i=test123; Version=1; SameSite=Strict"},
+    C5 = cookie("i", "test123", [ {same_site, strict}]),
+    C6 = {"Set-Cookie","i=test123; Version=1; SameSite=Lax"},
+    C6 = cookie("i", "test123", [ {same_site, lax}]),
+    C7 = {"Set-Cookie","i=test123; Version=1; SameSite=None"},
+    C7 = cookie("i", "test123", [ {same_site, none}]),
     ok.
 
 -endif.


[couchdb-mochiweb] 09/32: Remove compile(tuple_calls) from mochiweb_request

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit c3e45be3a746bb4e790eb1318532f8db8f374939
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Sat Mar 9 20:50:54 2019 +0000

    Remove compile(tuple_calls) from mochiweb_request
---
 src/mochiweb_request.erl | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/mochiweb_request.erl b/src/mochiweb_request.erl
index 240f043..3889d33 100644
--- a/src/mochiweb_request.erl
+++ b/src/mochiweb_request.erl
@@ -24,8 +24,6 @@
 -module(mochiweb_request).
 -author('bob@mochimedia.com').
 
--compile(tuple_calls).
-
 -include_lib("kernel/include/file.hrl").
 -include("internal.hrl").
 
@@ -428,7 +426,7 @@ ok({ContentType, Body}, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version,
     ok({ContentType, [], Body}, THIS);
 ok({ContentType, ResponseHeaders, Body}, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
     HResponse = mochiweb_headers:make(ResponseHeaders),
-    case THIS:get(range) of
+    case get(range, THIS) of
         X when (X =:= undefined orelse X =:= fail) orelse Body =:= chunked ->
             %% http://code.google.com/p/mochiweb/issues/detail?id=54
             %% Range header not supported when chunked, return 200 and provide


[couchdb-mochiweb] 19/32: Remove compile(tuple_calls) from test/mochiweb_request_tests

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 8892431f25516820400e76821b9c4d7d182e070d
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Tue Mar 12 01:41:45 2019 +0000

    Remove compile(tuple_calls) from test/mochiweb_request_tests
---
 test/mochiweb_request_tests.erl | 70 ++++++++++++++++++++---------------------
 1 file changed, 34 insertions(+), 36 deletions(-)

diff --git a/test/mochiweb_request_tests.erl b/test/mochiweb_request_tests.erl
index b8f93e2..47fe7ee 100644
--- a/test/mochiweb_request_tests.erl
+++ b/test/mochiweb_request_tests.erl
@@ -1,162 +1,160 @@
 -module(mochiweb_request_tests).
 
--compile(tuple_calls).
-
 -ifdef(TEST).
 -include_lib("eunit/include/eunit.hrl").
 
 accepts_content_type_test() ->
     Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "multipart/related"}])),
-    ?assertEqual(true, Req1:accepts_content_type("multipart/related")),
-    ?assertEqual(true, Req1:accepts_content_type(<<"multipart/related">>)),
+    ?assertEqual(true, mochiweb_request:accepts_content_type("multipart/related", Req1)),
+    ?assertEqual(true, mochiweb_request:accepts_content_type(<<"multipart/related">>, Req1)),
 
     Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html"}])),
-    ?assertEqual(false, Req2:accepts_content_type("multipart/related")),
+    ?assertEqual(false, mochiweb_request:accepts_content_type("multipart/related", Req2)),
 
     Req3 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html, multipart/*"}])),
-    ?assertEqual(true, Req3:accepts_content_type("multipart/related")),
+    ?assertEqual(true, mochiweb_request:accepts_content_type("multipart/related", Req3)),
 
     Req4 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html, multipart/*; q=0.0"}])),
-    ?assertEqual(false, Req4:accepts_content_type("multipart/related")),
+    ?assertEqual(false, mochiweb_request:accepts_content_type("multipart/related", Req4)),
 
     Req5 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html, multipart/*; q=0"}])),
-    ?assertEqual(false, Req5:accepts_content_type("multipart/related")),
+    ?assertEqual(false, mochiweb_request:accepts_content_type("multipart/related", Req5)),
 
     Req6 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html, */*; q=0.0"}])),
-    ?assertEqual(false, Req6:accepts_content_type("multipart/related")),
+    ?assertEqual(false, mochiweb_request:accepts_content_type("multipart/related", Req6)),
 
     Req7 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "multipart/*; q=0.0, */*"}])),
-    ?assertEqual(false, Req7:accepts_content_type("multipart/related")),
+    ?assertEqual(false, mochiweb_request:accepts_content_type("multipart/related", Req7)),
 
     Req8 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "*/*; q=0.0, multipart/*"}])),
-    ?assertEqual(true, Req8:accepts_content_type("multipart/related")),
+    ?assertEqual(true, mochiweb_request:accepts_content_type("multipart/related", Req8)),
 
     Req9 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "*/*; q=0.0, multipart/related"}])),
-    ?assertEqual(true, Req9:accepts_content_type("multipart/related")),
+    ?assertEqual(true, mochiweb_request:accepts_content_type("multipart/related", Req9)),
 
     Req10 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html; level=1"}])),
-    ?assertEqual(true, Req10:accepts_content_type("text/html;level=1")),
+    ?assertEqual(true, mochiweb_request:accepts_content_type("text/html;level=1", Req10)),
 
     Req11 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html; level=1, text/html"}])),
-    ?assertEqual(true, Req11:accepts_content_type("text/html")),
+    ?assertEqual(true, mochiweb_request:accepts_content_type("text/html", Req11)),
 
     Req12 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html; level=1; q=0.0, text/html"}])),
-    ?assertEqual(false, Req12:accepts_content_type("text/html;level=1")),
+    ?assertEqual(false, mochiweb_request:accepts_content_type("text/html;level=1", Req12)),
 
     Req13 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html; level=1; q=0.0, text/html"}])),
-    ?assertEqual(false, Req13:accepts_content_type("text/html; level=1")),
+    ?assertEqual(false, mochiweb_request:accepts_content_type("text/html; level=1", Req13)),
 
     Req14 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html;level=1;q=0.1, text/html"}])),
-    ?assertEqual(true, Req14:accepts_content_type("text/html; level=1")).
+    ?assertEqual(true, mochiweb_request:accepts_content_type("text/html; level=1", Req14)).
 
 accepted_encodings_test() ->
     Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
                                 mochiweb_headers:make([])),
     ?assertEqual(["identity"],
-                 Req1:accepted_encodings(["gzip", "identity"])),
+                 mochiweb_request:accepted_encodings(["gzip", "identity"], Req1)),
 
     Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept-Encoding", "gzip, deflate"}])),
     ?assertEqual(["gzip", "identity"],
-                 Req2:accepted_encodings(["gzip", "identity"])),
+                 mochiweb_request:accepted_encodings(["gzip", "identity"], Req2)),
 
     Req3 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept-Encoding", "gzip;q=0.5, deflate"}])),
     ?assertEqual(["deflate", "gzip", "identity"],
-                 Req3:accepted_encodings(["gzip", "deflate", "identity"])),
+                 mochiweb_request:accepted_encodings(["gzip", "deflate", "identity"], Req3)),
 
     Req4 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept-Encoding", "identity, *;q=0"}])),
     ?assertEqual(["identity"],
-                 Req4:accepted_encodings(["gzip", "deflate", "identity"])),
+                 mochiweb_request:accepted_encodings(["gzip", "deflate", "identity"], Req4)),
 
     Req5 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept-Encoding", "gzip; q=0.1, *;q=0"}])),
     ?assertEqual(["gzip"],
-                 Req5:accepted_encodings(["gzip", "deflate", "identity"])),
+                 mochiweb_request:accepted_encodings(["gzip", "deflate", "identity"], Req5)),
 
     Req6 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept-Encoding", "gzip; q=, *;q=0"}])),
     ?assertEqual(bad_accept_encoding_value,
-                 Req6:accepted_encodings(["gzip", "deflate", "identity"])),
+                 mochiweb_request:accepted_encodings(["gzip", "deflate", "identity"], Req6)),
 
     Req7 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept-Encoding", "gzip;q=2.0, *;q=0"}])),
     ?assertEqual(bad_accept_encoding_value,
-                 Req7:accepted_encodings(["gzip", "identity"])),
+                 mochiweb_request:accepted_encodings(["gzip", "identity"], Req7)),
 
     Req8 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept-Encoding", "deflate, *;q=0.0"}])),
     ?assertEqual([],
-                 Req8:accepted_encodings(["gzip", "identity"])).
+                 mochiweb_request:accepted_encodings(["gzip", "identity"], Req8)).
 
 accepted_content_types_test() ->
     Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html"}])),
     ?assertEqual(["text/html"],
-        Req1:accepted_content_types(["text/html", "application/json"])),
+        mochiweb_request:accepted_content_types(["text/html", "application/json"], Req1)),
 
     Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html, */*;q=0"}])),
     ?assertEqual(["text/html"],
-        Req2:accepted_content_types(["text/html", "application/json"])),
+        mochiweb_request:accepted_content_types(["text/html", "application/json"], Req2)),
 
     Req3 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/*, */*;q=0"}])),
     ?assertEqual(["text/html"],
-        Req3:accepted_content_types(["text/html", "application/json"])),
+        mochiweb_request:accepted_content_types(["text/html", "application/json"], Req3)),
 
     Req4 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/*;q=0.8, */*;q=0.5"}])),
     ?assertEqual(["text/html", "application/json"],
-        Req4:accepted_content_types(["application/json", "text/html"])),
+        mochiweb_request:accepted_content_types(["application/json", "text/html"], Req4)),
 
     Req5 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/*;q=0.8, */*;q=0.5"}])),
     ?assertEqual(["text/html", "application/json"],
-        Req5:accepted_content_types(["text/html", "application/json"])),
+        mochiweb_request:accepted_content_types(["text/html", "application/json"], Req5)),
 
     Req6 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/*;q=0.5, */*;q=0.5"}])),
     ?assertEqual(["application/json", "text/html"],
-        Req6:accepted_content_types(["application/json", "text/html"])),
+        mochiweb_request:accepted_content_types(["application/json", "text/html"], Req6)),
 
     Req7 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make(
             [{"Accept", "text/html;q=0.5, application/json;q=0.5"}])),
     ?assertEqual(["application/json", "text/html"],
-        Req7:accepted_content_types(["application/json", "text/html"])),
+        mochiweb_request:accepted_content_types(["application/json", "text/html"], Req7)),
 
     Req8 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/html"}])),
     ?assertEqual([],
-        Req8:accepted_content_types(["application/json"])),
+        mochiweb_request:accepted_content_types(["application/json"], Req8)),
 
     Req9 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
         mochiweb_headers:make([{"Accept", "text/*;q=0.9, text/html;q=0.5, */*;q=0.7"}])),
     ?assertEqual(["application/json", "text/html"],
-        Req9:accepted_content_types(["text/html", "application/json"])).
+        mochiweb_request:accepted_content_types(["text/html", "application/json"], Req9)).
 
 should_close_test() ->
     F = fun (V, H) ->
-                (mochiweb_request:new(
+                mochiweb_request:should_close(mochiweb_request:new(
                    nil, 'GET', "/", V,
                    mochiweb_headers:make(H)
-                  )):should_close()
+                  ))
         end,
     ?assertEqual(
        true,


[couchdb-mochiweb] 23/32: Update README.md

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 9f024df70a3286786b542c56250e77e343c2e58c
Author: penhs <46...@users.noreply.github.com>
AuthorDate: Tue May 21 17:26:37 2019 -0700

    Update README.md
---
 README.md | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 3f00b31..673e384 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,7 @@ The latest version of MochiWeb is available at http://github.com/mochi/mochiweb
 
 The mailing list for MochiWeb is at http://groups.google.com/group/mochiweb/
 
-Required for setting up the MochiWeb environment:
-   Erlang OTP: http://www.erlang.org/
+Erlang OTP is required for setting up the MochiWeb environment and is available at http://www.erlang.org/
 
 To create a new mochiweb using project:
    make app PROJECT=project_name
@@ -13,8 +12,7 @@ To create a new mochiweb using project:
 To create a new mochiweb using project in a specific directory:
    make app PROJECT=project_name PREFIX=$HOME/projects/
 
-Information about Rebar (Erlang build tool): 
-   https://github.com/rebar/rebar
+Information about Rebar (Erlang build tool) is available at https://github.com/rebar/rebar
 
 MochiWeb is currently tested with Erlang/OTP R15B03 through 21.2.3.
 


[couchdb-mochiweb] 03/32: Use more direct translation of RFC 6265 grammar

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 9a1b10967f65b051430d72f135e52952b503fff8
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Mon Mar 4 16:45:59 2019 +0000

    Use more direct translation of RFC 6265 grammar
---
 CHANGES.md               |  5 +++++
 src/mochiweb.app.src     |  2 +-
 src/mochiweb_cookies.erl | 19 ++++++++++++-------
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 45464d0..e4f10d7 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,8 @@
+Version 2.20.0 released 2019-XX-XX
+
+* Fix parsing of certain unquoted cookie values
+  https://github.com/mochi/mochiweb/pull/212
+
 Version 2.19.0 released 2019-01-17
 
 * Fix warning in 21.2.3 and crash on incompatible releases
diff --git a/src/mochiweb.app.src b/src/mochiweb.app.src
index 70c7165..6486fcb 100644
--- a/src/mochiweb.app.src
+++ b/src/mochiweb.app.src
@@ -1,7 +1,7 @@
 %% This is generated from src/mochiweb.app.src
 {application, mochiweb,
  [{description, "MochiMedia Web Server"},
-  {vsn, "2.19.0"},
+  {vsn, "2.20.0"},
   {modules, []},
   {registered, []},
   {env, []},
diff --git a/src/mochiweb_cookies.erl b/src/mochiweb_cookies.erl
index b6afb65..c7b0fcf 100644
--- a/src/mochiweb_cookies.erl
+++ b/src/mochiweb_cookies.erl
@@ -40,12 +40,17 @@
          C =:= ${ orelse C =:= $})).
 
 %% RFC 6265 cookie value allowed characters
--define(IS_COOKIE_VAL_ALLOWED(C),
-        (C =:= 33
-         orelse (C >= 35 andalso C =< 43)
-         orelse (C >= 45 andalso C =< 58)
-         orelse (C >= 60 andalso C =< 91)
-         orelse (C >= 93 andalso C =< 126))).
+%%  cookie-octet      = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
+%%                        ; US-ASCII characters excluding CTLs,
+%%                        ; whitespace DQUOTE, comma, semicolon,
+%%                        ; and backslash
+-define(IS_COOKIE_OCTET(C),
+        (C =:= 16#21
+         orelse (C >= 16#23 andalso C =< 16#2B)
+         orelse (C >= 16#2D andalso C =< 16#3A)
+         orelse (C >= 16#3C andalso C =< 16#5B)
+         orelse (C >= 16#5D andalso C =< 16#7E)
+        )).
 
 %% @type proplist() = [{Key::string(), Value::string()}].
 %% @type header() = {Name::string(), Value::string()}.
@@ -222,7 +227,7 @@ read_value(String) ->
     {"", String}.
 
 read_value_(String) ->
-    F = fun (C) -> ?IS_COOKIE_VAL_ALLOWED(C) end,
+    F = fun (C) -> ?IS_COOKIE_OCTET(C) end,
     lists:splitwith(F, String).
 
 read_quoted([?QUOTE | String]) ->


[couchdb-mochiweb] 07/32: Remove compile(tuple_calls) from mochiweb_http

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit dc741519b5fadf8c3b6aa13ee5607dcb306e0527
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Sat Mar 9 20:43:12 2019 +0000

    Remove compile(tuple_calls) from mochiweb_http
---
 src/mochiweb_http.erl | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/src/mochiweb_http.erl b/src/mochiweb_http.erl
index a4bfa9e..6854b6a 100644
--- a/src/mochiweb_http.erl
+++ b/src/mochiweb_http.erl
@@ -28,8 +28,6 @@
 -export([after_response/2, reentry/1]).
 -export([parse_range_request/1, range_skip_length/2]).
 
--compile(tuple_calls).
-
 -define(REQUEST_RECV_TIMEOUT, 300000).   %% timeout waiting for request line
 -define(HEADERS_RECV_TIMEOUT, 30000).    %% timeout waiting for headers
 
@@ -76,7 +74,7 @@ start_link(Options) ->
     ok = ensure_started(mochiweb_clock),
     mochiweb_socket_server:start_link(parse_options(Options)).
 
-ensure_started(M) ->
+ensure_started(M) when is_atom(M) ->
     case M:start() of
         {ok, _Pid} ->
             ok;
@@ -140,9 +138,9 @@ headers(Socket, Opts, Request, Headers, Body, HeaderCount) ->
         exit(normal)
     end.
 
-call_body({M, F, A}, Req) ->
+call_body({M, F, A}, Req) when is_atom(M) ->
     erlang:apply(M, F, [Req | A]);
-call_body({M, F}, Req) ->
+call_body({M, F}, Req) when is_atom(M) ->
     M:F(Req);
 call_body(Body, Req) ->
     Body(Req).
@@ -164,8 +162,8 @@ handle_invalid_msg_request(Msg, Socket, Opts, Request, RevHeaders) ->
 
 -spec handle_invalid_request(term(), term(), term(), term()) -> no_return().
 handle_invalid_request(Socket, Opts, Request, RevHeaders) ->
-    Req = new_request(Socket, Opts, Request, RevHeaders),
-    Req:respond({400, [], []}),
+    {ReqM, _} = Req = new_request(Socket, Opts, Request, RevHeaders),
+    ReqM:respond({400, [], []}, Req),
     mochiweb_socket:close(Socket),
     exit(normal).
 
@@ -173,14 +171,14 @@ new_request(Socket, Opts, Request, RevHeaders) ->
     ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, raw}])),
     mochiweb:new_request({Socket, Opts, Request, lists:reverse(RevHeaders)}).
 
-after_response(Body, Req) ->
-    Socket = Req:get(socket),
-    case Req:should_close() of
+after_response(Body, {ReqM, _} = Req) ->
+    Socket = ReqM:get(socket, Req),
+    case ReqM:should_close(Req) of
         true ->
             mochiweb_socket:close(Socket),
             exit(normal);
         false ->
-            Req:cleanup(),
+            ReqM:cleanup(Req),
             erlang:garbage_collect(),
             ?MODULE:loop(Socket, mochiweb_request:get(opts, Req), Body)
     end.


[couchdb-mochiweb] 11/32: Remove compile(tuple_calls) from mochiweb_websocket

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 5ae2f0af77695f2593b839a35c569ea8577dfac5
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Sat Mar 9 21:00:29 2019 +0000

    Remove compile(tuple_calls) from mochiweb_websocket
---
 src/mochiweb_websocket.erl | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/src/mochiweb_websocket.erl b/src/mochiweb_websocket.erl
index 690c91f..c162980 100644
--- a/src/mochiweb_websocket.erl
+++ b/src/mochiweb_websocket.erl
@@ -25,8 +25,6 @@
 
 %% @doc Websockets module for Mochiweb. Based on Misultin websockets module.
 
--compile(tuple_calls).
-
 -export([loop/5, upgrade_connection/2, request/5]).
 -export([send/3]).
 -ifdef(TEST).
@@ -79,11 +77,11 @@ send(Socket, Payload, hybi) ->
 send(Socket, Payload, hixie) ->
     mochiweb_socket:send(Socket, [0, Payload, 255]).
 
-upgrade_connection(Req, Body) ->
+upgrade_connection({ReqM, _} = Req, Body) ->
     case make_handshake(Req) of
         {Version, Response} ->
-            Req:respond(Response),
-            Socket = Req:get(socket),
+            ReqM:respond(Response, Req),
+            Socket = ReqM:get(socket, Req),
             ReplyChannel = fun (Payload) ->
                 ?MODULE:send(Socket, Payload, Version)
             end,
@@ -92,21 +90,21 @@ upgrade_connection(Req, Body) ->
             end,
             {Reentry, ReplyChannel};
         _ ->
-            mochiweb_socket:close(Req:get(socket)),
+            mochiweb_socket:close(ReqM:get(socket, Req)),
             exit(normal)
     end.
 
-make_handshake(Req) ->
-    SecKey  = Req:get_header_value("sec-websocket-key"),
-    Sec1Key = Req:get_header_value("Sec-WebSocket-Key1"),
-    Sec2Key = Req:get_header_value("Sec-WebSocket-Key2"),
-    Origin = Req:get_header_value(origin),
+make_handshake({ReqM, _} = Req) ->
+    SecKey  = ReqM:get_header_value("sec-websocket-key", Req),
+    Sec1Key = ReqM:get_header_value("Sec-WebSocket-Key1", Req),
+    Sec2Key = ReqM:get_header_value("Sec-WebSocket-Key2", Req),
+    Origin = ReqM:get_header_value(origin, Req),
     if SecKey =/= undefined ->
             hybi_handshake(SecKey);
        Sec1Key =/= undefined andalso Sec2Key =/= undefined ->
-            Host = Req:get_header_value("Host"),
-            Path = Req:get(path),
-            Body = Req:recv(8),
+            Host = ReqM:get_header_value("Host", Req),
+            Path = ReqM:get(path, Req),
+            Body = ReqM:recv(8, Req),
             Scheme = scheme(Req),
             hixie_handshake(Scheme, Host, Path, Sec1Key, Sec2Key, Body, Origin);
        true ->


[couchdb-mochiweb] 08/32: Remove compile(tuple_calls) from mochiweb_multipart

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 6f9452c0d83c5478f250b8d922f3bb0638edb947
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Sat Mar 9 20:47:44 2019 +0000

    Remove compile(tuple_calls) from mochiweb_multipart
---
 src/mochiweb_multipart.erl | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/src/mochiweb_multipart.erl b/src/mochiweb_multipart.erl
index 6f611c0..46b7090 100644
--- a/src/mochiweb_multipart.erl
+++ b/src/mochiweb_multipart.erl
@@ -24,8 +24,6 @@
 -module(mochiweb_multipart).
 -author('bob@mochimedia.com').
 
--compile(tuple_calls).
-
 -export([parse_form/1, parse_form/2]).
 -export([parse_multipart_request/2]).
 -export([parts_to_body/3, parts_to_multipart_body/4]).
@@ -146,11 +144,11 @@ default_file_handler_1(Filename, ContentType, Acc) ->
             default_file_handler_1(Filename, ContentType, [Next | Acc])
     end.
 
-parse_multipart_request(Req, Callback) ->
+parse_multipart_request({ReqM, _} = Req, Callback) ->
     %% TODO: Support chunked?
-    Length = list_to_integer(Req:get_combined_header_value("content-length")),
+    Length = list_to_integer(ReqM:get_combined_header_value("content-length", Req)),
     Boundary = iolist_to_binary(
-                 get_boundary(Req:get_header_value("content-type"))),
+                 get_boundary(ReqM:get_header_value("content-type", Req))),
     Prefix = <<"\r\n--", Boundary/binary>>,
     BS = byte_size(Boundary),
     Chunk = read_chunk(Req, Length),
@@ -182,12 +180,12 @@ split_header(Line) ->
     {string:to_lower(string:strip(Name)),
      mochiweb_util:parse_header(Value)}.
 
-read_chunk(Req, Length) when Length > 0 ->
+read_chunk({ReqM, _} = Req, Length) when Length > 0 ->
     case Length of
         Length when Length < ?CHUNKSIZE ->
-            Req:recv(Length);
+            ReqM:recv(Length, Req);
         _ ->
-            Req:recv(?CHUNKSIZE)
+            ReqM:recv(?CHUNKSIZE, Req)
     end.
 
 read_more(State=#mp{length=Length, buffer=Buffer, req=Req}) ->


[couchdb-mochiweb] 24/32: Debug Travis, it seems like older releases are not working

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 2b4b27287ed407bb210b6f0539a37fb11d8ab1eb
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Tue May 21 20:24:56 2019 -0700

    Debug Travis, it seems like older releases are not working
---
 .travis.yml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 18bf781..eb26c04 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,3 +12,5 @@ otp_release:
   - 17.5
   - R16B03-1
   - R15B03
+before_script:
+  - kerl list installations


[couchdb-mochiweb] 22/32: Update README.md

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 05d3cebaa348d331362a81e194ff539b297e14e2
Author: penhs <46...@users.noreply.github.com>
AuthorDate: Tue May 21 17:24:46 2019 -0700

    Update README.md
---
 README.md | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/README.md b/README.md
index 74e6620..3f00b31 100644
--- a/README.md
+++ b/README.md
@@ -4,12 +4,18 @@ The latest version of MochiWeb is available at http://github.com/mochi/mochiweb
 
 The mailing list for MochiWeb is at http://groups.google.com/group/mochiweb/
 
+Required for setting up the MochiWeb environment:
+   Erlang OTP: http://www.erlang.org/
+
 To create a new mochiweb using project:
    make app PROJECT=project_name
 
 To create a new mochiweb using project in a specific directory:
    make app PROJECT=project_name PREFIX=$HOME/projects/
 
+Information about Rebar (Erlang build tool): 
+   https://github.com/rebar/rebar
+
 MochiWeb is currently tested with Erlang/OTP R15B03 through 21.2.3.
 
 # OTP 21.2, 21.2.1, 21.2.2 warning


[couchdb-mochiweb] 12/32: Remove compile(tuple_calls) from the template

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit ef4f886c1a7c80891de6d4bb0b7ca1b8f4587a13
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Mon Mar 11 22:45:20 2019 +0000

    Remove compile(tuple_calls) from the template
---
 .../mochiwebapp_skel/src/mochiapp_web.erl          | 47 +++++++++++++++-------
 1 file changed, 33 insertions(+), 14 deletions(-)

diff --git a/support/templates/mochiwebapp_skel/src/mochiapp_web.erl b/support/templates/mochiwebapp_skel/src/mochiapp_web.erl
index 7ffb44d..ecd99c5 100644
--- a/support/templates/mochiwebapp_skel/src/mochiapp_web.erl
+++ b/support/templates/mochiwebapp_skel/src/mochiapp_web.erl
@@ -6,8 +6,6 @@
 -module({{appid}}_web).
 -author("{{author}}").
 
--compile(tuple_calls).
-
 -export([start/1, stop/0, loop/2]).
 
 %% External API
@@ -22,35 +20,56 @@ start(Options) ->
 stop() ->
     mochiweb_http:stop(?MODULE).
 
+
+%% OTP 21 is the first to define OTP_RELEASE and the first to support
+%% EEP-0047 direct stack trace capture.
+-ifdef(OTP_RELEASE).
+-if(?OTP_RELEASE >= 21).
+-define(HAS_DIRECT_STACKTRACE, true).
+-endif.
+-endif.
+
+-ifdef(HAS_DIRECT_STACKTRACE).
+-define(CAPTURE_EXC_PRE(Type, What, Trace), Type:What:Trace).
+-define(CAPTURE_EXC_GET(Trace), Trace).
+-else.
+-define(CAPTURE_EXC_PRE(Type, What, Trace), Type:What).
+-define(CAPTURE_EXC_GET(Trace), erlang:get_stacktrace()).
+-endif.
+
 loop(Req, DocRoot) ->
-    "/" ++ Path = Req:get(path),
+    "/" ++ Path = mochiweb_request:get(path, Req),
     try
-        case Req:get(method) of
+        case mochiweb_request:get(method, Req) of
             Method when Method =:= 'GET'; Method =:= 'HEAD' ->
                 case Path of
-                  "hello_world" ->
-                    Req:respond({200, [{"Content-Type", "text/plain"}],
-                    "Hello world!\n"});
+                    "hello_world" ->
+                        mochiweb_request:respond(
+                            {200, [{"Content-Type", "text/plain"}], "Hello world!\n"},
+                            Req
+                        );
                     _ ->
-                        Req:serve_file(Path, DocRoot)
+                        mochiweb_request:serve_file(Path, DocRoot, Req)
                 end;
             'POST' ->
                 case Path of
                     _ ->
-                        Req:not_found()
+                        mochiweb_request:not_found(Req)
                 end;
             _ ->
-                Req:respond({501, [], []})
+                mochiweb_request:respond({501, [], []}, Req)
         end
     catch
-        Type:What ->
+        ?CAPTURE_EXC_PRE(Type, What, Trace) ->
             Report = ["web request failed",
                       {path, Path},
                       {type, Type}, {what, What},
-                      {trace, erlang:get_stacktrace()}],
+                      {trace, ?CAPTURE_EXC_GET(Trace)}],
             error_logger:error_report(Report),
-            Req:respond({500, [{"Content-Type", "text/plain"}],
-                         "request failed, sorry\n"})
+            mochiweb_request:respond(
+                {500, [{"Content-Type", "text/plain"}], "request failed, sorry\n"},
+                Req
+            )
     end.
 
 %% Internal API


[couchdb-mochiweb] 10/32: Remove compile(tuple_calls) from mochiweb_response

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 763fa5269b75caab5d0bd760137e267bf85d0311
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Sat Mar 9 20:53:33 2019 +0000

    Remove compile(tuple_calls) from mochiweb_response
---
 src/mochiweb_response.erl | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/src/mochiweb_response.erl b/src/mochiweb_response.erl
index dc9569e..81325b5 100644
--- a/src/mochiweb_response.erl
+++ b/src/mochiweb_response.erl
@@ -24,8 +24,6 @@
 -module(mochiweb_response).
 -author('bob@mochimedia.com').
 
--compile(tuple_calls).
-
 -define(QUIP, "Any of you quaids got a smint?").
 
 -export([new/3, get_header_value/2, get/2, dump/1]).
@@ -56,26 +54,26 @@ get(headers, {?MODULE, [_Request, _Code, Headers]}) ->
 %% @spec dump(response()) -> {mochiweb_request, [{atom(), term()}]}
 %% @doc Dump the internal representation to a "human readable" set of terms
 %%      for debugging/inspection purposes.
-dump({?MODULE, [Request, Code, Headers]}) ->
-    [{request, Request:dump()},
+dump({?MODULE, [{ReqM, _} = Request, Code, Headers]}) ->
+    [{request, ReqM:dump(Request)},
      {code, Code},
      {headers, mochiweb_headers:to_list(Headers)}].
 
 %% @spec send(iodata(), response()) -> ok
 %% @doc Send data over the socket if the method is not HEAD.
-send(Data, {?MODULE, [Request, _Code, _Headers]}) ->
-    case Request:get(method) of
+send(Data, {?MODULE, [{ReqM, _} = Request, _Code, _Headers]}) ->
+    case ReqM:get(method, Request) of
         'HEAD' ->
             ok;
         _ ->
-            Request:send(Data)
+            ReqM:send(Data, Request)
     end.
 
 %% @spec write_chunk(iodata(), response()) -> ok
 %% @doc Write a chunk of a HTTP chunked response. If Data is zero length,
 %%      then the chunked response will be finished.
-write_chunk(Data, {?MODULE, [Request, _Code, _Headers]}=THIS) ->
-    case Request:get(version) of
+write_chunk(Data, {?MODULE, [{ReqM, _} = Request, _Code, _Headers]}=THIS) ->
+    case ReqM:get(version, Request) of
         Version when Version >= {1, 1} ->
             Length = iolist_size(Data),
             send([io_lib:format("~.16b\r\n", [Length]), Data, <<"\r\n">>], THIS);


[couchdb-mochiweb] 25/32: Use a matrix to get an older dist for old releases

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit d12ac647eadc3cf5bd9b2104401d0eee11a51aa8
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Tue May 21 20:31:18 2019 -0700

    Use a matrix to get an older dist for old releases
---
 .travis.yml | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index eb26c04..ecc72df 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,9 +8,13 @@ otp_release:
   - 21.0
   - 20.0
   - 19.0
-  - 18.3
-  - 17.5
-  - R16B03-1
-  - R15B03
-before_script:
-  - kerl list installations
+matrix:
+  include:
+  - otp_release: 18.3
+    dist: trusty
+  - otp_release: 17.5
+    dist: trusty
+  - otp_release: R16B03-1
+    dist: trusty
+  - otp_release: R15B03
+    dist: trusty


[couchdb-mochiweb] 01/32: Add missing issue URL to CHANGES.md

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 985fa8acb2d9c71b36548e4f90f0f96ef9c4eab6
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Thu Jan 17 18:01:02 2019 +0000

    Add missing issue URL to CHANGES.md
---
 CHANGES.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGES.md b/CHANGES.md
index e3ac5c3..45464d0 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -13,6 +13,7 @@ Version 2.19.0 released 2019-01-17
 * No longer crash when a socket is closed server-side
   https://github.com/mochi/mochiweb/pull/205
 * Support for SameSite cookie setting
+  https://github.com/mochi/mochiweb/pull/203
 
 Version 2.18.0 released 2018-05-12
 


[couchdb-mochiweb] 27/32: Use https for URLs in README.md

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit c692fd789774ecfdd0e833c1e05920fbddd1dcc3
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Tue May 21 20:41:21 2019 -0700

    Use https for URLs in README.md
---
 README.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 673e384..44e392b 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
 MochiWeb is an Erlang library for building lightweight HTTP servers.
 
-The latest version of MochiWeb is available at http://github.com/mochi/mochiweb
+The latest version of MochiWeb is available at https://github.com/mochi/mochiweb
 
-The mailing list for MochiWeb is at http://groups.google.com/group/mochiweb/
+The mailing list for MochiWeb is at https://groups.google.com/group/mochiweb/
 
-Erlang OTP is required for setting up the MochiWeb environment and is available at http://www.erlang.org/
+Erlang OTP is required for setting up the MochiWeb environment and is available at https://www.erlang.org/
 
 To create a new mochiweb using project:
    make app PROJECT=project_name


[couchdb-mochiweb] 02/32: fix cookie value parsing

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 458eedf810b7417180a870077dbf957463adf08d
Author: Oleg Nemanov <le...@yandex.ru>
AuthorDate: Mon Mar 4 15:24:50 2019 +0300

    fix cookie value parsing
    
    Cookie value(according to RFC6265) can contain US-ASCII characters
    excluding CTLs, whitespace, DQUOTE, comma, semicolon and backslash:
    
    cookie-header = "Cookie:" OWS cookie-string OWS
    cookie-string = cookie-pair *( ";" SP cookie-pair )
    cookie-pair       = cookie-name "=" cookie-value
    cookie-value      = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
    cookie-octet      = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
    
    But mochiweb_cookie:parse_cookie() use smaller allowed characters list.
    For example, if cookie value is base64 string like MQ==,
    then parse_cookie() makes it MQ.
    
    Fix this by using a separate function for value parsing instead of
    read_token().
---
 src/mochiweb_cookies.erl | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/mochiweb_cookies.erl b/src/mochiweb_cookies.erl
index 013dbe0..b6afb65 100644
--- a/src/mochiweb_cookies.erl
+++ b/src/mochiweb_cookies.erl
@@ -39,6 +39,14 @@
          C =:= $[ orelse C =:= $] orelse C =:= $? orelse C =:= $= orelse
          C =:= ${ orelse C =:= $})).
 
+%% RFC 6265 cookie value allowed characters
+-define(IS_COOKIE_VAL_ALLOWED(C),
+        (C =:= 33
+         orelse (C >= 35 andalso C =< 43)
+         orelse (C >= 45 andalso C =< 58)
+         orelse (C >= 60 andalso C =< 91)
+         orelse (C >= 93 andalso C =< 126))).
+
 %% @type proplist() = [{Key::string(), Value::string()}].
 %% @type header() = {Name::string(), Value::string()}.
 %% @type int_seconds() = integer().
@@ -208,11 +216,15 @@ read_value([$= | Value]) ->
         [?QUOTE | _] ->
             read_quoted(Value1);
         _ ->
-            read_token(Value1)
+            read_value_(Value1)
     end;
 read_value(String) ->
     {"", String}.
 
+read_value_(String) ->
+    F = fun (C) -> ?IS_COOKIE_VAL_ALLOWED(C) end,
+    lists:splitwith(F, String).
+
 read_quoted([?QUOTE | String]) ->
     read_quoted(String, []).
 
@@ -302,6 +314,12 @@ parse_cookie_test() ->
     ?assertEqual(
        [{"foo", "bar"}, {"baz", "wibble"}],
        parse_cookie("foo=bar , baz=wibble ")),
+    ?assertEqual(
+       [{"foo", "base64=="}, {"bar", "base64="}],
+       parse_cookie("foo=\"base64==\";bar=\"base64=\"")),
+    ?assertEqual(
+       [{"foo", "base64=="}, {"bar", "base64="}],
+       parse_cookie("foo=base64==;bar=base64=")),
     ok.
 
 domain_test() ->


[couchdb-mochiweb] 32/32: Merge pull request #226 from mochi/otp-22

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit cedc22f66a8e3f3885fb06babc0c0582418508f8
Merge: c5e7b83 0c68ac4
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Sun Jul 14 21:46:36 2019 -0400

    Merge pull request #226 from mochi/otp-22
    
    Update CHANGES and add OTP 21.3, 22 to travis matrix

 .travis.yml | 2 ++
 CHANGES.md  | 5 ++++-
 README.md   | 2 +-
 3 files changed, 7 insertions(+), 2 deletions(-)


[couchdb-mochiweb] 06/32: Remove compile(tuple_calls) from mochiweb_acceptor

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 2ab10af9c207c13947eab861a55b40d2c33550cf
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Sat Mar 9 20:38:37 2019 +0000

    Remove compile(tuple_calls) from mochiweb_acceptor
---
 src/mochiweb_acceptor.erl | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/src/mochiweb_acceptor.erl b/src/mochiweb_acceptor.erl
index 3fd6925..1b53552 100644
--- a/src/mochiweb_acceptor.erl
+++ b/src/mochiweb_acceptor.erl
@@ -24,8 +24,6 @@
 -module(mochiweb_acceptor).
 -author('bob@mochimedia.com').
 
--compile(tuple_calls).
-
 -include("internal.hrl").
 
 -export([start_link/3, start_link/4, init/4]).
@@ -75,11 +73,11 @@ init(Server, Listen, Loop, Opts) ->
             exit({error, accept_failed})
     end.
 
-call_loop({M, F}, Socket, Opts) ->
+call_loop({M, F}, Socket, Opts) when is_atom(M) ->
     M:F(Socket, Opts);
-call_loop({M, F, [A1]}, Socket, Opts) ->
+call_loop({M, F, [A1]}, Socket, Opts) when is_atom(M) ->
     M:F(Socket, Opts, A1);
-call_loop({M, F, A}, Socket, Opts) ->
+call_loop({M, F, A}, Socket, Opts) when is_atom(M) ->
     erlang:apply(M, F, [Socket, Opts | A]);
 call_loop(Loop, Socket, Opts) ->
     Loop(Socket, Opts).


[couchdb-mochiweb] 05/32: Remove compile(tuple_calls) from mochifmt

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 83fdebc7b0cbfdbafbfac1a246dacac26276c5b0
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Sat Mar 9 20:28:47 2019 +0000

    Remove compile(tuple_calls) from mochifmt
---
 src/mochifmt.erl | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/mochifmt.erl b/src/mochifmt.erl
index 5a5ed45..1aa01c3 100644
--- a/src/mochifmt.erl
+++ b/src/mochifmt.erl
@@ -25,8 +25,6 @@
 -module(mochifmt).
 -author('bob@mochimedia.com').
 
--compile(tuple_calls).
-
 -export([format/2, format_field/2, convert_field/2, get_value/2, get_field/2]).
 -export([tokenize/1, format/3, get_field/3, format_field/3]).
 -export([bformat/2, bformat/3]).
@@ -76,8 +74,7 @@ get_field(Key, Args) ->
 %%      is used to implement formats such as {0.0}.
 get_field(Key, Args, Module) ->
     {Name, Next} = lists:splitwith(fun (C) -> C =/= $. end, Key),
-    Res = try Module:get_value(Name, Args)
-          catch error:undef -> get_value(Name, Args) end,
+    Res = mod_get_value(Name, Args, Module),
     case Next of
         "" ->
             Res;
@@ -85,6 +82,16 @@ get_field(Key, Args, Module) ->
             get_field(S1, Res, Module)
     end.
 
+mod_get_value(Name, Args, Module) ->
+    try tuple_apply(Module, get_value, [Name, Args])
+    catch error:undef -> get_value(Name, Args)
+    end.
+
+tuple_apply(Module, F, Args) when is_atom(Module) ->
+    erlang:apply(Module, F, Args);
+tuple_apply(Module, F, Args) when is_tuple(Module), is_atom(element(1, Module)) ->
+    erlang:apply(element(1, Module), F, Args ++ [Module]).
+
 %% @spec format(Format::string(), Args) -> iolist()
 %% @doc Format Args with Format.
 format(Format, Args) ->
@@ -204,11 +211,11 @@ format2([{format, {Key, Convert, Format0}} | Rest], Args, Module, Acc) ->
                 V1 = convert_field(V0, Convert),
                 format_field(V1, Format);
             _ ->
-                V0 = try Module:get_field(Key, Args)
+                V0 = try tuple_apply(Module, get_field, [Key, Args])
                      catch error:undef -> get_field(Key, Args, Module) end,
-                V1 = try Module:convert_field(V0, Convert)
+                V1 = try tuple_apply(Module, convert_field, [V0, Convert])
                      catch error:undef -> convert_field(V0, Convert) end,
-                try Module:format_field(V1, Format)
+                try tuple_apply(Module, format_field, [V1, Format])
                 catch error:undef -> format_field(V1, Format, Module) end
         end,
     format2(Rest, Args, Module, [V | Acc]).
@@ -436,9 +443,9 @@ std_test() ->
 records_test() ->
     M = mochifmt_records:new([{conversion, record_info(fields, conversion)}]),
     R = #conversion{length=long, precision=hard, sign=peace},
-    long = M:get_value("length", R),
-    hard = M:get_value("precision", R),
-    peace = M:get_value("sign", R),
+    long = mochifmt_records:get_value("length", R, M),
+    hard = mochifmt_records:get_value("precision", R, M),
+    peace = mochifmt_records:get_value("sign", R, M),
     <<"long hard">> = bformat("{length} {precision}", R, M),
     <<"long hard">> = bformat("{0.length} {0.precision}", [R], M),
     ok.


[couchdb-mochiweb] 18/32: Remove compile(tuple_calls) from test/mochiweb_tests

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 105429811a23a77c5981f4ffc352649c906dc8a7
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Tue Mar 12 01:32:24 2019 +0000

    Remove compile(tuple_calls) from test/mochiweb_tests
---
 test/mochiweb_tests.erl | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/test/mochiweb_tests.erl b/test/mochiweb_tests.erl
index 697f7c6..ae88bda 100644
--- a/test/mochiweb_tests.erl
+++ b/test/mochiweb_tests.erl
@@ -2,14 +2,12 @@
 -include_lib("eunit/include/eunit.hrl").
 -include("mochiweb_test_util.hrl").
 
--compile(tuple_calls).
-
 with_server(Transport, ServerFun, ClientFun) ->
     mochiweb_test_util:with_server(Transport, ServerFun, ClientFun).
 
 request_test() ->
     R = mochiweb_request:new(z, z, "//foo///bar/baz%20wibble+quux?qs=2", z, []),
-    "/foo/bar/baz wibble quux" = R:get(path),
+    "/foo/bar/baz wibble quux" = mochiweb_request:get(path, R),
     ok.
 
 -define(LARGE_TIMEOUT, 60).
@@ -77,7 +75,7 @@ single_GET_scheme_test_() ->
 single_GET_absoluteURI_test_() ->
     Uri = "https://example.com:123/x/",
     ServerFun = fun (Req) ->
-                        Req:ok({"text/plain", Req:get(path)})
+                        mochiweb_request:ok({"text/plain", mochiweb_request:get(path, Req)}, Req)
                 end,
     %% Note that all the scheme/host/port information is discarded from path
     ClientFun = new_client_fun('GET', [#treq{path = Uri, xreply = <<"/x/">>}]),
@@ -91,7 +89,7 @@ single_CONNECT_test_() ->
 
 single_GET_any_test_() ->
     ServerFun = fun (Req) ->
-                        Req:ok({"text/plain", Req:get(path)})
+                        mochiweb_request:ok({"text/plain", mochiweb_request:get(path, Req)}, Req)
                 end,
     ClientFun = new_client_fun('GET', [#treq{path = "*", xreply = <<"*">>}]),
     [{atom_to_list(Transport),
@@ -104,8 +102,8 @@ cookie_header_test() ->
     ExHeaders = [{"Set-Cookie", "foo=bar"},
                  {"Set-Cookie", "foo=baz"}],
     ServerFun = fun (Req) ->
-                        Reply = ReplyPrefix ++ Req:get(path),
-                        Req:ok({"text/plain", ExHeaders, Reply})
+                        Reply = ReplyPrefix ++ mochiweb_request:get(path, Req),
+                        mochiweb_request:ok({"text/plain", ExHeaders, Reply}, Req)
                 end,
     Path = "cookie_header",
     ExpectedReply = list_to_binary(ReplyPrefix ++ Path),
@@ -119,8 +117,8 @@ do_CONNECT(Transport, Times) ->
     PathPrefix = "example.com:",
     ReplyPrefix = "You requested: ",
     ServerFun = fun (Req) ->
-                        Reply = ReplyPrefix ++ Req:get(path),
-                        Req:ok({"text/plain", Reply})
+                        Reply = ReplyPrefix ++ mochiweb_request:get(path, Req),
+                        mochiweb_request:ok({"text/plain", Reply}, Req)
                 end,
     TestReqs = [begin
                     Path = PathPrefix ++ integer_to_list(N),
@@ -137,8 +135,8 @@ do_GET(Transport, Times) ->
 do_GET(PathPrefix, Transport, Times) ->
     ReplyPrefix = "You requested: ",
     ServerFun = fun (Req) ->
-                        Reply = ReplyPrefix ++ Req:get(path),
-                        Req:ok({"text/plain", Reply})
+                        Reply = ReplyPrefix ++ mochiweb_request:get(path, Req),
+                        mochiweb_request:ok({"text/plain", Reply}, Req)
                 end,
     TestReqs = [begin
                     Path = PathPrefix ++ integer_to_list(N),
@@ -151,9 +149,9 @@ do_GET(PathPrefix, Transport, Times) ->
 
 do_POST(Transport, Size, Times) ->
     ServerFun = fun (Req) ->
-                        Body = Req:recv_body(),
+                        Body = mochiweb_request:recv_body(Req),
                         Headers = [{"Content-Type", "application/octet-stream"}],
-                        Req:respond({201, Headers, Body})
+                        mochiweb_request:respond({201, Headers, Body}, Req)
                 end,
     TestReqs = [begin
                     Path = "/stuff/" ++ integer_to_list(N),


[couchdb-mochiweb] 30/32: Merge pull request #225 from djnym/support-samesite-none

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit c5e7b835c6ab3397d4a2105e253593a28694ea9a
Merge: ad11980 fc8de2b
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Sun Jul 14 21:34:21 2019 -0400

    Merge pull request #225 from djnym/support-samesite-none
    
    add support for SameSite=none in cookies

 src/mochiweb_cookies.erl | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)


[couchdb-mochiweb] 20/32: Run erl_tidy on modified source files

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 69d6df7fe02990ebbf8c836215d26a1e1939716a
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Tue Mar 12 03:49:26 2019 +0000

    Run erl_tidy on modified source files
    
    ```erlang
    lists:foreach(
      fun (F) -> erl_tidy:file(F, [{backups, false}, keep_unused]) end,
      string:split(
        string:trim(
          os:cmd("git diff --name-only origin/master | grep \".erl$\"")
        ),
        "\n",
        all
      )
    ).
    ```
---
 examples/hmac_api/hmac_api_lib.erl                 |  354 +++---
 examples/https/https_store.erl                     |  142 +--
 examples/keepalive/keepalive.erl                   |   72 +-
 src/mochifmt.erl                                   |  405 ++++---
 src/mochiweb_acceptor.erl                          |   61 +-
 src/mochiweb_http.erl                              |  366 +++---
 src/mochiweb_multipart.erl                         | 1237 ++++++++++---------
 src/mochiweb_request.erl                           | 1280 ++++++++++++--------
 src/mochiweb_response.erl                          |   37 +-
 src/mochiweb_websocket.erl                         |  287 +++--
 .../mochiwebapp_skel/src/mochiapp_web.erl          |   79 +-
 test/mochiweb_http_tests.erl                       |   50 +-
 test/mochiweb_request_tests.erl                    |  292 +++--
 test/mochiweb_tests.erl                            |  244 ++--
 test/mochiweb_websocket_tests.erl                  |  189 +--
 15 files changed, 2741 insertions(+), 2354 deletions(-)

diff --git a/examples/hmac_api/hmac_api_lib.erl b/examples/hmac_api/hmac_api_lib.erl
index 4c26f2f..1dae62d 100644
--- a/examples/hmac_api/hmac_api_lib.erl
+++ b/examples/hmac_api/hmac_api_lib.erl
@@ -1,6 +1,7 @@
 -module(hmac_api_lib).
 
 -include("hmac_api.hrl").
+
 -include_lib("eunit/include/eunit.hrl").
 
 -author("Hypernumbers Ltd <go...@hypernumbers.com>").
@@ -21,11 +22,8 @@
 %%%
 %%% THE AMAZON API MUNGES HOSTNAME AND PATHS IN A CUSTOM WAY
 %%% THIS IMPLEMENTATION DOESN'T
--export([
-         authorize_request/1,
-         sign/5,
-         get_api_keypair/0
-        ]).
+-export([authorize_request/1, get_api_keypair/0,
+	 sign/5]).
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%                                                                          %%%
@@ -34,27 +32,27 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 authorize_request(Req) ->
-    Method      = mochiweb_request:get(method, Req),
-    Path        = mochiweb_request:get(path, Req),
-    Headers     = normalise(mochiweb_headers:to_list(mochiweb_request:get(headers, Req))),
-    ContentMD5  = get_header(Headers, "content-md5"),
+    Method = mochiweb_request:get(method, Req),
+    Path = mochiweb_request:get(path, Req),
+    Headers =
+	normalise(mochiweb_headers:to_list(mochiweb_request:get(headers,
+								Req))),
+    ContentMD5 = get_header(Headers, "content-md5"),
     ContentType = get_header(Headers, "content-type"),
-    Date        = get_header(Headers, "date"),
-    IncAuth     = get_header(Headers, "authorization"),
+    Date = get_header(Headers, "date"),
+    IncAuth = get_header(Headers, "authorization"),
     {_Schema, _PublicKey, _Sig} = breakout(IncAuth),
     %% normally you would use the public key to look up the private key
-    PrivateKey  = ?privatekey,
+    PrivateKey = (?privatekey),
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = Path},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = Path},
     Signed = sign_data(PrivateKey, Signature),
     {_, AuthHeader} = make_HTTPAuth_header(Signed),
     case AuthHeader of
-        IncAuth -> "match";
-        _       -> "no_match"
+      IncAuth -> "match";
+      _ -> "no_match"
     end.
 
 sign(PrivateKey, Method, URL, Headers, ContentType) ->
@@ -62,15 +60,12 @@ sign(PrivateKey, Method, URL, Headers, ContentType) ->
     ContentMD5 = get_header(Headers2, "content-md5"),
     Date = get_header(Headers2, "date"),
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = URL},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = URL},
     SignedSig = sign_data(PrivateKey, Signature),
     make_HTTPAuth_header(SignedSig).
 
-
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%                                                                          %%%
 %%% Internal Functions                                                       %%%
@@ -83,22 +78,30 @@ breakout(Header) ->
     {Schema, PublicKey, Signature}.
 
 get_api_keypair() ->
-    Public  = mochihex:to_hex(binary_to_list(crypto:strong_rand_bytes(16))),
-    Private = mochihex:to_hex(binary_to_list(crypto:strong_rand_bytes(16))),
+    Public =
+	mochihex:to_hex(binary_to_list(crypto:strong_rand_bytes(16))),
+    Private =
+	mochihex:to_hex(binary_to_list(crypto:strong_rand_bytes(16))),
     {Public, Private}.
 
 make_HTTPAuth_header(Signature) ->
-    {"Authorization", ?schema ++ " "
-     ++ ?publickey ++ ":" ++ Signature}.
+    {"Authorization",
+     (?schema) ++ " " ++ (?publickey) ++ ":" ++ Signature}.
 
 make_signature_string(#hmac_signature{} = S) ->
-    Date = get_date(S#hmac_signature.headers, S#hmac_signature.date),
-    string:to_upper(atom_to_list(S#hmac_signature.method)) ++ "\n"
-        ++ S#hmac_signature.contentmd5 ++ "\n"
-        ++ S#hmac_signature.contenttype ++ "\n"
-        ++ Date ++ "\n"
-        ++ canonicalise_headers(S#hmac_signature.headers)
-        ++ canonicalise_resource(S#hmac_signature.resource).
+    Date = get_date(S#hmac_signature.headers,
+		    S#hmac_signature.date),
+    string:to_upper(atom_to_list(S#hmac_signature.method))
+      ++
+      "\n" ++
+	S#hmac_signature.contentmd5 ++
+	  "\n" ++
+	    S#hmac_signature.contenttype ++
+	      "\n" ++
+		Date ++
+		  "\n" ++
+		    canonicalise_headers(S#hmac_signature.headers) ++
+		      canonicalise_resource(S#hmac_signature.resource).
 
 sign_data(PrivateKey, #hmac_signature{} = Signature) ->
     Str = make_signature_string(Signature),
@@ -109,35 +112,41 @@ sign_data(PrivateKey, #hmac_signature{} = Signature) ->
 %% yer Donald is well and truly Ducked so ye may as weel test it...
 sign2(PrivateKey, Str) ->
     Sign = xmerl_ucs:to_utf8(Str),
-    binary_to_list(base64:encode(crypto:sha_mac(PrivateKey, Sign))).
+    binary_to_list(base64:encode(crypto:sha_mac(PrivateKey,
+						Sign))).
 
 canonicalise_headers([]) -> "\n";
 canonicalise_headers(List) when is_list(List) ->
-    List2 = [{string:to_lower(K), V} || {K, V} <- lists:sort(List)],
+    List2 = [{string:to_lower(K), V}
+	     || {K, V} <- lists:sort(List)],
     c_headers2(consolidate(List2, []), []).
 
-c_headers2([], Acc)       -> string:join(Acc, "\n") ++ "\n";
-c_headers2([{?headerprefix ++ Rest, Key} | T], Acc) ->
-    Hd = string:strip(?headerprefix ++ Rest) ++ ":" ++ string:strip(Key),
+c_headers2([], Acc) -> string:join(Acc, "\n") ++ "\n";
+c_headers2([{(?headerprefix) ++ Rest, Key} | T], Acc) ->
+    Hd = string:strip((?headerprefix) ++ Rest) ++
+	   ":" ++ string:strip(Key),
     c_headers2(T, [Hd | Acc]);
 c_headers2([_H | T], Acc) -> c_headers2(T, Acc).
 
-consolidate([H | []], Acc) -> [H | Acc];
+consolidate([H], Acc) -> [H | Acc];
 consolidate([{H, K1}, {H, K2} | Rest], Acc) ->
     consolidate([{H, join(K1, K2)} | Rest], Acc);
 consolidate([{H1, K1}, {H2, K2} | Rest], Acc) ->
-    consolidate([{rectify(H2), rectify(K2)} | Rest], [{H1, K1} | Acc]).
+    consolidate([{rectify(H2), rectify(K2)} | Rest],
+		[{H1, K1} | Acc]).
 
 join(A, B) -> string:strip(A) ++ ";" ++ string:strip(B).
 
 %% removes line spacing as per RFC 2616 Section 4.2
 rectify(String) ->
-    Re = "[\x20* | \t*]+",
+    Re = "[ * | \t*]+",
     re:replace(String, Re, " ", [{return, list}, global]).
 
-canonicalise_resource("http://"  ++ Rest) -> c_res2(Rest);
-canonicalise_resource("https://" ++ Rest) -> c_res2(Rest);
-canonicalise_resource(X)                  -> c_res3(X).
+canonicalise_resource("http://" ++ Rest) ->
+    c_res2(Rest);
+canonicalise_resource("https://" ++ Rest) ->
+    c_res2(Rest);
+canonicalise_resource(X) -> c_res3(X).
 
 c_res2(Rest) ->
     N = string:str(Rest, "/"),
@@ -146,15 +155,15 @@ c_res2(Rest) ->
 
 c_res3(Tail) ->
     URL = case string:str(Tail, "#") of
-              0 -> Tail;
-              N -> {U, _Anchor} = lists:split(N, Tail),
-                   U
-          end,
+	    0 -> Tail;
+	    N -> {U, _Anchor} = lists:split(N, Tail), U
+	  end,
     U3 = case string:str(URL, "?") of
-             0  -> URL;
-             N2 -> {U2, Q} = lists:split(N2, URL),
-                   U2 ++ canonicalise_query(Q)
-         end,
+	   0 -> URL;
+	   N2 ->
+	       {U2, Q} = lists:split(N2, URL),
+	       U2 ++ canonicalise_query(Q)
+	 end,
     string:to_lower(U3).
 
 canonicalise_query(List) ->
@@ -163,11 +172,12 @@ canonicalise_query(List) ->
     string:join(lists:sort(List2), "&").
 
 %% if there's a header date take it and ditch the date
-get_date([], Date)            -> Date;
-get_date([{K, _V} | T], Date) -> case string:to_lower(K) of
-                                     ?dateheader -> [];
-                                     _           ->  get_date(T, Date)
-                                 end.
+get_date([], Date) -> Date;
+get_date([{K, _V} | T], Date) ->
+    case string:to_lower(K) of
+      ?dateheader -> [];
+      _ -> get_date(T, Date)
+    end.
 
 normalise(List) -> norm2(List, []).
 
@@ -178,11 +188,10 @@ norm2([H | T], Acc) -> norm2(T, [H | Acc]).
 
 get_header(Headers, Type) ->
     case lists:keyfind(Type, 1, Headers) of
-        false   -> [];
-        {_K, V} -> V
+      false -> [];
+      {_K, V} -> V
     end.
 
-
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%                                                                          %%%
 %%% Unit Tests                                                               %%%
@@ -190,10 +199,13 @@ get_header(Headers, Type) ->
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
                                                 % taken from Amazon docs
+
 %% http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?RESTAuthentication.html
 hash_test1(_) ->
-    Sig = "DELETE\n\n\n\nx-amz-date:Tue, 27 Mar 2007 21:20:26 +0000\n/johnsmith/photos/puppy.jpg",
-    Key = ?privatekey,
+    Sig = "DELETE\n\n\n\nx-amz-date:Tue, 27 Mar "
+	  "2007 21:20:26 +0000\n/johnsmith/photos/puppy."
+	  "jpg",
+    Key = (?privatekey),
     Hash = sign2(Key, Sig),
     Expected = "k3nL7gH3+PadhTEVn5Ip83xlYzk=",
     ?assertEqual(Expected, Hash).
@@ -201,7 +213,8 @@ hash_test1(_) ->
 %% taken from Amazon docs
 %% http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?RESTAuthentication.html
 hash_test2(_) ->
-    Sig = "GET\n\n\nTue, 27 Mar 2007 19:44:46 +0000\n/johnsmith/?acl",
+    Sig = "GET\n\n\nTue, 27 Mar 2007 19:44:46 +0000\n/jo"
+	  "hnsmith/?acl",
     Key = "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o",
     Hash = sign2(Key, Sig),
     Expected = "thdUi9VAkzhkniLj96JIrOPGi0g=",
@@ -210,8 +223,9 @@ hash_test2(_) ->
 %% taken from Amazon docs
 %% http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?RESTAuthentication.html
 hash_test3(_) ->
-    Sig = "GET\n\n\nWed, 28 Mar 2007 01:49:49 +0000\n/dictionary/"
-        ++ "fran%C3%A7ais/pr%c3%a9f%c3%a8re",
+    Sig = "GET\n\n\nWed, 28 Mar 2007 01:49:49 +0000\n/di"
+	  "ctionary/"
+	    ++ "fran%C3%A7ais/pr%c3%a9f%c3%a8re",
     Key = "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o",
     Hash = sign2(Key, Sig),
     Expected = "dxhSBHoI6eVSPcXJqEghlUzZMnY=",
@@ -225,13 +239,12 @@ signature_test1(_) ->
     Date = "Sun, 10 Jul 2011 05:07:19 UTC",
     Headers = [],
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = URL},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = URL},
     Sig = make_signature_string(Signature),
-    Expected = "POST\n\n\nSun, 10 Jul 2011 05:07:19 UTC\n\n/tongs/ya/bas",
+    Expected = "POST\n\n\nSun, 10 Jul 2011 05:07:19 "
+	       "UTC\n\n/tongs/ya/bas",
     ?assertEqual(Expected, Sig).
 
 signature_test2(_) ->
@@ -242,13 +255,13 @@ signature_test2(_) ->
     Date = "Sun, 10 Jul 2011 05:07:19 UTC",
     Headers = [{"x-amz-acl", "public-read"}],
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = URL},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = URL},
     Sig = make_signature_string(Signature),
-    Expected = "GET\n\n\nSun, 10 Jul 2011 05:07:19 UTC\nx-amz-acl:public-read\n/tongs/ya/bas",
+    Expected =
+	"GET\n\n\nSun, 10 Jul 2011 05:07:19 UTC\nx-amz"
+	"-acl:public-read\n/tongs/ya/bas",
     ?assertEqual(Expected, Sig).
 
 signature_test3(_) ->
@@ -258,17 +271,17 @@ signature_test3(_) ->
     ContentType = "",
     Date = "Sun, 10 Jul 2011 05:07:19 UTC",
     Headers = [{"x-amz-acl", "public-read"},
-               {"yantze", "blast-off"},
-               {"x-amz-doobie", "bongwater"},
-               {"x-amz-acl", "public-write"}],
+	       {"yantze", "blast-off"}, {"x-amz-doobie", "bongwater"},
+	       {"x-amz-acl", "public-write"}],
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = URL},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = URL},
     Sig = make_signature_string(Signature),
-    Expected = "GET\n\n\nSun, 10 Jul 2011 05:07:19 UTC\nx-amz-acl:public-read;public-write\nx-amz-doobie:bongwater\n/tongs/ya/bas",
+    Expected =
+	"GET\n\n\nSun, 10 Jul 2011 05:07:19 UTC\nx-amz"
+	"-acl:public-read;public-write\nx-amz-doobie:b"
+	"ongwater\n/tongs/ya/bas",
     ?assertEqual(Expected, Sig).
 
 signature_test4(_) ->
@@ -278,17 +291,18 @@ signature_test4(_) ->
     ContentType = "",
     Date = "Sun, 10 Jul 2011 05:07:19 UTC",
     Headers = [{"x-amz-acl", "public-read"},
-               {"yantze", "blast-off"},
-               {"x-amz-doobie  oobie \t boobie ", "bongwater"},
-               {"x-amz-acl", "public-write"}],
+	       {"yantze", "blast-off"},
+	       {"x-amz-doobie  oobie \t boobie ", "bongwater"},
+	       {"x-amz-acl", "public-write"}],
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = URL},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = URL},
     Sig = make_signature_string(Signature),
-    Expected = "GET\n\n\nSun, 10 Jul 2011 05:07:19 UTC\nx-amz-acl:public-read;public-write\nx-amz-doobie oobie boobie:bongwater\n/tongs/ya/bas",
+    Expected =
+	"GET\n\n\nSun, 10 Jul 2011 05:07:19 UTC\nx-amz"
+	"-acl:public-read;public-write\nx-amz-doobie "
+	"oobie boobie:bongwater\n/tongs/ya/bas",
     ?assertEqual(Expected, Sig).
 
 signature_test5(_) ->
@@ -298,138 +312,122 @@ signature_test5(_) ->
     ContentType = "",
     Date = "Sun, 10 Jul 2011 05:07:19 UTC",
     Headers = [{"x-amz-acl", "public-Read"},
-               {"yantze", "Blast-Off"},
-               {"x-amz-doobie  Oobie \t boobie ", "bongwater"},
-               {"x-amz-acl", "public-write"}],
+	       {"yantze", "Blast-Off"},
+	       {"x-amz-doobie  Oobie \t boobie ", "bongwater"},
+	       {"x-amz-acl", "public-write"}],
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = URL},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = URL},
     Sig = make_signature_string(Signature),
-    Expected = "GET\n\n\nSun, 10 Jul 2011 05:07:19 UTC\nx-amz-acl:public-Read;public-write\nx-amz-doobie oobie boobie:bongwater\n/tongs/ya/bas",
+    Expected =
+	"GET\n\n\nSun, 10 Jul 2011 05:07:19 UTC\nx-amz"
+	"-acl:public-Read;public-write\nx-amz-doobie "
+	"oobie boobie:bongwater\n/tongs/ya/bas",
     ?assertEqual(Expected, Sig).
 
 signature_test6(_) ->
-    URL = "http://example.com:90/tongs/ya/bas/?andy&zbish=bash&bosh=burp",
+    URL = "http://example.com:90/tongs/ya/bas/?andy&zbis"
+	  "h=bash&bosh=burp",
     Method = get,
     ContentMD5 = "",
     ContentType = "",
     Date = "Sun, 10 Jul 2011 05:07:19 UTC",
     Headers = [],
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = URL},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = URL},
     Sig = make_signature_string(Signature),
     Expected = "GET\n\n\nSun, 10 Jul 2011 05:07:19 UTC\n\n"
-        ++ "/tongs/ya/bas/?andy&bosh=burp&zbish=bash",
+		 ++ "/tongs/ya/bas/?andy&bosh=burp&zbish=bash",
     ?assertEqual(Expected, Sig).
 
 signature_test7(_) ->
-    URL = "http://exAMPLE.Com:90/tONgs/ya/bas/?ANdy&ZBish=Bash&bOsh=burp",
+    URL = "http://exAMPLE.Com:90/tONgs/ya/bas/?ANdy&ZBis"
+	  "h=Bash&bOsh=burp",
     Method = get,
     ContentMD5 = "",
     ContentType = "",
     Date = "Sun, 10 Jul 2011 05:07:19 UTC",
     Headers = [],
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = URL},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = URL},
     Sig = make_signature_string(Signature),
     Expected = "GET\n\n\nSun, 10 Jul 2011 05:07:19 UTC\n\n"
-        ++"/tongs/ya/bas/?andy&bosh=burp&zbish=bash",
+		 ++ "/tongs/ya/bas/?andy&bosh=burp&zbish=bash",
     ?assertEqual(Expected, Sig).
 
 signature_test8(_) ->
-    URL = "http://exAMPLE.Com:90/tONgs/ya/bas/?ANdy&ZBish=Bash&bOsh=burp",
+    URL = "http://exAMPLE.Com:90/tONgs/ya/bas/?ANdy&ZBis"
+	  "h=Bash&bOsh=burp",
     Method = get,
     ContentMD5 = "",
     ContentType = "",
     Date = "",
-    Headers = [{"x-aMz-daTe", "Tue, 27 Mar 2007 21:20:26 +0000"}],
+    Headers = [{"x-aMz-daTe",
+		"Tue, 27 Mar 2007 21:20:26 +0000"}],
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = URL},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = URL},
     Sig = make_signature_string(Signature),
-    Expected = "GET\n\n\n\n"
-        ++"x-amz-date:Tue, 27 Mar 2007 21:20:26 +0000\n"
-        ++"/tongs/ya/bas/?andy&bosh=burp&zbish=bash",
+    Expected = "GET\n\n\n\n" ++
+		 "x-amz-date:Tue, 27 Mar 2007 21:20:26 "
+		 "+0000\n"
+		   ++ "/tongs/ya/bas/?andy&bosh=burp&zbish=bash",
     ?assertEqual(Expected, Sig).
 
 signature_test9(_) ->
-    URL = "http://exAMPLE.Com:90/tONgs/ya/bas/?ANdy&ZBish=Bash&bOsh=burp",
+    URL = "http://exAMPLE.Com:90/tONgs/ya/bas/?ANdy&ZBis"
+	  "h=Bash&bOsh=burp",
     Method = get,
     ContentMD5 = "",
     ContentType = "",
     Date = "Sun, 10 Jul 2011 05:07:19 UTC",
-    Headers = [{"x-amz-date", "Tue, 27 Mar 2007 21:20:26 +0000"}],
+    Headers = [{"x-amz-date",
+		"Tue, 27 Mar 2007 21:20:26 +0000"}],
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = URL},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = URL},
     Sig = make_signature_string(Signature),
-    Expected = "GET\n\n\n\n"
-        ++"x-amz-date:Tue, 27 Mar 2007 21:20:26 +0000\n"
-        ++"/tongs/ya/bas/?andy&bosh=burp&zbish=bash",
+    Expected = "GET\n\n\n\n" ++
+		 "x-amz-date:Tue, 27 Mar 2007 21:20:26 "
+		 "+0000\n"
+		   ++ "/tongs/ya/bas/?andy&bosh=burp&zbish=bash",
     ?assertEqual(Expected, Sig).
 
 amazon_test1(_) ->
-    URL = "http://exAMPLE.Com:90/johnsmith/photos/puppy.jpg",
+    URL =
+	"http://exAMPLE.Com:90/johnsmith/photos/puppy.jpg",
     Method = delete,
     ContentMD5 = "",
     ContentType = "",
     Date = "",
-    Headers = [{"x-amz-date", "Tue, 27 Mar 2007 21:20:26 +0000"}],
+    Headers = [{"x-amz-date",
+		"Tue, 27 Mar 2007 21:20:26 +0000"}],
     Signature = #hmac_signature{method = Method,
-                                contentmd5 = ContentMD5,
-                                contenttype = ContentType,
-                                date = Date,
-                                headers = Headers,
-                                resource = URL},
+				contentmd5 = ContentMD5,
+				contenttype = ContentType, date = Date,
+				headers = Headers, resource = URL},
     Sig = sign_data(?privatekey, Signature),
     Expected = "k3nL7gH3+PadhTEVn5Ip83xlYzk=",
     ?assertEqual(Expected, Sig).
 
 unit_test_() ->
-    Setup   = fun() -> ok end,
-    Cleanup = fun(_) -> ok end,
-
-    Series1 = [
-               fun hash_test1/1,
-               fun hash_test2/1,
-               fun hash_test3/1
-              ],
-
-    Series2 = [
-               fun signature_test1/1,
-               fun signature_test2/1,
-               fun signature_test3/1,
-               fun signature_test4/1,
-               fun signature_test5/1,
-               fun signature_test6/1,
-               fun signature_test7/1,
-               fun signature_test8/1,
-               fun signature_test9/1
-              ],
-
-    Series3 = [
-               fun amazon_test1/1
-              ],
-
-    {setup, Setup, Cleanup, [
-                             {with, [], Series1},
-                             {with, [], Series2},
-                             {with, [], Series3}
-                            ]}.
+    Setup = fun () -> ok end,
+    Cleanup = fun (_) -> ok end,
+    Series1 = [fun hash_test1/1, fun hash_test2/1,
+	       fun hash_test3/1],
+    Series2 = [fun signature_test1/1, fun signature_test2/1,
+	       fun signature_test3/1, fun signature_test4/1,
+	       fun signature_test5/1, fun signature_test6/1,
+	       fun signature_test7/1, fun signature_test8/1,
+	       fun signature_test9/1],
+    Series3 = [fun amazon_test1/1],
+    {setup, Setup, Cleanup,
+     [{with, [], Series1}, {with, [], Series2},
+      {with, [], Series3}]}.
diff --git a/examples/https/https_store.erl b/examples/https/https_store.erl
index 719f206..a9a4ec0 100644
--- a/examples/https/https_store.erl
+++ b/examples/https/https_store.erl
@@ -1,4 +1,3 @@
-
 %% Trivial web storage app. It's available over both HTTP (port 8442)
 %% and HTTPS (port 8443). You use a PUT to store items, a GET to
 %% retrieve them and DELETE to delete them. The HTTP POST method is
@@ -34,113 +33,102 @@
 
 -module(https_store).
 
--export([start/0,
-         stop/0,
-         dispatch/1,
-         loop/1
-         ]).
+-export([dispatch/1, loop/1, start/0, stop/0]).
 
--define(HTTP_OPTS, [
-            {loop, {?MODULE, dispatch}},
-            {port, 8442},
-            {name, http_8442}
-            ]).
+-define(HTTP_OPTS,
+	[{loop, {?MODULE, dispatch}}, {port, 8442},
+	 {name, http_8442}]).
 
--define(HTTPS_OPTS, [
-            {loop, {?MODULE, dispatch}},
-            {port, 8443},
-            {name, https_8443},
-            {ssl, true},
-            {ssl_opts, [
-                {certfile, "server_cert.pem"},
-                {keyfile, "server_key.pem"}]}
-            ]).
+-define(HTTPS_OPTS,
+	[{loop, {?MODULE, dispatch}}, {port, 8443},
+	 {name, https_8443}, {ssl, true},
+	 {ssl_opts,
+	  [{certfile, "server_cert.pem"},
+	   {keyfile, "server_key.pem"}]}]).
 
 -record(sd, {http, https}).
+
 -record(resource, {type, data}).
 
 start() ->
     {ok, Http} = mochiweb_http:start(?HTTP_OPTS),
     {ok, Https} = mochiweb_http:start(?HTTPS_OPTS),
-    SD = #sd{http=Http, https=Https},
-    Pid = spawn_link(fun() ->
-                             ets:new(?MODULE, [named_table]),
-                             loop(SD)
-                     end),
+    SD = #sd{http = Http, https = Https},
+    Pid = spawn_link(fun () ->
+			     ets:new(?MODULE, [named_table]), loop(SD)
+		     end),
     register(http_store, Pid),
     ok.
 
-stop() ->
-    http_store ! stop,
-    ok.
+stop() -> http_store ! stop, ok.
 
 dispatch(Req) ->
     case mochiweb_request:get(method, Req) of
-        'GET' ->
-            get_resource(Req);
-        'PUT' ->
-            put_resource(Req);
-        'DELETE' ->
-            delete_resource(Req);
-        _ ->
-            Headers = [{"Allow", "GET,PUT,DELETE"}],
-            mochiweb_request:respond({405, Headers, "405 Method Not Allowed\r\n"}, Req)
+      'GET' -> get_resource(Req);
+      'PUT' -> put_resource(Req);
+      'DELETE' -> delete_resource(Req);
+      _ ->
+	  Headers = [{"Allow", "GET,PUT,DELETE"}],
+	  mochiweb_request:respond({405, Headers,
+				    "405 Method Not Allowed\r\n"},
+				   Req)
     end.
 
 get_resource(Req) ->
     Path = mochiweb_request:get(path, Req),
     case ets:lookup(?MODULE, Path) of
-        [{Path, #resource{type=Type, data=Data}}] ->
-            mochiweb_request:ok({Type, Data}, Req);
-        [] ->
-            mochiweb_request:respond({404, [], "404 Not Found\r\n"}, Req)
+      [{Path, #resource{type = Type, data = Data}}] ->
+	  mochiweb_request:ok({Type, Data}, Req);
+      [] ->
+	  mochiweb_request:respond({404, [], "404 Not Found\r\n"},
+				   Req)
     end.
 
 put_resource(Req) ->
-    ContentType = case mochiweb_request:get_header_value("Content-Type", Req) of
-        undefined ->
-            "application/octet-stream";
-        S ->
-            S
-    end,
-    Resource = #resource{type=ContentType, data=mochiweb_request:recv_body(Req)},
-    http_store ! {self(), {put, mochiweb_request:get(path, Req), Resource}},
+    ContentType = case
+		    mochiweb_request:get_header_value("Content-Type", Req)
+		      of
+		    undefined -> "application/octet-stream";
+		    S -> S
+		  end,
+    Resource = #resource{type = ContentType,
+			 data = mochiweb_request:recv_body(Req)},
+    http_store !
+      {self(),
+       {put, mochiweb_request:get(path, Req), Resource}},
     Pid = whereis(http_store),
     receive
-        {Pid, created} ->
-            mochiweb_request:respond({201, [], "201 Created\r\n"}, Req);
-        {Pid, updated} ->
-            mochiweb_request:respond({200, [], "200 OK\r\n"}, Req)
+      {Pid, created} ->
+	  mochiweb_request:respond({201, [], "201 Created\r\n"},
+				   Req);
+      {Pid, updated} ->
+	  mochiweb_request:respond({200, [], "200 OK\r\n"}, Req)
     end.
 
 delete_resource(Req) ->
-    http_store ! {self(), {delete, mochiweb_request:get(path, Req)}},
+    http_store !
+      {self(), {delete, mochiweb_request:get(path, Req)}},
     Pid = whereis(http_store),
     receive
-        {Pid, ok} ->
-            mochiweb_request:respond({200, [], "200 OK\r\n"}, Req)
+      {Pid, ok} ->
+	  mochiweb_request:respond({200, [], "200 OK\r\n"}, Req)
     end.
 
-loop(#sd{http=Http, https=Https} = SD) ->
+loop(#sd{http = Http, https = Https} = SD) ->
     receive
-        stop ->
-            ok = mochiweb_http:stop(Http),
-            ok = mochiweb_http:stop(Https),
-            exit(normal);
-        {From, {put, Key, Val}} ->
-            Exists = ets:member(?MODULE, Key),
-            ets:insert(?MODULE, {Key, Val}),
-            case Exists of
-                true ->
-                    From ! {self(), updated};
-                false ->
-                    From ! {self(), created}
-            end;
-        {From, {delete, Key}} ->
-            ets:delete(?MODULE, Key),
-            From ! {self(), ok};
-        _ ->
-            ignore
+      stop ->
+	  ok = mochiweb_http:stop(Http),
+	  ok = mochiweb_http:stop(Https),
+	  exit(normal);
+      {From, {put, Key, Val}} ->
+	  Exists = ets:member(?MODULE, Key),
+	  ets:insert(?MODULE, {Key, Val}),
+	  case Exists of
+	    true -> From ! {self(), updated};
+	    false -> From ! {self(), created}
+	  end;
+      {From, {delete, Key}} ->
+	  ets:delete(?MODULE, Key), From ! {self(), ok};
+      _ -> ignore
     end,
-    ?MODULE:loop(SD).
-
+    (?MODULE):loop(SD).
diff --git a/examples/keepalive/keepalive.erl b/examples/keepalive/keepalive.erl
index 51a7c3a..f6f4e53 100644
--- a/examples/keepalive/keepalive.erl
+++ b/examples/keepalive/keepalive.erl
@@ -18,64 +18,62 @@
 %% response.  if you do that then control flow returns to the proper place,
 %% and keep alives work like they would if you hadn't hibernated.
 
--export([ start/1, loop/1
-        ]).
+-export([loop/1, start/1]).
 
 %% internal export (so hibernate can reach it)
--export([ resume/3
-        ]).
+-export([resume/3]).
 
 -define(LOOP, {?MODULE, loop}).
 
 start(Options = [{port, _Port}]) ->
-    mochiweb_http:start([{name, ?MODULE}, {loop, ?LOOP} | Options]).
+    mochiweb_http:start([{name, ?MODULE}, {loop, ?LOOP}
+			 | Options]).
 
 loop(Req) ->
     Path = mochiweb_request:get(path, Req),
     case string:tokens(Path, "/") of
-        ["longpoll" | RestOfPath] ->
-            %% the "reentry" is a continuation -- what @mochiweb_http@
-            %% needs to do to start its loop back at the top
-            Reentry = mochiweb_http:reentry(?LOOP),
-
-            %% here we could send a message to some other process and hope
-            %% to get an interesting message back after a while.  for
-            %% simplicity let's just send ourselves a message after a few
-            %% seconds
-            erlang:send_after(2000, self(), "honk honk"),
-
-            %% since we expect to wait for a long time before getting a
-            %% reply, let's hibernate.  memory usage will be minimized, so
-            %% we won't be wasting memory just sitting in a @receive@
-            proc_lib:hibernate(?MODULE, resume, [Req, RestOfPath, Reentry]),
-
-            %% we'll never reach this point, and this function @loop/1@
-            %% won't ever return control to @mochiweb_http@.  luckily
-            %% @resume/3@ will take care of that.
-            io:format("not gonna happen~n", []);
-
-        _ ->
-            ok(Req, io_lib:format("some other page: ~p", [Path]))
+      ["longpoll" | RestOfPath] ->
+	  %% the "reentry" is a continuation -- what @mochiweb_http@
+	  %% needs to do to start its loop back at the top
+	  Reentry = mochiweb_http:reentry(?LOOP),
+	  %% here we could send a message to some other process and hope
+	  %% to get an interesting message back after a while.  for
+	  %% simplicity let's just send ourselves a message after a few
+	  %% seconds
+	  erlang:send_after(2000, self(), "honk honk"),
+	  %% since we expect to wait for a long time before getting a
+	  %% reply, let's hibernate.  memory usage will be minimized, so
+	  %% we won't be wasting memory just sitting in a @receive@
+	  proc_lib:hibernate(?MODULE, resume,
+			     [Req, RestOfPath, Reentry]),
+	  %% we'll never reach this point, and this function @loop/1@
+	  %% won't ever return control to @mochiweb_http@.  luckily
+	  %% @resume/3@ will take care of that.
+	  io:format("not gonna happen~n", []);
+      _ ->
+	  ok(Req, io_lib:format("some other page: ~p", [Path]))
     end,
-
     io:format("restarting loop normally in ~p~n", [Path]),
     ok.
 
 %% this is the function that's called when a message arrives.
 resume(Req, RestOfPath, Reentry) ->
     receive
-        Msg ->
-            Text = io_lib:format("wake up message: ~p~nrest of path: ~p", [Msg, RestOfPath]),
-            ok(Req, Text)
+      Msg ->
+	  Text =
+	      io_lib:format("wake up message: ~p~nrest of path: ~p",
+			    [Msg, RestOfPath]),
+	  ok(Req, Text)
     end,
-
     %% if we didn't call @Reentry@ here then the function would finish and the
     %% process would exit.  calling @Reentry@ takes care of returning control
     %% to @mochiweb_http@
-    io:format("reentering loop via continuation in ~p~n", [mochiweb_request:get(path, Req)]),
+    io:format("reentering loop via continuation in "
+	      "~p~n",
+	      [mochiweb_request:get(path, Req)]),
     Reentry(Req).
 
 ok(Req, Response) ->
-    mochiweb_request:ok(
-        {_ContentType = "text/plain", _Headers = [], Response},
-        Req).
+    mochiweb_request:ok({_ContentType = "text/plain",
+			 _Headers = [], Response},
+			Req).
diff --git a/src/mochifmt.erl b/src/mochifmt.erl
index 1aa01c3..e7b9b59 100644
--- a/src/mochifmt.erl
+++ b/src/mochifmt.erl
@@ -23,28 +23,31 @@
 %%      (<a href="http://www.python.org/dev/peps/pep-3101/">PEP 3101</a>).
 %%
 -module(mochifmt).
+
 -author('bob@mochimedia.com').
 
--export([format/2, format_field/2, convert_field/2, get_value/2, get_field/2]).
--export([tokenize/1, format/3, get_field/3, format_field/3]).
+-export([convert_field/2, format/2, format_field/2,
+	 get_field/2, get_value/2]).
+
+-export([format/3, format_field/3, get_field/3,
+	 tokenize/1]).
+
 -export([bformat/2, bformat/3]).
+
 -export([f/2, f/3]).
 
--record(conversion, {length, precision, ctype, align, fill_char, sign}).
+-record(conversion,
+	{length, precision, ctype, align, fill_char, sign}).
 
 %% @spec tokenize(S::string()) -> tokens()
 %% @doc Tokenize a format string into mochifmt's internal format.
-tokenize(S) ->
-    {?MODULE, tokenize(S, "", [])}.
+tokenize(S) -> {?MODULE, tokenize(S, "", [])}.
 
 %% @spec convert_field(Arg, Conversion::conversion()) -> term()
 %% @doc Process Arg according to the given explicit conversion specifier.
-convert_field(Arg, "") ->
-    Arg;
-convert_field(Arg, "r") ->
-    repr(Arg);
-convert_field(Arg, "s") ->
-    str(Arg).
+convert_field(Arg, "") -> Arg;
+convert_field(Arg, "r") -> repr(Arg);
+convert_field(Arg, "s") -> str(Arg).
 
 %% @spec get_value(Key::string(), Args::args()) -> term()
 %% @doc Get the Key from Args. If Args is a tuple then convert Key to
@@ -55,47 +58,43 @@ convert_field(Arg, "s") ->
 get_value(Key, Args) when is_tuple(Args) ->
     element(1 + list_to_integer(Key), Args);
 get_value(Key, Args) when is_list(Args) ->
-    try lists:nth(1 + list_to_integer(Key), Args)
-    catch error:_ ->
-            {_K, V} = proplist_lookup(Key, Args),
-            V
+    try lists:nth(1 + list_to_integer(Key), Args) catch
+      error:_ -> {_K, V} = proplist_lookup(Key, Args), V
     end.
 
 %% @spec get_field(Key::string(), Args) -> term()
 %% @doc Consecutively call get_value/2 on parts of Key delimited by ".",
 %%      replacing Args with the result of the previous get_value. This
 %%      is used to implement formats such as {0.0}.
-get_field(Key, Args) ->
-    get_field(Key, Args, ?MODULE).
+get_field(Key, Args) -> get_field(Key, Args, ?MODULE).
 
 %% @spec get_field(Key::string(), Args, Module) -> term()
 %% @doc Consecutively call Module:get_value/2 on parts of Key delimited by ".",
 %%      replacing Args with the result of the previous get_value. This
 %%      is used to implement formats such as {0.0}.
 get_field(Key, Args, Module) ->
-    {Name, Next} = lists:splitwith(fun (C) -> C =/= $. end, Key),
+    {Name, Next} = lists:splitwith(fun (C) -> C =/= $. end,
+				   Key),
     Res = mod_get_value(Name, Args, Module),
     case Next of
-        "" ->
-            Res;
-        "." ++ S1 ->
-            get_field(S1, Res, Module)
+      "" -> Res;
+      "." ++ S1 -> get_field(S1, Res, Module)
     end.
 
 mod_get_value(Name, Args, Module) ->
-    try tuple_apply(Module, get_value, [Name, Args])
-    catch error:undef -> get_value(Name, Args)
+    try tuple_apply(Module, get_value, [Name, Args]) catch
+      error:undef -> get_value(Name, Args)
     end.
 
 tuple_apply(Module, F, Args) when is_atom(Module) ->
     erlang:apply(Module, F, Args);
-tuple_apply(Module, F, Args) when is_tuple(Module), is_atom(element(1, Module)) ->
+tuple_apply(Module, F, Args)
+    when is_tuple(Module), is_atom(element(1, Module)) ->
     erlang:apply(element(1, Module), F, Args ++ [Module]).
 
 %% @spec format(Format::string(), Args) -> iolist()
 %% @doc Format Args with Format.
-format(Format, Args) ->
-    format(Format, Args, ?MODULE).
+format(Format, Args) -> format(Format, Args, ?MODULE).
 
 %% @spec format(Format::string(), Args, Module) -> iolist()
 %% @doc Format Args with Format using Module.
@@ -117,17 +116,14 @@ format_field(Arg, Format, _Module) ->
 
 %% @spec f(Format::string(), Args) -> string()
 %% @doc Format Args with Format and return a string().
-f(Format, Args) ->
-    f(Format, Args, ?MODULE).
+f(Format, Args) -> f(Format, Args, ?MODULE).
 
 %% @spec f(Format::string(), Args, Module) -> string()
 %% @doc Format Args with Format using Module and return a string().
 f(Format, Args, Module) ->
     case lists:member(${, Format) of
-        true ->
-            binary_to_list(bformat(Format, Args, Module));
-        false ->
-            Format
+      true -> binary_to_list(bformat(Format, Args, Module));
+      false -> Format
     end.
 
 %% @spec bformat(Format::string(), Args) -> binary()
@@ -142,25 +138,22 @@ bformat(Format, Args, Module) ->
 
 %% Internal API
 
-add_raw("", Acc) ->
-    Acc;
-add_raw(S, Acc) ->
-    [{raw, lists:reverse(S)} | Acc].
+add_raw("", Acc) -> Acc;
+add_raw(S, Acc) -> [{raw, lists:reverse(S)} | Acc].
 
-tokenize([], S, Acc) ->
-    lists:reverse(add_raw(S, Acc));
+tokenize([], S, Acc) -> lists:reverse(add_raw(S, Acc));
 tokenize("{{" ++ Rest, S, Acc) ->
     tokenize(Rest, "{" ++ S, Acc);
 tokenize("{" ++ Rest, S, Acc) ->
     {Format, Rest1} = tokenize_format(Rest),
-    tokenize(Rest1, "", [{format, make_format(Format)} | add_raw(S, Acc)]);
+    tokenize(Rest1, "",
+	     [{format, make_format(Format)} | add_raw(S, Acc)]);
 tokenize("}}" ++ Rest, S, Acc) ->
     tokenize(Rest, "}" ++ S, Acc);
 tokenize([C | Rest], S, Acc) ->
     tokenize(Rest, [C | S], Acc).
 
-tokenize_format(S) ->
-    tokenize_format(S, 1, []).
+tokenize_format(S) -> tokenize_format(S, 1, []).
 
 tokenize_format("}" ++ Rest, 1, Acc) ->
     {lists:reverse(Acc), Rest};
@@ -172,90 +165,96 @@ tokenize_format([C | Rest], N, Acc) ->
     tokenize_format(Rest, N, [C | Acc]).
 
 make_format(S) ->
-    {Name0, Spec} = case lists:splitwith(fun (C) -> C =/= $: end, S) of
-                        {_, ""} ->
-                            {S, ""};
-                        {SN, ":" ++ SS} ->
-                            {SN, SS}
-                    end,
-    {Name, Transform} = case lists:splitwith(fun (C) -> C =/= $! end, Name0) of
-                            {_, ""} ->
-                                {Name0, ""};
-                            {TN, "!" ++ TT} ->
-                                {TN, TT}
-                        end,
+    {Name0, Spec} = case lists:splitwith(fun (C) -> C =/= $:
+					 end,
+					 S)
+			of
+		      {_, ""} -> {S, ""};
+		      {SN, ":" ++ SS} -> {SN, SS}
+		    end,
+    {Name, Transform} = case lists:splitwith(fun (C) ->
+						     C =/= $!
+					     end,
+					     Name0)
+			    of
+			  {_, ""} -> {Name0, ""};
+			  {TN, "!" ++ TT} -> {TN, TT}
+			end,
     {Name, Transform, Spec}.
 
 proplist_lookup(S, P) ->
-    A = try list_to_existing_atom(S)
-        catch error:_ -> make_ref() end,
-    B = try list_to_binary(S)
-        catch error:_ -> make_ref() end,
+    A = try list_to_existing_atom(S) catch
+	  error:_ -> make_ref()
+	end,
+    B = try list_to_binary(S) catch
+	  error:_ -> make_ref()
+	end,
     proplist_lookup2({S, A, B}, P).
 
 proplist_lookup2({KS, KA, KB}, [{K, V} | _])
-  when KS =:= K orelse KA =:= K orelse KB =:= K ->
+    when KS =:= K orelse KA =:= K orelse KB =:= K ->
     {K, V};
 proplist_lookup2(Keys, [_ | Rest]) ->
     proplist_lookup2(Keys, Rest).
 
-format2([], _Args, _Module, Acc) ->
-    lists:reverse(Acc);
+format2([], _Args, _Module, Acc) -> lists:reverse(Acc);
 format2([{raw, S} | Rest], Args, Module, Acc) ->
     format2(Rest, Args, Module, [S | Acc]);
-format2([{format, {Key, Convert, Format0}} | Rest], Args, Module, Acc) ->
+format2([{format, {Key, Convert, Format0}} | Rest],
+	Args, Module, Acc) ->
     Format = f(Format0, Args, Module),
     V = case Module of
-            ?MODULE ->
-                V0 = get_field(Key, Args),
-                V1 = convert_field(V0, Convert),
-                format_field(V1, Format);
-            _ ->
-                V0 = try tuple_apply(Module, get_field, [Key, Args])
-                     catch error:undef -> get_field(Key, Args, Module) end,
-                V1 = try tuple_apply(Module, convert_field, [V0, Convert])
-                     catch error:undef -> convert_field(V0, Convert) end,
-                try tuple_apply(Module, format_field, [V1, Format])
-                catch error:undef -> format_field(V1, Format, Module) end
-        end,
+	  ?MODULE ->
+	      V0 = get_field(Key, Args),
+	      V1 = convert_field(V0, Convert),
+	      format_field(V1, Format);
+	  _ ->
+	      V0 = try tuple_apply(Module, get_field, [Key, Args])
+		   catch
+		     error:undef -> get_field(Key, Args, Module)
+		   end,
+	      V1 = try tuple_apply(Module, convert_field,
+				   [V0, Convert])
+		   catch
+		     error:undef -> convert_field(V0, Convert)
+		   end,
+	      try tuple_apply(Module, format_field, [V1, Format])
+	      catch
+		error:undef -> format_field(V1, Format, Module)
+	      end
+	end,
     format2(Rest, Args, Module, [V | Acc]).
 
-default_ctype(_Arg, C=#conversion{ctype=N}) when N =/= undefined ->
+default_ctype(_Arg, C = #conversion{ctype = N})
+    when N =/= undefined ->
     C;
 default_ctype(Arg, C) when is_integer(Arg) ->
-    C#conversion{ctype=decimal};
+    C#conversion{ctype = decimal};
 default_ctype(Arg, C) when is_float(Arg) ->
-    C#conversion{ctype=general};
-default_ctype(_Arg, C) ->
-    C#conversion{ctype=string}.
+    C#conversion{ctype = general};
+default_ctype(_Arg, C) -> C#conversion{ctype = string}.
 
-fix_padding(Arg, #conversion{length=undefined}) ->
+fix_padding(Arg, #conversion{length = undefined}) ->
     Arg;
-fix_padding(Arg, F=#conversion{length=Length, fill_char=Fill0, align=Align0,
-                               ctype=Type}) ->
+fix_padding(Arg,
+	    F = #conversion{length = Length, fill_char = Fill0,
+			    align = Align0, ctype = Type}) ->
     Padding = Length - iolist_size(Arg),
     Fill = case Fill0 of
-               undefined ->
-                   $\s;
-               _ ->
-                   Fill0
-           end,
+	     undefined -> $\s;
+	     _ -> Fill0
+	   end,
     Align = case Align0 of
-                undefined ->
-                    case Type of
-                        string ->
-                            left;
-                        _ ->
-                            right
-                    end;
-                _ ->
-                    Align0
-            end,
+	      undefined ->
+		  case Type of
+		    string -> left;
+		    _ -> right
+		  end;
+	      _ -> Align0
+	    end,
     case Padding > 0 of
-        true ->
-            do_padding(Arg, Padding, Fill, Align, F);
-        false ->
-            Arg
+      true -> do_padding(Arg, Padding, Fill, Align, F);
+      false -> Arg
     end.
 
 do_padding(Arg, Padding, Fill, right, _F) ->
@@ -263,31 +262,31 @@ do_padding(Arg, Padding, Fill, right, _F) ->
 do_padding(Arg, Padding, Fill, center, _F) ->
     LPadding = lists:duplicate(Padding div 2, Fill),
     RPadding = case Padding band 1 of
-                   1 ->
-                       [Fill | LPadding];
-                   _ ->
-                       LPadding
-               end,
+		 1 -> [Fill | LPadding];
+		 _ -> LPadding
+	       end,
     [LPadding, Arg, RPadding];
 do_padding([$- | Arg], Padding, Fill, sign_right, _F) ->
     [[$- | lists:duplicate(Padding, Fill)], Arg];
-do_padding(Arg, Padding, Fill, sign_right, #conversion{sign=$-}) ->
+do_padding(Arg, Padding, Fill, sign_right,
+	   #conversion{sign = $-}) ->
     [lists:duplicate(Padding, Fill), Arg];
-do_padding([S | Arg], Padding, Fill, sign_right, #conversion{sign=S}) ->
+do_padding([S | Arg], Padding, Fill, sign_right,
+	   #conversion{sign = S}) ->
     [[S | lists:duplicate(Padding, Fill)], Arg];
-do_padding(Arg, Padding, Fill, sign_right, #conversion{sign=undefined}) ->
+do_padding(Arg, Padding, Fill, sign_right,
+	   #conversion{sign = undefined}) ->
     [lists:duplicate(Padding, Fill), Arg];
 do_padding(Arg, Padding, Fill, left, _F) ->
     [Arg | lists:duplicate(Padding, Fill)].
 
-fix_sign(Arg, #conversion{sign=$+}) when Arg >= 0 ->
+fix_sign(Arg, #conversion{sign = $+}) when Arg >= 0 ->
     [$+, Arg];
-fix_sign(Arg, #conversion{sign=$\s}) when Arg >= 0 ->
+fix_sign(Arg, #conversion{sign = $\s}) when Arg >= 0 ->
     [$\s, Arg];
-fix_sign(Arg, _F) ->
-    Arg.
+fix_sign(Arg, _F) -> Arg.
 
-ctype($\%) -> percent;
+ctype($%) -> percent;
 ctype($s) -> string;
 ctype($b) -> bin;
 ctype($o) -> oct;
@@ -304,107 +303,123 @@ align($>) -> right;
 align($^) -> center;
 align($=) -> sign_right.
 
-convert2(Arg, F=#conversion{ctype=percent}) ->
-    [convert2(100.0 * Arg, F#conversion{ctype=fixed}), $\%];
-convert2(Arg, #conversion{ctype=string}) ->
-    str(Arg);
-convert2(Arg, #conversion{ctype=bin}) ->
+convert2(Arg, F = #conversion{ctype = percent}) ->
+    [convert2(1.0e+2 * Arg, F#conversion{ctype = fixed}),
+     $%];
+convert2(Arg, #conversion{ctype = string}) -> str(Arg);
+convert2(Arg, #conversion{ctype = bin}) ->
     erlang:integer_to_list(Arg, 2);
-convert2(Arg, #conversion{ctype=oct}) ->
+convert2(Arg, #conversion{ctype = oct}) ->
     erlang:integer_to_list(Arg, 8);
-convert2(Arg, #conversion{ctype=upper_hex}) ->
+convert2(Arg, #conversion{ctype = upper_hex}) ->
     erlang:integer_to_list(Arg, 16);
-convert2(Arg, #conversion{ctype=hex}) ->
+convert2(Arg, #conversion{ctype = hex}) ->
     string:to_lower(erlang:integer_to_list(Arg, 16));
-convert2(Arg, #conversion{ctype=char}) when Arg < 16#80 ->
+convert2(Arg, #conversion{ctype = char})
+    when Arg < 128 ->
     [Arg];
-convert2(Arg, #conversion{ctype=char}) ->
+convert2(Arg, #conversion{ctype = char}) ->
     xmerl_ucs:to_utf8(Arg);
-convert2(Arg, #conversion{ctype=decimal}) ->
+convert2(Arg, #conversion{ctype = decimal}) ->
     integer_to_list(Arg);
-convert2(Arg, #conversion{ctype=general, precision=undefined}) ->
-    try mochinum:digits(Arg)
-    catch error:undef -> io_lib:format("~g", [Arg]) end;
-convert2(Arg, #conversion{ctype=fixed, precision=undefined}) ->
+convert2(Arg,
+	 #conversion{ctype = general, precision = undefined}) ->
+    try mochinum:digits(Arg) catch
+      error:undef -> io_lib:format("~g", [Arg])
+    end;
+convert2(Arg,
+	 #conversion{ctype = fixed, precision = undefined}) ->
     io_lib:format("~f", [Arg]);
-convert2(Arg, #conversion{ctype=exp, precision=undefined}) ->
+convert2(Arg,
+	 #conversion{ctype = exp, precision = undefined}) ->
     io_lib:format("~e", [Arg]);
-convert2(Arg, #conversion{ctype=general, precision=P}) ->
+convert2(Arg,
+	 #conversion{ctype = general, precision = P}) ->
     io_lib:format("~." ++ integer_to_list(P) ++ "g", [Arg]);
-convert2(Arg, #conversion{ctype=fixed, precision=P}) ->
+convert2(Arg,
+	 #conversion{ctype = fixed, precision = P}) ->
     io_lib:format("~." ++ integer_to_list(P) ++ "f", [Arg]);
-convert2(Arg, #conversion{ctype=exp, precision=P}) ->
+convert2(Arg,
+	 #conversion{ctype = exp, precision = P}) ->
     io_lib:format("~." ++ integer_to_list(P) ++ "e", [Arg]).
 
-str(A) when is_atom(A) ->
-    atom_to_list(A);
-str(I) when is_integer(I) ->
-    integer_to_list(I);
+str(A) when is_atom(A) -> atom_to_list(A);
+str(I) when is_integer(I) -> integer_to_list(I);
 str(F) when is_float(F) ->
-    try mochinum:digits(F)
-    catch error:undef -> io_lib:format("~g", [F]) end;
-str(L) when is_list(L) ->
-    L;
-str(B) when is_binary(B) ->
-    B;
-str(P) ->
-    repr(P).
+    try mochinum:digits(F) catch
+      error:undef -> io_lib:format("~g", [F])
+    end;
+str(L) when is_list(L) -> L;
+str(B) when is_binary(B) -> B;
+str(P) -> repr(P).
 
 repr(P) when is_float(P) ->
-    try mochinum:digits(P)
-    catch error:undef -> float_to_list(P) end;
-repr(P) ->
-    io_lib:format("~p", [P]).
+    try mochinum:digits(P) catch
+      error:undef -> float_to_list(P)
+    end;
+repr(P) -> io_lib:format("~p", [P]).
 
 parse_std_conversion(S) ->
     parse_std_conversion(S, #conversion{}).
 
-parse_std_conversion("", Acc) ->
-    Acc;
+parse_std_conversion("", Acc) -> Acc;
 parse_std_conversion([Fill, Align | Spec], Acc)
-  when Align =:= $< orelse Align =:= $> orelse Align =:= $= orelse Align =:= $^ ->
-    parse_std_conversion(Spec, Acc#conversion{fill_char=Fill,
-                                              align=align(Align)});
+    when Align =:= $< orelse
+	   Align =:= $> orelse Align =:= $= orelse Align =:= $^ ->
+    parse_std_conversion(Spec,
+			 Acc#conversion{fill_char = Fill,
+					align = align(Align)});
 parse_std_conversion([Align | Spec], Acc)
-  when Align =:= $< orelse Align =:= $> orelse Align =:= $= orelse Align =:= $^ ->
-    parse_std_conversion(Spec, Acc#conversion{align=align(Align)});
+    when Align =:= $< orelse
+	   Align =:= $> orelse Align =:= $= orelse Align =:= $^ ->
+    parse_std_conversion(Spec,
+			 Acc#conversion{align = align(Align)});
 parse_std_conversion([Sign | Spec], Acc)
-  when Sign =:= $+ orelse Sign =:= $- orelse Sign =:= $\s ->
-    parse_std_conversion(Spec, Acc#conversion{sign=Sign});
+    when Sign =:= $+ orelse
+	   Sign =:= $- orelse Sign =:= $\s ->
+    parse_std_conversion(Spec, Acc#conversion{sign = Sign});
 parse_std_conversion("0" ++ Spec, Acc) ->
     Align = case Acc#conversion.align of
-                undefined ->
-                    sign_right;
-                A ->
-                    A
-            end,
-    parse_std_conversion(Spec, Acc#conversion{fill_char=$0, align=Align});
-parse_std_conversion(Spec=[D|_], Acc) when D >= $0 andalso D =< $9 ->
-    {W, Spec1} = lists:splitwith(fun (C) -> C >= $0 andalso C =< $9 end, Spec),
-    parse_std_conversion(Spec1, Acc#conversion{length=list_to_integer(W)});
+	      undefined -> sign_right;
+	      A -> A
+	    end,
+    parse_std_conversion(Spec,
+			 Acc#conversion{fill_char = $0, align = Align});
+parse_std_conversion(Spec = [D | _], Acc)
+    when D >= $0 andalso D =< $9 ->
+    {W, Spec1} = lists:splitwith(fun (C) ->
+					 C >= $0 andalso C =< $9
+				 end,
+				 Spec),
+    parse_std_conversion(Spec1,
+			 Acc#conversion{length = list_to_integer(W)});
 parse_std_conversion([$. | Spec], Acc) ->
-    case lists:splitwith(fun (C) -> C >= $0 andalso C =< $9 end, Spec) of
-        {"", Spec1} ->
-            parse_std_conversion(Spec1, Acc);
-        {P, Spec1} ->
-            parse_std_conversion(Spec1,
-                                 Acc#conversion{precision=list_to_integer(P)})
+    case lists:splitwith(fun (C) -> C >= $0 andalso C =< $9
+			 end,
+			 Spec)
+	of
+      {"", Spec1} -> parse_std_conversion(Spec1, Acc);
+      {P, Spec1} ->
+	  parse_std_conversion(Spec1,
+			       Acc#conversion{precision = list_to_integer(P)})
     end;
 parse_std_conversion([Type], Acc) ->
-    parse_std_conversion("", Acc#conversion{ctype=ctype(Type)}).
-
+    parse_std_conversion("",
+			 Acc#conversion{ctype = ctype(Type)}).
 
 %%
 %% Tests
 %%
 -ifdef(TEST).
+
 -include_lib("eunit/include/eunit.hrl").
 
 tokenize_test() ->
     {?MODULE, [{raw, "ABC"}]} = tokenize("ABC"),
     {?MODULE, [{format, {"0", "", ""}}]} = tokenize("{0}"),
-    {?MODULE, [{raw, "ABC"}, {format, {"1", "", ""}}, {raw, "DEF"}]} =
-        tokenize("ABC{1}DEF"),
+    {?MODULE,
+     [{raw, "ABC"}, {format, {"1", "", ""}}, {raw, "DEF"}]} =
+	tokenize("ABC{1}DEF"),
     ok.
 
 format_test() ->
@@ -413,26 +428,31 @@ format_test() ->
     <<"   4">> = bformat("{0:{0}}", [4]),
     <<"4   ">> = bformat("{0:4}", ["4"]),
     <<"4   ">> = bformat("{0:{0}}", ["4"]),
-    <<"1.2yoDEF">> = bformat("{2}{0}{1}{3}", {yo, "DE", 1.2, <<"F">>}),
-    <<"cafebabe">> = bformat("{0:x}", {16#cafebabe}),
-    <<"CAFEBABE">> = bformat("{0:X}", {16#cafebabe}),
-    <<"CAFEBABE">> = bformat("{0:X}", {16#cafebabe}),
-    <<"755">> = bformat("{0:o}", {8#755}),
+    <<"1.2yoDEF">> = bformat("{2}{0}{1}{3}",
+			     {yo, "DE", 1.19999999999999995559, <<"F">>}),
+    <<"cafebabe">> = bformat("{0:x}", {3405691582}),
+    <<"CAFEBABE">> = bformat("{0:X}", {3405691582}),
+    <<"CAFEBABE">> = bformat("{0:X}", {3405691582}),
+    <<"755">> = bformat("{0:o}", {493}),
     <<"a">> = bformat("{0:c}", {97}),
     %% Horizontal ellipsis
-    <<226, 128, 166>> = bformat("{0:c}", {16#2026}),
+    <<226, 128, 166>> = bformat("{0:c}", {8230}),
     <<"11">> = bformat("{0:b}", {3}),
     <<"11">> = bformat("{0:b}", [3]),
     <<"11">> = bformat("{three:b}", [{three, 3}]),
     <<"11">> = bformat("{three:b}", [{"three", 3}]),
     <<"11">> = bformat("{three:b}", [{<<"three">>, 3}]),
     <<"\"foo\"">> = bformat("{0!r}", {"foo"}),
-    <<"2008-5-4">> = bformat("{0.0}-{0.1}-{0.2}", {{2008,5,4}}),
-    <<"2008-05-04">> = bformat("{0.0:04}-{0.1:02}-{0.2:02}", {{2008,5,4}}),
+    <<"2008-5-4">> = bformat("{0.0}-{0.1}-{0.2}",
+			     {{2008, 5, 4}}),
+    <<"2008-05-04">> = bformat("{0.0:04}-{0.1:02}-{0.2:02}",
+			       {{2008, 5, 4}}),
     <<"foo6bar-6">> = bformat("foo{1}{0}-{1}", {bar, 6}),
-    <<"-'atom test'-">> = bformat("-{arg!r}-", [{arg, 'atom test'}]),
-    <<"2008-05-04">> = bformat("{0.0:0{1.0}}-{0.1:0{1.1}}-{0.2:0{1.2}}",
-                               {{2008,5,4}, {4, 2, 2}}),
+    <<"-'atom test'-">> = bformat("-{arg!r}-",
+				  [{arg, 'atom test'}]),
+    <<"2008-05-04">> =
+	bformat("{0.0:0{1.0}}-{0.1:0{1.1}}-{0.2:0{1.2}}",
+		{{2008, 5, 4}, {4, 2, 2}}),
     ok.
 
 std_test() ->
@@ -441,13 +461,16 @@ std_test() ->
     ok.
 
 records_test() ->
-    M = mochifmt_records:new([{conversion, record_info(fields, conversion)}]),
-    R = #conversion{length=long, precision=hard, sign=peace},
+    M = mochifmt_records:new([{conversion,
+			       record_info(fields, conversion)}]),
+    R = #conversion{length = long, precision = hard,
+		    sign = peace},
     long = mochifmt_records:get_value("length", R, M),
     hard = mochifmt_records:get_value("precision", R, M),
     peace = mochifmt_records:get_value("sign", R, M),
     <<"long hard">> = bformat("{length} {precision}", R, M),
-    <<"long hard">> = bformat("{0.length} {0.precision}", [R], M),
+    <<"long hard">> = bformat("{0.length} {0.precision}",
+			      [R], M),
     ok.
 
 -endif.
diff --git a/src/mochiweb_acceptor.erl b/src/mochiweb_acceptor.erl
index 1b53552..2fed6bd 100644
--- a/src/mochiweb_acceptor.erl
+++ b/src/mochiweb_acceptor.erl
@@ -22,11 +22,12 @@
 %% @doc MochiWeb acceptor.
 
 -module(mochiweb_acceptor).
+
 -author('bob@mochimedia.com').
 
 -include("internal.hrl").
 
--export([start_link/3, start_link/4, init/4]).
+-export([init/4, start_link/3, start_link/4]).
 
 -define(EMFILE_SLEEP_MSEC, 100).
 
@@ -34,43 +35,40 @@ start_link(Server, Listen, Loop) ->
     start_link(Server, Listen, Loop, []).
 
 start_link(Server, Listen, Loop, Opts) ->
-    proc_lib:spawn_link(?MODULE, init, [Server, Listen, Loop, Opts]).
+    proc_lib:spawn_link(?MODULE, init,
+			[Server, Listen, Loop, Opts]).
 
 do_accept(Server, Listen) ->
     T1 = os:timestamp(),
     case mochiweb_socket:transport_accept(Listen) of
-        {ok, Socket} ->
-            gen_server:cast(Server, {accepted, self(), timer:now_diff(os:timestamp(), T1)}),
-            mochiweb_socket:finish_accept(Socket);
-        Other ->
-            Other
+      {ok, Socket} ->
+	  gen_server:cast(Server,
+			  {accepted, self(),
+			   timer:now_diff(os:timestamp(), T1)}),
+	  mochiweb_socket:finish_accept(Socket);
+      Other -> Other
     end.
 
 init(Server, Listen, Loop, Opts) ->
     case catch do_accept(Server, Listen) of
-        {ok, Socket} ->
-            call_loop(Loop, Socket, Opts);
-        {error, Err} when Err =:= closed orelse
-                          Err =:= esslaccept orelse
-                          Err =:= timeout ->
-            exit(normal);
-        Other ->
-            %% Mitigate out of file descriptor scenario by sleeping for a
-            %% short time to slow error rate
-            case Other of
-                {error, emfile} ->
-                    receive
-                    after ?EMFILE_SLEEP_MSEC ->
-                            ok
-                    end;
-                _ ->
-                    ok
-            end,
-            error_logger:error_report(
-              [{application, mochiweb},
-               "Accept failed error",
-               lists:flatten(io_lib:format("~p", [Other]))]),
-            exit({error, accept_failed})
+      {ok, Socket} -> call_loop(Loop, Socket, Opts);
+      {error, Err}
+	  when Err =:= closed orelse
+		 Err =:= esslaccept orelse Err =:= timeout ->
+	  exit(normal);
+      Other ->
+	  %% Mitigate out of file descriptor scenario by sleeping for a
+	  %% short time to slow error rate
+	  case Other of
+	    {error, emfile} ->
+		receive  after ?EMFILE_SLEEP_MSEC -> ok end;
+	    _ -> ok
+	  end,
+	  error_logger:error_report([{application, mochiweb},
+				     "Accept failed error",
+				     lists:flatten(io_lib:format("~p",
+								 [Other]))]),
+	  exit({error, accept_failed})
     end.
 
 call_loop({M, F}, Socket, Opts) when is_atom(M) ->
@@ -79,5 +77,4 @@ call_loop({M, F, [A1]}, Socket, Opts) when is_atom(M) ->
     M:F(Socket, Opts, A1);
 call_loop({M, F, A}, Socket, Opts) when is_atom(M) ->
     erlang:apply(M, F, [Socket, Opts | A]);
-call_loop(Loop, Socket, Opts) ->
-    Loop(Socket, Opts).
+call_loop(Loop, Socket, Opts) -> Loop(Socket, Opts).
diff --git a/src/mochiweb_http.erl b/src/mochiweb_http.erl
index 6854b6a..aff95aa 100644
--- a/src/mochiweb_http.erl
+++ b/src/mochiweb_http.erl
@@ -22,38 +22,47 @@
 %% @doc HTTP server.
 
 -module(mochiweb_http).
+
 -author('bob@mochimedia.com').
+
 -export([start/1, start_link/1, stop/0, stop/1]).
+
 -export([loop/3]).
+
 -export([after_response/2, reentry/1]).
+
 -export([parse_range_request/1, range_skip_length/2]).
 
--define(REQUEST_RECV_TIMEOUT, 300000).   %% timeout waiting for request line
--define(HEADERS_RECV_TIMEOUT, 30000).    %% timeout waiting for headers
+-define(REQUEST_RECV_TIMEOUT,
+	300000).   %% timeout waiting for request line
+
+-define(HEADERS_RECV_TIMEOUT,
+	30000).    %% timeout waiting for headers
 
 -define(MAX_HEADERS, 1000).
--define(DEFAULTS, [{name, ?MODULE},
-                   {port, 8888}]).
+
+-define(DEFAULTS, [{name, ?MODULE}, {port, 8888}]).
 
 -ifdef(gen_tcp_r15b_workaround).
-r15b_workaround() -> true.
--else.
+
 r15b_workaround() -> false.
--endif.
 
+-else.
+
+r15b_workaround() -> false.
 
+-endif.
 
 parse_options(Options) ->
     {loop, HttpLoop} = proplists:lookup(loop, Options),
     Loop = {?MODULE, loop, [HttpLoop]},
-    Options1 = [{loop, Loop} | proplists:delete(loop, Options)],
+    Options1 = [{loop, Loop} | proplists:delete(loop,
+						Options)],
     mochilists:set_defaults(?DEFAULTS, Options1).
 
-stop() ->
-    mochiweb_socket_server:stop(?MODULE).
+stop() -> mochiweb_socket_server:stop(?MODULE).
 
-stop(Name) ->
-    mochiweb_socket_server:stop(Name).
+stop(Name) -> mochiweb_socket_server:stop(Name).
 
 %% @spec start(Options) -> ServerRet
 %%     Options = [option()]
@@ -76,240 +85,263 @@ start_link(Options) ->
 
 ensure_started(M) when is_atom(M) ->
     case M:start() of
-        {ok, _Pid} ->
-            ok;
-        {error, {already_started, _Pid}} ->
-            ok
+      {ok, _Pid} -> ok;
+      {error, {already_started, _Pid}} -> ok
     end.
 
 loop(Socket, Opts, Body) ->
-    ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, http}])),
+    ok =
+	mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+							       [{packet,
+								 http}])),
     request(Socket, Opts, Body).
 
 request(Socket, Opts, Body) ->
-    ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{active, once}])),
+    ok =
+	mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+							       [{active,
+								 once}])),
     receive
-        {Protocol, _, {http_request, Method, Path, Version}} when Protocol == http orelse Protocol == ssl ->
-            ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, httph}])),
-            headers(Socket, Opts, {Method, Path, Version}, [], Body, 0);
-        {Protocol, _, {http_error, "\r\n"}} when Protocol == http orelse Protocol == ssl ->
-            request(Socket, Opts, Body);
-        {Protocol, _, {http_error, "\n"}} when Protocol == http orelse Protocol == ssl ->
-            request(Socket, Opts, Body);
-        {tcp_closed, _} ->
-            mochiweb_socket:close(Socket),
-            exit(normal);
-        {tcp_error, _, emsgsize} = Other ->
-            handle_invalid_msg_request(Other, Socket, Opts);
-        {ssl_closed, _} ->
-            mochiweb_socket:close(Socket),
-            exit(normal)
-    after ?REQUEST_RECV_TIMEOUT ->
-        mochiweb_socket:close(Socket),
-        exit(normal)
+      {Protocol, _, {http_request, Method, Path, Version}}
+	  when Protocol == http orelse Protocol == ssl ->
+	  ok =
+	      mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+								     [{packet,
+								       httph}])),
+	  headers(Socket, Opts, {Method, Path, Version}, [], Body,
+		  0);
+      {Protocol, _, {http_error, "\r\n"}}
+	  when Protocol == http orelse Protocol == ssl ->
+	  request(Socket, Opts, Body);
+      {Protocol, _, {http_error, "\n"}}
+	  when Protocol == http orelse Protocol == ssl ->
+	  request(Socket, Opts, Body);
+      {tcp_closed, _} ->
+	  mochiweb_socket:close(Socket), exit(normal);
+      {tcp_error, _, emsgsize} = Other ->
+	  handle_invalid_msg_request(Other, Socket, Opts);
+      {ssl_closed, _} ->
+	  mochiweb_socket:close(Socket), exit(normal)
+      after ?REQUEST_RECV_TIMEOUT ->
+		mochiweb_socket:close(Socket), exit(normal)
     end.
 
 reentry(Body) ->
-    fun (Req) ->
-            ?MODULE:after_response(Body, Req)
-    end.
+    fun (Req) -> (?MODULE):after_response(Body, Req) end.
 
-headers(Socket, Opts, Request, Headers, _Body, ?MAX_HEADERS) ->
+headers(Socket, Opts, Request, Headers, _Body,
+	?MAX_HEADERS) ->
     %% Too many headers sent, bad request.
-    ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, raw}])),
+    ok =
+	mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+							       [{packet,
+								 raw}])),
     handle_invalid_request(Socket, Opts, Request, Headers);
-headers(Socket, Opts, Request, Headers, Body, HeaderCount) ->
-    ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{active, once}])),
+headers(Socket, Opts, Request, Headers, Body,
+	HeaderCount) ->
+    ok =
+	mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+							       [{active,
+								 once}])),
     receive
-        {Protocol, _, http_eoh} when Protocol == http orelse Protocol == ssl ->
-            Req = new_request(Socket, Opts, Request, Headers),
-            call_body(Body, Req),
-            ?MODULE:after_response(Body, Req);
-        {Protocol, _, {http_header, _, Name, _, Value}} when Protocol == http orelse Protocol == ssl ->
-            headers(Socket, Opts, Request, [{Name, Value} | Headers], Body,
-                    1 + HeaderCount);
-        {tcp_closed, _} ->
-            mochiweb_socket:close(Socket),
-            exit(normal);
-        {tcp_error, _, emsgsize} = Other ->
-            handle_invalid_msg_request(Other, Socket, Opts, Request, Headers)
-    after ?HEADERS_RECV_TIMEOUT ->
-        mochiweb_socket:close(Socket),
-        exit(normal)
+      {Protocol, _, http_eoh}
+	  when Protocol == http orelse Protocol == ssl ->
+	  Req = new_request(Socket, Opts, Request, Headers),
+	  call_body(Body, Req),
+	  (?MODULE):after_response(Body, Req);
+      {Protocol, _, {http_header, _, Name, _, Value}}
+	  when Protocol == http orelse Protocol == ssl ->
+	  headers(Socket, Opts, Request,
+		  [{Name, Value} | Headers], Body, 1 + HeaderCount);
+      {tcp_closed, _} ->
+	  mochiweb_socket:close(Socket), exit(normal);
+      {tcp_error, _, emsgsize} = Other ->
+	  handle_invalid_msg_request(Other, Socket, Opts, Request,
+				     Headers)
+      after ?HEADERS_RECV_TIMEOUT ->
+		mochiweb_socket:close(Socket), exit(normal)
     end.
 
 call_body({M, F, A}, Req) when is_atom(M) ->
     erlang:apply(M, F, [Req | A]);
-call_body({M, F}, Req) when is_atom(M) ->
-    M:F(Req);
-call_body(Body, Req) ->
-    Body(Req).
+call_body({M, F}, Req) when is_atom(M) -> M:F(Req);
+call_body(Body, Req) -> Body(Req).
+
+-spec handle_invalid_msg_request(term(), term(),
+				 term()) -> no_return().
 
--spec handle_invalid_msg_request(term(), term(), term()) -> no_return().
 handle_invalid_msg_request(Msg, Socket, Opts) ->
-    handle_invalid_msg_request(Msg, Socket, Opts, {'GET', {abs_path, "/"}, {0,9}}, []).
+    handle_invalid_msg_request(Msg, Socket, Opts,
+			       {'GET', {abs_path, "/"}, {0, 9}}, []).
+
+-spec handle_invalid_msg_request(term(), term(), term(),
+				 term(), term()) -> no_return().
 
--spec handle_invalid_msg_request(term(), term(), term(), term(), term()) -> no_return().
-handle_invalid_msg_request(Msg, Socket, Opts, Request, RevHeaders) ->
+handle_invalid_msg_request(Msg, Socket, Opts, Request,
+			   RevHeaders) ->
     case {Msg, r15b_workaround()} of
-        {{tcp_error,_,emsgsize}, true} ->
-            %% R15B02 returns this then closes the socket, so close and exit
-            mochiweb_socket:close(Socket),
-            exit(normal);
-        _ ->
-            handle_invalid_request(Socket, Opts, Request, RevHeaders)
+      {{tcp_error, _, emsgsize}, true} ->
+	  %% R15B02 returns this then closes the socket, so close and exit
+	  mochiweb_socket:close(Socket),
+	  exit(normal);
+      _ ->
+	  handle_invalid_request(Socket, Opts, Request,
+				 RevHeaders)
     end.
 
--spec handle_invalid_request(term(), term(), term(), term()) -> no_return().
-handle_invalid_request(Socket, Opts, Request, RevHeaders) ->
-    {ReqM, _} = Req = new_request(Socket, Opts, Request, RevHeaders),
+-spec handle_invalid_request(term(), term(), term(),
+			     term()) -> no_return().
+
+handle_invalid_request(Socket, Opts, Request,
+		       RevHeaders) ->
+    {ReqM, _} = Req = new_request(Socket, Opts, Request,
+				  RevHeaders),
     ReqM:respond({400, [], []}, Req),
     mochiweb_socket:close(Socket),
     exit(normal).
 
 new_request(Socket, Opts, Request, RevHeaders) ->
-    ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, raw}])),
-    mochiweb:new_request({Socket, Opts, Request, lists:reverse(RevHeaders)}).
+    ok =
+	mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+							       [{packet,
+								 raw}])),
+    mochiweb:new_request({Socket, Opts, Request,
+			  lists:reverse(RevHeaders)}).
 
 after_response(Body, {ReqM, _} = Req) ->
     Socket = ReqM:get(socket, Req),
     case ReqM:should_close(Req) of
-        true ->
-            mochiweb_socket:close(Socket),
-            exit(normal);
-        false ->
-            ReqM:cleanup(Req),
-            erlang:garbage_collect(),
-            ?MODULE:loop(Socket, mochiweb_request:get(opts, Req), Body)
+      true -> mochiweb_socket:close(Socket), exit(normal);
+      false ->
+	  ReqM:cleanup(Req),
+	  erlang:garbage_collect(),
+	  (?MODULE):loop(Socket, mochiweb_request:get(opts, Req),
+			 Body)
     end.
 
 parse_range_request(RawRange) when is_list(RawRange) ->
-    try
-        "bytes=" ++ RangeString = RawRange,
-        RangeTokens = [string:strip(R) || R <- string:tokens(RangeString, ",")],
-        Ranges = [R || R <- RangeTokens, string:len(R) > 0],
-        lists:map(fun ("-" ++ V)  ->
-                          {none, list_to_integer(V)};
-                      (R) ->
-                          case string:tokens(R, "-") of
-                              [S1, S2] ->
-                                  {list_to_integer(S1), list_to_integer(S2)};
-                              [S] ->
-                                  {list_to_integer(S), none}
-                          end
-                  end,
-                  Ranges)
+    try "bytes=" ++ RangeString = RawRange,
+	RangeTokens = [string:strip(R)
+		       || R <- string:tokens(RangeString, ",")],
+	Ranges = [R || R <- RangeTokens, string:len(R) > 0],
+	[parse_range_request_1(V1) || V1 <- Ranges]
     catch
-        _:_ ->
-            fail
+      _:_ -> fail
+    end.
+
+parse_range_request_1("-" ++ V) ->
+    {none, list_to_integer(V)};
+parse_range_request_1(R) ->
+    case string:tokens(R, "-") of
+      [S1, S2] -> {list_to_integer(S1), list_to_integer(S2)};
+      [S] -> {list_to_integer(S), none}
     end.
 
 range_skip_length(Spec, Size) ->
     case Spec of
-        {none, R} when R =< Size, R >= 0 ->
-            {Size - R, R};
-        {none, _OutOfRange} ->
-            {0, Size};
-        {R, none} when R >= 0, R < Size ->
-            {R, Size - R};
-        {_OutOfRange, none} ->
-            invalid_range;
-        {Start, End} when Start >= 0, Start < Size, Start =< End ->
-            {Start, erlang:min(End + 1, Size) - Start};
-        {_InvalidStart, _InvalidEnd} ->
-            invalid_range
+      {none, R} when R =< Size, R >= 0 -> {Size - R, R};
+      {none, _OutOfRange} -> {0, Size};
+      {R, none} when R >= 0, R < Size -> {R, Size - R};
+      {_OutOfRange, none} -> invalid_range;
+      {Start, End}
+	  when Start >= 0, Start < Size, Start =< End ->
+	  {Start, erlang:min(End + 1, Size) - Start};
+      {_InvalidStart, _InvalidEnd} -> invalid_range
     end.
 
 %%
 %% Tests
 %%
 -ifdef(TEST).
+
 -include_lib("eunit/include/eunit.hrl").
 
 range_test() ->
     %% valid, single ranges
-    ?assertEqual([{20, 30}], parse_range_request("bytes=20-30")),
-    ?assertEqual([{20, none}], parse_range_request("bytes=20-")),
-    ?assertEqual([{none, 20}], parse_range_request("bytes=-20")),
-
+    ?assertEqual([{20, 30}],
+		 (parse_range_request("bytes=20-30"))),
+    ?assertEqual([{20, none}],
+		 (parse_range_request("bytes=20-"))),
+    ?assertEqual([{none, 20}],
+		 (parse_range_request("bytes=-20"))),
     %% trivial single range
-    ?assertEqual([{0, none}], parse_range_request("bytes=0-")),
-
+    ?assertEqual([{0, none}],
+		 (parse_range_request("bytes=0-"))),
     %% invalid, single ranges
-    ?assertEqual(fail, parse_range_request("")),
-    ?assertEqual(fail, parse_range_request("garbage")),
-    ?assertEqual(fail, parse_range_request("bytes=-20-30")),
-
+    ?assertEqual(fail, (parse_range_request(""))),
+    ?assertEqual(fail, (parse_range_request("garbage"))),
+    ?assertEqual(fail,
+		 (parse_range_request("bytes=-20-30"))),
     %% valid, multiple range
-    ?assertEqual(
-       [{20, 30}, {50, 100}, {110, 200}],
-       parse_range_request("bytes=20-30,50-100,110-200")),
-    ?assertEqual(
-       [{20, none}, {50, 100}, {none, 200}],
-       parse_range_request("bytes=20-,50-100,-200")),
-
+    ?assertEqual([{20, 30}, {50, 100}, {110, 200}],
+		 (parse_range_request("bytes=20-30,50-100,110-200"))),
+    ?assertEqual([{20, none}, {50, 100}, {none, 200}],
+		 (parse_range_request("bytes=20-,50-100,-200"))),
     %% valid, multiple range with whitespace
-    ?assertEqual(
-       [{20, 30}, {50, 100}, {110, 200}],
-       parse_range_request("bytes=20-30, 50-100 , 110-200")),
-
+    ?assertEqual([{20, 30}, {50, 100}, {110, 200}],
+		 (parse_range_request("bytes=20-30, 50-100 , 110-200"))),
     %% valid, multiple range with extra commas
-    ?assertEqual(
-       [{20, 30}, {50, 100}, {110, 200}],
-       parse_range_request("bytes=20-30,,50-100,110-200")),
-    ?assertEqual(
-       [{20, 30}, {50, 100}, {110, 200}],
-       parse_range_request("bytes=20-30, ,50-100,,,110-200")),
-
+    ?assertEqual([{20, 30}, {50, 100}, {110, 200}],
+		 (parse_range_request("bytes=20-30,,50-100,110-200"))),
+    ?assertEqual([{20, 30}, {50, 100}, {110, 200}],
+		 (parse_range_request("bytes=20-30, ,50-100,,,110-200"))),
     %% no ranges
-    ?assertEqual([], parse_range_request("bytes=")),
+    ?assertEqual([], (parse_range_request("bytes="))),
     ok.
 
 range_skip_length_test() ->
-    Body = <<"012345678901234567890123456789012345678901234567890123456789">>,
+    Body = <<"012345678901234567890123456789012345678901234"
+	     "567890123456789">>,
     BodySize = byte_size(Body), %% 60
     BodySize = 60,
-
     %% these values assume BodySize =:= 60
-    ?assertEqual({1,9}, range_skip_length({1,9}, BodySize)), %% 1-9
-    ?assertEqual({10,10}, range_skip_length({10,19}, BodySize)), %% 10-19
-    ?assertEqual({40, 20}, range_skip_length({none, 20}, BodySize)), %% -20
-    ?assertEqual({30, 30}, range_skip_length({30, none}, BodySize)), %% 30-
-
+    ?assertEqual({1, 9},
+		 (range_skip_length({1, 9}, BodySize))), %% 1-9
+    ?assertEqual({10, 10},
+		 (range_skip_length({10, 19}, BodySize))), %% 10-19
+    ?assertEqual({40, 20},
+		 (range_skip_length({none, 20}, BodySize))), %% -20
+    ?assertEqual({30, 30},
+		 (range_skip_length({30, none}, BodySize))), %% 30-
     %% valid edge cases for range_skip_length
-    ?assertEqual({BodySize, 0}, range_skip_length({none, 0}, BodySize)),
-    ?assertEqual({0, BodySize}, range_skip_length({none, BodySize}, BodySize)),
-    ?assertEqual({0, BodySize}, range_skip_length({0, none}, BodySize)),
-    ?assertEqual({0, BodySize}, range_skip_length({0, BodySize + 1}, BodySize)),
+    ?assertEqual({BodySize, 0},
+		 (range_skip_length({none, 0}, BodySize))),
+    ?assertEqual({0, BodySize},
+		 (range_skip_length({none, BodySize}, BodySize))),
+    ?assertEqual({0, BodySize},
+		 (range_skip_length({0, none}, BodySize))),
+    ?assertEqual({0, BodySize},
+		 (range_skip_length({0, BodySize + 1}, BodySize))),
     BodySizeLess1 = BodySize - 1,
     ?assertEqual({BodySizeLess1, 1},
-                 range_skip_length({BodySize - 1, none}, BodySize)),
+		 (range_skip_length({BodySize - 1, none}, BodySize))),
     ?assertEqual({BodySizeLess1, 1},
-                 range_skip_length({BodySize - 1, BodySize+5}, BodySize)),
+		 (range_skip_length({BodySize - 1, BodySize + 5},
+				    BodySize))),
     ?assertEqual({BodySizeLess1, 1},
-                 range_skip_length({BodySize - 1, BodySize}, BodySize)),
-
+		 (range_skip_length({BodySize - 1, BodySize},
+				    BodySize))),
     %% out of range, return whole thing
     ?assertEqual({0, BodySize},
-                 range_skip_length({none, BodySize + 1}, BodySize)),
+		 (range_skip_length({none, BodySize + 1}, BodySize))),
     ?assertEqual({0, BodySize},
-                 range_skip_length({none, -1}, BodySize)),
+		 (range_skip_length({none, -1}, BodySize))),
     ?assertEqual({0, BodySize},
-                 range_skip_length({0, BodySize + 1}, BodySize)),
-
+		 (range_skip_length({0, BodySize + 1}, BodySize))),
     %% invalid ranges
     ?assertEqual(invalid_range,
-                 range_skip_length({-1, 30}, BodySize)),
+		 (range_skip_length({-1, 30}, BodySize))),
     ?assertEqual(invalid_range,
-                 range_skip_length({-1, BodySize + 1}, BodySize)),
+		 (range_skip_length({-1, BodySize + 1}, BodySize))),
     ?assertEqual(invalid_range,
-                 range_skip_length({BodySize, 40}, BodySize)),
+		 (range_skip_length({BodySize, 40}, BodySize))),
     ?assertEqual(invalid_range,
-                 range_skip_length({-1, none}, BodySize)),
+		 (range_skip_length({-1, none}, BodySize))),
     ?assertEqual(invalid_range,
-                 range_skip_length({BodySize, none}, BodySize)),
+		 (range_skip_length({BodySize, none}, BodySize))),
     ?assertEqual(invalid_range,
-                 range_skip_length({BodySize + 1, BodySize + 5}, BodySize)),
+		 (range_skip_length({BodySize + 1, BodySize + 5},
+				    BodySize))),
     ok.
 
 -endif.
diff --git a/src/mochiweb_multipart.erl b/src/mochiweb_multipart.erl
index 46b7090..21b23bb 100644
--- a/src/mochiweb_multipart.erl
+++ b/src/mochiweb_multipart.erl
@@ -22,16 +22,21 @@
 %% @doc Utilities for parsing multipart/form-data.
 
 -module(mochiweb_multipart).
+
 -author('bob@mochimedia.com').
 
 -export([parse_form/1, parse_form/2]).
+
 -export([parse_multipart_request/2]).
+
 -export([parts_to_body/3, parts_to_multipart_body/4]).
+
 -export([default_file_handler/2]).
 
 -define(CHUNKSIZE, 4096).
 
--record(mp, {state, boundary, length, buffer, callback, req}).
+-record(mp,
+	{state, boundary, length, buffer, callback, req}).
 
 %% TODO: DOCUMENT THIS MODULE.
 %% @type key() = atom() | string() | binary().
@@ -47,28 +52,30 @@
 %%                     Size::integer()) -> {[header()], iolist()}
 %% @doc Return {[header()], iolist()} representing the body for the given
 %%      parts, may be a single part or multipart.
-parts_to_body([{Start, End, Body}], ContentType, Size) ->
+parts_to_body([{Start, End, Body}], ContentType,
+	      Size) ->
     HeaderList = [{"Content-Type", ContentType},
-                  {"Content-Range",
-                   ["bytes ",
-                    mochiweb_util:make_io(Start), "-", mochiweb_util:make_io(End),
-                    "/", mochiweb_util:make_io(Size)]}],
+		  {"Content-Range",
+		   ["bytes ", mochiweb_util:make_io(Start), "-",
+		    mochiweb_util:make_io(End), "/",
+		    mochiweb_util:make_io(Size)]}],
     {HeaderList, Body};
-parts_to_body(BodyList, ContentType, Size) when is_list(BodyList) ->
+parts_to_body(BodyList, ContentType, Size)
+    when is_list(BodyList) ->
     parts_to_multipart_body(BodyList, ContentType, Size,
-                            mochihex:to_hex(crypto:strong_rand_bytes(8))).
+			    mochihex:to_hex(crypto:strong_rand_bytes(8))).
 
 %% @spec parts_to_multipart_body([bodypart()], ContentType::string(),
 %%                               Size::integer(), Boundary::string()) ->
 %%           {[header()], iolist()}
 %% @doc Return {[header()], iolist()} representing the body for the given
 %%      parts, always a multipart response.
-parts_to_multipart_body(BodyList, ContentType, Size, Boundary) ->
+parts_to_multipart_body(BodyList, ContentType, Size,
+			Boundary) ->
     HeaderList = [{"Content-Type",
-                   ["multipart/byteranges; ",
-                    "boundary=", Boundary]}],
-    MultiPartBody = multipart_body(BodyList, ContentType, Boundary, Size),
-
+		   ["multipart/byteranges; ", "boundary=", Boundary]}],
+    MultiPartBody = multipart_body(BodyList, ContentType,
+				   Boundary, Size),
     {HeaderList, MultiPartBody}.
 
 %% @spec multipart_body([bodypart()], ContentType::string(),
@@ -76,14 +83,15 @@ parts_to_multipart_body(BodyList, ContentType, Size, Boundary) ->
 %% @doc Return the representation of a multipart body for the given [bodypart()].
 multipart_body([], _ContentType, Boundary, _Size) ->
     ["--", Boundary, "--\r\n"];
-multipart_body([{Start, End, Body} | BodyList], ContentType, Boundary, Size) ->
-    ["--", Boundary, "\r\n",
-     "Content-Type: ", ContentType, "\r\n",
-     "Content-Range: ",
-         "bytes ", mochiweb_util:make_io(Start), "-", mochiweb_util:make_io(End),
-             "/", mochiweb_util:make_io(Size), "\r\n\r\n",
-     Body, "\r\n"
-     | multipart_body(BodyList, ContentType, Boundary, Size)].
+multipart_body([{Start, End, Body} | BodyList],
+	       ContentType, Boundary, Size) ->
+    ["--", Boundary, "\r\n", "Content-Type: ", ContentType,
+     "\r\n", "Content-Range: ", "bytes ",
+     mochiweb_util:make_io(Start), "-",
+     mochiweb_util:make_io(End), "/",
+     mochiweb_util:make_io(Size), "\r\n\r\n", Body, "\r\n"
+     | multipart_body(BodyList, ContentType, Boundary,
+		      Size)].
 
 %% @spec parse_form(request()) -> [{string(), string() | formfile()}]
 %% @doc Parse a multipart form from the given request using the in-memory
@@ -94,168 +102,196 @@ parse_form(Req) ->
 %% @spec parse_form(request(), F::file_handler()) -> [{string(), string() | term()}]
 %% @doc Parse a multipart form from the given request using the given file_handler().
 parse_form(Req, FileHandler) ->
-    Callback = fun (Next) -> parse_form_outer(Next, FileHandler, []) end,
+    Callback = fun (Next) ->
+		       parse_form_outer(Next, FileHandler, [])
+	       end,
     {_, _, Res} = parse_multipart_request(Req, Callback),
     Res.
 
-parse_form_outer(eof, _, Acc) ->
-    lists:reverse(Acc);
+parse_form_outer(eof, _, Acc) -> lists:reverse(Acc);
 parse_form_outer({headers, H}, FileHandler, State) ->
-    {"form-data", H1} = proplists:get_value("content-disposition", H),
+    {"form-data", H1} =
+	proplists:get_value("content-disposition", H),
     Name = proplists:get_value("name", H1),
     Filename = proplists:get_value("filename", H1),
     case Filename of
-        undefined ->
-            fun (Next) ->
-                    parse_form_value(Next, {Name, []}, FileHandler, State)
-            end;
-        _ ->
-            ContentType = proplists:get_value("content-type", H),
-            Handler = FileHandler(Filename, ContentType),
-            fun (Next) ->
-                    parse_form_file(Next, {Name, Handler}, FileHandler, State)
-            end
+      undefined ->
+	  fun (Next) ->
+		  parse_form_value(Next, {Name, []}, FileHandler, State)
+	  end;
+      _ ->
+	  ContentType = proplists:get_value("content-type", H),
+	  Handler = FileHandler(Filename, ContentType),
+	  fun (Next) ->
+		  parse_form_file(Next, {Name, Handler}, FileHandler,
+				  State)
+	  end
     end.
 
-parse_form_value(body_end, {Name, Acc}, FileHandler, State) ->
-    Value = binary_to_list(iolist_to_binary(lists:reverse(Acc))),
+parse_form_value(body_end, {Name, Acc}, FileHandler,
+		 State) ->
+    Value =
+	binary_to_list(iolist_to_binary(lists:reverse(Acc))),
     State1 = [{Name, Value} | State],
-    fun (Next) -> parse_form_outer(Next, FileHandler, State1) end;
-parse_form_value({body, Data}, {Name, Acc}, FileHandler, State) ->
+    fun (Next) ->
+	    parse_form_outer(Next, FileHandler, State1)
+    end;
+parse_form_value({body, Data}, {Name, Acc}, FileHandler,
+		 State) ->
     Acc1 = [Data | Acc],
-    fun (Next) -> parse_form_value(Next, {Name, Acc1}, FileHandler, State) end.
+    fun (Next) ->
+	    parse_form_value(Next, {Name, Acc1}, FileHandler, State)
+    end.
 
-parse_form_file(body_end, {Name, Handler}, FileHandler, State) ->
+parse_form_file(body_end, {Name, Handler}, FileHandler,
+		State) ->
     Value = Handler(eof),
     State1 = [{Name, Value} | State],
-    fun (Next) -> parse_form_outer(Next, FileHandler, State1) end;
-parse_form_file({body, Data}, {Name, Handler}, FileHandler, State) ->
+    fun (Next) ->
+	    parse_form_outer(Next, FileHandler, State1)
+    end;
+parse_form_file({body, Data}, {Name, Handler},
+		FileHandler, State) ->
     H1 = Handler(Data),
-    fun (Next) -> parse_form_file(Next, {Name, H1}, FileHandler, State) end.
+    fun (Next) ->
+	    parse_form_file(Next, {Name, H1}, FileHandler, State)
+    end.
 
 default_file_handler(Filename, ContentType) ->
     default_file_handler_1(Filename, ContentType, []).
 
 default_file_handler_1(Filename, ContentType, Acc) ->
-    fun(eof) ->
-            Value = iolist_to_binary(lists:reverse(Acc)),
-            {Filename, ContentType, Value};
-       (Next) ->
-            default_file_handler_1(Filename, ContentType, [Next | Acc])
+    fun (eof) ->
+	    Value = iolist_to_binary(lists:reverse(Acc)),
+	    {Filename, ContentType, Value};
+	(Next) ->
+	    default_file_handler_1(Filename, ContentType,
+				   [Next | Acc])
     end.
 
 parse_multipart_request({ReqM, _} = Req, Callback) ->
     %% TODO: Support chunked?
-    Length = list_to_integer(ReqM:get_combined_header_value("content-length", Req)),
-    Boundary = iolist_to_binary(
-                 get_boundary(ReqM:get_header_value("content-type", Req))),
+    Length =
+	list_to_integer(ReqM:get_combined_header_value("content-length",
+						       Req)),
+    Boundary =
+	iolist_to_binary(get_boundary(ReqM:get_header_value("content-type",
+							    Req))),
     Prefix = <<"\r\n--", Boundary/binary>>,
     BS = byte_size(Boundary),
     Chunk = read_chunk(Req, Length),
     Length1 = Length - byte_size(Chunk),
-    <<"--", Boundary:BS/binary, "\r\n", Rest/binary>> = Chunk,
-    feed_mp(headers, flash_multipart_hack(#mp{boundary=Prefix,
-                                              length=Length1,
-                                              buffer=Rest,
-                                              callback=Callback,
-                                              req=Req})).
-
-parse_headers(<<>>) ->
-    [];
-parse_headers(Binary) ->
-    parse_headers(Binary, []).
+    <<"--", Boundary:BS/binary, "\r\n", Rest/binary>> =
+	Chunk,
+    feed_mp(headers,
+	    flash_multipart_hack(#mp{boundary = Prefix,
+				     length = Length1, buffer = Rest,
+				     callback = Callback, req = Req})).
+
+parse_headers(<<>>) -> [];
+parse_headers(Binary) -> parse_headers(Binary, []).
 
 parse_headers(Binary, Acc) ->
     case find_in_binary(<<"\r\n">>, Binary) of
-        {exact, N} ->
-            <<Line:N/binary, "\r\n", Rest/binary>> = Binary,
-            parse_headers(Rest, [split_header(Line) | Acc]);
-        not_found ->
-            lists:reverse([split_header(Binary) | Acc])
+      {exact, N} ->
+	  <<Line:N/binary, "\r\n", Rest/binary>> = Binary,
+	  parse_headers(Rest, [split_header(Line) | Acc]);
+      not_found -> lists:reverse([split_header(Binary) | Acc])
     end.
 
 split_header(Line) ->
-    {Name, [$: | Value]} = lists:splitwith(fun (C) -> C =/= $: end,
-                                           binary_to_list(Line)),
+    {Name, [$: | Value]} = lists:splitwith(fun (C) ->
+						   C =/= $:
+					   end,
+					   binary_to_list(Line)),
     {string:to_lower(string:strip(Name)),
      mochiweb_util:parse_header(Value)}.
 
 read_chunk({ReqM, _} = Req, Length) when Length > 0 ->
     case Length of
-        Length when Length < ?CHUNKSIZE ->
-            ReqM:recv(Length, Req);
-        _ ->
-            ReqM:recv(?CHUNKSIZE, Req)
+      Length when Length < (?CHUNKSIZE) ->
+	  ReqM:recv(Length, Req);
+      _ -> ReqM:recv(?CHUNKSIZE, Req)
     end.
 
-read_more(State=#mp{length=Length, buffer=Buffer, req=Req}) ->
+read_more(State = #mp{length = Length, buffer = Buffer,
+		      req = Req}) ->
     Data = read_chunk(Req, Length),
     Buffer1 = <<Buffer/binary, Data/binary>>,
-    flash_multipart_hack(State#mp{length=Length - byte_size(Data),
-                                  buffer=Buffer1}).
+    flash_multipart_hack(State#mp{length =
+				      Length - byte_size(Data),
+				  buffer = Buffer1}).
 
-flash_multipart_hack(State=#mp{length=0, buffer=Buffer, boundary=Prefix}) ->
+flash_multipart_hack(State = #mp{length = 0,
+				 buffer = Buffer, boundary = Prefix}) ->
     %% http://code.google.com/p/mochiweb/issues/detail?id=22
     %% Flash doesn't terminate multipart with \r\n properly so we fix it up here
     PrefixSize = size(Prefix),
     case size(Buffer) - (2 + PrefixSize) of
-        Seek when Seek >= 0 ->
-            case Buffer of
-                <<_:Seek/binary, Prefix:PrefixSize/binary, "--">> ->
-                    Buffer1 = <<Buffer/binary, "\r\n">>,
-                    State#mp{buffer=Buffer1};
-                _ ->
-                    State
-            end;
-        _ ->
-            State
+      Seek when Seek >= 0 ->
+	  case Buffer of
+	    <<_:Seek/binary, Prefix:PrefixSize/binary, "--">> ->
+		Buffer1 = <<Buffer/binary, "\r\n">>,
+		State#mp{buffer = Buffer1};
+	    _ -> State
+	  end;
+      _ -> State
     end;
-flash_multipart_hack(State) ->
-    State.
-
-feed_mp(headers, State=#mp{buffer=Buffer, callback=Callback}) ->
-    {State1, P} = case find_in_binary(<<"\r\n\r\n">>, Buffer) of
-                      {exact, N} ->
-                          {State, N};
-                      _ ->
-                          S1 = read_more(State),
-                          %% Assume headers must be less than ?CHUNKSIZE
-                          {exact, N} = find_in_binary(<<"\r\n\r\n">>,
-                                                      S1#mp.buffer),
-                          {S1, N}
-                  end,
-    <<Headers:P/binary, "\r\n\r\n", Rest/binary>> = State1#mp.buffer,
-    NextCallback = Callback({headers, parse_headers(Headers)}),
-    feed_mp(body, State1#mp{buffer=Rest,
-                            callback=NextCallback});
-feed_mp(body, State=#mp{boundary=Prefix, buffer=Buffer, callback=Callback}) ->
+flash_multipart_hack(State) -> State.
+
+feed_mp(headers,
+	State = #mp{buffer = Buffer, callback = Callback}) ->
+    {State1, P} = case find_in_binary(<<"\r\n\r\n">>,
+				      Buffer)
+		      of
+		    {exact, N} -> {State, N};
+		    _ ->
+			S1 = read_more(State),
+			%% Assume headers must be less than ?CHUNKSIZE
+			{exact, N} = find_in_binary(<<"\r\n\r\n">>,
+						    S1#mp.buffer),
+			{S1, N}
+		  end,
+    <<Headers:P/binary, "\r\n\r\n", Rest/binary>> =
+	State1#mp.buffer,
+    NextCallback = Callback({headers,
+			     parse_headers(Headers)}),
+    feed_mp(body,
+	    State1#mp{buffer = Rest, callback = NextCallback});
+feed_mp(body,
+	State = #mp{boundary = Prefix, buffer = Buffer,
+		    callback = Callback}) ->
     Boundary = find_boundary(Prefix, Buffer),
     case Boundary of
-        {end_boundary, Start, Skip} ->
-            <<Data:Start/binary, _:Skip/binary, Rest/binary>> = Buffer,
-            C1 = Callback({body, Data}),
-            C2 = C1(body_end),
-            {State#mp.length, Rest, C2(eof)};
-        {next_boundary, Start, Skip} ->
-            <<Data:Start/binary, _:Skip/binary, Rest/binary>> = Buffer,
-            C1 = Callback({body, Data}),
-            feed_mp(headers, State#mp{callback=C1(body_end),
-                                      buffer=Rest});
-        {maybe, Start} ->
-            <<Data:Start/binary, Rest/binary>> = Buffer,
-            feed_mp(body, read_more(State#mp{callback=Callback({body, Data}),
-                                             buffer=Rest}));
-        not_found ->
-            {Data, Rest} = {Buffer, <<>>},
-            feed_mp(body, read_more(State#mp{callback=Callback({body, Data}),
-                                             buffer=Rest}))
+      {end_boundary, Start, Skip} ->
+	  <<Data:Start/binary, _:Skip/binary, Rest/binary>> =
+	      Buffer,
+	  C1 = Callback({body, Data}),
+	  C2 = C1(body_end),
+	  {State#mp.length, Rest, C2(eof)};
+      {next_boundary, Start, Skip} ->
+	  <<Data:Start/binary, _:Skip/binary, Rest/binary>> =
+	      Buffer,
+	  C1 = Callback({body, Data}),
+	  feed_mp(headers,
+		  State#mp{callback = C1(body_end), buffer = Rest});
+      {maybe, Start} ->
+	  <<Data:Start/binary, Rest/binary>> = Buffer,
+	  feed_mp(body,
+		  read_more(State#mp{callback = Callback({body, Data}),
+				     buffer = Rest}));
+      not_found ->
+	  {Data, Rest} = {Buffer, <<>>},
+	  feed_mp(body,
+		  read_more(State#mp{callback = Callback({body, Data}),
+				     buffer = Rest}))
     end.
 
 get_boundary(ContentType) ->
-    {"multipart/form-data", Opts} = mochiweb_util:parse_header(ContentType),
+    {"multipart/form-data", Opts} =
+	mochiweb_util:parse_header(ContentType),
     case proplists:get_value("boundary", Opts) of
-        S when is_list(S) ->
-            S
+      S when is_list(S) -> S
     end.
 
 %% @spec find_in_binary(Pattern::binary(), Data::binary()) ->
@@ -265,323 +301,332 @@ find_in_binary(P, Data) when size(P) > 0 ->
     PS = size(P),
     DS = size(Data),
     case DS - PS of
-        Last when Last < 0 ->
-            partial_find(P, Data, 0, DS);
-        Last ->
-            case binary:match(Data, P) of
-                {Pos, _} -> {exact, Pos};
-                nomatch -> partial_find(P, Data, Last+1, PS-1)
-            end
+      Last when Last < 0 -> partial_find(P, Data, 0, DS);
+      Last ->
+	  case binary:match(Data, P) of
+	    {Pos, _} -> {exact, Pos};
+	    nomatch -> partial_find(P, Data, Last + 1, PS - 1)
+	  end
     end.
 
-partial_find(_B, _D, _N, 0) ->
-    not_found;
+partial_find(_B, _D, _N, 0) -> not_found;
 partial_find(B, D, N, K) ->
     <<B1:K/binary, _/binary>> = B,
     case D of
-        <<_Skip:N/binary, B1:K/binary>> ->
-            {partial, N, K};
-        _ ->
-            partial_find(B, D, 1 + N, K - 1)
+      <<_Skip:N/binary, B1:K/binary>> -> {partial, N, K};
+      _ -> partial_find(B, D, 1 + N, K - 1)
     end.
 
 find_boundary(Prefix, Data) ->
     case find_in_binary(Prefix, Data) of
-        {exact, Skip} ->
-            PrefixSkip = Skip + size(Prefix),
-            case Data of
-                <<_:PrefixSkip/binary, "\r\n", _/binary>> ->
-                    {next_boundary, Skip, size(Prefix) + 2};
-                <<_:PrefixSkip/binary, "--\r\n", _/binary>> ->
-                    {end_boundary, Skip, size(Prefix) + 4};
-                _ when size(Data) < PrefixSkip + 4 ->
-                    %% Underflow
-                    {maybe, Skip};
-                _ ->
-                    %% False positive
-                    not_found
-            end;
-        {partial, Skip, Length} when (Skip + Length) =:= size(Data) ->
-            %% Underflow
-            {maybe, Skip};
-        _ ->
-            not_found
+      {exact, Skip} ->
+	  PrefixSkip = Skip + size(Prefix),
+	  case Data of
+	    <<_:PrefixSkip/binary, "\r\n", _/binary>> ->
+		{next_boundary, Skip, size(Prefix) + 2};
+	    <<_:PrefixSkip/binary, "--\r\n", _/binary>> ->
+		{end_boundary, Skip, size(Prefix) + 4};
+	    _ when size(Data) < PrefixSkip + 4 ->
+		%% Underflow
+		{maybe, Skip};
+	    _ ->
+		%% False positive
+		not_found
+	  end;
+      {partial, Skip, Length}
+	  when Skip + Length =:= size(Data) ->
+	  %% Underflow
+	  {maybe, Skip};
+      _ -> not_found
     end.
 
 %%
 %% Tests
 %%
 -ifdef(TEST).
+
 -include_lib("eunit/include/eunit.hrl").
 
 ssl_cert_opts() ->
     EbinDir = filename:dirname(code:which(?MODULE)),
-    CertDir = filename:join([EbinDir, "..", "support", "test-materials"]),
+    CertDir = filename:join([EbinDir, "..", "support",
+			     "test-materials"]),
     CertFile = filename:join(CertDir, "test_ssl_cert.pem"),
     KeyFile = filename:join(CertDir, "test_ssl_key.pem"),
     [{certfile, CertFile}, {keyfile, KeyFile}].
 
 with_socket_server(Transport, ServerFun, ClientFun) ->
-    ServerOpts0 = [{ip, "127.0.0.1"}, {port, 0}, {loop, ServerFun}],
+    ServerOpts0 = [{ip, "127.0.0.1"}, {port, 0},
+		   {loop, ServerFun}],
     ServerOpts = case Transport of
-        plain ->
-            ServerOpts0;
-        ssl ->
-            ServerOpts0 ++ [{ssl, true}, {ssl_opts, ssl_cert_opts()}]
-    end,
-    {ok, Server} = mochiweb_socket_server:start_link(ServerOpts),
+		   plain -> ServerOpts0;
+		   ssl ->
+		       ServerOpts0 ++
+			 [{ssl, true}, {ssl_opts, ssl_cert_opts()}]
+		 end,
+    {ok, Server} =
+	mochiweb_socket_server:start_link(ServerOpts),
     Port = mochiweb_socket_server:get(Server, port),
     ClientOpts = [binary, {active, false}],
     {ok, Client} = case Transport of
-        plain ->
-            gen_tcp:connect("127.0.0.1", Port, ClientOpts);
-        ssl ->
-            ClientOpts1 = mochiweb_test_util:ssl_client_opts(ClientOpts),
-            {ok, SslSocket} = ssl:connect("127.0.0.1", Port, ClientOpts1),
-            {ok, {ssl, SslSocket}}
-    end,
+		     plain -> gen_tcp:connect("127.0.0.1", Port, ClientOpts);
+		     ssl ->
+			 ClientOpts1 =
+			     mochiweb_test_util:ssl_client_opts(ClientOpts),
+			 {ok, SslSocket} = ssl:connect("127.0.0.1", Port,
+						       ClientOpts1),
+			 {ok, {ssl, SslSocket}}
+		   end,
     Res = (catch ClientFun(Client)),
     mochiweb_socket_server:stop(Server),
     Res.
 
 fake_request(Socket, ContentType, Length) ->
-    mochiweb_request:new(Socket,
-                         'POST',
-                         "/multipart",
-                         {1,1},
-                         mochiweb_headers:make(
-                           [{"content-type", ContentType},
-                            {"content-length", Length}])).
-
-test_callback({body, <<>>}, Rest=[body_end | _]) ->
+    mochiweb_request:new(Socket, 'POST', "/multipart",
+			 {1, 1},
+			 mochiweb_headers:make([{"content-type", ContentType},
+						{"content-length", Length}])).
+
+test_callback({body, <<>>}, Rest = [body_end | _]) ->
     %% When expecting the body_end we might get an empty binary
     fun (Next) -> test_callback(Next, Rest) end;
-test_callback({body, Got}, [{body, Expect} | Rest]) when Got =/= Expect ->
+test_callback({body, Got}, [{body, Expect} | Rest])
+    when Got =/= Expect ->
     %% Partial response
     GotSize = size(Got),
     <<Got:GotSize/binary, Expect1/binary>> = Expect,
-    fun (Next) -> test_callback(Next, [{body, Expect1} | Rest]) end;
+    fun (Next) ->
+	    test_callback(Next, [{body, Expect1} | Rest])
+    end;
 test_callback(Got, [Expect | Rest]) ->
     ?assertEqual(Got, Expect),
     case Rest of
-        [] ->
-            ok;
-        _ ->
-            fun (Next) -> test_callback(Next, Rest) end
+      [] -> ok;
+      _ -> fun (Next) -> test_callback(Next, Rest) end
     end.
 
-parse3_http_test() ->
-    parse3(plain).
+parse3_http_test() -> parse3(plain).
 
-parse3_https_test() ->
-    parse3(ssl).
+parse3_https_test() -> parse3(ssl).
 
 parse3(Transport) ->
-    ContentType = "multipart/form-data; boundary=---------------------------7386909285754635891697677882",
-    BinContent = <<"-----------------------------7386909285754635891697677882\r\nContent-Disposition: form-data; name=\"hidden\"\r\n\r\nmultipart message\r\n-----------------------------7386909285754635891697677882\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test_file.txt\"\r\nContent-Type: text/plain\r\n\r\nWoo multiline text file\n\nLa la la\r\n-----------------------------7386909285754635891697677882--\r\n">>,
+    ContentType =
+	"multipart/form-data; boundary=---------------"
+	"------------7386909285754635891697677882",
+    BinContent =
+	<<"-----------------------------7386909285754635"
+	  "891697677882\r\nContent-Disposition: "
+	  "form-data; name=\"hidden\"\r\n\r\nmultipart "
+	  "message\r\n-----------------------------73869"
+	  "09285754635891697677882\r\nContent-Dispositio"
+	  "n: form-data; name=\"file\"; filename=\"test_"
+	  "file.txt\"\r\nContent-Type: text/plain\r\n\r\n"
+	  "Woo multiline text file\n\nLa la la\r\n------"
+	  "-----------------------7386909285754635891697"
+	  "677882--\r\n">>,
     Expect = [{headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "hidden"}]}}]},
-              {body, <<"multipart message">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "file"}, {"filename", "test_file.txt"}]}},
-                {"content-type", {"text/plain", []}}]},
-              {body, <<"Woo multiline text file\n\nLa la la">>},
-              body_end,
-              eof],
-    TestCallback = fun (Next) -> test_callback(Next, Expect) end,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "hidden"}]}}]},
+	      {body, <<"multipart message">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data",
+		  [{"name", "file"}, {"filename", "test_file.txt"}]}},
+		{"content-type", {"text/plain", []}}]},
+	      {body, <<"Woo multiline text file\n\nLa la la">>},
+	      body_end, eof],
+    TestCallback = fun (Next) -> test_callback(Next, Expect)
+		   end,
     ServerFun = fun (Socket, _Opts) ->
-                        ok = mochiweb_socket:send(Socket, BinContent),
-                        exit(normal)
-                end,
+			ok = mochiweb_socket:send(Socket, BinContent),
+			exit(normal)
+		end,
     ClientFun = fun (Socket) ->
-                        Req = fake_request(Socket, ContentType,
-                                           byte_size(BinContent)),
-                        Res = parse_multipart_request(Req, TestCallback),
-                        {0, <<>>, ok} = Res,
-                        ok
-                end,
-    ok = with_socket_server(Transport, ServerFun, ClientFun),
+			Req = fake_request(Socket, ContentType,
+					   byte_size(BinContent)),
+			Res = parse_multipart_request(Req, TestCallback),
+			{0, <<>>, ok} = Res,
+			ok
+		end,
+    ok = with_socket_server(Transport, ServerFun,
+			    ClientFun),
     ok.
 
-parse2_http_test() ->
-    parse2(plain).
+parse2_http_test() -> parse2(plain).
 
-parse2_https_test() ->
-    parse2(ssl).
+parse2_https_test() -> parse2(ssl).
 
 parse2(Transport) ->
-    ContentType = "multipart/form-data; boundary=---------------------------6072231407570234361599764024",
-    BinContent = <<"-----------------------------6072231407570234361599764024\r\nContent-Disposition: form-data; name=\"hidden\"\r\n\r\nmultipart message\r\n-----------------------------6072231407570234361599764024\r\nContent-Disposition: form-data; name=\"file\"; filename=\"\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----------------------------6072231407570234361599764024--\r\n">>,
+    ContentType =
+	"multipart/form-data; boundary=---------------"
+	"------------6072231407570234361599764024",
+    BinContent =
+	<<"-----------------------------6072231407570234"
+	  "361599764024\r\nContent-Disposition: "
+	  "form-data; name=\"hidden\"\r\n\r\nmultipart "
+	  "message\r\n-----------------------------60722"
+	  "31407570234361599764024\r\nContent-Dispositio"
+	  "n: form-data; name=\"file\"; filename=\"\"\r\n"
+	  "Content-Type: application/octet-stream\r\n\r\n\r\n"
+	  "-----------------------------6072231407570234"
+	  "361599764024--\r\n">>,
     Expect = [{headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "hidden"}]}}]},
-              {body, <<"multipart message">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "file"}, {"filename", ""}]}},
-                {"content-type", {"application/octet-stream", []}}]},
-              {body, <<>>},
-              body_end,
-              eof],
-    TestCallback = fun (Next) -> test_callback(Next, Expect) end,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "hidden"}]}}]},
+	      {body, <<"multipart message">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "file"}, {"filename", ""}]}},
+		{"content-type", {"application/octet-stream", []}}]},
+	      {body, <<>>}, body_end, eof],
+    TestCallback = fun (Next) -> test_callback(Next, Expect)
+		   end,
     ServerFun = fun (Socket, _Opts) ->
-                        ok = mochiweb_socket:send(Socket, BinContent),
-                        exit(normal)
-                end,
+			ok = mochiweb_socket:send(Socket, BinContent),
+			exit(normal)
+		end,
     ClientFun = fun (Socket) ->
-                        Req = fake_request(Socket, ContentType,
-                                           byte_size(BinContent)),
-                        Res = parse_multipart_request(Req, TestCallback),
-                        {0, <<>>, ok} = Res,
-                        ok
-                end,
-    ok = with_socket_server(Transport, ServerFun, ClientFun),
+			Req = fake_request(Socket, ContentType,
+					   byte_size(BinContent)),
+			Res = parse_multipart_request(Req, TestCallback),
+			{0, <<>>, ok} = Res,
+			ok
+		end,
+    ok = with_socket_server(Transport, ServerFun,
+			    ClientFun),
     ok.
 
-parse_form_http_test() ->
-    do_parse_form(plain).
+parse_form_http_test() -> do_parse_form(plain).
 
-parse_form_https_test() ->
-    do_parse_form(ssl).
+parse_form_https_test() -> do_parse_form(ssl).
 
 do_parse_form(Transport) ->
     ContentType = "multipart/form-data; boundary=AaB03x",
     "AaB03x" = get_boundary(ContentType),
-    Content = mochiweb_util:join(
-                ["--AaB03x",
-                 "Content-Disposition: form-data; name=\"submit-name\"",
-                 "",
-                 "Larry",
-                 "--AaB03x",
-                 "Content-Disposition: form-data; name=\"files\";"
-                 ++ "filename=\"file1.txt\"",
-                 "Content-Type: text/plain",
-                 "",
-                 "... contents of file1.txt ...",
-                 "--AaB03x--",
-                 ""], "\r\n"),
+    Content = mochiweb_util:join(["--AaB03x",
+				  "Content-Disposition: form-data; name=\"submit"
+				  "-name\"",
+				  "", "Larry", "--AaB03x",
+				  "Content-Disposition: form-data; name=\"files\";"
+				    ++ "filename=\"file1.txt\"",
+				  "Content-Type: text/plain", "",
+				  "... contents of file1.txt ...", "--AaB03x--",
+				  ""],
+				 "\r\n"),
     BinContent = iolist_to_binary(Content),
     ServerFun = fun (Socket, _Opts) ->
-                        ok = mochiweb_socket:send(Socket, BinContent),
-                        exit(normal)
-                end,
+			ok = mochiweb_socket:send(Socket, BinContent),
+			exit(normal)
+		end,
     ClientFun = fun (Socket) ->
-                        Req = fake_request(Socket, ContentType,
-                                           byte_size(BinContent)),
-                        Res = parse_form(Req),
-                        [{"submit-name", "Larry"},
-                         {"files", {"file1.txt", {"text/plain",[]},
-                                    <<"... contents of file1.txt ...">>}
-                         }] = Res,
-                        ok
-                end,
-    ok = with_socket_server(Transport, ServerFun, ClientFun),
+			Req = fake_request(Socket, ContentType,
+					   byte_size(BinContent)),
+			Res = parse_form(Req),
+			[{"submit-name", "Larry"},
+			 {"files",
+			  {"file1.txt", {"text/plain", []},
+			   <<"... contents of file1.txt ...">>}}] =
+			    Res,
+			ok
+		end,
+    ok = with_socket_server(Transport, ServerFun,
+			    ClientFun),
     ok.
 
-parse_http_test() ->
-    do_parse(plain).
+parse_http_test() -> do_parse(plain).
 
-parse_https_test() ->
-    do_parse(ssl).
+parse_https_test() -> do_parse(ssl).
 
 do_parse(Transport) ->
     ContentType = "multipart/form-data; boundary=AaB03x",
     "AaB03x" = get_boundary(ContentType),
-    Content = mochiweb_util:join(
-                ["--AaB03x",
-                 "Content-Disposition: form-data; name=\"submit-name\"",
-                 "",
-                 "Larry",
-                 "--AaB03x",
-                 "Content-Disposition: form-data; name=\"files\";"
-                 ++ "filename=\"file1.txt\"",
-                 "Content-Type: text/plain",
-                 "",
-                 "... contents of file1.txt ...",
-                 "--AaB03x--",
-                 ""], "\r\n"),
+    Content = mochiweb_util:join(["--AaB03x",
+				  "Content-Disposition: form-data; name=\"submit"
+				  "-name\"",
+				  "", "Larry", "--AaB03x",
+				  "Content-Disposition: form-data; name=\"files\";"
+				    ++ "filename=\"file1.txt\"",
+				  "Content-Type: text/plain", "",
+				  "... contents of file1.txt ...", "--AaB03x--",
+				  ""],
+				 "\r\n"),
     BinContent = iolist_to_binary(Content),
     Expect = [{headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "submit-name"}]}}]},
-              {body, <<"Larry">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "files"}, {"filename", "file1.txt"}]}},
-                 {"content-type", {"text/plain", []}}]},
-              {body, <<"... contents of file1.txt ...">>},
-              body_end,
-              eof],
-    TestCallback = fun (Next) -> test_callback(Next, Expect) end,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "submit-name"}]}}]},
+	      {body, <<"Larry">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data",
+		  [{"name", "files"}, {"filename", "file1.txt"}]}},
+		{"content-type", {"text/plain", []}}]},
+	      {body, <<"... contents of file1.txt ...">>}, body_end,
+	      eof],
+    TestCallback = fun (Next) -> test_callback(Next, Expect)
+		   end,
     ServerFun = fun (Socket, _Opts) ->
-                        ok = mochiweb_socket:send(Socket, BinContent),
-                        exit(normal)
-                end,
+			ok = mochiweb_socket:send(Socket, BinContent),
+			exit(normal)
+		end,
     ClientFun = fun (Socket) ->
-                        Req = fake_request(Socket, ContentType,
-                                           byte_size(BinContent)),
-                        Res = parse_multipart_request(Req, TestCallback),
-                        {0, <<>>, ok} = Res,
-                        ok
-                end,
-    ok = with_socket_server(Transport, ServerFun, ClientFun),
+			Req = fake_request(Socket, ContentType,
+					   byte_size(BinContent)),
+			Res = parse_multipart_request(Req, TestCallback),
+			{0, <<>>, ok} = Res,
+			ok
+		end,
+    ok = with_socket_server(Transport, ServerFun,
+			    ClientFun),
     ok.
 
 parse_partial_body_boundary_http_test() ->
-   parse_partial_body_boundary(plain).
+    parse_partial_body_boundary(plain).
 
 parse_partial_body_boundary_https_test() ->
-   parse_partial_body_boundary(ssl).
+    parse_partial_body_boundary(ssl).
 
 parse_partial_body_boundary(Transport) ->
     Boundary = string:copies("$", 2048),
-    ContentType = "multipart/form-data; boundary=" ++ Boundary,
-    ?assertEqual(Boundary, get_boundary(ContentType)),
-    Content = mochiweb_util:join(
-                ["--" ++ Boundary,
-                 "Content-Disposition: form-data; name=\"submit-name\"",
-                 "",
-                 "Larry",
-                 "--" ++ Boundary,
-                 "Content-Disposition: form-data; name=\"files\";"
-                 ++ "filename=\"file1.txt\"",
-                 "Content-Type: text/plain",
-                 "",
-                 "... contents of file1.txt ...",
-                 "--" ++ Boundary ++ "--",
-                 ""], "\r\n"),
+    ContentType = "multipart/form-data; boundary=" ++
+		    Boundary,
+    ?assertEqual(Boundary, (get_boundary(ContentType))),
+    Content = mochiweb_util:join(["--" ++ Boundary,
+				  "Content-Disposition: form-data; name=\"submit"
+				  "-name\"",
+				  "", "Larry", "--" ++ Boundary,
+				  "Content-Disposition: form-data; name=\"files\";"
+				    ++ "filename=\"file1.txt\"",
+				  "Content-Type: text/plain", "",
+				  "... contents of file1.txt ...",
+				  "--" ++ Boundary ++ "--", ""],
+				 "\r\n"),
     BinContent = iolist_to_binary(Content),
     Expect = [{headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "submit-name"}]}}]},
-              {body, <<"Larry">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "files"}, {"filename", "file1.txt"}]}},
-                {"content-type", {"text/plain", []}}
-               ]},
-              {body, <<"... contents of file1.txt ...">>},
-              body_end,
-              eof],
-    TestCallback = fun (Next) -> test_callback(Next, Expect) end,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "submit-name"}]}}]},
+	      {body, <<"Larry">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data",
+		  [{"name", "files"}, {"filename", "file1.txt"}]}},
+		{"content-type", {"text/plain", []}}]},
+	      {body, <<"... contents of file1.txt ...">>}, body_end,
+	      eof],
+    TestCallback = fun (Next) -> test_callback(Next, Expect)
+		   end,
     ServerFun = fun (Socket, _Opts) ->
-                        ok = mochiweb_socket:send(Socket, BinContent),
-                        exit(normal)
-                end,
+			ok = mochiweb_socket:send(Socket, BinContent),
+			exit(normal)
+		end,
     ClientFun = fun (Socket) ->
-                        Req = fake_request(Socket, ContentType,
-                                           byte_size(BinContent)),
-                        Res = parse_multipart_request(Req, TestCallback),
-                        {0, <<>>, ok} = Res,
-                        ok
-                end,
-    ok = with_socket_server(Transport, ServerFun, ClientFun),
+			Req = fake_request(Socket, ContentType,
+					   byte_size(BinContent)),
+			Res = parse_multipart_request(Req, TestCallback),
+			{0, <<>>, ok} = Res,
+			ok
+		end,
+    ok = with_socket_server(Transport, ServerFun,
+			    ClientFun),
     ok.
 
 parse_large_header_http_test() ->
@@ -593,64 +638,69 @@ parse_large_header_https_test() ->
 parse_large_header(Transport) ->
     ContentType = "multipart/form-data; boundary=AaB03x",
     "AaB03x" = get_boundary(ContentType),
-    Content = mochiweb_util:join(
-                ["--AaB03x",
-                 "Content-Disposition: form-data; name=\"submit-name\"",
-                 "",
-                 "Larry",
-                 "--AaB03x",
-                 "Content-Disposition: form-data; name=\"files\";"
-                 ++ "filename=\"file1.txt\"",
-                 "Content-Type: text/plain",
-                 "x-large-header: " ++ string:copies("%", 4096),
-                 "",
-                 "... contents of file1.txt ...",
-                 "--AaB03x--",
-                 ""], "\r\n"),
+    Content = mochiweb_util:join(["--AaB03x",
+				  "Content-Disposition: form-data; name=\"submit"
+				  "-name\"",
+				  "", "Larry", "--AaB03x",
+				  "Content-Disposition: form-data; name=\"files\";"
+				    ++ "filename=\"file1.txt\"",
+				  "Content-Type: text/plain",
+				  "x-large-header: " ++
+				    string:copies("%", 4096),
+				  "", "... contents of file1.txt ...",
+				  "--AaB03x--", ""],
+				 "\r\n"),
     BinContent = iolist_to_binary(Content),
     Expect = [{headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "submit-name"}]}}]},
-              {body, <<"Larry">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "files"}, {"filename", "file1.txt"}]}},
-                {"content-type", {"text/plain", []}},
-                {"x-large-header", {string:copies("%", 4096), []}}
-               ]},
-              {body, <<"... contents of file1.txt ...">>},
-              body_end,
-              eof],
-    TestCallback = fun (Next) -> test_callback(Next, Expect) end,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "submit-name"}]}}]},
+	      {body, <<"Larry">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data",
+		  [{"name", "files"}, {"filename", "file1.txt"}]}},
+		{"content-type", {"text/plain", []}},
+		{"x-large-header", {string:copies("%", 4096), []}}]},
+	      {body, <<"... contents of file1.txt ...">>}, body_end,
+	      eof],
+    TestCallback = fun (Next) -> test_callback(Next, Expect)
+		   end,
     ServerFun = fun (Socket, _Opts) ->
-                        ok = mochiweb_socket:send(Socket, BinContent),
-                        exit(normal)
-                end,
+			ok = mochiweb_socket:send(Socket, BinContent),
+			exit(normal)
+		end,
     ClientFun = fun (Socket) ->
-                        Req = fake_request(Socket, ContentType,
-                                           byte_size(BinContent)),
-                        Res = parse_multipart_request(Req, TestCallback),
-                        {0, <<>>, ok} = Res,
-                        ok
-                end,
-    ok = with_socket_server(Transport, ServerFun, ClientFun),
+			Req = fake_request(Socket, ContentType,
+					   byte_size(BinContent)),
+			Res = parse_multipart_request(Req, TestCallback),
+			{0, <<>>, ok} = Res,
+			ok
+		end,
+    ok = with_socket_server(Transport, ServerFun,
+			    ClientFun),
     ok.
 
 find_boundary_test() ->
     B = <<"\r\n--X">>,
-    {next_boundary, 0, 7} = find_boundary(B, <<"\r\n--X\r\nRest">>),
-    {next_boundary, 1, 7} = find_boundary(B, <<"!\r\n--X\r\nRest">>),
-    {end_boundary, 0, 9} = find_boundary(B, <<"\r\n--X--\r\nRest">>),
-    {end_boundary, 1, 9} = find_boundary(B, <<"!\r\n--X--\r\nRest">>),
+    {next_boundary, 0, 7} = find_boundary(B,
+					  <<"\r\n--X\r\nRest">>),
+    {next_boundary, 1, 7} = find_boundary(B,
+					  <<"!\r\n--X\r\nRest">>),
+    {end_boundary, 0, 9} = find_boundary(B,
+					 <<"\r\n--X--\r\nRest">>),
+    {end_boundary, 1, 9} = find_boundary(B,
+					 <<"!\r\n--X--\r\nRest">>),
     not_found = find_boundary(B, <<"--X\r\nRest">>),
     {maybe, 0} = find_boundary(B, <<"\r\n--X\r">>),
     {maybe, 1} = find_boundary(B, <<"!\r\n--X\r">>),
-    P = <<"\r\n-----------------------------16037454351082272548568224146">>,
-    B0 = <<55,212,131,77,206,23,216,198,35,87,252,118,252,8,25,211,132,229,
-          182,42,29,188,62,175,247,243,4,4,0,59, 13,10,45,45,45,45,45,45,45,
-          45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
-          49,54,48,51,55,52,53,52,51,53,49>>,
+    P = <<"\r\n-----------------------------160374543510"
+	  "82272548568224146">>,
+    B0 = <<55, 212, 131, 77, 206, 23, 216, 198, 35, 87, 252,
+	   118, 252, 8, 25, 211, 132, 229, 182, 42, 29, 188, 62,
+	   175, 247, 243, 4, 4, 0, 59, 13, 10, 45, 45, 45, 45, 45,
+	   45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+	   45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 49, 54, 48, 51,
+	   55, 52, 53, 52, 51, 53, 49>>,
     {maybe, 30} = find_boundary(P, B0),
     not_found = find_boundary(B, <<"\r\n--XJOPKE">>),
     ok.
@@ -660,231 +710,262 @@ find_in_binary_test() ->
     {exact, 1} = find_in_binary(<<"oo">>, <<"foobarbaz">>),
     {exact, 8} = find_in_binary(<<"z">>, <<"foobarbaz">>),
     not_found = find_in_binary(<<"q">>, <<"foobarbaz">>),
-    {partial, 7, 2} = find_in_binary(<<"azul">>, <<"foobarbaz">>),
-    {exact, 0} = find_in_binary(<<"foobarbaz">>, <<"foobarbaz">>),
-    {partial, 0, 3} = find_in_binary(<<"foobar">>, <<"foo">>),
-    {partial, 1, 3} = find_in_binary(<<"foobar">>, <<"afoo">>),
+    {partial, 7, 2} = find_in_binary(<<"azul">>,
+				     <<"foobarbaz">>),
+    {exact, 0} = find_in_binary(<<"foobarbaz">>,
+				<<"foobarbaz">>),
+    {partial, 0, 3} = find_in_binary(<<"foobar">>,
+				     <<"foo">>),
+    {partial, 1, 3} = find_in_binary(<<"foobar">>,
+				     <<"afoo">>),
     ok.
 
-flash_parse_http_test() ->
-    flash_parse(plain).
+flash_parse_http_test() -> flash_parse(plain).
 
-flash_parse_https_test() ->
-    flash_parse(ssl).
+flash_parse_https_test() -> flash_parse(ssl).
 
 flash_parse(Transport) ->
-    ContentType = "multipart/form-data; boundary=----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5",
-    "----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5" = get_boundary(ContentType),
-    BinContent = <<"------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"Filename\"\r\n\r\nhello.txt\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"success_action_status\"\r\n\r\n201\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"file\"; filename=\"hello.txt\"\r\nContent-Type: application/octet-stream\r\n\r\nhello\n\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Dis [...]
+    ContentType =
+	"multipart/form-data; boundary=----------ei4GI"
+	"3GI3Ij5Ef1ae0KM7Ij5ei4Ij5",
+    "----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5" =
+	get_boundary(ContentType),
+    BinContent =
+	<<"------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\n"
+	  "Content-Disposition: form-data; name=\"Filena"
+	  "me\"\r\n\r\nhello.txt\r\n------------ei4GI3GI"
+	  "3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition"
+	  ": form-data; name=\"success_action_status\"\r\n\r\n"
+	  "201\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei"
+	  "4Ij5\r\nContent-Disposition: form-data; "
+	  "name=\"file\"; filename=\"hello.txt\"\r\nCont"
+	  "ent-Type: application/octet-stream\r\n\r\nhel"
+	  "lo\n\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5e"
+	  "i4Ij5\r\nContent-Disposition: form-data; "
+	  "name=\"Upload\"\r\n\r\nSubmit Query\r\n------"
+	  "------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5--">>,
     Expect = [{headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "Filename"}]}}]},
-              {body, <<"hello.txt">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "success_action_status"}]}}]},
-              {body, <<"201">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "file"}, {"filename", "hello.txt"}]}},
-                {"content-type", {"application/octet-stream", []}}]},
-              {body, <<"hello\n">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "Upload"}]}}]},
-              {body, <<"Submit Query">>},
-              body_end,
-              eof],
-    TestCallback = fun (Next) -> test_callback(Next, Expect) end,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "Filename"}]}}]},
+	      {body, <<"hello.txt">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "success_action_status"}]}}]},
+	      {body, <<"201">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data",
+		  [{"name", "file"}, {"filename", "hello.txt"}]}},
+		{"content-type", {"application/octet-stream", []}}]},
+	      {body, <<"hello\n">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "Upload"}]}}]},
+	      {body, <<"Submit Query">>}, body_end, eof],
+    TestCallback = fun (Next) -> test_callback(Next, Expect)
+		   end,
     ServerFun = fun (Socket, _Opts) ->
-                        ok = mochiweb_socket:send(Socket, BinContent),
-                        exit(normal)
-                end,
+			ok = mochiweb_socket:send(Socket, BinContent),
+			exit(normal)
+		end,
     ClientFun = fun (Socket) ->
-                        Req = fake_request(Socket, ContentType,
-                                           byte_size(BinContent)),
-                        Res = parse_multipart_request(Req, TestCallback),
-                        {0, <<>>, ok} = Res,
-                        ok
-                end,
-    ok = with_socket_server(Transport, ServerFun, ClientFun),
+			Req = fake_request(Socket, ContentType,
+					   byte_size(BinContent)),
+			Res = parse_multipart_request(Req, TestCallback),
+			{0, <<>>, ok} = Res,
+			ok
+		end,
+    ok = with_socket_server(Transport, ServerFun,
+			    ClientFun),
     ok.
 
-flash_parse2_http_test() ->
-    flash_parse2(plain).
+flash_parse2_http_test() -> flash_parse2(plain).
 
-flash_parse2_https_test() ->
-    flash_parse2(ssl).
+flash_parse2_https_test() -> flash_parse2(ssl).
 
 flash_parse2(Transport) ->
-    ContentType = "multipart/form-data; boundary=----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5",
-    "----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5" = get_boundary(ContentType),
+    ContentType =
+	"multipart/form-data; boundary=----------ei4GI"
+	"3GI3Ij5Ef1ae0KM7Ij5ei4Ij5",
+    "----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5" =
+	get_boundary(ContentType),
     Chunk = iolist_to_binary(string:copies("%", 4096)),
-    BinContent = <<"------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"Filename\"\r\n\r\nhello.txt\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"success_action_status\"\r\n\r\n201\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"file\"; filename=\"hello.txt\"\r\nContent-Type: application/octet-stream\r\n\r\n", Chunk/binary, "\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\n [...]
+    BinContent =
+	<<"------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\n"
+	  "Content-Disposition: form-data; name=\"Filena"
+	  "me\"\r\n\r\nhello.txt\r\n------------ei4GI3GI"
+	  "3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition"
+	  ": form-data; name=\"success_action_status\"\r\n\r\n"
+	  "201\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei"
+	  "4Ij5\r\nContent-Disposition: form-data; "
+	  "name=\"file\"; filename=\"hello.txt\"\r\nCont"
+	  "ent-Type: application/octet-stream\r\n\r\n",
+	  Chunk/binary,
+	  "\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij"
+	  "5\r\nContent-Disposition: form-data; "
+	  "name=\"Upload\"\r\n\r\nSubmit Query\r\n------"
+	  "------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5--">>,
     Expect = [{headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "Filename"}]}}]},
-              {body, <<"hello.txt">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "success_action_status"}]}}]},
-              {body, <<"201">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "file"}, {"filename", "hello.txt"}]}},
-                {"content-type", {"application/octet-stream", []}}]},
-              {body, Chunk},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "Upload"}]}}]},
-              {body, <<"Submit Query">>},
-              body_end,
-              eof],
-    TestCallback = fun (Next) -> test_callback(Next, Expect) end,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "Filename"}]}}]},
+	      {body, <<"hello.txt">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "success_action_status"}]}}]},
+	      {body, <<"201">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data",
+		  [{"name", "file"}, {"filename", "hello.txt"}]}},
+		{"content-type", {"application/octet-stream", []}}]},
+	      {body, Chunk}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "Upload"}]}}]},
+	      {body, <<"Submit Query">>}, body_end, eof],
+    TestCallback = fun (Next) -> test_callback(Next, Expect)
+		   end,
     ServerFun = fun (Socket, _Opts) ->
-                        ok = mochiweb_socket:send(Socket, BinContent),
-                        exit(normal)
-                end,
+			ok = mochiweb_socket:send(Socket, BinContent),
+			exit(normal)
+		end,
     ClientFun = fun (Socket) ->
-                        Req = fake_request(Socket, ContentType,
-                                           byte_size(BinContent)),
-                        Res = parse_multipart_request(Req, TestCallback),
-                        {0, <<>>, ok} = Res,
-                        ok
-                end,
-    ok = with_socket_server(Transport, ServerFun, ClientFun),
+			Req = fake_request(Socket, ContentType,
+					   byte_size(BinContent)),
+			Res = parse_multipart_request(Req, TestCallback),
+			{0, <<>>, ok} = Res,
+			ok
+		end,
+    ok = with_socket_server(Transport, ServerFun,
+			    ClientFun),
     ok.
 
 parse_headers_test() ->
-    ?assertEqual([], parse_headers(<<>>)).
+    ?assertEqual([], (parse_headers(<<>>))).
 
 flash_multipart_hack_test() ->
     Buffer = <<"prefix-">>,
     Prefix = <<"prefix">>,
-    State = #mp{length=0, buffer=Buffer, boundary=Prefix},
-    ?assertEqual(State,
-                 flash_multipart_hack(State)).
+    State = #mp{length = 0, buffer = Buffer,
+		boundary = Prefix},
+    ?assertEqual(State, (flash_multipart_hack(State))).
 
 parts_to_body_single_test() ->
     {HL, B} = parts_to_body([{0, 5, <<"01234">>}],
-                            "text/plain",
-                            10),
-    [{"Content-Range", Range},
-     {"Content-Type", Type}] = lists:sort(HL),
-    ?assertEqual(
-       <<"bytes 0-5/10">>,
-       iolist_to_binary(Range)),
-    ?assertEqual(
-       <<"text/plain">>,
-       iolist_to_binary(Type)),
-    ?assertEqual(
-       <<"01234">>,
-       iolist_to_binary(B)),
+			    "text/plain", 10),
+    [{"Content-Range", Range}, {"Content-Type", Type}] =
+	lists:sort(HL),
+    ?assertEqual(<<"bytes 0-5/10">>,
+		 (iolist_to_binary(Range))),
+    ?assertEqual(<<"text/plain">>,
+		 (iolist_to_binary(Type))),
+    ?assertEqual(<<"01234">>, (iolist_to_binary(B))),
     ok.
 
 parts_to_body_multi_test() ->
-    {[{"Content-Type", Type}],
-     _B} = parts_to_body([{0, 5, <<"01234">>}, {5, 10, <<"56789">>}],
-                        "text/plain",
-                        10),
-    ?assertMatch(
-       <<"multipart/byteranges; boundary=", _/binary>>,
-       iolist_to_binary(Type)),
+    {[{"Content-Type", Type}], _B} = parts_to_body([{0, 5,
+						     <<"01234">>},
+						    {5, 10, <<"56789">>}],
+						   "text/plain", 10),
+    ?assertMatch(<<"multipart/byteranges; boundary=",
+		   _/binary>>,
+		 (iolist_to_binary(Type))),
     ok.
 
 parts_to_multipart_body_test() ->
-    {[{"Content-Type", V}], B} = parts_to_multipart_body(
-                                   [{0, 5, <<"01234">>}, {5, 10, <<"56789">>}],
-                                   "text/plain",
-                                   10,
-                                   "BOUNDARY"),
-    MB = multipart_body(
-           [{0, 5, <<"01234">>}, {5, 10, <<"56789">>}],
-           "text/plain",
-           "BOUNDARY",
-           10),
-    ?assertEqual(
-       <<"multipart/byteranges; boundary=BOUNDARY">>,
-       iolist_to_binary(V)),
-    ?assertEqual(
-       iolist_to_binary(MB),
-       iolist_to_binary(B)),
+    {[{"Content-Type", V}], B} =
+	parts_to_multipart_body([{0, 5, <<"01234">>},
+				 {5, 10, <<"56789">>}],
+				"text/plain", 10, "BOUNDARY"),
+    MB = multipart_body([{0, 5, <<"01234">>},
+			 {5, 10, <<"56789">>}],
+			"text/plain", "BOUNDARY", 10),
+    ?assertEqual(<<"multipart/byteranges; boundary=BOUNDARY">>,
+		 (iolist_to_binary(V))),
+    ?assertEqual((iolist_to_binary(MB)),
+		 (iolist_to_binary(B))),
     ok.
 
 multipart_body_test() ->
-    ?assertEqual(
-       <<"--BOUNDARY--\r\n">>,
-       iolist_to_binary(multipart_body([], "text/plain", "BOUNDARY", 0))),
-    ?assertEqual(
-       <<"--BOUNDARY\r\n"
-         "Content-Type: text/plain\r\n"
-         "Content-Range: bytes 0-5/10\r\n\r\n"
-         "01234\r\n"
-         "--BOUNDARY\r\n"
-         "Content-Type: text/plain\r\n"
-         "Content-Range: bytes 5-10/10\r\n\r\n"
-         "56789\r\n"
-         "--BOUNDARY--\r\n">>,
-       iolist_to_binary(multipart_body([{0, 5, <<"01234">>}, {5, 10, <<"56789">>}],
-                                       "text/plain",
-                                       "BOUNDARY",
-                                       10))),
+    ?assertEqual(<<"--BOUNDARY--\r\n">>,
+		 (iolist_to_binary(multipart_body([], "text/plain",
+						  "BOUNDARY", 0)))),
+    ?assertEqual(<<"--BOUNDARY\r\nContent-Type: text/plain\r\nCon"
+		   "tent-Range: bytes 0-5/10\r\n\r\n01234\r\n--BO"
+		   "UNDARY\r\nContent-Type: text/plain\r\nContent"
+		   "-Range: bytes 5-10/10\r\n\r\n56789\r\n--BOUND"
+		   "ARY--\r\n">>,
+		 (iolist_to_binary(multipart_body([{0, 5, <<"01234">>},
+						   {5, 10, <<"56789">>}],
+						  "text/plain", "BOUNDARY",
+						  10)))),
     ok.
 
 %% @todo Move somewhere more appropriate than in the test suite
 
 multipart_parsing_benchmark_test() ->
-  run_multipart_parsing_benchmark(1).
+    run_multipart_parsing_benchmark(1).
 
 run_multipart_parsing_benchmark(0) -> ok;
 run_multipart_parsing_benchmark(N) ->
-     multipart_parsing_benchmark(),
-     run_multipart_parsing_benchmark(N-1).
+    multipart_parsing_benchmark(),
+    run_multipart_parsing_benchmark(N - 1).
 
 multipart_parsing_benchmark() ->
-    ContentType = "multipart/form-data; boundary=----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5",
-    Chunk = binary:copy(<<"This Is_%Some=Quite0Long4String2Used9For7BenchmarKing.5">>, 102400),
-    BinContent = <<"------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"Filename\"\r\n\r\nhello.txt\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"success_action_status\"\r\n\r\n201\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"file\"; filename=\"hello.txt\"\r\nContent-Type: application/octet-stream\r\n\r\n", Chunk/binary, "\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\n [...]
+    ContentType =
+	"multipart/form-data; boundary=----------ei4GI"
+	"3GI3Ij5Ef1ae0KM7Ij5ei4Ij5",
+    Chunk =
+	binary:copy(<<"This Is_%Some=Quite0Long4String2Used9For7Benc"
+		      "hmarKing.5">>,
+		    102400),
+    BinContent =
+	<<"------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\n"
+	  "Content-Disposition: form-data; name=\"Filena"
+	  "me\"\r\n\r\nhello.txt\r\n------------ei4GI3GI"
+	  "3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition"
+	  ": form-data; name=\"success_action_status\"\r\n\r\n"
+	  "201\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei"
+	  "4Ij5\r\nContent-Disposition: form-data; "
+	  "name=\"file\"; filename=\"hello.txt\"\r\nCont"
+	  "ent-Type: application/octet-stream\r\n\r\n",
+	  Chunk/binary,
+	  "\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij"
+	  "5\r\nContent-Disposition: form-data; "
+	  "name=\"Upload\"\r\n\r\nSubmit Query\r\n------"
+	  "------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5--">>,
     Expect = [{headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "Filename"}]}}]},
-              {body, <<"hello.txt">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "success_action_status"}]}}]},
-              {body, <<"201">>},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "file"}, {"filename", "hello.txt"}]}},
-                {"content-type", {"application/octet-stream", []}}]},
-              {body, Chunk},
-              body_end,
-              {headers,
-               [{"content-disposition",
-                 {"form-data", [{"name", "Upload"}]}}]},
-              {body, <<"Submit Query">>},
-              body_end,
-              eof],
-    TestCallback = fun (Next) -> test_callback(Next, Expect) end,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "Filename"}]}}]},
+	      {body, <<"hello.txt">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "success_action_status"}]}}]},
+	      {body, <<"201">>}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data",
+		  [{"name", "file"}, {"filename", "hello.txt"}]}},
+		{"content-type", {"application/octet-stream", []}}]},
+	      {body, Chunk}, body_end,
+	      {headers,
+	       [{"content-disposition",
+		 {"form-data", [{"name", "Upload"}]}}]},
+	      {body, <<"Submit Query">>}, body_end, eof],
+    TestCallback = fun (Next) -> test_callback(Next, Expect)
+		   end,
     ServerFun = fun (Socket, _Opts) ->
-                        ok = mochiweb_socket:send(Socket, BinContent),
-                        exit(normal)
-                end,
+			ok = mochiweb_socket:send(Socket, BinContent),
+			exit(normal)
+		end,
     ClientFun = fun (Socket) ->
-                        Req = fake_request(Socket, ContentType,
-                                           byte_size(BinContent)),
-                        Res = parse_multipart_request(Req, TestCallback),
-                        {0, <<>>, ok} = Res,
-                        ok
-                end,
+			Req = fake_request(Socket, ContentType,
+					   byte_size(BinContent)),
+			Res = parse_multipart_request(Req, TestCallback),
+			{0, <<>>, ok} = Res,
+			ok
+		end,
     ok = with_socket_server(plain, ServerFun, ClientFun),
     ok.
+
 -endif.
diff --git a/src/mochiweb_request.erl b/src/mochiweb_request.erl
index 3889d33..a1d2d6e 100644
--- a/src/mochiweb_request.erl
+++ b/src/mochiweb_request.erl
@@ -22,33 +22,57 @@
 %% @doc MochiWeb HTTP Request abstraction.
 
 -module(mochiweb_request).
+
 -author('bob@mochimedia.com').
 
 -include_lib("kernel/include/file.hrl").
+
 -include("internal.hrl").
 
 -define(QUIP, "Any of you quaids got a smint?").
 
 -export([new/5, new/6]).
--export([get_header_value/2, get_primary_header_value/2, get_combined_header_value/2, get/2, dump/1]).
--export([send/2, recv/2, recv/3, recv_body/1, recv_body/2, stream_body/4, stream_body/5]).
--export([start_response/2, start_response_length/2, start_raw_response/2]).
--export([respond/2, ok/2]).
+
+-export([dump/1, get/2, get_combined_header_value/2,
+	 get_header_value/2, get_primary_header_value/2]).
+
+-export([recv/2, recv/3, recv_body/1, recv_body/2,
+	 send/2, stream_body/4, stream_body/5]).
+
+-export([start_raw_response/2, start_response/2,
+	 start_response_length/2]).
+
+-export([ok/2, respond/2]).
+
 -export([not_found/1, not_found/2]).
+
 -export([parse_post/1, parse_qs/1]).
--export([should_close/1, cleanup/1]).
--export([parse_cookie/1, get_cookie_value/2]).
+
+-export([cleanup/1, should_close/1]).
+
+-export([get_cookie_value/2, parse_cookie/1]).
+
 -export([serve_file/3, serve_file/4]).
+
 -export([accepted_encodings/2]).
--export([accepts_content_type/2, accepted_content_types/2]).
+
+-export([accepted_content_types/2,
+	 accepts_content_type/2]).
 
 -define(SAVE_QS, mochiweb_request_qs).
+
 -define(SAVE_PATH, mochiweb_request_path).
+
 -define(SAVE_RECV, mochiweb_request_recv).
+
 -define(SAVE_BODY, mochiweb_request_body).
+
 -define(SAVE_BODY_LENGTH, mochiweb_request_body_length).
+
 -define(SAVE_POST, mochiweb_request_post).
+
 -define(SAVE_COOKIE, mochiweb_request_cookie).
+
 -define(SAVE_FORCE_CLOSE, mochiweb_request_force_close).
 
 %% @type key() = atom() | string() | binary()
@@ -62,7 +86,7 @@
 -define(IDLE_TIMEOUT, 300000).
 
 % Maximum recv_body() length of 1MB
--define(MAX_RECV_BODY, (1024*1024)).
+-define(MAX_RECV_BODY, 1024 * 1024).
 
 %% @spec new(Socket, Method, RawPath, Version, headers()) -> request()
 %% @doc Create a new request instance.
@@ -72,17 +96,27 @@ new(Socket, Method, RawPath, Version, Headers) ->
 %% @spec new(Socket, Opts, Method, RawPath, Version, headers()) -> request()
 %% @doc Create a new request instance.
 new(Socket, Opts, Method, RawPath, Version, Headers) ->
-    {?MODULE, [Socket, Opts, Method, RawPath, Version, Headers]}.
+    {?MODULE,
+     [Socket, Opts, Method, RawPath, Version, Headers]}.
 
 %% @spec get_header_value(K, request()) -> undefined | Value
 %% @doc Get the value of a given request header.
-get_header_value(K, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, Headers]}) ->
+get_header_value(K,
+		 {?MODULE,
+		  [_Socket, _Opts, _Method, _RawPath, _Version,
+		   Headers]}) ->
     mochiweb_headers:get_value(K, Headers).
 
-get_primary_header_value(K, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, Headers]}) ->
+get_primary_header_value(K,
+			 {?MODULE,
+			  [_Socket, _Opts, _Method, _RawPath, _Version,
+			   Headers]}) ->
     mochiweb_headers:get_primary_value(K, Headers).
 
-get_combined_header_value(K, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, Headers]}) ->
+get_combined_header_value(K,
+			  {?MODULE,
+			   [_Socket, _Opts, _Method, _RawPath, _Version,
+			    Headers]}) ->
     mochiweb_headers:get_combined_value(K, Headers).
 
 %% @type field() = socket | scheme | method | raw_path | version | headers | peer | path | body_length | range
@@ -93,246 +127,303 @@ get_combined_header_value(K, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Vers
 %%      an ssl socket will be returned as <code>{ssl, SslSocket}</code>.
 %%      You can use <code>SslSocket</code> with the <code>ssl</code>
 %%      application, eg: <code>ssl:peercert(SslSocket)</code>.
-get(socket, {?MODULE, [Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
+get(socket,
+    {?MODULE,
+     [Socket, _Opts, _Method, _RawPath, _Version,
+      _Headers]}) ->
     Socket;
-get(scheme, {?MODULE, [Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
+get(scheme,
+    {?MODULE,
+     [Socket, _Opts, _Method, _RawPath, _Version,
+      _Headers]}) ->
     case mochiweb_socket:type(Socket) of
-        plain ->
-            http;
-        ssl ->
-            https
+      plain -> http;
+      ssl -> https
     end;
-get(method, {?MODULE, [_Socket, _Opts, Method, _RawPath, _Version, _Headers]}) ->
+get(method,
+    {?MODULE,
+     [_Socket, _Opts, Method, _RawPath, _Version,
+      _Headers]}) ->
     Method;
-get(raw_path, {?MODULE, [_Socket, _Opts, _Method, RawPath, _Version, _Headers]}) ->
+get(raw_path,
+    {?MODULE,
+     [_Socket, _Opts, _Method, RawPath, _Version,
+      _Headers]}) ->
     RawPath;
-get(version, {?MODULE, [_Socket, _Opts, _Method, _RawPath, Version, _Headers]}) ->
+get(version,
+    {?MODULE,
+     [_Socket, _Opts, _Method, _RawPath, Version,
+      _Headers]}) ->
     Version;
-get(headers, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, Headers]}) ->
+get(headers,
+    {?MODULE,
+     [_Socket, _Opts, _Method, _RawPath, _Version,
+      Headers]}) ->
     Headers;
-get(peer, {?MODULE, [Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+get(peer,
+    {?MODULE,
+     [Socket, _Opts, _Method, _RawPath, _Version,
+      _Headers]} =
+	THIS) ->
     case mochiweb_socket:peername(Socket) of
-        {ok, {Addr={10, _, _, _}, _Port}} ->
-            case get_header_value("x-forwarded-for", THIS) of
-                undefined ->
-                    inet_parse:ntoa(Addr);
-                Hosts ->
-                    string:strip(lists:last(string:tokens(Hosts, ",")))
-            end;
-        %% Copied this syntax from webmachine contributor Steve Vinoski
-        {ok, {Addr={172, Second, _, _}, _Port}} when (Second > 15) andalso (Second < 32) ->
-            case get_header_value("x-forwarded-for", THIS) of
-                undefined ->
-                    inet_parse:ntoa(Addr);
-                Hosts ->
-                    string:strip(lists:last(string:tokens(Hosts, ",")))
-            end;
-        %% According to RFC 6598, contributor Gerald Xv
-        {ok, {Addr={100, Second, _, _}, _Port}} when (Second > 63) andalso (Second < 128) ->
-            case get_header_value("x-forwarded-for", THIS) of
-                undefined ->
-                    inet_parse:ntoa(Addr);
-                Hosts ->
-                    string:strip(lists:last(string:tokens(Hosts, ",")))
-            end;
-        {ok, {Addr={192, 168, _, _}, _Port}} ->
-            case get_header_value("x-forwarded-for", THIS) of
-                undefined ->
-                    inet_parse:ntoa(Addr);
-                Hosts ->
-                    string:strip(lists:last(string:tokens(Hosts, ",")))
-            end;
-        {ok, {{127, 0, 0, 1}, _Port}} ->
-            case get_header_value("x-forwarded-for", THIS) of
-                undefined ->
-                    "127.0.0.1";
-                Hosts ->
-                    string:strip(lists:last(string:tokens(Hosts, ",")))
-            end;
-        {ok, {Addr, _Port}} ->
-            inet_parse:ntoa(Addr);
-        {error, enotconn} ->
-            exit(normal)
+      {ok, {Addr = {10, _, _, _}, _Port}} ->
+	  case get_header_value("x-forwarded-for", THIS) of
+	    undefined -> inet_parse:ntoa(Addr);
+	    Hosts ->
+		string:strip(lists:last(string:tokens(Hosts, ",")))
+	  end;
+      %% Copied this syntax from webmachine contributor Steve Vinoski
+      {ok, {Addr = {172, Second, _, _}, _Port}}
+	  when Second > 15 andalso Second < 32 ->
+	  case get_header_value("x-forwarded-for", THIS) of
+	    undefined -> inet_parse:ntoa(Addr);
+	    Hosts ->
+		string:strip(lists:last(string:tokens(Hosts, ",")))
+	  end;
+      %% According to RFC 6598, contributor Gerald Xv
+      {ok, {Addr = {100, Second, _, _}, _Port}}
+	  when Second > 63 andalso Second < 128 ->
+	  case get_header_value("x-forwarded-for", THIS) of
+	    undefined -> inet_parse:ntoa(Addr);
+	    Hosts ->
+		string:strip(lists:last(string:tokens(Hosts, ",")))
+	  end;
+      {ok, {Addr = {192, 168, _, _}, _Port}} ->
+	  case get_header_value("x-forwarded-for", THIS) of
+	    undefined -> inet_parse:ntoa(Addr);
+	    Hosts ->
+		string:strip(lists:last(string:tokens(Hosts, ",")))
+	  end;
+      {ok, {{127, 0, 0, 1}, _Port}} ->
+	  case get_header_value("x-forwarded-for", THIS) of
+	    undefined -> "127.0.0.1";
+	    Hosts ->
+		string:strip(lists:last(string:tokens(Hosts, ",")))
+	  end;
+      {ok, {Addr, _Port}} -> inet_parse:ntoa(Addr);
+      {error, enotconn} -> exit(normal)
     end;
-get(path, {?MODULE, [_Socket, _Opts, _Method, RawPath, _Version, _Headers]}) ->
+get(path,
+    {?MODULE,
+     [_Socket, _Opts, _Method, RawPath, _Version,
+      _Headers]}) ->
     case erlang:get(?SAVE_PATH) of
-        undefined ->
-            {Path0, _, _} = mochiweb_util:urlsplit_path(RawPath),
-            Path = mochiweb_util:normalize_path(mochiweb_util:unquote(Path0)),
-            put(?SAVE_PATH, Path),
-            Path;
-        Cached ->
-            Cached
+      undefined ->
+	  {Path0, _, _} = mochiweb_util:urlsplit_path(RawPath),
+	  Path =
+	      mochiweb_util:normalize_path(mochiweb_util:unquote(Path0)),
+	  put(?SAVE_PATH, Path),
+	  Path;
+      Cached -> Cached
     end;
-get(body_length, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+get(body_length,
+    {?MODULE,
+     [_Socket, _Opts, _Method, _RawPath, _Version,
+      _Headers]} =
+	THIS) ->
     case erlang:get(?SAVE_BODY_LENGTH) of
-        undefined ->
-            BodyLength = body_length(THIS),
-            put(?SAVE_BODY_LENGTH, {cached, BodyLength}),
-            BodyLength;
-        {cached, Cached} ->
-            Cached
+      undefined ->
+	  BodyLength = body_length(THIS),
+	  put(?SAVE_BODY_LENGTH, {cached, BodyLength}),
+	  BodyLength;
+      {cached, Cached} -> Cached
     end;
-get(range, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+get(range,
+    {?MODULE,
+     [_Socket, _Opts, _Method, _RawPath, _Version,
+      _Headers]} =
+	THIS) ->
     case get_header_value(range, THIS) of
-        undefined ->
-            undefined;
-        RawRange ->
-            mochiweb_http:parse_range_request(RawRange)
+      undefined -> undefined;
+      RawRange -> mochiweb_http:parse_range_request(RawRange)
     end;
-get(opts, {?MODULE, [_Socket, Opts, _Method, _RawPath, _Version, _Headers]}) ->
+get(opts,
+    {?MODULE,
+     [_Socket, Opts, _Method, _RawPath, _Version,
+      _Headers]}) ->
     Opts.
 
 %% @spec dump(request()) -> {mochiweb_request, [{atom(), term()}]}
 %% @doc Dump the internal representation to a "human readable" set of terms
 %%      for debugging/inspection purposes.
-dump({?MODULE, [_Socket, Opts, Method, RawPath, Version, Headers]}) ->
-    {?MODULE, [{method, Method},
-               {version, Version},
-               {raw_path, RawPath},
-               {opts, Opts},
-               {headers, mochiweb_headers:to_list(Headers)}]}.
+dump({?MODULE,
+      [_Socket, Opts, Method, RawPath, Version, Headers]}) ->
+    {?MODULE,
+     [{method, Method}, {version, Version},
+      {raw_path, RawPath}, {opts, Opts},
+      {headers, mochiweb_headers:to_list(Headers)}]}.
 
 %% @spec send(iodata(), request()) -> ok
 %% @doc Send data over the socket.
-send(Data, {?MODULE, [Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
+send(Data,
+     {?MODULE,
+      [Socket, _Opts, _Method, _RawPath, _Version,
+       _Headers]}) ->
     case mochiweb_socket:send(Socket, Data) of
-        ok ->
-            ok;
-        _ ->
-            exit(normal)
+      ok -> ok;
+      _ -> exit(normal)
     end.
 
 %% @spec recv(integer(), request()) -> binary()
 %% @doc Receive Length bytes from the client as a binary, with the default
 %%      idle timeout.
-recv(Length, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+recv(Length,
+     {?MODULE,
+      [_Socket, _Opts, _Method, _RawPath, _Version,
+       _Headers]} =
+	 THIS) ->
     recv(Length, ?IDLE_TIMEOUT, THIS).
 
 %% @spec recv(integer(), integer(), request()) -> binary()
 %% @doc Receive Length bytes from the client as a binary, with the given
 %%      Timeout in msec.
-recv(Length, Timeout, {?MODULE, [Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
+recv(Length, Timeout,
+     {?MODULE,
+      [Socket, _Opts, _Method, _RawPath, _Version,
+       _Headers]}) ->
     case mochiweb_socket:recv(Socket, Length, Timeout) of
-        {ok, Data} ->
-            put(?SAVE_RECV, true),
-            Data;
-        _ ->
-            exit(normal)
+      {ok, Data} -> put(?SAVE_RECV, true), Data;
+      _ -> exit(normal)
     end.
 
 %% @spec body_length(request()) -> undefined | chunked | unknown_transfer_encoding | integer()
 %% @doc  Infer body length from transfer-encoding and content-length headers.
-body_length({?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+body_length({?MODULE,
+	     [_Socket, _Opts, _Method, _RawPath, _Version,
+	      _Headers]} =
+		THIS) ->
     case get_header_value("transfer-encoding", THIS) of
-        undefined ->
-            case get_combined_header_value("content-length", THIS) of
-                undefined ->
-                    undefined;
-                Length ->
-                    list_to_integer(Length)
-            end;
-        "chunked" ->
-            chunked;
-        Unknown ->
-            {unknown_transfer_encoding, Unknown}
+      undefined ->
+	  case get_combined_header_value("content-length", THIS)
+	      of
+	    undefined -> undefined;
+	    Length -> list_to_integer(Length)
+	  end;
+      "chunked" -> chunked;
+      Unknown -> {unknown_transfer_encoding, Unknown}
     end.
 
-
 %% @spec recv_body(request()) -> binary()
 %% @doc Receive the body of the HTTP request (defined by Content-Length).
 %%      Will only receive up to the default max-body length of 1MB.
-recv_body({?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+recv_body({?MODULE,
+	   [_Socket, _Opts, _Method, _RawPath, _Version,
+	    _Headers]} =
+	      THIS) ->
     recv_body(?MAX_RECV_BODY, THIS).
 
 %% @spec recv_body(integer(), request()) -> binary()
 %% @doc Receive the body of the HTTP request (defined by Content-Length).
 %%      Will receive up to MaxBody bytes.
-recv_body(MaxBody, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+recv_body(MaxBody,
+	  {?MODULE,
+	   [_Socket, _Opts, _Method, _RawPath, _Version,
+	    _Headers]} =
+	      THIS) ->
     case erlang:get(?SAVE_BODY) of
-        undefined ->
-            % we could use a sane constant for max chunk size
-            Body = stream_body(?MAX_RECV_BODY, fun
-                ({0, _ChunkedFooter}, {_LengthAcc, BinAcc}) ->
-                    iolist_to_binary(lists:reverse(BinAcc));
-                ({Length, Bin}, {LengthAcc, BinAcc}) ->
-                    NewLength = Length + LengthAcc,
-                    if NewLength > MaxBody ->
-                        exit({body_too_large, chunked});
-                    true ->
-                        {NewLength, [Bin | BinAcc]}
-                    end
-                end, {0, []}, MaxBody, THIS),
-            put(?SAVE_BODY, Body),
-            Body;
-        Cached -> Cached
+      undefined ->
+	  % we could use a sane constant for max chunk size
+	  Body = stream_body(?MAX_RECV_BODY,
+			     fun ({0, _ChunkedFooter}, {_LengthAcc, BinAcc}) ->
+				     iolist_to_binary(lists:reverse(BinAcc));
+				 ({Length, Bin}, {LengthAcc, BinAcc}) ->
+				     NewLength = Length + LengthAcc,
+				     if NewLength > MaxBody ->
+					    exit({body_too_large, chunked});
+					true -> {NewLength, [Bin | BinAcc]}
+				     end
+			     end,
+			     {0, []}, MaxBody, THIS),
+	  put(?SAVE_BODY, Body),
+	  Body;
+      Cached -> Cached
     end.
 
-stream_body(MaxChunkSize, ChunkFun, FunState, {?MODULE,[_Socket,_Opts,_Method,_RawPath,_Version,_Headers]}=THIS) ->
-    stream_body(MaxChunkSize, ChunkFun, FunState, undefined, THIS).
-
-stream_body(MaxChunkSize, ChunkFun, FunState, MaxBodyLength,
-            {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+stream_body(MaxChunkSize, ChunkFun, FunState,
+	    {?MODULE,
+	     [_Socket, _Opts, _Method, _RawPath, _Version,
+	      _Headers]} =
+		THIS) ->
+    stream_body(MaxChunkSize, ChunkFun, FunState, undefined,
+		THIS).
+
+stream_body(MaxChunkSize, ChunkFun, FunState,
+	    MaxBodyLength,
+	    {?MODULE,
+	     [_Socket, _Opts, _Method, _RawPath, _Version,
+	      _Headers]} =
+		THIS) ->
     Expect = case get_header_value("expect", THIS) of
-                 undefined ->
-                     undefined;
-                 Value when is_list(Value) ->
-                     string:to_lower(Value)
-             end,
+	       undefined -> undefined;
+	       Value when is_list(Value) -> string:to_lower(Value)
+	     end,
     case Expect of
-        "100-continue" ->
-            _ = start_raw_response({100, gb_trees:empty()}, THIS),
-            ok;
-        _Else ->
-            ok
+      "100-continue" ->
+	  _ = start_raw_response({100, gb_trees:empty()}, THIS),
+	  ok;
+      _Else -> ok
     end,
     case body_length(THIS) of
-        undefined ->
-            undefined;
-        {unknown_transfer_encoding, Unknown} ->
-            exit({unknown_transfer_encoding, Unknown});
-        chunked ->
-            % In this case the MaxBody is actually used to
-            % determine the maximum allowed size of a single
-            % chunk.
-            stream_chunked_body(MaxChunkSize, ChunkFun, FunState, THIS);
-        0 ->
-            <<>>;
-        Length when is_integer(Length) ->
-            case MaxBodyLength of
-            MaxBodyLength when is_integer(MaxBodyLength), MaxBodyLength < Length ->
-                exit({body_too_large, content_length});
-            _ ->
-                stream_unchunked_body(MaxChunkSize,Length, ChunkFun, FunState, THIS)
-            end
+      undefined -> undefined;
+      {unknown_transfer_encoding, Unknown} ->
+	  exit({unknown_transfer_encoding, Unknown});
+      chunked ->
+	  % In this case the MaxBody is actually used to
+	  % determine the maximum allowed size of a single
+	  % chunk.
+	  stream_chunked_body(MaxChunkSize, ChunkFun, FunState,
+			      THIS);
+      0 -> <<>>;
+      Length when is_integer(Length) ->
+	  case MaxBodyLength of
+	    MaxBodyLength
+		when is_integer(MaxBodyLength),
+		     MaxBodyLength < Length ->
+		exit({body_too_large, content_length});
+	    _ ->
+		stream_unchunked_body(MaxChunkSize, Length, ChunkFun,
+				      FunState, THIS)
+	  end
     end.
 
-
 %% @spec start_response({integer(), ioheaders()}, request()) -> response()
 %% @doc Start the HTTP response by sending the Code HTTP response and
 %%      ResponseHeaders. The server will set header defaults such as Server
 %%      and Date if not present in ResponseHeaders.
-start_response({Code, ResponseHeaders}, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+start_response({Code, ResponseHeaders},
+	       {?MODULE,
+		[_Socket, _Opts, _Method, _RawPath, _Version,
+		 _Headers]} =
+		   THIS) ->
     start_raw_response({Code, ResponseHeaders}, THIS).
 
 %% @spec start_raw_response({integer(), headers()}, request()) -> response()
 %% @doc Start the HTTP response by sending the Code HTTP response and
 %%      ResponseHeaders.
-start_raw_response({Code, ResponseHeaders}, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
-    {Header, Response} = format_response_header({Code, ResponseHeaders}, THIS),
+start_raw_response({Code, ResponseHeaders},
+		   {?MODULE,
+		    [_Socket, _Opts, _Method, _RawPath, _Version,
+		     _Headers]} =
+		       THIS) ->
+    {Header, Response} = format_response_header({Code,
+						 ResponseHeaders},
+						THIS),
     send(Header, THIS),
     Response.
 
-
 %% @spec start_response_length({integer(), ioheaders(), integer()}, request()) -> response()
 %% @doc Start the HTTP response by sending the Code HTTP response and
 %%      ResponseHeaders including a Content-Length of Length. The server
 %%      will set header defaults such as Server
 %%      and Date if not present in ResponseHeaders.
 start_response_length({Code, ResponseHeaders, Length},
-                      {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+		      {?MODULE,
+		       [_Socket, _Opts, _Method, _RawPath, _Version,
+			_Headers]} =
+			  THIS) ->
     HResponse = mochiweb_headers:make(ResponseHeaders),
-    HResponse1 = mochiweb_headers:enter("Content-Length", Length, HResponse),
+    HResponse1 = mochiweb_headers:enter("Content-Length",
+					Length, HResponse),
     start_response({Code, HResponse1}, THIS).
 
 %% @spec format_response_header({integer(), ioheaders()} | {integer(), ioheaders(), integer()}, request()) -> iolist()
@@ -340,23 +431,37 @@ start_response_length({Code, ResponseHeaders, Length},
 %%      ResponseHeaders including an optional Content-Length of Length. The server
 %%      will set header defaults such as Server
 %%      and Date if not present in ResponseHeaders.
-format_response_header({Code, ResponseHeaders}, {?MODULE, [_Socket, _Opts, _Method, _RawPath, Version, _Headers]}=THIS) ->
+format_response_header({Code, ResponseHeaders},
+		       {?MODULE,
+			[_Socket, _Opts, _Method, _RawPath, Version,
+			 _Headers]} =
+			   THIS) ->
     HResponse = mochiweb_headers:make(ResponseHeaders),
-    HResponse1 = mochiweb_headers:default_from_list(server_headers(), HResponse),
+    HResponse1 =
+	mochiweb_headers:default_from_list(server_headers(),
+					   HResponse),
     HResponse2 = case should_close(THIS) of
-                     true ->
-                         mochiweb_headers:enter("Connection", "close", HResponse1);
-                     false ->
-                         HResponse1
-                 end,
-    End = [[mochiweb_util:make_io(K), <<": ">>, V, <<"\r\n">>]
-           || {K, V} <- mochiweb_headers:to_list(HResponse2)],
-    Response = mochiweb:new_response({THIS, Code, HResponse2}),
-    {[make_version(Version), make_code(Code), <<"\r\n">> | [End, <<"\r\n">>]], Response};
+		   true ->
+		       mochiweb_headers:enter("Connection", "close",
+					      HResponse1);
+		   false -> HResponse1
+		 end,
+    End = [[mochiweb_util:make_io(K), <<": ">>, V,
+	    <<"\r\n">>]
+	   || {K, V} <- mochiweb_headers:to_list(HResponse2)],
+    Response = mochiweb:new_response({THIS, Code,
+				      HResponse2}),
+    {[make_version(Version), make_code(Code), <<"\r\n">>,
+      End, <<"\r\n">>],
+     Response};
 format_response_header({Code, ResponseHeaders, Length},
-                       {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+		       {?MODULE,
+			[_Socket, _Opts, _Method, _RawPath, _Version,
+			 _Headers]} =
+			   THIS) ->
     HResponse = mochiweb_headers:make(ResponseHeaders),
-    HResponse1 = mochiweb_headers:enter("Content-Length", Length, HResponse),
+    HResponse1 = mochiweb_headers:enter("Content-Length",
+					Length, HResponse),
     format_response_header({Code, HResponse1}, THIS).
 
 %% @spec respond({integer(), ioheaders(), iodata() | chunked | {file, IoDevice}}, request()) -> response()
@@ -365,293 +470,391 @@ format_response_header({Code, ResponseHeaders, Length},
 %%      will be set by the Body length, and the server will insert header
 %%      defaults.
 respond({Code, ResponseHeaders, {file, IoDevice}},
-        {?MODULE, [_Socket, _Opts, Method, _RawPath, _Version, _Headers]}=THIS) ->
+	{?MODULE,
+	 [_Socket, _Opts, Method, _RawPath, _Version,
+	  _Headers]} =
+	    THIS) ->
     Length = mochiweb_io:iodevice_size(IoDevice),
-    Response = start_response_length({Code, ResponseHeaders, Length}, THIS),
+    Response = start_response_length({Code, ResponseHeaders,
+				      Length},
+				     THIS),
     case Method of
-        'HEAD' ->
-            ok;
-        _ ->
-            mochiweb_io:iodevice_stream(
-              fun (Body) -> send(Body, THIS) end,
-              IoDevice)
+      'HEAD' -> ok;
+      _ ->
+	  mochiweb_io:iodevice_stream(fun (Body) ->
+					      send(Body, THIS)
+				      end,
+				      IoDevice)
     end,
     Response;
-respond({Code, ResponseHeaders, chunked}, {?MODULE, [_Socket, _Opts, Method, _RawPath, Version, _Headers]}=THIS) ->
+respond({Code, ResponseHeaders, chunked},
+	{?MODULE,
+	 [_Socket, _Opts, Method, _RawPath, Version, _Headers]} =
+	    THIS) ->
     HResponse = mochiweb_headers:make(ResponseHeaders),
     HResponse1 = case Method of
-                     'HEAD' ->
-                         %% This is what Google does, http://www.google.com/
-                         %% is chunked but HEAD gets Content-Length: 0.
-                         %% The RFC is ambiguous so emulating Google is smart.
-                         mochiweb_headers:enter("Content-Length", "0",
-                                                HResponse);
-                     _ when Version >= {1, 1} ->
-                         %% Only use chunked encoding for HTTP/1.1
-                         mochiweb_headers:enter("Transfer-Encoding", "chunked",
-                                                HResponse);
-                     _ ->
-                         %% For pre-1.1 clients we send the data as-is
-                         %% without a Content-Length header and without
-                         %% chunk delimiters. Since the end of the document
-                         %% is now ambiguous we must force a close.
-                         put(?SAVE_FORCE_CLOSE, true),
-                         HResponse
-                 end,
+		   'HEAD' ->
+		       %% This is what Google does, http://www.google.com/
+		       %% is chunked but HEAD gets Content-Length: 0.
+		       %% The RFC is ambiguous so emulating Google is smart.
+		       mochiweb_headers:enter("Content-Length", "0",
+					      HResponse);
+		   _ when Version >= {1, 1} ->
+		       %% Only use chunked encoding for HTTP/1.1
+		       mochiweb_headers:enter("Transfer-Encoding", "chunked",
+					      HResponse);
+		   _ ->
+		       %% For pre-1.1 clients we send the data as-is
+		       %% without a Content-Length header and without
+		       %% chunk delimiters. Since the end of the document
+		       %% is now ambiguous we must force a close.
+		       put(?SAVE_FORCE_CLOSE, true),
+		       HResponse
+		 end,
     start_response({Code, HResponse1}, THIS);
-respond({Code, ResponseHeaders, Body}, {?MODULE, [_Socket, _Opts, Method, _RawPath, _Version, _Headers]}=THIS) ->
-    {Header, Response} = format_response_header({Code, ResponseHeaders, iolist_size(Body)}, THIS),
+respond({Code, ResponseHeaders, Body},
+	{?MODULE,
+	 [_Socket, _Opts, Method, _RawPath, _Version,
+	  _Headers]} =
+	    THIS) ->
+    {Header, Response} = format_response_header({Code,
+						 ResponseHeaders,
+						 iolist_size(Body)},
+						THIS),
     case Method of
-        'HEAD' -> send(Header, THIS);
-        _      -> send([Header, Body], THIS)
+      'HEAD' -> send(Header, THIS);
+      _ -> send([Header, Body], THIS)
     end,
     Response.
 
 %% @spec not_found(request()) -> response()
 %% @doc Alias for <code>not_found([])</code>.
-not_found({?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+not_found({?MODULE,
+	   [_Socket, _Opts, _Method, _RawPath, _Version,
+	    _Headers]} =
+	      THIS) ->
     not_found([], THIS).
 
 %% @spec not_found(ExtraHeaders, request()) -> response()
 %% @doc Alias for <code>respond({404, [{"Content-Type", "text/plain"}
 %% | ExtraHeaders], &lt;&lt;"Not found."&gt;&gt;})</code>.
-not_found(ExtraHeaders, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
-    respond({404, [{"Content-Type", "text/plain"} | ExtraHeaders],
-             <<"Not found.">>}, THIS).
+not_found(ExtraHeaders,
+	  {?MODULE,
+	   [_Socket, _Opts, _Method, _RawPath, _Version,
+	    _Headers]} =
+	      THIS) ->
+    respond({404,
+	     [{"Content-Type", "text/plain"} | ExtraHeaders],
+	     <<"Not found.">>},
+	    THIS).
 
 %% @spec ok({value(), iodata()} | {value(), ioheaders(), iodata() | {file, IoDevice}}, request()) ->
 %%           response()
 %% @doc respond({200, [{"Content-Type", ContentType} | Headers], Body}).
-ok({ContentType, Body}, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ok({ContentType, Body},
+   {?MODULE,
+    [_Socket, _Opts, _Method, _RawPath, _Version,
+     _Headers]} =
+       THIS) ->
     ok({ContentType, [], Body}, THIS);
-ok({ContentType, ResponseHeaders, Body}, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ok({ContentType, ResponseHeaders, Body},
+   {?MODULE,
+    [_Socket, _Opts, _Method, _RawPath, _Version,
+     _Headers]} =
+       THIS) ->
     HResponse = mochiweb_headers:make(ResponseHeaders),
     case get(range, THIS) of
-        X when (X =:= undefined orelse X =:= fail) orelse Body =:= chunked ->
-            %% http://code.google.com/p/mochiweb/issues/detail?id=54
-            %% Range header not supported when chunked, return 200 and provide
-            %% full response.
-            HResponse1 = mochiweb_headers:enter("Content-Type", ContentType,
-                                                HResponse),
-            respond({200, HResponse1, Body}, THIS);
-        Ranges ->
-            {PartList, Size} = range_parts(Body, Ranges),
-            case PartList of
-                [] -> %% no valid ranges
-                    HResponse1 = mochiweb_headers:enter("Content-Type",
-                                                        ContentType,
-                                                        HResponse),
-                    %% could be 416, for now we'll just return 200
-                    respond({200, HResponse1, Body}, THIS);
-                PartList ->
-                    {RangeHeaders, RangeBody} =
-                        mochiweb_multipart:parts_to_body(PartList, ContentType, Size),
-                    HResponse1 = mochiweb_headers:enter_from_list(
-                                   [{"Accept-Ranges", "bytes"} |
-                                    RangeHeaders],
-                                   HResponse),
-                    respond({206, HResponse1, RangeBody}, THIS)
-            end
+      X
+	  when (X =:= undefined orelse X =:= fail) orelse
+		 Body =:= chunked ->
+	  %% http://code.google.com/p/mochiweb/issues/detail?id=54
+	  %% Range header not supported when chunked, return 200 and provide
+	  %% full response.
+	  HResponse1 = mochiweb_headers:enter("Content-Type",
+					      ContentType, HResponse),
+	  respond({200, HResponse1, Body}, THIS);
+      Ranges ->
+	  {PartList, Size} = range_parts(Body, Ranges),
+	  case PartList of
+	    [] -> %% no valid ranges
+		HResponse1 = mochiweb_headers:enter("Content-Type",
+						    ContentType, HResponse),
+		%% could be 416, for now we'll just return 200
+		respond({200, HResponse1, Body}, THIS);
+	    PartList ->
+		{RangeHeaders, RangeBody} =
+		    mochiweb_multipart:parts_to_body(PartList, ContentType,
+						     Size),
+		HResponse1 =
+		    mochiweb_headers:enter_from_list([{"Accept-Ranges",
+						       "bytes"}
+						      | RangeHeaders],
+						     HResponse),
+		respond({206, HResponse1, RangeBody}, THIS)
+	  end
     end.
 
 %% @spec should_close(request()) -> bool()
 %% @doc Return true if the connection must be closed. If false, using
 %%      Keep-Alive should be safe.
-should_close({?MODULE, [_Socket, _Opts, _Method, _RawPath, Version, _Headers]}=THIS) ->
-    ForceClose = erlang:get(?SAVE_FORCE_CLOSE) =/= undefined,
+should_close({?MODULE,
+	      [_Socket, _Opts, _Method, _RawPath, Version,
+	       _Headers]} =
+		 THIS) ->
+    ForceClose = erlang:get(?SAVE_FORCE_CLOSE) =/=
+		   undefined,
     DidNotRecv = erlang:get(?SAVE_RECV) =:= undefined,
-    ForceClose orelse Version < {1, 0}
-        %% Connection: close
-        orelse is_close(get_header_value("connection", THIS))
-        %% HTTP 1.0 requires Connection: Keep-Alive
-        orelse (Version =:= {1, 0}
-                andalso get_header_value("connection", THIS) =/= "Keep-Alive")
-        %% unread data left on the socket, can't safely continue
-        orelse (DidNotRecv
-                andalso get_combined_header_value("content-length", THIS) =/= undefined
-                andalso list_to_integer(get_combined_header_value("content-length", THIS)) > 0)
-        orelse (DidNotRecv
-                andalso get_header_value("transfer-encoding", THIS) =:= "chunked").
-
-is_close("close") ->
-    true;
-is_close(S=[_C, _L, _O, _S, _E]) ->
+    ForceClose orelse
+      Version < {1, 0}
+	%% Connection: close
+	orelse
+	is_close(get_header_value("connection", THIS))
+	  %% HTTP 1.0 requires Connection: Keep-Alive
+	  orelse
+	  Version =:= {1, 0} andalso
+	    get_header_value("connection", THIS) =/= "Keep-Alive"
+	    %% unread data left on the socket, can't safely continue
+	    orelse
+	    DidNotRecv andalso
+	      get_combined_header_value("content-length", THIS) =/=
+		undefined
+		andalso
+		list_to_integer(get_combined_header_value("content-length",
+							  THIS))
+		  > 0
+	      orelse
+	      DidNotRecv andalso
+		get_header_value("transfer-encoding", THIS) =:=
+		  "chunked".
+
+is_close("close") -> true;
+is_close(S = [_C, _L, _O, _S, _E]) ->
     string:to_lower(S) =:= "close";
-is_close(_) ->
-    false.
+is_close(_) -> false.
 
 %% @spec cleanup(request()) -> ok
 %% @doc Clean up any junk in the process dictionary, required before continuing
 %%      a Keep-Alive request.
-cleanup({?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
-    L = [?SAVE_QS, ?SAVE_PATH, ?SAVE_RECV, ?SAVE_BODY, ?SAVE_BODY_LENGTH,
-         ?SAVE_POST, ?SAVE_COOKIE, ?SAVE_FORCE_CLOSE],
-    lists:foreach(fun(K) ->
-                          erase(K)
-                  end, L),
+cleanup({?MODULE,
+	 [_Socket, _Opts, _Method, _RawPath, _Version,
+	  _Headers]}) ->
+    L = [?SAVE_QS, ?SAVE_PATH, ?SAVE_RECV, ?SAVE_BODY,
+	 ?SAVE_BODY_LENGTH, ?SAVE_POST, ?SAVE_COOKIE,
+	 ?SAVE_FORCE_CLOSE],
+    lists:foreach(fun (K) -> erase(K) end, L),
     ok.
 
 %% @spec parse_qs(request()) -> [{Key::string(), Value::string()}]
 %% @doc Parse the query string of the URL.
-parse_qs({?MODULE, [_Socket, _Opts, _Method, RawPath, _Version, _Headers]}) ->
+parse_qs({?MODULE,
+	  [_Socket, _Opts, _Method, RawPath, _Version,
+	   _Headers]}) ->
     case erlang:get(?SAVE_QS) of
-        undefined ->
-            {_, QueryString, _} = mochiweb_util:urlsplit_path(RawPath),
-            Parsed = mochiweb_util:parse_qs(QueryString),
-            put(?SAVE_QS, Parsed),
-            Parsed;
-        Cached ->
-            Cached
+      undefined ->
+	  {_, QueryString, _} =
+	      mochiweb_util:urlsplit_path(RawPath),
+	  Parsed = mochiweb_util:parse_qs(QueryString),
+	  put(?SAVE_QS, Parsed),
+	  Parsed;
+      Cached -> Cached
     end.
 
 %% @spec get_cookie_value(Key::string, request()) -> string() | undefined
 %% @doc Get the value of the given cookie.
-get_cookie_value(Key, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+get_cookie_value(Key,
+		 {?MODULE,
+		  [_Socket, _Opts, _Method, _RawPath, _Version,
+		   _Headers]} =
+		     THIS) ->
     proplists:get_value(Key, parse_cookie(THIS)).
 
 %% @spec parse_cookie(request()) -> [{Key::string(), Value::string()}]
 %% @doc Parse the cookie header.
-parse_cookie({?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+parse_cookie({?MODULE,
+	      [_Socket, _Opts, _Method, _RawPath, _Version,
+	       _Headers]} =
+		 THIS) ->
     case erlang:get(?SAVE_COOKIE) of
-        undefined ->
-            Cookies = case get_header_value("cookie", THIS) of
-                          undefined ->
-                              [];
-                          Value ->
-                              mochiweb_cookies:parse_cookie(Value)
-                      end,
-            put(?SAVE_COOKIE, Cookies),
-            Cookies;
-        Cached ->
-            Cached
+      undefined ->
+	  Cookies = case get_header_value("cookie", THIS) of
+		      undefined -> [];
+		      Value -> mochiweb_cookies:parse_cookie(Value)
+		    end,
+	  put(?SAVE_COOKIE, Cookies),
+	  Cookies;
+      Cached -> Cached
     end.
 
 %% @spec parse_post(request()) -> [{Key::string(), Value::string()}]
 %% @doc Parse an application/x-www-form-urlencoded form POST. This
 %%      has the side-effect of calling recv_body().
-parse_post({?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+parse_post({?MODULE,
+	    [_Socket, _Opts, _Method, _RawPath, _Version,
+	     _Headers]} =
+	       THIS) ->
     case erlang:get(?SAVE_POST) of
-        undefined ->
-            Parsed = case recv_body(THIS) of
-                         undefined ->
-                             [];
-                         Binary ->
-                             case get_primary_header_value("content-type",THIS) of
-                                 "application/x-www-form-urlencoded" ++ _ ->
-                                     mochiweb_util:parse_qs(Binary);
-                                 _ ->
-                                     []
-                             end
-                     end,
-            put(?SAVE_POST, Parsed),
-            Parsed;
-        Cached ->
-            Cached
+      undefined ->
+	  Parsed = case recv_body(THIS) of
+		     undefined -> [];
+		     Binary ->
+			 case get_primary_header_value("content-type", THIS) of
+			   "application/x-www-form-urlencoded" ++ _ ->
+			       mochiweb_util:parse_qs(Binary);
+			   _ -> []
+			 end
+		   end,
+	  put(?SAVE_POST, Parsed),
+	  Parsed;
+      Cached -> Cached
     end.
 
 %% @spec stream_chunked_body(integer(), fun(), term(), request()) -> term()
 %% @doc The function is called for each chunk.
 %%      Used internally by read_chunked_body.
 stream_chunked_body(MaxChunkSize, Fun, FunState,
-                    {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+		    {?MODULE,
+		     [_Socket, _Opts, _Method, _RawPath, _Version,
+		      _Headers]} =
+			THIS) ->
     case read_chunk_length(THIS) of
-        0 ->
-            Fun({0, read_chunk(0, THIS)}, FunState);
-        Length when Length > MaxChunkSize ->
-            NewState = read_sub_chunks(Length, MaxChunkSize, Fun, FunState, THIS),
-            stream_chunked_body(MaxChunkSize, Fun, NewState, THIS);
-        Length ->
-            NewState = Fun({Length, read_chunk(Length, THIS)}, FunState),
-            stream_chunked_body(MaxChunkSize, Fun, NewState, THIS)
+      0 -> Fun({0, read_chunk(0, THIS)}, FunState);
+      Length when Length > MaxChunkSize ->
+	  NewState = read_sub_chunks(Length, MaxChunkSize, Fun,
+				     FunState, THIS),
+	  stream_chunked_body(MaxChunkSize, Fun, NewState, THIS);
+      Length ->
+	  NewState = Fun({Length, read_chunk(Length, THIS)},
+			 FunState),
+	  stream_chunked_body(MaxChunkSize, Fun, NewState, THIS)
     end.
 
-stream_unchunked_body(_MaxChunkSize, 0, Fun, FunState, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
+stream_unchunked_body(_MaxChunkSize, 0, Fun, FunState,
+		      {?MODULE,
+		       [_Socket, _Opts, _Method, _RawPath, _Version,
+			_Headers]}) ->
     Fun({0, <<>>}, FunState);
-stream_unchunked_body(MaxChunkSize, Length, Fun, FunState,
-                      {?MODULE, [_Socket, Opts, _Method, _RawPath, _Version, _Headers]}=THIS) when Length > 0 ->
-    RecBuf = case mochilists:get_value(recbuf, Opts, ?RECBUF_SIZE) of
-        undefined -> %os controlled buffer size
-            MaxChunkSize;
-        Val  ->
-            Val
-    end,
-    PktSize=min(Length,RecBuf),
+stream_unchunked_body(MaxChunkSize, Length, Fun,
+		      FunState,
+		      {?MODULE,
+		       [_Socket, Opts, _Method, _RawPath, _Version,
+			_Headers]} =
+			  THIS)
+    when Length > 0 ->
+    RecBuf = case mochilists:get_value(recbuf, Opts,
+				       ?RECBUF_SIZE)
+		 of
+	       undefined -> %os controlled buffer size
+		   MaxChunkSize;
+	       Val -> Val
+	     end,
+    PktSize = min(Length, RecBuf),
     Bin = recv(PktSize, THIS),
     NewState = Fun({PktSize, Bin}, FunState),
-    stream_unchunked_body(MaxChunkSize, Length - PktSize, Fun, NewState, THIS).
+    stream_unchunked_body(MaxChunkSize, Length - PktSize,
+			  Fun, NewState, THIS).
 
 %% @spec read_chunk_length(request()) -> integer()
 %% @doc Read the length of the next HTTP chunk.
-read_chunk_length({?MODULE, [Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
-    ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, line}])),
+read_chunk_length({?MODULE,
+		   [Socket, _Opts, _Method, _RawPath, _Version,
+		    _Headers]}) ->
+    ok =
+	mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+							       [{packet,
+								 line}])),
     case mochiweb_socket:recv(Socket, 0, ?IDLE_TIMEOUT) of
-        {ok, Header} ->
-            ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, raw}])),
-            Splitter = fun (C) ->
-                               C =/= $\r andalso C =/= $\n andalso C =/= $
-                       end,
-            {Hex, _Rest} = lists:splitwith(Splitter, binary_to_list(Header)),
-            mochihex:to_int(Hex);
-        _ ->
-            exit(normal)
+      {ok, Header} ->
+	  ok =
+	      mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+								     [{packet,
+								       raw}])),
+	  Splitter = fun (C) ->
+			     C =/= $\r andalso C =/= $\n andalso C =/= $\n
+		     end,
+	  {Hex, _Rest} = lists:splitwith(Splitter,
+					 binary_to_list(Header)),
+	  mochihex:to_int(Hex);
+      _ -> exit(normal)
     end.
 
 %% @spec read_chunk(integer(), request()) -> Chunk::binary() | [Footer::binary()]
 %% @doc Read in a HTTP chunk of the given length. If Length is 0, then read the
 %%      HTTP footers (as a list of binaries, since they're nominal).
-read_chunk(0, {?MODULE, [Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
-    ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, line}])),
+read_chunk(0,
+	   {?MODULE,
+	    [Socket, _Opts, _Method, _RawPath, _Version,
+	     _Headers]}) ->
+    ok =
+	mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+							       [{packet,
+								 line}])),
     F = fun (F1, Acc) ->
-                case mochiweb_socket:recv(Socket, 0, ?IDLE_TIMEOUT) of
-                    {ok, <<"\r\n">>} ->
-                        Acc;
-                    {ok, Footer} ->
-                        F1(F1, [Footer | Acc]);
-                    _ ->
-                        exit(normal)
-                end
-        end,
+		case mochiweb_socket:recv(Socket, 0, ?IDLE_TIMEOUT) of
+		  {ok, <<"\r\n">>} -> Acc;
+		  {ok, Footer} -> F1(F1, [Footer | Acc]);
+		  _ -> exit(normal)
+		end
+	end,
     Footers = F(F, []),
-    ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, raw}])),
+    ok =
+	mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+							       [{packet,
+								 raw}])),
     put(?SAVE_RECV, true),
     Footers;
-read_chunk(Length, {?MODULE, [Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
-    case mochiweb_socket:recv(Socket, 2 + Length, ?IDLE_TIMEOUT) of
-        {ok, <<Chunk:Length/binary, "\r\n">>} ->
-            Chunk;
-        _ ->
-            exit(normal)
+read_chunk(Length,
+	   {?MODULE,
+	    [Socket, _Opts, _Method, _RawPath, _Version,
+	     _Headers]}) ->
+    case mochiweb_socket:recv(Socket, 2 + Length,
+			      ?IDLE_TIMEOUT)
+	of
+      {ok, <<Chunk:Length/binary, "\r\n">>} -> Chunk;
+      _ -> exit(normal)
     end.
 
 read_sub_chunks(Length, MaxChunkSize, Fun, FunState,
-                {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) when Length > MaxChunkSize ->
+		{?MODULE,
+		 [_Socket, _Opts, _Method, _RawPath, _Version,
+		  _Headers]} =
+		    THIS)
+    when Length > MaxChunkSize ->
     Bin = recv(MaxChunkSize, THIS),
     NewState = Fun({size(Bin), Bin}, FunState),
-    read_sub_chunks(Length - MaxChunkSize, MaxChunkSize, Fun, NewState, THIS);
-
+    read_sub_chunks(Length - MaxChunkSize, MaxChunkSize,
+		    Fun, NewState, THIS);
 read_sub_chunks(Length, _MaxChunkSize, Fun, FunState,
-                {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+		{?MODULE,
+		 [_Socket, _Opts, _Method, _RawPath, _Version,
+		  _Headers]} =
+		    THIS) ->
     Fun({Length, read_chunk(Length, THIS)}, FunState).
 
 %% @spec serve_file(Path, DocRoot, request()) -> Response
 %% @doc Serve a file relative to DocRoot.
-serve_file(Path, DocRoot, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+serve_file(Path, DocRoot,
+	   {?MODULE,
+	    [_Socket, _Opts, _Method, _RawPath, _Version,
+	     _Headers]} =
+	       THIS) ->
     serve_file(Path, DocRoot, [], THIS).
 
 %% @spec serve_file(Path, DocRoot, ExtraHeaders, request()) -> Response
 %% @doc Serve a file relative to DocRoot.
-serve_file(Path, DocRoot, ExtraHeaders, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+serve_file(Path, DocRoot, ExtraHeaders,
+	   {?MODULE,
+	    [_Socket, _Opts, _Method, _RawPath, _Version,
+	     _Headers]} =
+	       THIS) ->
     case mochiweb_util:safe_relative_path(Path) of
-        undefined ->
-            not_found(ExtraHeaders, THIS);
-        RelPath ->
-            FullPath = filename:join([DocRoot, RelPath]),
-            case filelib:is_dir(FullPath) of
-                true ->
-                    maybe_redirect(RelPath, FullPath, ExtraHeaders, THIS);
-                false ->
-                    maybe_serve_file(FullPath, ExtraHeaders, THIS)
-            end
+      undefined -> not_found(ExtraHeaders, THIS);
+      RelPath ->
+	  FullPath = filename:join([DocRoot, RelPath]),
+	  case filelib:is_dir(FullPath) of
+	    true ->
+		maybe_redirect(RelPath, FullPath, ExtraHeaders, THIS);
+	    false -> maybe_serve_file(FullPath, ExtraHeaders, THIS)
+	  end
     end.
 
 %% Internal API
@@ -660,104 +863,111 @@ serve_file(Path, DocRoot, ExtraHeaders, {?MODULE, [_Socket, _Opts, _Method, _Raw
 directory_index(FullPath) ->
     filename:join([FullPath, "index.html"]).
 
-maybe_redirect([], FullPath, ExtraHeaders, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
-    maybe_serve_file(directory_index(FullPath), ExtraHeaders, THIS);
-
+maybe_redirect([], FullPath, ExtraHeaders,
+	       {?MODULE,
+		[_Socket, _Opts, _Method, _RawPath, _Version,
+		 _Headers]} =
+		   THIS) ->
+    maybe_serve_file(directory_index(FullPath),
+		     ExtraHeaders, THIS);
 maybe_redirect(RelPath, FullPath, ExtraHeaders,
-               {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, Headers]}=THIS) ->
+	       {?MODULE,
+		[_Socket, _Opts, _Method, _RawPath, _Version,
+		 Headers]} =
+		   THIS) ->
     case string:right(RelPath, 1) of
-        "/" ->
-            maybe_serve_file(directory_index(FullPath), ExtraHeaders, THIS);
-        _   ->
-            Host = mochiweb_headers:get_value("host", Headers),
-            Location = "http://" ++ Host  ++ "/" ++ RelPath ++ "/",
-            LocationBin = list_to_binary(Location),
-            MoreHeaders = [{"Location", Location},
-                           {"Content-Type", "text/html"} | ExtraHeaders],
-            Top = <<"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">"
-            "<html><head>"
-            "<title>301 Moved Permanently</title>"
-            "</head><body>"
-            "<h1>Moved Permanently</h1>"
-            "<p>The document has moved <a href=\"">>,
-            Bottom = <<">here</a>.</p></body></html>\n">>,
-            Body = <<Top/binary, LocationBin/binary, Bottom/binary>>,
-            respond({301, MoreHeaders, Body}, THIS)
+      "/" ->
+	  maybe_serve_file(directory_index(FullPath),
+			   ExtraHeaders, THIS);
+      _ ->
+	  Host = mochiweb_headers:get_value("host", Headers),
+	  Location = "http://" ++ Host ++ "/" ++ RelPath ++ "/",
+	  LocationBin = list_to_binary(Location),
+	  MoreHeaders = [{"Location", Location},
+			 {"Content-Type", "text/html"}
+			 | ExtraHeaders],
+	  Top = <<"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD "
+		  "HTML 2.0//EN\"><html><head><title>301 "
+		  "Moved Permanently</title></head><body><h1>Mov"
+		  "ed Permanently</h1><p>The document has "
+		  "moved <a href=\"">>,
+	  Bottom = <<">here</a>.</p></body></html>\n">>,
+	  Body = <<Top/binary, LocationBin/binary,
+		   Bottom/binary>>,
+	  respond({301, MoreHeaders, Body}, THIS)
     end.
 
-maybe_serve_file(File, ExtraHeaders, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+maybe_serve_file(File, ExtraHeaders,
+		 {?MODULE,
+		  [_Socket, _Opts, _Method, _RawPath, _Version,
+		   _Headers]} =
+		     THIS) ->
     case file:read_file_info(File) of
-        {ok, FileInfo} ->
-            LastModified = httpd_util:rfc1123_date(FileInfo#file_info.mtime),
-            case get_header_value("if-modified-since", THIS) of
-                LastModified ->
-                    respond({304, ExtraHeaders, ""}, THIS);
-                _ ->
-                    case file:open(File, [raw, binary]) of
-                        {ok, IoDevice} ->
-                            ContentType = mochiweb_util:guess_mime(File),
-                            Res = ok({ContentType,
-                                      [{"last-modified", LastModified}
-                                       | ExtraHeaders],
-                                      {file, IoDevice}}, THIS),
-                            ok = file:close(IoDevice),
-                            Res;
-                        _ ->
-                            not_found(ExtraHeaders, THIS)
-                    end
-            end;
-        {error, _} ->
-            not_found(ExtraHeaders, THIS)
+      {ok, FileInfo} ->
+	  LastModified =
+	      httpd_util:rfc1123_date(FileInfo#file_info.mtime),
+	  case get_header_value("if-modified-since", THIS) of
+	    LastModified -> respond({304, ExtraHeaders, ""}, THIS);
+	    _ ->
+		case file:open(File, [raw, binary]) of
+		  {ok, IoDevice} ->
+		      ContentType = mochiweb_util:guess_mime(File),
+		      Res = ok({ContentType,
+				[{"last-modified", LastModified}
+				 | ExtraHeaders],
+				{file, IoDevice}},
+			       THIS),
+		      ok = file:close(IoDevice),
+		      Res;
+		  _ -> not_found(ExtraHeaders, THIS)
+		end
+	  end;
+      {error, _} -> not_found(ExtraHeaders, THIS)
     end.
 
 server_headers() ->
-    [{"Server", "MochiWeb/1.0 (" ++ ?QUIP ++ ")"},
+    [{"Server", "MochiWeb/1.0 (" ++ (?QUIP) ++ ")"},
      {"Date", mochiweb_clock:rfc1123()}].
 
 make_code(X) when is_integer(X) ->
-    [integer_to_list(X), [" " | httpd_util:reason_phrase(X)]];
-make_code(Io) when is_list(Io); is_binary(Io) ->
-    Io.
+    [integer_to_list(X),
+     [" " | httpd_util:reason_phrase(X)]];
+make_code(Io) when is_list(Io); is_binary(Io) -> Io.
 
-make_version({1, 0}) ->
-    <<"HTTP/1.0 ">>;
-make_version(_) ->
-    <<"HTTP/1.1 ">>.
+make_version({1, 0}) -> <<"HTTP/1.0 ">>;
+make_version(_) -> <<"HTTP/1.1 ">>.
 
 range_parts({file, IoDevice}, Ranges) ->
     Size = mochiweb_io:iodevice_size(IoDevice),
     F = fun (Spec, Acc) ->
-                case mochiweb_http:range_skip_length(Spec, Size) of
-                    invalid_range ->
-                        Acc;
-                    V ->
-                        [V | Acc]
-                end
-        end,
+		case mochiweb_http:range_skip_length(Spec, Size) of
+		  invalid_range -> Acc;
+		  V -> [V | Acc]
+		end
+	end,
     LocNums = lists:foldr(F, [], Ranges),
     {ok, Data} = file:pread(IoDevice, LocNums),
-    Bodies = lists:zipwith(fun ({Skip, Length}, PartialBody) ->
-                                   case Length of
-                                       0 ->
-                                           {Skip, Skip, <<>>};
-                                       _ ->
-                                           {Skip, Skip + Length - 1, PartialBody}
-                                   end
-                           end,
-                           LocNums, Data),
+    Bodies = lists:zipwith(fun ({Skip, Length},
+				PartialBody) ->
+				   case Length of
+				     0 -> {Skip, Skip, <<>>};
+				     _ -> {Skip, Skip + Length - 1, PartialBody}
+				   end
+			   end,
+			   LocNums, Data),
     {Bodies, Size};
 range_parts(Body0, Ranges) ->
     Body = iolist_to_binary(Body0),
     Size = size(Body),
-    F = fun(Spec, Acc) ->
-                case mochiweb_http:range_skip_length(Spec, Size) of
-                    invalid_range ->
-                        Acc;
-                    {Skip, Length} ->
-                        <<_:Skip/binary, PartialBody:Length/binary, _/binary>> = Body,
-                        [{Skip, Skip + Length - 1, PartialBody} | Acc]
-                end
-        end,
+    F = fun (Spec, Acc) ->
+		case mochiweb_http:range_skip_length(Spec, Size) of
+		  invalid_range -> Acc;
+		  {Skip, Length} ->
+		      <<_:Skip/binary, PartialBody:Length/binary, _/binary>> =
+			  Body,
+		      [{Skip, Skip + Length - 1, PartialBody} | Acc]
+		end
+	end,
     {lists:foldr(F, [], Ranges), Size}.
 
 %% @spec accepted_encodings([encoding()], request()) -> [encoding()] | bad_accept_encoding_value
@@ -784,20 +994,23 @@ range_parts(Body0, Ranges) ->
 %%         accepted_encodings(["gzip", "deflate", "identity"]) ->
 %%            ["deflate", "gzip", "identity"]
 %%
-accepted_encodings(SupportedEncodings, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
-    AcceptEncodingHeader = case get_header_value("Accept-Encoding", THIS) of
-        undefined ->
-            "";
-        Value ->
-            Value
-    end,
-    case mochiweb_util:parse_qvalues(AcceptEncodingHeader) of
-        invalid_qvalue_string ->
-            bad_accept_encoding_value;
-        QList ->
-            mochiweb_util:pick_accepted_encodings(
-                QList, SupportedEncodings, "identity"
-            )
+accepted_encodings(SupportedEncodings,
+		   {?MODULE,
+		    [_Socket, _Opts, _Method, _RawPath, _Version,
+		     _Headers]} =
+		       THIS) ->
+    AcceptEncodingHeader = case
+			     get_header_value("Accept-Encoding", THIS)
+			       of
+			     undefined -> "";
+			     Value -> Value
+			   end,
+    case mochiweb_util:parse_qvalues(AcceptEncodingHeader)
+	of
+      invalid_qvalue_string -> bad_accept_encoding_value;
+      QList ->
+	  mochiweb_util:pick_accepted_encodings(QList,
+						SupportedEncodings, "identity")
     end.
 
 %% @spec accepts_content_type(string() | binary(), request()) -> boolean() | bad_accept_header
@@ -822,27 +1035,28 @@ accepted_encodings(SupportedEncodings, {?MODULE, [_Socket, _Opts, _Method, _RawP
 %%      5) For an "Accept" header with value "text/*; q=0.0, */*":
 %%         accepts_content_type("text/plain") -> false
 %%
-accepts_content_type(ContentType1, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
-    ContentType = re:replace(ContentType1, "\\s", "", [global, {return, list}]),
+accepts_content_type(ContentType1,
+		     {?MODULE,
+		      [_Socket, _Opts, _Method, _RawPath, _Version,
+		       _Headers]} =
+			 THIS) ->
+    ContentType = re:replace(ContentType1, "\\s", "",
+			     [global, {return, list}]),
     AcceptHeader = accept_header(THIS),
     case mochiweb_util:parse_qvalues(AcceptHeader) of
-        invalid_qvalue_string ->
-            bad_accept_header;
-        QList ->
-            [MainType, _SubType] = string:tokens(ContentType, "/"),
-            SuperType = MainType ++ "/*",
-            lists:any(
-                fun({"*/*", Q}) when Q > 0.0 ->
-                        true;
-                    ({Type, Q}) when Q > 0.0 ->
-                        Type =:= ContentType orelse Type =:= SuperType;
-                    (_) ->
-                        false
-                end,
-                QList
-            ) andalso
-            (not lists:member({ContentType, 0.0}, QList)) andalso
-            (not lists:member({SuperType, 0.0}, QList))
+      invalid_qvalue_string -> bad_accept_header;
+      QList ->
+	  [MainType, _SubType] = string:tokens(ContentType, "/"),
+	  SuperType = MainType ++ "/*",
+	  lists:any(fun ({"*/*", Q}) when Q > 0.0 -> true;
+			({Type, Q}) when Q > 0.0 ->
+			    Type =:= ContentType orelse Type =:= SuperType;
+			(_) -> false
+		    end,
+		    QList)
+	    andalso
+	    not lists:member({ContentType, 0.0}, QList) andalso
+	      not lists:member({SuperType, 0.0}, QList)
     end.
 
 %% @spec accepted_content_types([string() | binary()], request()) -> [string()] | bad_accept_header
@@ -871,57 +1085,67 @@ accepts_content_type(ContentType1, {?MODULE, [_Socket, _Opts, _Method, _RawPath,
 %%         accepts_content_types(["application/json", "text/html"]) ->
 %%             ["text/html", "application/json"]
 %%
-accepted_content_types(Types1, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
-    Types = lists:map(
-        fun(T) -> re:replace(T, "\\s", "", [global, {return, list}]) end,
-        Types1),
+accepted_content_types(Types1,
+		       {?MODULE,
+			[_Socket, _Opts, _Method, _RawPath, _Version,
+			 _Headers]} =
+			   THIS) ->
+    Types = [accepted_content_types_1(V1) || V1 <- Types1],
     AcceptHeader = accept_header(THIS),
     case mochiweb_util:parse_qvalues(AcceptHeader) of
-        invalid_qvalue_string ->
-            bad_accept_header;
-        QList ->
-            TypesQ = lists:foldr(
-                fun(T, Acc) ->
-                    case proplists:get_value(T, QList) of
-                        undefined ->
-                            [MainType, _SubType] = string:tokens(T, "/"),
-                            case proplists:get_value(MainType ++ "/*", QList) of
-                                undefined ->
-                                    case proplists:get_value("*/*", QList) of
-                                        Q when is_float(Q), Q > 0.0 ->
-                                            [{Q, T} | Acc];
-                                        _ ->
-                                            Acc
-                                    end;
-                                Q when Q > 0.0 ->
-                                    [{Q, T} | Acc];
-                                _ ->
-                                    Acc
-                            end;
-                        Q when Q > 0.0 ->
-                            [{Q, T} | Acc];
-                        _ ->
-                            Acc
-                    end
-                end,
-                [], Types),
-            % Note: Stable sort. If 2 types have the same Q value we leave them in the
-            % same order as in the input list.
-            SortFun = fun({Q1, _}, {Q2, _}) -> Q1 >= Q2 end,
-            [Type || {_Q, Type} <- lists:sort(SortFun, TypesQ)]
+      invalid_qvalue_string -> bad_accept_header;
+      QList ->
+	  TypesQ = lists:foldr(fun (T, Acc) ->
+				       case proplists:get_value(T, QList) of
+					 undefined ->
+					     [MainType, _SubType] =
+						 string:tokens(T, "/"),
+					     case proplists:get_value(MainType
+									++ "/*",
+								      QList)
+						 of
+					       undefined ->
+						   case
+						     proplists:get_value("*/*",
+									 QList)
+						       of
+						     Q
+							 when is_float(Q),
+							      Q > 0.0 ->
+							 [{Q, T} | Acc];
+						     _ -> Acc
+						   end;
+					       Q when Q > 0.0 -> [{Q, T} | Acc];
+					       _ -> Acc
+					     end;
+					 Q when Q > 0.0 -> [{Q, T} | Acc];
+					 _ -> Acc
+				       end
+			       end,
+			       [], Types),
+	  % Note: Stable sort. If 2 types have the same Q value we leave them in the
+	  % same order as in the input list.
+	  SortFun = fun ({Q1, _}, {Q2, _}) -> Q1 >= Q2 end,
+	  [Type || {_Q, Type} <- lists:sort(SortFun, TypesQ)]
     end.
 
-accept_header({?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+accepted_content_types_1(T) ->
+    re:replace(T, "\\s", "", [global, {return, list}]).
+
+accept_header({?MODULE,
+	       [_Socket, _Opts, _Method, _RawPath, _Version,
+		_Headers]} =
+		  THIS) ->
     case get_header_value("Accept", THIS) of
-        undefined ->
-            "*/*";
-        Value ->
-            Value
+      undefined -> "*/*";
+      Value -> Value
     end.
 
 %%
 %% Tests
 %%
 -ifdef(TEST).
+
 -include_lib("eunit/include/eunit.hrl").
+
 -endif.
diff --git a/src/mochiweb_response.erl b/src/mochiweb_response.erl
index 81325b5..2f5b544 100644
--- a/src/mochiweb_response.erl
+++ b/src/mochiweb_response.erl
@@ -22,11 +22,13 @@
 %% @doc Response abstraction.
 
 -module(mochiweb_response).
+
 -author('bob@mochimedia.com').
 
 -define(QUIP, "Any of you quaids got a smint?").
 
--export([new/3, get_header_value/2, get/2, dump/1]).
+-export([dump/1, get/2, get_header_value/2, new/3]).
+
 -export([send/2, write_chunk/2]).
 
 %% @type response(). A mochiweb_response parameterized module instance.
@@ -39,7 +41,8 @@ new(Request, Code, Headers) ->
 %% @spec get_header_value(string() | atom() | binary(), response()) ->
 %%           string() | undefined
 %% @doc Get the value of the given response header.
-get_header_value(K, {?MODULE, [_Request, _Code, Headers]}) ->
+get_header_value(K,
+		 {?MODULE, [_Request, _Code, Headers]}) ->
     mochiweb_headers:get_value(K, Headers).
 
 %% @spec get(request | code | headers, response()) -> term()
@@ -55,36 +58,38 @@ get(headers, {?MODULE, [_Request, _Code, Headers]}) ->
 %% @doc Dump the internal representation to a "human readable" set of terms
 %%      for debugging/inspection purposes.
 dump({?MODULE, [{ReqM, _} = Request, Code, Headers]}) ->
-    [{request, ReqM:dump(Request)},
-     {code, Code},
+    [{request, ReqM:dump(Request)}, {code, Code},
      {headers, mochiweb_headers:to_list(Headers)}].
 
 %% @spec send(iodata(), response()) -> ok
 %% @doc Send data over the socket if the method is not HEAD.
-send(Data, {?MODULE, [{ReqM, _} = Request, _Code, _Headers]}) ->
+send(Data,
+     {?MODULE, [{ReqM, _} = Request, _Code, _Headers]}) ->
     case ReqM:get(method, Request) of
-        'HEAD' ->
-            ok;
-        _ ->
-            ReqM:send(Data, Request)
+      'HEAD' -> ok;
+      _ -> ReqM:send(Data, Request)
     end.
 
 %% @spec write_chunk(iodata(), response()) -> ok
 %% @doc Write a chunk of a HTTP chunked response. If Data is zero length,
 %%      then the chunked response will be finished.
-write_chunk(Data, {?MODULE, [{ReqM, _} = Request, _Code, _Headers]}=THIS) ->
+write_chunk(Data,
+	    {?MODULE, [{ReqM, _} = Request, _Code, _Headers]} =
+		THIS) ->
     case ReqM:get(version, Request) of
-        Version when Version >= {1, 1} ->
-            Length = iolist_size(Data),
-            send([io_lib:format("~.16b\r\n", [Length]), Data, <<"\r\n">>], THIS);
-        _ ->
-            send(Data, THIS)
+      Version when Version >= {1, 1} ->
+	  Length = iolist_size(Data),
+	  send([io_lib:format("~.16b\r\n", [Length]), Data,
+		<<"\r\n">>],
+	       THIS);
+      _ -> send(Data, THIS)
     end.
 
-
 %%
 %% Tests
 %%
 -ifdef(TEST).
+
 -include_lib("eunit/include/eunit.hrl").
+
 -endif.
diff --git a/src/mochiweb_websocket.erl b/src/mochiweb_websocket.erl
index c162980..c2e2ab6 100644
--- a/src/mochiweb_websocket.erl
+++ b/src/mochiweb_websocket.erl
@@ -1,4 +1,5 @@
 -module(mochiweb_websocket).
+
 -author('lukasz.lalik@zadane.pl').
 
 %% The MIT License (MIT)
@@ -25,43 +26,45 @@
 
 %% @doc Websockets module for Mochiweb. Based on Misultin websockets module.
 
--export([loop/5, upgrade_connection/2, request/5]).
+-export([loop/5, request/5, upgrade_connection/2]).
+
 -export([send/3]).
+
 -ifdef(TEST).
--export([make_handshake/1, hixie_handshake/7, parse_hybi_frames/3, parse_hixie_frames/2]).
+
+-export([hixie_handshake/7, make_handshake/1,
+	 parse_hixie_frames/2, parse_hybi_frames/3]).
+
 -endif.
 
 loop(Socket, Body, State, WsVersion, ReplyChannel) ->
-    ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, 0}, {active, once}])),
+    ok =
+	mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+							       [{packet, 0},
+								{active,
+								 once}])),
     proc_lib:hibernate(?MODULE, request,
-                       [Socket, Body, State, WsVersion, ReplyChannel]).
+		       [Socket, Body, State, WsVersion, ReplyChannel]).
 
 request(Socket, Body, State, WsVersion, ReplyChannel) ->
     receive
-        {tcp_closed, _} ->
-            mochiweb_socket:close(Socket),
-            exit(normal);
-        {ssl_closed, _} ->
-            mochiweb_socket:close(Socket),
-            exit(normal);
-        {tcp_error, _, _} ->
-            mochiweb_socket:close(Socket),
-            exit(normal);
-        {Proto, _, WsFrames} when Proto =:= tcp orelse Proto =:= ssl ->
-            case parse_frames(WsVersion, WsFrames, Socket) of
-                close ->
-                    mochiweb_socket:close(Socket),
-                    exit(normal);
-                error ->
-                    mochiweb_socket:close(Socket),
-                    exit(normal);
-                Payload ->
-                    NewState = call_body(Body, Payload, State, ReplyChannel),
-                    loop(Socket, Body, NewState, WsVersion, ReplyChannel)
-            end;
-        _ ->
-            mochiweb_socket:close(Socket),
-            exit(normal)
+      {tcp_closed, _} ->
+	  mochiweb_socket:close(Socket), exit(normal);
+      {ssl_closed, _} ->
+	  mochiweb_socket:close(Socket), exit(normal);
+      {tcp_error, _, _} ->
+	  mochiweb_socket:close(Socket), exit(normal);
+      {Proto, _, WsFrames}
+	  when Proto =:= tcp orelse Proto =:= ssl ->
+	  case parse_frames(WsVersion, WsFrames, Socket) of
+	    close -> mochiweb_socket:close(Socket), exit(normal);
+	    error -> mochiweb_socket:close(Socket), exit(normal);
+	    Payload ->
+		NewState = call_body(Body, Payload, State,
+				     ReplyChannel),
+		loop(Socket, Body, NewState, WsVersion, ReplyChannel)
+	  end;
+      _ -> mochiweb_socket:close(Socket), exit(normal)
     end.
 
 call_body({M, F, A}, Payload, State, ReplyChannel) ->
@@ -72,63 +75,68 @@ call_body(Body, Payload, State, ReplyChannel) ->
     Body(Payload, State, ReplyChannel).
 
 send(Socket, Payload, hybi) ->
-    Prefix = <<1:1, 0:3, 1:4, (payload_length(iolist_size(Payload)))/binary>>,
+    Prefix = <<1:1, 0:3, 1:4,
+	       (payload_length(iolist_size(Payload)))/binary>>,
     mochiweb_socket:send(Socket, [Prefix, Payload]);
 send(Socket, Payload, hixie) ->
     mochiweb_socket:send(Socket, [0, Payload, 255]).
 
 upgrade_connection({ReqM, _} = Req, Body) ->
     case make_handshake(Req) of
-        {Version, Response} ->
-            ReqM:respond(Response, Req),
-            Socket = ReqM:get(socket, Req),
-            ReplyChannel = fun (Payload) ->
-                ?MODULE:send(Socket, Payload, Version)
-            end,
-            Reentry = fun (State) ->
-                ?MODULE:loop(Socket, Body, State, Version, ReplyChannel)
-            end,
-            {Reentry, ReplyChannel};
-        _ ->
-            mochiweb_socket:close(ReqM:get(socket, Req)),
-            exit(normal)
+      {Version, Response} ->
+	  ReqM:respond(Response, Req),
+	  Socket = ReqM:get(socket, Req),
+	  ReplyChannel = fun (Payload) ->
+				 (?MODULE):send(Socket, Payload, Version)
+			 end,
+	  Reentry = fun (State) ->
+			    (?MODULE):loop(Socket, Body, State, Version,
+					   ReplyChannel)
+		    end,
+	  {Reentry, ReplyChannel};
+      _ ->
+	  mochiweb_socket:close(ReqM:get(socket, Req)),
+	  exit(normal)
     end.
 
 make_handshake({ReqM, _} = Req) ->
-    SecKey  = ReqM:get_header_value("sec-websocket-key", Req),
-    Sec1Key = ReqM:get_header_value("Sec-WebSocket-Key1", Req),
-    Sec2Key = ReqM:get_header_value("Sec-WebSocket-Key2", Req),
+    SecKey = ReqM:get_header_value("sec-websocket-key",
+				   Req),
+    Sec1Key = ReqM:get_header_value("Sec-WebSocket-Key1",
+				    Req),
+    Sec2Key = ReqM:get_header_value("Sec-WebSocket-Key2",
+				    Req),
     Origin = ReqM:get_header_value(origin, Req),
-    if SecKey =/= undefined ->
-            hybi_handshake(SecKey);
+    if SecKey =/= undefined -> hybi_handshake(SecKey);
        Sec1Key =/= undefined andalso Sec2Key =/= undefined ->
-            Host = ReqM:get_header_value("Host", Req),
-            Path = ReqM:get(path, Req),
-            Body = ReqM:recv(8, Req),
-            Scheme = scheme(Req),
-            hixie_handshake(Scheme, Host, Path, Sec1Key, Sec2Key, Body, Origin);
-       true ->
-          error
+	   Host = ReqM:get_header_value("Host", Req),
+	   Path = ReqM:get(path, Req),
+	   Body = ReqM:recv(8, Req),
+	   Scheme = scheme(Req),
+	   hixie_handshake(Scheme, Host, Path, Sec1Key, Sec2Key,
+			   Body, Origin);
+       true -> error
     end.
 
 hybi_handshake(SecKey) ->
     BinKey = list_to_binary(SecKey),
-    Bin = <<BinKey/binary, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11">>,
+    Bin = <<BinKey/binary,
+	    "258EAFA5-E914-47DA-95CA-C5AB0DC85B11">>,
     Challenge = base64:encode(crypto:hash(sha, Bin)),
-    Response = {101, [{"Connection", "Upgrade"},
-                      {"Upgrade", "websocket"},
-                      {"Sec-Websocket-Accept", Challenge}], ""},
+    Response = {101,
+		[{"Connection", "Upgrade"}, {"Upgrade", "websocket"},
+		 {"Sec-Websocket-Accept", Challenge}],
+		""},
     {hybi, Response}.
 
 scheme(Req) ->
     case mochiweb_request:get(scheme, Req) of
-        http ->
-            "ws://";
-        https ->
-            "wss://"
+      http -> "ws://";
+      https -> "wss://"
     end.
 
-hixie_handshake(Scheme, Host, Path, Key1, Key2, Body, Origin) ->
+hixie_handshake(Scheme, Host, Path, Key1, Key2, Body,
+		Origin) ->
     Ikey1 = [D || D <- Key1, $0 =< D, D =< $9],
     Ikey2 = [D || D <- Key2, $0 =< D, D =< $9],
     Blank1 = length([D || D <- Key1, D =:= 32]),
@@ -136,116 +144,93 @@ hixie_handshake(Scheme, Host, Path, Key1, Key2, Body, Origin) ->
     Part1 = erlang:list_to_integer(Ikey1) div Blank1,
     Part2 = erlang:list_to_integer(Ikey2) div Blank2,
     Ckey = <<Part1:4/big-unsigned-integer-unit:8,
-            Part2:4/big-unsigned-integer-unit:8,
-            Body/binary>>,
+	     Part2:4/big-unsigned-integer-unit:8, Body/binary>>,
     Challenge = erlang:md5(Ckey),
     Location = lists:concat([Scheme, Host, Path]),
-    Response = {101, [{"Upgrade", "WebSocket"},
-                      {"Connection", "Upgrade"},
-                      {"Sec-WebSocket-Origin", Origin},
-                      {"Sec-WebSocket-Location", Location}],
-                Challenge},
+    Response = {101,
+		[{"Upgrade", "WebSocket"}, {"Connection", "Upgrade"},
+		 {"Sec-WebSocket-Origin", Origin},
+		 {"Sec-WebSocket-Location", Location}],
+		Challenge},
     {hixie, Response}.
 
 parse_frames(hybi, Frames, Socket) ->
     try parse_hybi_frames(Socket, Frames, []) of
-        Parsed -> process_frames(Parsed, [])
+      Parsed -> process_frames(Parsed, [])
     catch
-        _:_ -> error
+      _:_ -> error
     end;
 parse_frames(hixie, Frames, _Socket) ->
     try parse_hixie_frames(Frames, []) of
-        Payload -> Payload
+      Payload -> Payload
     catch
-        _:_ -> error
+      _:_ -> error
     end.
 
 %%
 %% Websockets internal functions for RFC6455 and hybi draft
 %%
-process_frames([], Acc) ->
-    lists:reverse(Acc);
+process_frames([], Acc) -> lists:reverse(Acc);
 process_frames([{Opcode, Payload} | Rest], Acc) ->
     case Opcode of
-        8 -> close;
-        _ ->
-            process_frames(Rest, [Payload | Acc])
+      8 -> close;
+      _ -> process_frames(Rest, [Payload | Acc])
     end.
 
-parse_hybi_frames(_, <<>>, Acc) ->
-    lists:reverse(Acc);
-parse_hybi_frames(S, <<_Fin:1,
-                      _Rsv:3,
-                      Opcode:4,
-                      _Mask:1,
-                      PayloadLen:7,
-                      MaskKey:4/binary,
-                      Payload:PayloadLen/binary-unit:8,
-                      Rest/binary>>,
-                  Acc) when PayloadLen < 126 ->
+parse_hybi_frames(_, <<>>, Acc) -> lists:reverse(Acc);
+parse_hybi_frames(S,
+		  <<_Fin:1, _Rsv:3, Opcode:4, _Mask:1, PayloadLen:7,
+		    MaskKey:4/binary, Payload:PayloadLen/binary-unit:8,
+		    Rest/binary>>,
+		  Acc)
+    when PayloadLen < 126 ->
     Payload2 = hybi_unmask(Payload, MaskKey, <<>>),
     parse_hybi_frames(S, Rest, [{Opcode, Payload2} | Acc]);
-parse_hybi_frames(S, <<_Fin:1,
-                      _Rsv:3,
-                      Opcode:4,
-                      _Mask:1,
-                      126:7,
-                      PayloadLen:16,
-                      MaskKey:4/binary,
-                      Payload:PayloadLen/binary-unit:8,
-                      Rest/binary>>,
-                  Acc) ->
+parse_hybi_frames(S,
+		  <<_Fin:1, _Rsv:3, Opcode:4, _Mask:1, 126:7,
+		    PayloadLen:16, MaskKey:4/binary,
+		    Payload:PayloadLen/binary-unit:8, Rest/binary>>,
+		  Acc) ->
     Payload2 = hybi_unmask(Payload, MaskKey, <<>>),
     parse_hybi_frames(S, Rest, [{Opcode, Payload2} | Acc]);
-parse_hybi_frames(Socket, <<_Fin:1,
-                           _Rsv:3,
-                           _Opcode:4,
-                           _Mask:1,
-                           126:7,
-                           _PayloadLen:16,
-                           _MaskKey:4/binary,
-                           _/binary-unit:8>> = PartFrame,
-                  Acc) ->
-    ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, 0}, {active, once}])),
+parse_hybi_frames(Socket,
+		  <<_Fin:1, _Rsv:3, _Opcode:4, _Mask:1, 126:7,
+		    _PayloadLen:16, _MaskKey:4/binary, _/binary-unit:8>> =
+		      PartFrame,
+		  Acc) ->
+    ok =
+	mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket,
+							       [{packet, 0},
+								{active,
+								 once}])),
     receive
-        {tcp_closed, _} ->
-            mochiweb_socket:close(Socket),
-            exit(normal);
-        {ssl_closed, _} ->
-            mochiweb_socket:close(Socket),
-            exit(normal);
-        {tcp_error, _, _} ->
-            mochiweb_socket:close(Socket),
-            exit(normal);
-        {Proto, _, Continuation} when Proto =:= tcp orelse Proto =:= ssl ->
-            parse_hybi_frames(Socket, <<PartFrame/binary, Continuation/binary>>,
-                              Acc);
-        _ ->
-            mochiweb_socket:close(Socket),
-            exit(normal)
-    after
-        5000 ->
-            mochiweb_socket:close(Socket),
-            exit(normal)
+      {tcp_closed, _} ->
+	  mochiweb_socket:close(Socket), exit(normal);
+      {ssl_closed, _} ->
+	  mochiweb_socket:close(Socket), exit(normal);
+      {tcp_error, _, _} ->
+	  mochiweb_socket:close(Socket), exit(normal);
+      {Proto, _, Continuation}
+	  when Proto =:= tcp orelse Proto =:= ssl ->
+	  parse_hybi_frames(Socket,
+			    <<PartFrame/binary, Continuation/binary>>, Acc);
+      _ -> mochiweb_socket:close(Socket), exit(normal)
+      after 5000 ->
+		mochiweb_socket:close(Socket), exit(normal)
     end;
-parse_hybi_frames(S, <<_Fin:1,
-                      _Rsv:3,
-                      Opcode:4,
-                      _Mask:1,
-                      127:7,
-                      0:1,
-                      PayloadLen:63,
-                      MaskKey:4/binary,
-                      Payload:PayloadLen/binary-unit:8,
-                      Rest/binary>>,
-                  Acc) ->
+parse_hybi_frames(S,
+		  <<_Fin:1, _Rsv:3, Opcode:4, _Mask:1, 127:7, 0:1,
+		    PayloadLen:63, MaskKey:4/binary,
+		    Payload:PayloadLen/binary-unit:8, Rest/binary>>,
+		  Acc) ->
     Payload2 = hybi_unmask(Payload, MaskKey, <<>>),
     parse_hybi_frames(S, Rest, [{Opcode, Payload2} | Acc]).
 
 %% Unmasks RFC 6455 message
 hybi_unmask(<<O:32, Rest/bits>>, MaskKey, Acc) ->
     <<MaskKey2:32>> = MaskKey,
-    hybi_unmask(Rest, MaskKey, <<Acc/binary, (O bxor MaskKey2):32>>);
+    hybi_unmask(Rest, MaskKey,
+		<<Acc/binary, (O bxor MaskKey2):32>>);
 hybi_unmask(<<O:24>>, MaskKey, Acc) ->
     <<MaskKey2:24, _:8>> = MaskKey,
     <<Acc/binary, (O bxor MaskKey2):24>>;
@@ -255,27 +240,25 @@ hybi_unmask(<<O:16>>, MaskKey, Acc) ->
 hybi_unmask(<<O:8>>, MaskKey, Acc) ->
     <<MaskKey2:8, _:24>> = MaskKey,
     <<Acc/binary, (O bxor MaskKey2):8>>;
-hybi_unmask(<<>>, _MaskKey, Acc) ->
-    Acc.
+hybi_unmask(<<>>, _MaskKey, Acc) -> Acc.
 
 payload_length(N) ->
     case N of
-        N when N =< 125 -> << N >>;
-        N when N =< 16#ffff -> << 126, N:16 >>;
-        N when N =< 16#7fffffffffffffff -> << 127, N:64 >>
+      N when N =< 125 -> <<N>>;
+      N when N =< 65535 -> <<126, N:16>>;
+      N when N =< 9223372036854775807 -> <<127, N:64>>
     end.
 
-
 %%
 %% Websockets internal functions for hixie-76 websocket version
 %%
 parse_hixie_frames(<<>>, Frames) ->
-  lists:reverse(Frames);
+    lists:reverse(Frames);
 parse_hixie_frames(<<0, T/binary>>, Frames) ->
-  {Frame, Rest} = parse_hixie(T, <<>>),
-  parse_hixie_frames(Rest, [Frame | Frames]).
+    {Frame, Rest} = parse_hixie(T, <<>>),
+    parse_hixie_frames(Rest, [Frame | Frames]).
 
 parse_hixie(<<255, Rest/binary>>, Buffer) ->
-  {Buffer, Rest};
+    {Buffer, Rest};
 parse_hixie(<<H, T/binary>>, Buffer) ->
-  parse_hixie(T, <<Buffer/binary, H>>).
+    parse_hixie(T, <<Buffer/binary, H>>).
diff --git a/support/templates/mochiwebapp_skel/src/mochiapp_web.erl b/support/templates/mochiwebapp_skel/src/mochiapp_web.erl
index ecd99c5..0b586b0 100644
--- a/support/templates/mochiwebapp_skel/src/mochiapp_web.erl
+++ b/support/templates/mochiwebapp_skel/src/mochiapp_web.erl
@@ -3,90 +3,69 @@
 
 %% @doc Web server for {{appid}}.
 
--module({{appid}}_web).
+-module('{{appid}}_web').
+
 -author("{{author}}").
 
--export([start/1, stop/0, loop/2]).
+-export([loop/2, start/1, stop/0]).
 
 %% External API
 
 start(Options) ->
     {DocRoot, Options1} = get_option(docroot, Options),
-    Loop = fun (Req) ->
-                   ?MODULE:loop(Req, DocRoot)
-           end,
-    mochiweb_http:start([{name, ?MODULE}, {loop, Loop} | Options1]).
-
-stop() ->
-    mochiweb_http:stop(?MODULE).
+    Loop = fun (Req) -> (?MODULE):loop(Req, DocRoot) end,
+    mochiweb_http:start([{name, ?MODULE}, {loop, Loop}
+			 | Options1]).
 
+stop() -> mochiweb_http:stop(?MODULE).
 
 %% OTP 21 is the first to define OTP_RELEASE and the first to support
 %% EEP-0047 direct stack trace capture.
 -ifdef(OTP_RELEASE).
--if(?OTP_RELEASE >= 21).
+
+-if((?OTP_RELEASE) >= 21).
+
 -define(HAS_DIRECT_STACKTRACE, true).
+
 -endif.
+
 -endif.
 
 -ifdef(HAS_DIRECT_STACKTRACE).
--define(CAPTURE_EXC_PRE(Type, What, Trace), Type:What:Trace).
+
+- define ( CAPTURE_EXC_PRE ( Type , What , Trace ) , Type : What : Trace ) .
+
+
 -define(CAPTURE_EXC_GET(Trace), Trace).
+
 -else.
+
 -define(CAPTURE_EXC_PRE(Type, What, Trace), Type:What).
--define(CAPTURE_EXC_GET(Trace), erlang:get_stacktrace()).
+
+-define(CAPTURE_EXC_GET(Trace),
+	erlang:get_stacktrace()).
+
 -endif.
 
-loop(Req, DocRoot) ->
-    "/" ++ Path = mochiweb_request:get(path, Req),
-    try
-        case mochiweb_request:get(method, Req) of
-            Method when Method =:= 'GET'; Method =:= 'HEAD' ->
-                case Path of
-                    "hello_world" ->
-                        mochiweb_request:respond(
-                            {200, [{"Content-Type", "text/plain"}], "Hello world!\n"},
-                            Req
-                        );
-                    _ ->
-                        mochiweb_request:serve_file(Path, DocRoot, Req)
-                end;
-            'POST' ->
-                case Path of
-                    _ ->
-                        mochiweb_request:not_found(Req)
-                end;
-            _ ->
-                mochiweb_request:respond({501, [], []}, Req)
-        end
-    catch
-        ?CAPTURE_EXC_PRE(Type, What, Trace) ->
-            Report = ["web request failed",
-                      {path, Path},
-                      {type, Type}, {what, What},
-                      {trace, ?CAPTURE_EXC_GET(Trace)}],
-            error_logger:error_report(Report),
-            mochiweb_request:respond(
-                {500, [{"Content-Type", "text/plain"}], "request failed, sorry\n"},
-                Req
-            )
-    end.
+loop ( Req , DocRoot ) -> "/" ++ Path = mochiweb_request : get ( path , Req ) , try case mochiweb_request : get ( method , Req ) of Method when Method =:= 'GET' ; Method =:= 'HEAD' -> case Path of "hello_world" -> mochiweb_request : respond ( { 200 , [ { "Content-Type" , "text/plain" } ] , "Hello world!\n" } , Req ) ; _ -> mochiweb_request : serve_file ( Path , DocRoot , Req ) end ; 'POST' -> case Path of _ -> mochiweb_request : not_found ( Req ) end ; _ -> mochiweb_request : respond ( { [...]
+
 
 %% Internal API
 
 get_option(Option, Options) ->
-    {proplists:get_value(Option, Options), proplists:delete(Option, Options)}.
+    {proplists:get_value(Option, Options),
+     proplists:delete(Option, Options)}.
 
 %%
 %% Tests
 %%
 -ifdef(TEST).
+
 -include_lib("eunit/include/eunit.hrl").
 
 you_should_write_a_test() ->
-    ?assertEqual(
-       "No, but I will!",
-       "Have you written any tests?"),
+    ?assertEqual("No, but I will!",
+		 "Have you written any tests?"),
     ok.
 
 -endif.
diff --git a/test/mochiweb_http_tests.erl b/test/mochiweb_http_tests.erl
index 8fbf0f3..d58971a 100644
--- a/test/mochiweb_http_tests.erl
+++ b/test/mochiweb_http_tests.erl
@@ -1,49 +1,51 @@
 -module(mochiweb_http_tests).
+
 -include_lib("eunit/include/eunit.hrl").
 
 -ifdef(gen_tcp_r15b_workaround).
+
 -define(SHOULD_HAVE_BUG, true).
+
 -else.
+
 -define(SHOULD_HAVE_BUG, false).
+
 -endif.
 
 has_acceptor_bug_test_() ->
-    {setup,
-     fun start_server/0,
-     fun mochiweb_http:stop/1,
+    {setup, fun start_server/0, fun mochiweb_http:stop/1,
      fun has_acceptor_bug_tests/1}.
 
 start_server() ->
     application:start(inets),
     {ok, Pid} = mochiweb_http:start_link([{port, 0},
-                                          {loop, fun responder/1}]),
+					  {loop, fun responder/1}]),
     Pid.
 
 has_acceptor_bug_tests(Server) ->
     Port = mochiweb_socket_server:get(Server, port),
     [{"1000 should be fine even with the bug",
-      ?_assertEqual(false, has_bug(Port, 1000))},
+      ?_assertEqual(false, (has_bug(Port, 1000)))},
      {"10000 should trigger the bug if present",
-      ?_assertEqual(?SHOULD_HAVE_BUG, has_bug(Port, 10000))}].
+      ?_assertEqual((?SHOULD_HAVE_BUG),
+		    (has_bug(Port, 10000)))}].
 
 responder(Req) ->
-    mochiweb_request:respond(
-        {
-            200,
-            [{"Content-Type", "text/html"}],
-            ["<html><body>Hello</body></html>"]
-        },
-        Req).
+    mochiweb_request:respond({200,
+			      [{"Content-Type", "text/html"}],
+			      ["<html><body>Hello</body></html>"]},
+			     Req).
 
 has_bug(Port, Len) ->
-  case
-    httpc:request(get, {"http://127.0.0.1:" ++ integer_to_list(Port) ++ "/",
-                        [{"X-Random", lists:duplicate(Len, $a)}]}, [], [])
-  of
-      {error, socket_closed_remotely} ->
-          true;
-      {ok, {{"HTTP/1.1", 200, "OK"}, _, "<html><body>Hello</body></html>"}} ->
-          false;
-      {ok, {{"HTTP/1.1", 400, "Bad Request"}, _, []}} ->
-          false
-  end.
+    case httpc:request(get,
+		       {"http://127.0.0.1:" ++ integer_to_list(Port) ++ "/",
+			[{"X-Random", lists:duplicate(Len, $a)}]},
+		       [], [])
+	of
+      {error, socket_closed_remotely} -> true;
+      {ok,
+       {{"HTTP/1.1", 200, "OK"}, _,
+	"<html><body>Hello</body></html>"}} ->
+	  false;
+      {ok, {{"HTTP/1.1", 400, "Bad Request"}, _, []}} -> false
+    end.
diff --git a/test/mochiweb_request_tests.erl b/test/mochiweb_request_tests.erl
index 47fe7ee..119fc81 100644
--- a/test/mochiweb_request_tests.erl
+++ b/test/mochiweb_request_tests.erl
@@ -1,182 +1,238 @@
 -module(mochiweb_request_tests).
 
 -ifdef(TEST).
+
 -include_lib("eunit/include/eunit.hrl").
 
 accepts_content_type_test() ->
     Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "multipart/related"}])),
-    ?assertEqual(true, mochiweb_request:accepts_content_type("multipart/related", Req1)),
-    ?assertEqual(true, mochiweb_request:accepts_content_type(<<"multipart/related">>, Req1)),
-
+				mochiweb_headers:make([{"Accept",
+							"multipart/related"}])),
+    ?assertEqual(true,
+		 (mochiweb_request:accepts_content_type("multipart/related",
+							Req1))),
+    ?assertEqual(true,
+		 (mochiweb_request:accepts_content_type(<<"multipart/related">>,
+							Req1))),
     Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html"}])),
-    ?assertEqual(false, mochiweb_request:accepts_content_type("multipart/related", Req2)),
-
+				mochiweb_headers:make([{"Accept",
+							"text/html"}])),
+    ?assertEqual(false,
+		 (mochiweb_request:accepts_content_type("multipart/related",
+							Req2))),
     Req3 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html, multipart/*"}])),
-    ?assertEqual(true, mochiweb_request:accepts_content_type("multipart/related", Req3)),
-
+				mochiweb_headers:make([{"Accept",
+							"text/html, multipart/*"}])),
+    ?assertEqual(true,
+		 (mochiweb_request:accepts_content_type("multipart/related",
+							Req3))),
     Req4 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html, multipart/*; q=0.0"}])),
-    ?assertEqual(false, mochiweb_request:accepts_content_type("multipart/related", Req4)),
-
+				mochiweb_headers:make([{"Accept",
+							"text/html, multipart/*; q=0.0"}])),
+    ?assertEqual(false,
+		 (mochiweb_request:accepts_content_type("multipart/related",
+							Req4))),
     Req5 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html, multipart/*; q=0"}])),
-    ?assertEqual(false, mochiweb_request:accepts_content_type("multipart/related", Req5)),
-
+				mochiweb_headers:make([{"Accept",
+							"text/html, multipart/*; q=0"}])),
+    ?assertEqual(false,
+		 (mochiweb_request:accepts_content_type("multipart/related",
+							Req5))),
     Req6 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html, */*; q=0.0"}])),
-    ?assertEqual(false, mochiweb_request:accepts_content_type("multipart/related", Req6)),
-
+				mochiweb_headers:make([{"Accept",
+							"text/html, */*; q=0.0"}])),
+    ?assertEqual(false,
+		 (mochiweb_request:accepts_content_type("multipart/related",
+							Req6))),
     Req7 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "multipart/*; q=0.0, */*"}])),
-    ?assertEqual(false, mochiweb_request:accepts_content_type("multipart/related", Req7)),
-
+				mochiweb_headers:make([{"Accept",
+							"multipart/*; q=0.0, */*"}])),
+    ?assertEqual(false,
+		 (mochiweb_request:accepts_content_type("multipart/related",
+							Req7))),
     Req8 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "*/*; q=0.0, multipart/*"}])),
-    ?assertEqual(true, mochiweb_request:accepts_content_type("multipart/related", Req8)),
-
+				mochiweb_headers:make([{"Accept",
+							"*/*; q=0.0, multipart/*"}])),
+    ?assertEqual(true,
+		 (mochiweb_request:accepts_content_type("multipart/related",
+							Req8))),
     Req9 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "*/*; q=0.0, multipart/related"}])),
-    ?assertEqual(true, mochiweb_request:accepts_content_type("multipart/related", Req9)),
-
+				mochiweb_headers:make([{"Accept",
+							"*/*; q=0.0, multipart/related"}])),
+    ?assertEqual(true,
+		 (mochiweb_request:accepts_content_type("multipart/related",
+							Req9))),
     Req10 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html; level=1"}])),
-    ?assertEqual(true, mochiweb_request:accepts_content_type("text/html;level=1", Req10)),
-
+				 mochiweb_headers:make([{"Accept",
+							 "text/html; level=1"}])),
+    ?assertEqual(true,
+		 (mochiweb_request:accepts_content_type("text/html;level=1",
+							Req10))),
     Req11 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html; level=1, text/html"}])),
-    ?assertEqual(true, mochiweb_request:accepts_content_type("text/html", Req11)),
-
+				 mochiweb_headers:make([{"Accept",
+							 "text/html; level=1, text/html"}])),
+    ?assertEqual(true,
+		 (mochiweb_request:accepts_content_type("text/html",
+							Req11))),
     Req12 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html; level=1; q=0.0, text/html"}])),
-    ?assertEqual(false, mochiweb_request:accepts_content_type("text/html;level=1", Req12)),
-
+				 mochiweb_headers:make([{"Accept",
+							 "text/html; level=1; q=0.0, text/html"}])),
+    ?assertEqual(false,
+		 (mochiweb_request:accepts_content_type("text/html;level=1",
+							Req12))),
     Req13 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html; level=1; q=0.0, text/html"}])),
-    ?assertEqual(false, mochiweb_request:accepts_content_type("text/html; level=1", Req13)),
-
+				 mochiweb_headers:make([{"Accept",
+							 "text/html; level=1; q=0.0, text/html"}])),
+    ?assertEqual(false,
+		 (mochiweb_request:accepts_content_type("text/html; level=1",
+							Req13))),
     Req14 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html;level=1;q=0.1, text/html"}])),
-    ?assertEqual(true, mochiweb_request:accepts_content_type("text/html; level=1", Req14)).
+				 mochiweb_headers:make([{"Accept",
+							 "text/html;level=1;q=0.1, text/html"}])),
+    ?assertEqual(true,
+		 (mochiweb_request:accepts_content_type("text/html; level=1",
+							Req14))).
 
 accepted_encodings_test() ->
     Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-                                mochiweb_headers:make([])),
+				mochiweb_headers:make([])),
     ?assertEqual(["identity"],
-                 mochiweb_request:accepted_encodings(["gzip", "identity"], Req1)),
-
+		 (mochiweb_request:accepted_encodings(["gzip",
+						       "identity"],
+						      Req1))),
     Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept-Encoding", "gzip, deflate"}])),
+				mochiweb_headers:make([{"Accept-Encoding",
+							"gzip, deflate"}])),
     ?assertEqual(["gzip", "identity"],
-                 mochiweb_request:accepted_encodings(["gzip", "identity"], Req2)),
-
+		 (mochiweb_request:accepted_encodings(["gzip",
+						       "identity"],
+						      Req2))),
     Req3 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept-Encoding", "gzip;q=0.5, deflate"}])),
+				mochiweb_headers:make([{"Accept-Encoding",
+							"gzip;q=0.5, deflate"}])),
     ?assertEqual(["deflate", "gzip", "identity"],
-                 mochiweb_request:accepted_encodings(["gzip", "deflate", "identity"], Req3)),
-
+		 (mochiweb_request:accepted_encodings(["gzip", "deflate",
+						       "identity"],
+						      Req3))),
     Req4 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept-Encoding", "identity, *;q=0"}])),
+				mochiweb_headers:make([{"Accept-Encoding",
+							"identity, *;q=0"}])),
     ?assertEqual(["identity"],
-                 mochiweb_request:accepted_encodings(["gzip", "deflate", "identity"], Req4)),
-
+		 (mochiweb_request:accepted_encodings(["gzip", "deflate",
+						       "identity"],
+						      Req4))),
     Req5 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept-Encoding", "gzip; q=0.1, *;q=0"}])),
+				mochiweb_headers:make([{"Accept-Encoding",
+							"gzip; q=0.1, *;q=0"}])),
     ?assertEqual(["gzip"],
-                 mochiweb_request:accepted_encodings(["gzip", "deflate", "identity"], Req5)),
-
+		 (mochiweb_request:accepted_encodings(["gzip", "deflate",
+						       "identity"],
+						      Req5))),
     Req6 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept-Encoding", "gzip; q=, *;q=0"}])),
+				mochiweb_headers:make([{"Accept-Encoding",
+							"gzip; q=, *;q=0"}])),
     ?assertEqual(bad_accept_encoding_value,
-                 mochiweb_request:accepted_encodings(["gzip", "deflate", "identity"], Req6)),
-
+		 (mochiweb_request:accepted_encodings(["gzip", "deflate",
+						       "identity"],
+						      Req6))),
     Req7 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept-Encoding", "gzip;q=2.0, *;q=0"}])),
+				mochiweb_headers:make([{"Accept-Encoding",
+							"gzip;q=2.0, *;q=0"}])),
     ?assertEqual(bad_accept_encoding_value,
-                 mochiweb_request:accepted_encodings(["gzip", "identity"], Req7)),
-
+		 (mochiweb_request:accepted_encodings(["gzip",
+						       "identity"],
+						      Req7))),
     Req8 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept-Encoding", "deflate, *;q=0.0"}])),
+				mochiweb_headers:make([{"Accept-Encoding",
+							"deflate, *;q=0.0"}])),
     ?assertEqual([],
-                 mochiweb_request:accepted_encodings(["gzip", "identity"], Req8)).
+		 (mochiweb_request:accepted_encodings(["gzip",
+						       "identity"],
+						      Req8))).
 
 accepted_content_types_test() ->
     Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html"}])),
+				mochiweb_headers:make([{"Accept",
+							"text/html"}])),
     ?assertEqual(["text/html"],
-        mochiweb_request:accepted_content_types(["text/html", "application/json"], Req1)),
-
+		 (mochiweb_request:accepted_content_types(["text/html",
+							   "application/json"],
+							  Req1))),
     Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html, */*;q=0"}])),
+				mochiweb_headers:make([{"Accept",
+							"text/html, */*;q=0"}])),
     ?assertEqual(["text/html"],
-        mochiweb_request:accepted_content_types(["text/html", "application/json"], Req2)),
-
+		 (mochiweb_request:accepted_content_types(["text/html",
+							   "application/json"],
+							  Req2))),
     Req3 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/*, */*;q=0"}])),
+				mochiweb_headers:make([{"Accept",
+							"text/*, */*;q=0"}])),
     ?assertEqual(["text/html"],
-        mochiweb_request:accepted_content_types(["text/html", "application/json"], Req3)),
-
+		 (mochiweb_request:accepted_content_types(["text/html",
+							   "application/json"],
+							  Req3))),
     Req4 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/*;q=0.8, */*;q=0.5"}])),
+				mochiweb_headers:make([{"Accept",
+							"text/*;q=0.8, */*;q=0.5"}])),
     ?assertEqual(["text/html", "application/json"],
-        mochiweb_request:accepted_content_types(["application/json", "text/html"], Req4)),
-
+		 (mochiweb_request:accepted_content_types(["application/json",
+							   "text/html"],
+							  Req4))),
     Req5 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/*;q=0.8, */*;q=0.5"}])),
+				mochiweb_headers:make([{"Accept",
+							"text/*;q=0.8, */*;q=0.5"}])),
     ?assertEqual(["text/html", "application/json"],
-        mochiweb_request:accepted_content_types(["text/html", "application/json"], Req5)),
-
+		 (mochiweb_request:accepted_content_types(["text/html",
+							   "application/json"],
+							  Req5))),
     Req6 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/*;q=0.5, */*;q=0.5"}])),
+				mochiweb_headers:make([{"Accept",
+							"text/*;q=0.5, */*;q=0.5"}])),
     ?assertEqual(["application/json", "text/html"],
-        mochiweb_request:accepted_content_types(["application/json", "text/html"], Req6)),
-
+		 (mochiweb_request:accepted_content_types(["application/json",
+							   "text/html"],
+							  Req6))),
     Req7 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make(
-            [{"Accept", "text/html;q=0.5, application/json;q=0.5"}])),
+				mochiweb_headers:make([{"Accept",
+							"text/html;q=0.5, application/json;q=0.5"}])),
     ?assertEqual(["application/json", "text/html"],
-        mochiweb_request:accepted_content_types(["application/json", "text/html"], Req7)),
-
+		 (mochiweb_request:accepted_content_types(["application/json",
+							   "text/html"],
+							  Req7))),
     Req8 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/html"}])),
+				mochiweb_headers:make([{"Accept",
+							"text/html"}])),
     ?assertEqual([],
-        mochiweb_request:accepted_content_types(["application/json"], Req8)),
-
+		 (mochiweb_request:accepted_content_types(["application/json"],
+							  Req8))),
     Req9 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
-        mochiweb_headers:make([{"Accept", "text/*;q=0.9, text/html;q=0.5, */*;q=0.7"}])),
+				mochiweb_headers:make([{"Accept",
+							"text/*;q=0.9, text/html;q=0.5, */*;q=0.7"}])),
     ?assertEqual(["application/json", "text/html"],
-        mochiweb_request:accepted_content_types(["text/html", "application/json"], Req9)).
+		 (mochiweb_request:accepted_content_types(["text/html",
+							   "application/json"],
+							  Req9))).
 
 should_close_test() ->
     F = fun (V, H) ->
-                mochiweb_request:should_close(mochiweb_request:new(
-                   nil, 'GET', "/", V,
-                   mochiweb_headers:make(H)
-                  ))
-        end,
-    ?assertEqual(
-       true,
-       F({1, 1}, [{"Connection", "close"}])),
-    ?assertEqual(
-       true,
-       F({1, 0}, [{"Connection", "close"}])),
-    ?assertEqual(
-       true,
-       F({1, 1}, [{"Connection", "ClOSe"}])),
-    ?assertEqual(
-       false,
-       F({1, 1}, [{"Connection", "closer"}])),
-    ?assertEqual(
-       false,
-       F({1, 1}, [])),
-    ?assertEqual(
-       true,
-       F({1, 0}, [])),
-    ?assertEqual(
-       false,
-       F({1, 0}, [{"Connection", "Keep-Alive"}])),
+		mochiweb_request:should_close(mochiweb_request:new(nil,
+								   'GET', "/",
+								   V,
+								   mochiweb_headers:make(H)))
+	end,
+    ?assertEqual(true,
+		 (F({1, 1}, [{"Connection", "close"}]))),
+    ?assertEqual(true,
+		 (F({1, 0}, [{"Connection", "close"}]))),
+    ?assertEqual(true,
+		 (F({1, 1}, [{"Connection", "ClOSe"}]))),
+    ?assertEqual(false,
+		 (F({1, 1}, [{"Connection", "closer"}]))),
+    ?assertEqual(false, (F({1, 1}, []))),
+    ?assertEqual(true, (F({1, 0}, []))),
+    ?assertEqual(false,
+		 (F({1, 0}, [{"Connection", "Keep-Alive"}]))),
     ok.
 
 -endif.
diff --git a/test/mochiweb_tests.erl b/test/mochiweb_tests.erl
index ae88bda..ef688f1 100644
--- a/test/mochiweb_tests.erl
+++ b/test/mochiweb_tests.erl
@@ -1,130 +1,149 @@
 -module(mochiweb_tests).
+
 -include_lib("eunit/include/eunit.hrl").
+
 -include("mochiweb_test_util.hrl").
 
 with_server(Transport, ServerFun, ClientFun) ->
-    mochiweb_test_util:with_server(Transport, ServerFun, ClientFun).
+    mochiweb_test_util:with_server(Transport, ServerFun,
+				   ClientFun).
 
 request_test() ->
-    R = mochiweb_request:new(z, z, "//foo///bar/baz%20wibble+quux?qs=2", z, []),
-    "/foo/bar/baz wibble quux" = mochiweb_request:get(path, R),
+    R = mochiweb_request:new(z, z,
+			     "//foo///bar/baz%20wibble+quux?qs=2", z, []),
+    "/foo/bar/baz wibble quux" = mochiweb_request:get(path,
+						      R),
     ok.
 
 -define(LARGE_TIMEOUT, 60).
 
-single_http_GET_test() ->
-    do_GET(plain, 1).
+single_http_GET_test() -> do_GET(plain, 1).
 
-single_https_GET_test() ->
-    do_GET(ssl, 1).
+single_https_GET_test() -> do_GET(ssl, 1).
 
-multiple_http_GET_test() ->
-    do_GET(plain, 3).
+multiple_http_GET_test() -> do_GET(plain, 3).
 
-multiple_https_GET_test() ->
-    do_GET(ssl, 3).
+multiple_https_GET_test() -> do_GET(ssl, 3).
 
-hundred_http_GET_test_() -> % note the underscore
+hundred_http_GET_test_() ->
+    % note the underscore
     {timeout, ?LARGE_TIMEOUT,
-     fun() -> ?assertEqual(ok, do_GET(plain,100)) end}.
+     fun () -> ?assertEqual(ok, (do_GET(plain, 100))) end}.
 
-hundred_https_GET_test_() -> % note the underscore
+hundred_https_GET_test_() ->
+    % note the underscore
     {timeout, ?LARGE_TIMEOUT,
-     fun() -> ?assertEqual(ok, do_GET(ssl,100)) end}.
+     fun () -> ?assertEqual(ok, (do_GET(ssl, 100))) end}.
 
-single_128_http_POST_test() ->
-    do_POST(plain, 128, 1).
+single_128_http_POST_test() -> do_POST(plain, 128, 1).
 
-single_128_https_POST_test() ->
-    do_POST(ssl, 128, 1).
+single_128_https_POST_test() -> do_POST(ssl, 128, 1).
 
-single_2k_http_POST_test() ->
-    do_POST(plain, 2048, 1).
+single_2k_http_POST_test() -> do_POST(plain, 2048, 1).
 
-single_2k_https_POST_test() ->
-    do_POST(ssl, 2048, 1).
+single_2k_https_POST_test() -> do_POST(ssl, 2048, 1).
 
-single_100k_http_POST_test_() -> % note the underscore
+single_100k_http_POST_test_() ->
+    % note the underscore
     {timeout, ?LARGE_TIMEOUT,
-     fun() -> ?assertEqual(ok, do_POST(plain, 102400, 1)) end}.
+     fun () -> ?assertEqual(ok, (do_POST(plain, 102400, 1)))
+     end}.
 
-single_100k_https_POST_test_() -> % note the underscore
+single_100k_https_POST_test_() ->
+    % note the underscore
     {timeout, ?LARGE_TIMEOUT,
-     fun() -> ?assertEqual(ok, do_POST(ssl, 102400, 1)) end}.
+     fun () -> ?assertEqual(ok, (do_POST(ssl, 102400, 1)))
+     end}.
 
 multiple_100k_http_POST_test() ->
     {timeout, ?LARGE_TIMEOUT,
-     fun() -> ?assertEqual(ok, do_POST(plain, 102400, 3)) end}.
+     fun () -> ?assertEqual(ok, (do_POST(plain, 102400, 3)))
+     end}.
 
 multiple_100K_https_POST_test() ->
     {timeout, ?LARGE_TIMEOUT,
-     fun() -> ?assertEqual(ok, do_POST(ssl, 102400, 3)) end}.
+     fun () -> ?assertEqual(ok, (do_POST(ssl, 102400, 3)))
+     end}.
 
-hundred_128_http_POST_test_() -> % note the underscore
+hundred_128_http_POST_test_() ->
+    % note the underscore
     {timeout, ?LARGE_TIMEOUT,
-     fun() -> ?assertEqual(ok, do_POST(plain, 128, 100)) end}.
+     fun () -> ?assertEqual(ok, (do_POST(plain, 128, 100)))
+     end}.
 
-hundred_128_https_POST_test_() -> % note the underscore
+hundred_128_https_POST_test_() ->
+    % note the underscore
     {timeout, ?LARGE_TIMEOUT,
-     fun() -> ?assertEqual(ok, do_POST(ssl, 128, 100)) end}.
+     fun () -> ?assertEqual(ok, (do_POST(ssl, 128, 100)))
+     end}.
 
 single_GET_scheme_test_() ->
-    [{"ssl", ?_assertEqual(ok, do_GET("derp", ssl, 1))},
-     {"plain", ?_assertEqual(ok, do_GET("derp", plain, 1))}].
+    [{"ssl", ?_assertEqual(ok, (do_GET("derp", ssl, 1)))},
+     {"plain",
+      ?_assertEqual(ok, (do_GET("derp", plain, 1)))}].
 
 single_GET_absoluteURI_test_() ->
     Uri = "https://example.com:123/x/",
     ServerFun = fun (Req) ->
-                        mochiweb_request:ok({"text/plain", mochiweb_request:get(path, Req)}, Req)
-                end,
+			mochiweb_request:ok({"text/plain",
+					     mochiweb_request:get(path, Req)},
+					    Req)
+		end,
     %% Note that all the scheme/host/port information is discarded from path
-    ClientFun = new_client_fun('GET', [#treq{path = Uri, xreply = <<"/x/">>}]),
+    ClientFun = new_client_fun('GET',
+			       [#treq{path = Uri, xreply = <<"/x/">>}]),
     [{atom_to_list(Transport),
-      ?_assertEqual(ok, with_server(Transport, ServerFun, ClientFun))}
+      ?_assertEqual(ok,
+		    (with_server(Transport, ServerFun, ClientFun)))}
      || Transport <- [ssl, plain]].
 
 single_CONNECT_test_() ->
-    [{"ssl", ?_assertEqual(ok, do_CONNECT(ssl, 1))},
-     {"plain", ?_assertEqual(ok, do_CONNECT(plain, 1))}].
+    [{"ssl", ?_assertEqual(ok, (do_CONNECT(ssl, 1)))},
+     {"plain", ?_assertEqual(ok, (do_CONNECT(plain, 1)))}].
 
 single_GET_any_test_() ->
     ServerFun = fun (Req) ->
-                        mochiweb_request:ok({"text/plain", mochiweb_request:get(path, Req)}, Req)
-                end,
-    ClientFun = new_client_fun('GET', [#treq{path = "*", xreply = <<"*">>}]),
+			mochiweb_request:ok({"text/plain",
+					     mochiweb_request:get(path, Req)},
+					    Req)
+		end,
+    ClientFun = new_client_fun('GET',
+			       [#treq{path = "*", xreply = <<"*">>}]),
     [{atom_to_list(Transport),
-      ?_assertEqual(ok, with_server(Transport, ServerFun, ClientFun))}
+      ?_assertEqual(ok,
+		    (with_server(Transport, ServerFun, ClientFun)))}
      || Transport <- [ssl, plain]].
 
-
 cookie_header_test() ->
     ReplyPrefix = "You requested: ",
     ExHeaders = [{"Set-Cookie", "foo=bar"},
-                 {"Set-Cookie", "foo=baz"}],
+		 {"Set-Cookie", "foo=baz"}],
     ServerFun = fun (Req) ->
-                        Reply = ReplyPrefix ++ mochiweb_request:get(path, Req),
-                        mochiweb_request:ok({"text/plain", ExHeaders, Reply}, Req)
-                end,
+			Reply = ReplyPrefix ++ mochiweb_request:get(path, Req),
+			mochiweb_request:ok({"text/plain", ExHeaders, Reply},
+					    Req)
+		end,
     Path = "cookie_header",
     ExpectedReply = list_to_binary(ReplyPrefix ++ Path),
-    TestReqs = [#treq{path=Path, xreply=ExpectedReply, xheaders=ExHeaders}],
+    TestReqs = [#treq{path = Path, xreply = ExpectedReply,
+		      xheaders = ExHeaders}],
     ClientFun = new_client_fun('GET', TestReqs),
     ok = with_server(plain, ServerFun, ClientFun),
     ok.
 
-
 do_CONNECT(Transport, Times) ->
     PathPrefix = "example.com:",
     ReplyPrefix = "You requested: ",
     ServerFun = fun (Req) ->
-                        Reply = ReplyPrefix ++ mochiweb_request:get(path, Req),
-                        mochiweb_request:ok({"text/plain", Reply}, Req)
-                end,
+			Reply = ReplyPrefix ++ mochiweb_request:get(path, Req),
+			mochiweb_request:ok({"text/plain", Reply}, Req)
+		end,
     TestReqs = [begin
-                    Path = PathPrefix ++ integer_to_list(N),
-                    ExpectedReply = list_to_binary(ReplyPrefix ++ Path),
-                    #treq{path=Path, xreply=ExpectedReply}
-                end || N <- lists:seq(1, Times)],
+		  Path = PathPrefix ++ integer_to_list(N),
+		  ExpectedReply = list_to_binary(ReplyPrefix ++ Path),
+		  #treq{path = Path, xreply = ExpectedReply}
+		end
+		|| N <- lists:seq(1, Times)],
     ClientFun = new_client_fun('CONNECT', TestReqs),
     ok = with_server(Transport, ServerFun, ClientFun),
     ok.
@@ -135,86 +154,85 @@ do_GET(Transport, Times) ->
 do_GET(PathPrefix, Transport, Times) ->
     ReplyPrefix = "You requested: ",
     ServerFun = fun (Req) ->
-                        Reply = ReplyPrefix ++ mochiweb_request:get(path, Req),
-                        mochiweb_request:ok({"text/plain", Reply}, Req)
-                end,
+			Reply = ReplyPrefix ++ mochiweb_request:get(path, Req),
+			mochiweb_request:ok({"text/plain", Reply}, Req)
+		end,
     TestReqs = [begin
-                    Path = PathPrefix ++ integer_to_list(N),
-                    ExpectedReply = list_to_binary(ReplyPrefix ++ Path),
-                    #treq{path=Path, xreply=ExpectedReply}
-                end || N <- lists:seq(1, Times)],
+		  Path = PathPrefix ++ integer_to_list(N),
+		  ExpectedReply = list_to_binary(ReplyPrefix ++ Path),
+		  #treq{path = Path, xreply = ExpectedReply}
+		end
+		|| N <- lists:seq(1, Times)],
     ClientFun = new_client_fun('GET', TestReqs),
     ok = with_server(Transport, ServerFun, ClientFun),
     ok.
 
 do_POST(Transport, Size, Times) ->
     ServerFun = fun (Req) ->
-                        Body = mochiweb_request:recv_body(Req),
-                        Headers = [{"Content-Type", "application/octet-stream"}],
-                        mochiweb_request:respond({201, Headers, Body}, Req)
-                end,
+			Body = mochiweb_request:recv_body(Req),
+			Headers = [{"Content-Type",
+				    "application/octet-stream"}],
+			mochiweb_request:respond({201, Headers, Body}, Req)
+		end,
     TestReqs = [begin
-                    Path = "/stuff/" ++ integer_to_list(N),
-                    Body = crypto:strong_rand_bytes(Size),
-                    #treq{path=Path, body=Body, xreply=Body}
-                end || N <- lists:seq(1, Times)],
+		  Path = "/stuff/" ++ integer_to_list(N),
+		  Body = crypto:strong_rand_bytes(Size),
+		  #treq{path = Path, body = Body, xreply = Body}
+		end
+		|| N <- lists:seq(1, Times)],
     ClientFun = new_client_fun('POST', TestReqs),
     ok = with_server(Transport, ServerFun, ClientFun),
     ok.
 
 new_client_fun(Method, TestReqs) ->
     fun (Transport, Port) ->
-            mochiweb_test_util:client_request(Transport, Port, Method, TestReqs)
+	    mochiweb_test_util:client_request(Transport, Port,
+					      Method, TestReqs)
     end.
 
 close_on_unread_data_test() ->
-    ok = with_server(
-           plain,
-           fun mochiweb_request:not_found/1,
-           fun close_on_unread_data_client/2).
+    ok = with_server(plain,
+		     fun mochiweb_request:not_found/1,
+		     fun close_on_unread_data_client/2).
 
 close_on_unread_data_client(Transport, Port) ->
     SockFun = mochiweb_test_util:sock_fun(Transport, Port),
     %% A normal GET request should not trigger this behavior
-    Request0 = string:join(
-                 ["GET / HTTP/1.1",
-                  "Host: localhost",
-                  "",
-                  ""],
-                 "\r\n"),
+    Request0 = string:join(["GET / HTTP/1.1",
+			    "Host: localhost", "", ""],
+			   "\r\n"),
     ok = SockFun({setopts, [{packet, http}]}),
     ok = SockFun({send, Request0}),
-    ?assertMatch(
-       {ok, {http_response, {1, 1}, 404, _}},
-       SockFun(recv)),
-    Headers0 = mochiweb_test_util:read_server_headers(SockFun),
-    ?assertEqual(
-       undefined,
-       mochiweb_headers:get_value("Connection", Headers0)),
-    Len0 = list_to_integer(
-             mochiweb_headers:get_value("Content-Length", Headers0)),
-    _Body0 = mochiweb_test_util:drain_reply(SockFun, Len0, <<>>),
+    ?assertMatch({ok, {http_response, {1, 1}, 404, _}},
+		 (SockFun(recv))),
+    Headers0 =
+	mochiweb_test_util:read_server_headers(SockFun),
+    ?assertEqual(undefined,
+		 (mochiweb_headers:get_value("Connection", Headers0))),
+    Len0 =
+	list_to_integer(mochiweb_headers:get_value("Content-Length",
+						   Headers0)),
+    _Body0 = mochiweb_test_util:drain_reply(SockFun, Len0,
+					    <<>>),
     %% Re-use same socket
-    Request = string:join(
-                ["POST / HTTP/1.1",
-                 "Host: localhost",
-                 "Content-Type: application/json",
-                 "Content-Length: 2",
-                 "",
-                 "{}"],
-                "\r\n"),
+    Request = string:join(["POST / HTTP/1.1",
+			   "Host: localhost", "Content-Type: application/json",
+			   "Content-Length: 2", "", "{}"],
+			  "\r\n"),
     ok = SockFun({setopts, [{packet, http}]}),
     ok = SockFun({send, Request}),
-    ?assertMatch(
-       {ok, {http_response, {1, 1}, 404, _}},
-       SockFun(recv)),
-    Headers = mochiweb_test_util:read_server_headers(SockFun),
+    ?assertMatch({ok, {http_response, {1, 1}, 404, _}},
+		 (SockFun(recv))),
+    Headers =
+	mochiweb_test_util:read_server_headers(SockFun),
     %% Expect to see a Connection: close header when we know the
     %% server will close the connection re #146
-    ?assertEqual(
-       "close",
-       mochiweb_headers:get_value("Connection", Headers)),
-    Len = list_to_integer(mochiweb_headers:get_value("Content-Length", Headers)),
-    _Body = mochiweb_test_util:drain_reply(SockFun, Len, <<>>),
-    ?assertEqual({error, closed}, SockFun(recv)),
+    ?assertEqual("close",
+		 (mochiweb_headers:get_value("Connection", Headers))),
+    Len =
+	list_to_integer(mochiweb_headers:get_value("Content-Length",
+						   Headers)),
+    _Body = mochiweb_test_util:drain_reply(SockFun, Len,
+					   <<>>),
+    ?assertEqual({error, closed}, (SockFun(recv))),
     ok.
diff --git a/test/mochiweb_websocket_tests.erl b/test/mochiweb_websocket_tests.erl
index 0af29b7..5fd6273 100644
--- a/test/mochiweb_websocket_tests.erl
+++ b/test/mochiweb_websocket_tests.erl
@@ -1,4 +1,5 @@
 -module(mochiweb_websocket_tests).
+
 -author('lukasz.lalik@zadane.pl').
 
 %% The MIT License (MIT)
@@ -27,76 +28,81 @@
 
 make_handshake_for_correct_client_test() ->
     %% Hybi handshake
-    Req1 = mochiweb_request:new(
-             nil, 'GET', "/foo", {1, 1},
-             mochiweb_headers:make([{"Sec-WebSocket-Key",
-                                     "Xn3fdKyc3qEXPuj2A3O+ZA=="}])),
-
-    {Version1,
-     {HttpCode1, Headers1, _}} = mochiweb_websocket:make_handshake(Req1),
+    Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
+				mochiweb_headers:make([{"Sec-WebSocket-Key",
+							"Xn3fdKyc3qEXPuj2A3O+ZA=="}])),
+    {Version1, {HttpCode1, Headers1, _}} =
+	mochiweb_websocket:make_handshake(Req1),
     ?assertEqual(hybi, Version1),
     ?assertEqual(101, HttpCode1),
-    ?assertEqual("Upgrade", proplists:get_value("Connection", Headers1)),
+    ?assertEqual("Upgrade",
+		 (proplists:get_value("Connection", Headers1))),
     ?assertEqual(<<"BIFTHkJk4r5t8kuud82tZJaQsCE=">>,
-                 proplists:get_value("Sec-Websocket-Accept", Headers1)),
-
+		 (proplists:get_value("Sec-Websocket-Accept",
+				      Headers1))),
     %% Hixie handshake
     {Version2, {HttpCode2, Headers2, Body2}} =
-        mochiweb_websocket:hixie_handshake(
-          "ws://",
-          "localhost", "/",
-          "33j284    9  z63 e 9 7",
-          "TF'3|6D12659H 7 70",
-          <<175,181,191,215,128,195,144,120>>,
-          "null"),
+	mochiweb_websocket:hixie_handshake("ws://", "localhost",
+					   "/", "33j284    9  z63 e 9 7",
+					   "TF'3|6D12659H 7 70",
+					   <<175, 181, 191, 215, 128, 195, 144,
+					     120>>,
+					   "null"),
     ?assertEqual(hixie, Version2),
     ?assertEqual(101, HttpCode2),
-    ?assertEqual("null", proplists:get_value("Sec-WebSocket-Origin", Headers2)),
+    ?assertEqual("null",
+		 (proplists:get_value("Sec-WebSocket-Origin",
+				      Headers2))),
     ?assertEqual("ws://localhost/",
-                 proplists:get_value("Sec-WebSocket-Location", Headers2)),
-    ?assertEqual(
-       <<230,144,237,94,84,214,41,69,244,150,134,167,221,103,239,246>>,
-       Body2).
+		 (proplists:get_value("Sec-WebSocket-Location",
+				      Headers2))),
+    ?assertEqual(<<230, 144, 237, 94, 84, 214, 41, 69, 244,
+		   150, 134, 167, 221, 103, 239, 246>>,
+		 Body2).
 
 hybi_frames_decode_test() ->
-    ?assertEqual(
-       [{1, <<"foo">>}],
-       mochiweb_websocket:parse_hybi_frames(
-         nil, <<129,131,118,21,153,58,16,122,246>>, [])),
-    ?assertEqual(
-       [{1, <<"foo">>}, {1, <<"bar">>}],
-       mochiweb_websocket:parse_hybi_frames(
-         nil,
-         <<129,131,1,225,201,42,103,142,166,129,131,93,222,214,66,63,191,164>>,
-         [])).
+    ?assertEqual([{1, <<"foo">>}],
+		 (mochiweb_websocket:parse_hybi_frames(nil,
+						       <<129, 131, 118, 21, 153,
+							 58, 16, 122, 246>>,
+						       []))),
+    ?assertEqual([{1, <<"foo">>}, {1, <<"bar">>}],
+		 (mochiweb_websocket:parse_hybi_frames(nil,
+						       <<129, 131, 1, 225, 201,
+							 42, 103, 142, 166, 129,
+							 131, 93, 222, 214, 66,
+							 63, 191, 164>>,
+						       []))).
 
 hixie_frames_decode_test() ->
-    ?assertEqual(
-       [],
-       mochiweb_websocket:parse_hixie_frames(<<>>, [])),
-    ?assertEqual(
-       [<<"foo">>],
-       mochiweb_websocket:parse_hixie_frames(<<0,102,111,111,255>>, [])),
-    ?assertEqual(
-       [<<"foo">>, <<"bar">>],
-       mochiweb_websocket:parse_hixie_frames(
-         <<0,102,111,111,255,0,98,97,114,255>>,
-         [])).
+    ?assertEqual([],
+		 (mochiweb_websocket:parse_hixie_frames(<<>>, []))),
+    ?assertEqual([<<"foo">>],
+		 (mochiweb_websocket:parse_hixie_frames(<<0, 102, 111,
+							  111, 255>>,
+							[]))),
+    ?assertEqual([<<"foo">>, <<"bar">>],
+		 (mochiweb_websocket:parse_hixie_frames(<<0, 102, 111,
+							  111, 255, 0, 98, 97,
+							  114, 255>>,
+							[]))).
 
 end_to_end_test_factory(ServerTransport) ->
-    mochiweb_test_util:with_server(
-      ServerTransport,
-      fun end_to_end_server/1,
-      fun (Transport, Port) ->
-              end_to_end_client(mochiweb_test_util:sock_fun(Transport, Port))
-      end).
+    mochiweb_test_util:with_server(ServerTransport,
+				   fun end_to_end_server/1,
+				   fun (Transport, Port) ->
+					   end_to_end_client(mochiweb_test_util:sock_fun(Transport,
+											 Port))
+				   end).
 
 end_to_end_server(Req) ->
-    ?assertEqual("Upgrade", mochiweb_request:get_header_value("connection", Req)),
-    ?assertEqual("websocket", mochiweb_request:get_header_value("upgrade", Req)),
-    {ReentryWs, _ReplyChannel} = mochiweb_websocket:upgrade_connection(
-                                   Req,
-                                   fun end_to_end_ws_loop/3),
+    ?assertEqual("Upgrade",
+		 (mochiweb_request:get_header_value("connection", Req))),
+    ?assertEqual("websocket",
+		 (mochiweb_request:get_header_value("upgrade", Req))),
+    {ReentryWs, _ReplyChannel} =
+	mochiweb_websocket:upgrade_connection(Req,
+					      fun end_to_end_ws_loop/3),
     ReentryWs(ok).
 
 end_to_end_ws_loop(Payload, State, ReplyChannel) ->
@@ -106,55 +112,52 @@ end_to_end_ws_loop(Payload, State, ReplyChannel) ->
 
 end_to_end_client(S) ->
     %% Key and Accept per https://tools.ietf.org/html/rfc6455
-    UpgradeReq = string:join(
-                   ["GET / HTTP/1.1",
-                    "Host: localhost",
-                    "Upgrade: websocket",
-                    "Connection: Upgrade",
-                    "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==",
-                    "",
-                    ""], "\r\n"),
+    UpgradeReq = string:join(["GET / HTTP/1.1",
+			      "Host: localhost", "Upgrade: websocket",
+			      "Connection: Upgrade",
+			      "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==", "",
+			      ""],
+			     "\r\n"),
     ok = S({send, UpgradeReq}),
-    {ok, {http_response, {1,1}, 101, _}} = S(recv),
-    read_expected_headers(
-      S,
-      [{'Upgrade', "websocket"},
-       {'Connection', "Upgrade"},
-       {'Content-Length', "0"},
-       {"Sec-Websocket-Accept", "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="}]),
+    {ok, {http_response, {1, 1}, 101, _}} = S(recv),
+    read_expected_headers(S,
+			  [{'Upgrade', "websocket"}, {'Connection', "Upgrade"},
+			   {'Content-Length', "0"},
+			   {"Sec-Websocket-Accept",
+			    "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="}]),
     %% The first message sent over telegraph :)
     SmallMessage = <<"What hath God wrought?">>,
     ok = S({send,
-       << 1:1, %% Fin
-          0:1, %% Rsv1
-          0:1, %% Rsv2
-          0:1, %% Rsv3
-          2:4, %% Opcode, 1 = text frame
-          1:1, %% Mask on
-          (byte_size(SmallMessage)):7, %% Length, <125 case
-          0:32, %% Mask (trivial)
-          SmallMessage/binary >>}),
+	    <<1:1, %% Fin
+	      0:1, %% Rsv1
+	      0:1, %% Rsv2
+	      0:1, %% Rsv3
+	      2:4, %% Opcode, 1 = text frame
+	      1:1, %% Mask on
+	      (byte_size(SmallMessage)):7, %% Length, <125 case
+	      0:32, %% Mask (trivial)
+	      SmallMessage/binary>>}),
     {ok, WsFrames} = S(recv),
-    << 1:1, %% Fin
-       0:1, %% Rsv1
-       0:1, %% Rsv2
-       0:1, %% Rsv3
-       1:4, %% Opcode, text frame (all mochiweb suports for now)
-       MsgSize:8, %% Expecting small size
-       SmallMessage/binary >> = WsFrames,
-    ?assertEqual(MsgSize, byte_size(SmallMessage)),
+    <<1:1, %% Fin
+      0:1, %% Rsv1
+      0:1, %% Rsv2
+      0:1, %% Rsv3
+      1:4, %% Opcode, text frame (all mochiweb suports for now)
+      MsgSize:8, %% Expecting small size
+      SmallMessage/binary>> =
+	WsFrames,
+    ?assertEqual(MsgSize, (byte_size(SmallMessage))),
     ok.
 
 read_expected_headers(S, D) ->
     Headers = mochiweb_test_util:read_server_headers(S),
-    lists:foreach(
-      fun ({K, V}) ->
-              ?assertEqual(V, mochiweb_headers:get_value(K, Headers))
-      end,
-      D).
+    lists:foreach(fun ({K, V}) ->
+			  ?assertEqual(V,
+				       (mochiweb_headers:get_value(K, Headers)))
+		  end,
+		  D).
 
 end_to_end_http_test() ->
     end_to_end_test_factory(plain).
 
-end_to_end_https_test() ->
-    end_to_end_test_factory(ssl).
+end_to_end_https_test() -> end_to_end_test_factory(ssl).


[couchdb-mochiweb] 14/32: Remove compile(tuple_calls) from examples/https_store

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit b6b3ff102d4675b1d641b49b89a9ae8f2a5a72f1
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Mon Mar 11 22:55:44 2019 +0000

    Remove compile(tuple_calls) from examples/https_store
---
 examples/https/https_store.erl | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/examples/https/https_store.erl b/examples/https/https_store.erl
index 23e2447..719f206 100644
--- a/examples/https/https_store.erl
+++ b/examples/https/https_store.erl
@@ -34,8 +34,6 @@
 
 -module(https_store).
 
--compile(tuple_calls).
-
 -export([start/0,
          stop/0,
          dispatch/1,
@@ -77,7 +75,7 @@ stop() ->
     ok.
 
 dispatch(Req) ->
-    case Req:get(method) of
+    case mochiweb_request:get(method, Req) of
         'GET' ->
             get_resource(Req);
         'PUT' ->
@@ -86,41 +84,41 @@ dispatch(Req) ->
             delete_resource(Req);
         _ ->
             Headers = [{"Allow", "GET,PUT,DELETE"}],
-            Req:respond({405, Headers, "405 Method Not Allowed\r\n"})
+            mochiweb_request:respond({405, Headers, "405 Method Not Allowed\r\n"}, Req)
     end.
 
 get_resource(Req) ->
-    Path = Req:get(path),
+    Path = mochiweb_request:get(path, Req),
     case ets:lookup(?MODULE, Path) of
         [{Path, #resource{type=Type, data=Data}}] ->
-            Req:ok({Type, Data});
+            mochiweb_request:ok({Type, Data}, Req);
         [] ->
-            Req:respond({404, [], "404 Not Found\r\n"})
+            mochiweb_request:respond({404, [], "404 Not Found\r\n"}, Req)
     end.
 
 put_resource(Req) ->
-    ContentType = case Req:get_header_value("Content-Type") of
+    ContentType = case mochiweb_request:get_header_value("Content-Type", Req) of
         undefined ->
             "application/octet-stream";
         S ->
             S
     end,
-    Resource = #resource{type=ContentType, data=Req:recv_body()},
-    http_store ! {self(), {put, Req:get(path), Resource}},
+    Resource = #resource{type=ContentType, data=mochiweb_request:recv_body(Req)},
+    http_store ! {self(), {put, mochiweb_request:get(path, Req), Resource}},
     Pid = whereis(http_store),
     receive
         {Pid, created} ->
-            Req:respond({201, [], "201 Created\r\n"});
+            mochiweb_request:respond({201, [], "201 Created\r\n"}, Req);
         {Pid, updated} ->
-            Req:respond({200, [], "200 OK\r\n"})
+            mochiweb_request:respond({200, [], "200 OK\r\n"}, Req)
     end.
 
 delete_resource(Req) ->
-    http_store ! {self(), {delete, Req:get(path)}},
+    http_store ! {self(), {delete, mochiweb_request:get(path, Req)}},
     Pid = whereis(http_store),
     receive
         {Pid, ok} ->
-            Req:respond({200, [], "200 OK\r\n"})
+            mochiweb_request:respond({200, [], "200 OK\r\n"}, Req)
     end.
 
 loop(#sd{http=Http, https=Https} = SD) ->


[couchdb-mochiweb] 16/32: Remove compile(tuple_calls) from test/mochiweb_http_tests

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 1092472db8b8184f4e1d32babf3f36a080d13cf6
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Tue Mar 12 01:26:08 2019 +0000

    Remove compile(tuple_calls) from test/mochiweb_http_tests
---
 examples/hmac_api/README     |  2 +-
 test/mochiweb_http_tests.erl | 12 +++++++-----
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/examples/hmac_api/README b/examples/hmac_api/README
index 3771323..d69821a 100644
--- a/examples/hmac_api/README
+++ b/examples/hmac_api/README
@@ -159,7 +159,7 @@ authorize/request/1 should be called in the loop of project_name_web.erl as per:
     loop(Req, DocRoot) ->
         Auth = hmac_api_lib:authorize_request(Req),
         io:format("Auth is ~p~n", [Auth]),
-        "/" ++ Path = Req:get(path),
+        "/" ++ Path = mochiweb_request:get(path, Req),
         ...
 
 When this is done you are ready to test the api:
diff --git a/test/mochiweb_http_tests.erl b/test/mochiweb_http_tests.erl
index 1057755..8fbf0f3 100644
--- a/test/mochiweb_http_tests.erl
+++ b/test/mochiweb_http_tests.erl
@@ -7,8 +7,6 @@
 -define(SHOULD_HAVE_BUG, false).
 -endif.
 
--compile(tuple_calls).
-
 has_acceptor_bug_test_() ->
     {setup,
      fun start_server/0,
@@ -29,9 +27,13 @@ has_acceptor_bug_tests(Server) ->
       ?_assertEqual(?SHOULD_HAVE_BUG, has_bug(Port, 10000))}].
 
 responder(Req) ->
-    Req:respond({200,
-                 [{"Content-Type", "text/html"}],
-                 ["<html><body>Hello</body></html>"]}).
+    mochiweb_request:respond(
+        {
+            200,
+            [{"Content-Type", "text/html"}],
+            ["<html><body>Hello</body></html>"]
+        },
+        Req).
 
 has_bug(Port, Len) ->
   case


[couchdb-mochiweb] 26/32: Merge pull request #221 from mochi/fix-travis-build

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit ec988737eef15bff73f9862d34a6f57819680b8d
Merge: 2cb3104 d12ac64
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Tue May 21 20:39:49 2019 -0700

    Merge pull request #221 from mochi/fix-travis-build
    
    Use dist: trusty for Travis builds with old Erlang releases

 .travis.yml | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)


[couchdb-mochiweb] 15/32: Remove compile(tuple_calls) from examples/keepalive

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 58699cbe9a8be680ae9a956a07ea5a6a859e0038
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Mon Mar 11 22:57:58 2019 +0000

    Remove compile(tuple_calls) from examples/keepalive
---
 examples/keepalive/keepalive.erl | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/examples/keepalive/keepalive.erl b/examples/keepalive/keepalive.erl
index a371e91..51a7c3a 100644
--- a/examples/keepalive/keepalive.erl
+++ b/examples/keepalive/keepalive.erl
@@ -1,7 +1,5 @@
 -module(keepalive).
 
--compile(tuple_calls).
-
 %% your web app can push data to clients using a technique called comet long
 %% polling.  browsers make a request and your server waits to send a
 %% response until data is available.  see wikipedia for a better explanation:
@@ -33,7 +31,7 @@ start(Options = [{port, _Port}]) ->
     mochiweb_http:start([{name, ?MODULE}, {loop, ?LOOP} | Options]).
 
 loop(Req) ->
-    Path = Req:get(path),
+    Path = mochiweb_request:get(path, Req),
     case string:tokens(Path, "/") of
         ["longpoll" | RestOfPath] ->
             %% the "reentry" is a continuation -- what @mochiweb_http@
@@ -74,10 +72,10 @@ resume(Req, RestOfPath, Reentry) ->
     %% if we didn't call @Reentry@ here then the function would finish and the
     %% process would exit.  calling @Reentry@ takes care of returning control
     %% to @mochiweb_http@
-    io:format("reentering loop via continuation in ~p~n", [Req:get(path)]),
+    io:format("reentering loop via continuation in ~p~n", [mochiweb_request:get(path, Req)]),
     Reentry(Req).
 
 ok(Req, Response) ->
-    Req:ok({_ContentType = "text/plain",
-            _Headers = [],
-            Response}).
+    mochiweb_request:ok(
+        {_ContentType = "text/plain", _Headers = [], Response},
+        Req).


[couchdb-mochiweb] 13/32: Remove compile(tuple_calls) from examples/hmac_api

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 1c73aaf8e92912c67d4c4ac1f98b52e3181f5716
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Mon Mar 11 22:51:02 2019 +0000

    Remove compile(tuple_calls) from examples/hmac_api
---
 examples/hmac_api/hmac_api_lib.erl | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/examples/hmac_api/hmac_api_lib.erl b/examples/hmac_api/hmac_api_lib.erl
index 95d7c58..4c26f2f 100644
--- a/examples/hmac_api/hmac_api_lib.erl
+++ b/examples/hmac_api/hmac_api_lib.erl
@@ -5,8 +5,6 @@
 
 -author("Hypernumbers Ltd <go...@hypernumbers.com>").
 
--compile(tuple_calls).
-
 %%% this library supports the hmac_sha api on both the client-side
 %%% AND the server-side
 %%%
@@ -36,9 +34,9 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 authorize_request(Req) ->
-    Method      = Req:get(method),
-    Path        = Req:get(path),
-    Headers     = normalise(mochiweb_headers:to_list(Req:get(headers))),
+    Method      = mochiweb_request:get(method, Req),
+    Path        = mochiweb_request:get(path, Req),
+    Headers     = normalise(mochiweb_headers:to_list(mochiweb_request:get(headers, Req))),
     ContentMD5  = get_header(Headers, "content-md5"),
     ContentType = get_header(Headers, "content-type"),
     Date        = get_header(Headers, "date"),


[couchdb-mochiweb] 31/32: Update CHANGES and add OTP 21.3, 22 to travis matrix

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 0c68ac4bec4e0de866a9a47650692ee8b8e6cd2f
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Sun Jul 14 21:39:43 2019 -0400

    Update CHANGES and add OTP 21.3, 22 to travis matrix
---
 .travis.yml | 2 ++
 CHANGES.md  | 5 ++++-
 README.md   | 2 +-
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index ecc72df..271323e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,8 @@ language: erlang
 notifications:
   email: false
 otp_release:
+  - 22.0
+  - 21.3
   - 21.2.3
   - 21.1
   - 21.0
diff --git a/CHANGES.md b/CHANGES.md
index e4f10d7..fdf306b 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,8 @@
-Version 2.20.0 released 2019-XX-XX
+Version 2.20.0 released 2019-07-14
 
+* Expand testing matrix to include Erlang/OTP 22.0 and Erlang/OTP 21.3
+* Add support for SameSite=none in cookies
+  https://github.com/mochi/mochiweb/pull/225
 * Fix parsing of certain unquoted cookie values
   https://github.com/mochi/mochiweb/pull/212
 
diff --git a/README.md b/README.md
index 44e392b..dcd96f8 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ To create a new mochiweb using project in a specific directory:
 
 Information about Rebar (Erlang build tool) is available at https://github.com/rebar/rebar
 
-MochiWeb is currently tested with Erlang/OTP R15B03 through 21.2.3.
+MochiWeb is currently tested with Erlang/OTP R15B03 through 22.0.
 
 # OTP 21.2, 21.2.1, 21.2.2 warning
 


[couchdb-mochiweb] 21/32: Merge pull request #215 from mochi/remove-tuple-calls

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 2cb310469bdca7715229e5dcc697ad4478bb7c3a
Merge: 7884405 69d6df7
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Tue Mar 12 13:07:23 2019 -0700

    Merge pull request #215 from mochi/remove-tuple-calls
    
    Remove tuple calls

 examples/hmac_api/README                           |    2 +-
 examples/hmac_api/hmac_api_lib.erl                 |  356 +++---
 examples/https/https_store.erl                     |  148 +--
 examples/keepalive/keepalive.erl                   |   76 +-
 src/mochifmt.erl                                   |  418 ++++---
 src/mochiweb_acceptor.erl                          |   69 +-
 src/mochiweb_http.erl                              |  380 +++---
 src/mochiweb_multipart.erl                         | 1243 ++++++++++---------
 src/mochiweb_request.erl                           | 1284 ++++++++++++--------
 src/mochiweb_response.erl                          |   45 +-
 src/mochiweb_websocket.erl                         |  293 +++--
 .../mochiwebapp_skel/src/mochiapp_web.erl          |   90 +-
 test/mochiweb_http_tests.erl                       |   48 +-
 test/mochiweb_request_tests.erl                    |  294 +++--
 test/mochiweb_tests.erl                            |  246 ++--
 test/mochiweb_websocket_tests.erl                  |  191 +--
 16 files changed, 2787 insertions(+), 2396 deletions(-)


[couchdb-mochiweb] 28/32: Merge pull request #220 from penhs/master

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit ad1198018429e22cdf2bb530a2a64ec456c88ab6
Merge: ec98873 c692fd7
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Sat May 25 19:19:02 2019 -0700

    Merge pull request #220 from penhs/master
    
    Update README.md

 README.md | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)


[couchdb-mochiweb] 04/32: Merge pull request #213 from mochi/lego12239-master

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 788440585fefed404a375c5bb6da238d68016fa9
Merge: 985fa8a 9a1b109
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Mon Mar 4 08:55:44 2019 -0800

    Merge pull request #213 from mochi/lego12239-master
    
    fix cookie value parsing (follow up)

 CHANGES.md               |  5 +++++
 src/mochiweb.app.src     |  2 +-
 src/mochiweb_cookies.erl | 25 ++++++++++++++++++++++++-
 3 files changed, 30 insertions(+), 2 deletions(-)


[couchdb-mochiweb] 17/32: Remove compile(tuple_calls) from test/mochiweb_websocket_tests

Posted by wi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git

commit 2cae81351e74a5dacef62944597198ce4da8a981
Author: Bob Ippolito <bo...@redivi.com>
AuthorDate: Tue Mar 12 01:32:14 2019 +0000

    Remove compile(tuple_calls) from test/mochiweb_websocket_tests
---
 test/mochiweb_websocket_tests.erl | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/test/mochiweb_websocket_tests.erl b/test/mochiweb_websocket_tests.erl
index 71fb9a6..0af29b7 100644
--- a/test/mochiweb_websocket_tests.erl
+++ b/test/mochiweb_websocket_tests.erl
@@ -23,8 +23,6 @@
 %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 %% THE SOFTWARE.
 
--compile(tuple_calls).
-
 -include_lib("eunit/include/eunit.hrl").
 
 make_handshake_for_correct_client_test() ->
@@ -94,8 +92,8 @@ end_to_end_test_factory(ServerTransport) ->
       end).
 
 end_to_end_server(Req) ->
-    ?assertEqual("Upgrade", Req:get_header_value("connection")),
-    ?assertEqual("websocket", Req:get_header_value("upgrade")),
+    ?assertEqual("Upgrade", mochiweb_request:get_header_value("connection", Req)),
+    ?assertEqual("websocket", mochiweb_request:get_header_value("upgrade", Req)),
     {ReentryWs, _ReplyChannel} = mochiweb_websocket:upgrade_connection(
                                    Req,
                                    fun end_to_end_ws_loop/3),