diff options
author | Adam Kocoloski <kocolosk@apache.org> | 2010-04-23 16:12:37 +0000 |
---|---|---|
committer | Adam Kocoloski <kocolosk@apache.org> | 2010-04-23 16:12:37 +0000 |
commit | e8f1ad6493c9bee70a0faab929e4f3a375fc0746 (patch) | |
tree | 54fc9d5e00b6be321d75923647a456ac000439f7 /src | |
parent | c6361aa24b6974ad1f89841ccfe6711f5323a588 (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')
-rw-r--r-- | src/couchdb/couch_httpd_db.erl | 33 |
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; |