You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2014/02/12 07:21:56 UTC

[24/50] [abbrv] mochiweb commit: updated refs/heads/import-master to 3a54dbf

Provide Content-MD5 header support for attachments.

Fixes COUCHDB-558.

Thanks to Filipe Manana we now have checks for attachment transfer integrity
using the Content-MD5 header (or trailer). Use of this integrity check is
triggered by specifying a Content-MD5 header in your request with a value that
is a base64 encoded md5. For requests that are using a chunked Transfer-Encoding
it is also possible to use a trailer so that the Content-MD5 doesn't need to be
known before transfer. This works by specifying a header "Trailer:
Content-MD5" and then in the final chunk (the one with a size of zero) you can
specify a Content-MD5 with exactly the same format as in the request headers.

See the ETap test 130-attachments-md5.t for explicit examples of the request
messages.



git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@891077 13f79535-47bb-0310-9956-ffa450edef68


Project: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/commit/72d05973
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/tree/72d05973
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/diff/72d05973

Branch: refs/heads/import-master
Commit: 72d05973ebbac3f20c5fe9c80584a6b279ead55a
Parents: 11513d3
Author: Paul Joseph Davis <da...@apache.org>
Authored: Wed Dec 16 00:05:35 2009 +0000
Committer: Paul Joseph Davis <da...@apache.org>
Committed: Wed Dec 16 00:05:35 2009 +0000

----------------------------------------------------------------------
 mochiweb_headers.erl | 65 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/72d05973/mochiweb_headers.erl
----------------------------------------------------------------------
diff --git a/mochiweb_headers.erl b/mochiweb_headers.erl
index 6fcec7c..d90fd67 100644
--- a/mochiweb_headers.erl
+++ b/mochiweb_headers.erl
@@ -9,6 +9,7 @@
 -export([delete_any/2, get_primary_value/2]).
 -export([default/3, enter_from_list/2, default_from_list/2]).
 -export([to_list/1, make/1]).
+-export([from_binary/1]).
 -export([test/0]).
 
 %% @type headers().
@@ -37,6 +38,36 @@ test() ->
                                              "content-type", H4),
     H4 = ?MODULE:delete_any("nonexistent-header", H4),
     H3 = ?MODULE:delete_any("content-type", H4),
+    HB = <<"Content-Length: 47\r\nContent-Type: text/plain\r\n\r\n">>,
+    H_HB = ?MODULE:from_binary(HB),
+    H_HB = ?MODULE:from_binary(binary_to_list(HB)),
+    "47" = ?MODULE:get_value("Content-Length", H_HB),
+    "text/plain" = ?MODULE:get_value("Content-Type", H_HB),
+    L_H_HB = ?MODULE:to_list(H_HB),
+    2 = length(L_H_HB),
+    true = lists:member({'Content-Length', "47"}, L_H_HB),
+    true = lists:member({'Content-Type', "text/plain"}, L_H_HB),
+    HL = [ <<"Content-Length: 47\r\n">>, <<"Content-Type: text/plain\r\n">> ],
+    HL2 = [ "Content-Length: 47\r\n", <<"Content-Type: text/plain\r\n">> ],
+    HL3 = [ <<"Content-Length: 47\r\n">>, "Content-Type: text/plain\r\n" ],
+    H_HL = ?MODULE:from_binary(HL),
+    H_HL = ?MODULE:from_binary(HL2),
+    H_HL = ?MODULE:from_binary(HL3),
+    "47" = ?MODULE:get_value("Content-Length", H_HL),
+    "text/plain" = ?MODULE:get_value("Content-Type", H_HL),
+    L_H_HL = ?MODULE:to_list(H_HL),
+    2 = length(L_H_HL),
+    true = lists:member({'Content-Length', "47"}, L_H_HL),
+    true = lists:member({'Content-Type', "text/plain"}, L_H_HL),
+    [] = ?MODULE:to_list(?MODULE:from_binary(<<>>)),
+    [] = ?MODULE:to_list(?MODULE:from_binary(<<"">>)),
+    [] = ?MODULE:to_list(?MODULE:from_binary(<<"\r\n">>)),
+    [] = ?MODULE:to_list(?MODULE:from_binary(<<"\r\n\r\n">>)),
+    [] = ?MODULE:to_list(?MODULE:from_binary("")),
+    [] = ?MODULE:to_list(?MODULE:from_binary([<<>>])),
+    [] = ?MODULE:to_list(?MODULE:from_binary([<<"">>])),
+    [] = ?MODULE:to_list(?MODULE:from_binary([<<"\r\n">>])),
+    [] = ?MODULE:to_list(?MODULE:from_binary([<<"\r\n\r\n">>])),
     ok.
 
 %% @spec empty() -> headers()
@@ -52,6 +83,40 @@ make(L) when is_list(L) ->
 make(T) when is_tuple(T) ->
     T.
 
+%% @spec from_binary(RawHttpHeader()) -> headers() 
+%% @type RawHttpHeader() -> string() | binary() | [ string() | binary() ]
+%%
+%% @doc Transforms a raw HTTP header into a mochiweb headers structure.
+%%
+%%      The given raw HTTP header can be one of the following:
+%%
+%%      1) A string or a binary representing a full HTTP header ending with 
+%%         double CRLF.
+%%         Examples:
+%%         "Content-Length: 47\r\nContent-Type: text/plain\r\n\r\n"
+%%         <<"Content-Length: 47\r\nContent-Type: text/plain\r\n\r\n">>
+%%
+%%      2) A list of binaries or strings where each element represents a raw 
+%%         HTTP header line ending with a single CRLF.
+%%         Examples:
+%%         [ <<"Content-Length: 47\r\n">>, <<"Content-Type: text/plain\r\n">> ]
+%%         [ "Content-Length: 47\r\n", "Content-Type: text/plain\r\n" ]
+%%         [ "Content-Length: 47\r\n", <<"Content-Type: text/plain\r\n">> ]
+%%
+from_binary(RawHttpHeader) when is_binary(RawHttpHeader) ->
+    from_binary(RawHttpHeader, []);
+
+from_binary(RawHttpHeaderList) ->
+    from_binary(list_to_binary([RawHttpHeaderList, "\r\n"])).
+
+from_binary(RawHttpHeader, Acc) ->
+    case erlang:decode_packet(httph, RawHttpHeader, []) of
+        { ok, {http_header, _, H, _, V}, Rest } ->
+            from_binary(Rest, [{H, V} | Acc]);
+        _ ->
+            make(Acc)
+    end.
+
 %% @spec from_list([{key(), value()}]) -> headers()
 %% @doc Construct a headers() from the given list.
 from_list(List) ->