summaryrefslogtreecommitdiff
path: root/src/couchdb
diff options
context:
space:
mode:
authorAdam Kocoloski <kocolosk@apache.org>2010-04-23 16:12:37 +0000
committerAdam Kocoloski <kocolosk@apache.org>2010-04-23 16:12:37 +0000
commite8f1ad6493c9bee70a0faab929e4f3a375fc0746 (patch)
tree54fc9d5e00b6be321d75923647a456ac000439f7 /src/couchdb
parentc6361aa24b6974ad1f89841ccfe6711f5323a588 (diff)
identity transfer w/ Content-Length when possible. thx rnewson. COUCHDB-745
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@937352 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/couchdb')
-rw-r--r--src/couchdb/couch_httpd_db.erl33
1 files changed, 29 insertions, 4 deletions
diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl
index d7f479bc..f1f6b0d3 100644
--- a/src/couchdb/couch_httpd_db.erl
+++ b/src/couchdb/couch_httpd_db.erl
@@ -853,7 +853,7 @@ db_attachment_req(#httpd{method='GET'}=Req, Db, DocId, FileNameParts) ->
case [A || A <- Atts, A#att.name == FileName] of
[] ->
throw({not_found, "Document is missing attachment"});
- [#att{type=Type, encoding=Enc}=Att] ->
+ [#att{type=Type, encoding=Enc, disk_len=DiskLen, att_len=AttLen}=Att] ->
Etag = couch_httpd:doc_etag(Doc),
ReqAcceptsAttEnc = lists:member(
atom_to_list(Enc),
@@ -869,6 +869,25 @@ db_attachment_req(#httpd{method='GET'}=Req, Db, DocId, FileNameParts) ->
_ ->
[]
end,
+ Len = case {Enc, ReqAcceptsAttEnc} of
+ {identity, _} ->
+ % stored and served in identity form
+ DiskLen;
+ {_, false} when DiskLen =/= AttLen ->
+ % Stored encoded, but client doesn't accept the encoding we used,
+ % so we need to decode on the fly. DiskLen is the identity length
+ % of the attachment.
+ DiskLen;
+ {_, true} ->
+ % Stored and served encoded. AttLen is the encoded length.
+ AttLen;
+ _ ->
+ % We received an encoded attachment and stored it as such, so we
+ % don't know the identity length. The client doesn't accept the
+ % encoding, and since we cannot serve a correct Content-Length
+ % header we'll fall back to a chunked response.
+ undefined
+ end,
AttFun = case ReqAcceptsAttEnc of
false ->
fun couch_doc:att_foldl_decode/3;
@@ -879,9 +898,15 @@ db_attachment_req(#httpd{method='GET'}=Req, Db, DocId, FileNameParts) ->
Req,
Etag,
fun() ->
- {ok, Resp} = start_chunked_response(Req, 200, Headers),
- AttFun(Att, fun(Seg, _) -> send_chunk(Resp, Seg) end, ok),
- last_chunk(Resp)
+ case Len of
+ undefined ->
+ {ok, Resp} = start_chunked_response(Req, 200, Headers),
+ AttFun(Att, fun(Seg, _) -> send_chunk(Resp, Seg) end, ok),
+ last_chunk(Resp);
+ _ ->
+ {ok, Resp} = start_response_length(Req, 200, Headers, Len),
+ AttFun(Att, fun(Seg, _) -> send(Resp, Seg) end, ok)
+ end
end
)
end;