summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2010-08-24 09:43:59 +0000
committerRobert Newson <rnewson@apache.org>2010-08-24 09:43:59 +0000
commitf3597fc4871cd5654a794144e1fef598078b3c5e (patch)
tree788036bbdeaa96817611334fdcd93a134ad32310 /src
parent3c985840f1b394ca9ec43412d086ea9ca6cd1ddb (diff)
support multiple byte ranges in Range header.
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@988451 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/couchdb/couch_httpd_db.erl29
1 files changed, 26 insertions, 3 deletions
diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl
index 17b27b13..9181fcc5 100644
--- a/src/couchdb/couch_httpd_db.erl
+++ b/src/couchdb/couch_httpd_db.erl
@@ -775,9 +775,32 @@ send_docs_multipart(Req, Results, Options) ->
couch_httpd:send_chunk(Resp, <<"--">>),
couch_httpd:last_chunk(Resp).
+send_ranges_multipart(Req, ContentType, Len, Att, Ranges) ->
+ Boundary = couch_uuids:random(),
+ CType = {"Content-Type",
+ "multipart/byteranges; boundary=\"" ++ ?b2l(Boundary) ++ "\""},
+ {ok, Resp} = start_chunked_response(Req, 206, [CType]),
+ couch_httpd:send_chunk(Resp, <<"--", Boundary/binary>>),
+ lists:foreach(fun({From, To}) ->
+ ContentRange = make_content_range(From, To, Len),
+ couch_httpd:send_chunk(Resp,
+ <<"\r\nContent-Type: ", ContentType/binary, "\r\n",
+ "Content-Range: ", ContentRange/binary, "\r\n",
+ "\r\n">>),
+ couch_doc:range_att_foldl(Att, From, To + 1,
+ fun(Seg, _) -> send_chunk(Resp, Seg) end, {ok, Resp}),
+ couch_httpd:send_chunk(Resp, <<"\r\n--", Boundary/binary>>)
+ end, Ranges),
+ couch_httpd:send_chunk(Resp, <<"--">>),
+ couch_httpd:last_chunk(Resp),
+ {ok, Resp}.
+
receive_request_data(Req) ->
{couch_httpd:recv(Req, 0), fun() -> receive_request_data(Req) end}.
+make_content_range(From, To, Len) ->
+ ?l2b(io_lib:format("bytes ~B-~B/~B", [From, To, Len])).
+
update_doc_result_to_json({{Id, Rev}, Error}) ->
{_Code, Err, Msg} = couch_httpd:error_info(Error),
{[{id, Id}, {rev, couch_doc:rev_to_str(Rev)},
@@ -929,13 +952,13 @@ db_attachment_req(#httpd{method='GET',mochi_req=MochiReq}=Req, Db, DocId, FileNa
Ranges = parse_ranges(MochiReq:get(range), Len),
case {Enc, Ranges} of
{identity, [{From, To}]} ->
- Headers1 = [{<<"Content-Range">>,
- ?l2b(io_lib:format("bytes ~B-~B/~B", [From, To, Len]))}]
+ Headers1 = [{<<"Content-Range">>, make_content_range(From, To, Len)}]
++ Headers,
{ok, Resp} = start_response_length(Req, 206, Headers1, To - From + 1),
couch_doc:range_att_foldl(Att, From, To + 1,
fun(Seg, _) -> send(Resp, Seg) end, {ok, Resp});
- %% {identity, Ranges} when is_list(Ranges) ->
+ {identity, Ranges} when is_list(Ranges) ->
+ send_ranges_multipart(Req, Type, Len, Att, Ranges);
_ ->
{ok, Resp} = start_response_length(Req, 200, Headers, Len),
AttFun(Att, fun(Seg, _) -> send(Resp, Seg) end, {ok, Resp})