diff options
Diffstat (limited to 'src/couch/src/couch_att.erl')
-rw-r--r-- | src/couch/src/couch_att.erl | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/src/couch/src/couch_att.erl b/src/couch/src/couch_att.erl index 9d38cfae2..e78d6ef11 100644 --- a/src/couch/src/couch_att.erl +++ b/src/couch/src/couch_att.erl @@ -50,6 +50,11 @@ downgrade/1 ]). +-export([ + max_attachment_size/0, + validate_attachment_size/3 +]). + -compile(nowarn_deprecated_type). -export_type([att/0]). @@ -500,6 +505,8 @@ flush_data(Fd, Data, Att) when is_binary(Data) -> couch_stream:write(OutputStream, Data) end); flush_data(Fd, Fun, Att) when is_function(Fun) -> + AttName = fetch(name, Att), + MaxAttSize = max_attachment_size(), case fetch(att_len, Att) of undefined -> couch_db:with_stream(Fd, Att, fun(OutputStream) -> @@ -510,7 +517,7 @@ flush_data(Fd, Fun, Att) when is_function(Fun) -> % WriterFun({0, _Footers}, State) % Called with Length == 0 on the last time. % WriterFun returns NewState. - fun({0, Footers}, _) -> + fun({0, Footers}, _Total) -> F = mochiweb_headers:from_binary(Footers), case mochiweb_headers:get_value("Content-MD5", F) of undefined -> @@ -518,11 +525,15 @@ flush_data(Fd, Fun, Att) when is_function(Fun) -> Md5 -> {md5, base64:decode(Md5)} end; - ({_Length, Chunk}, _) -> - couch_stream:write(OutputStream, Chunk) - end, ok) + ({Length, Chunk}, Total0) -> + Total = Total0 + Length, + validate_attachment_size(AttName, Total, MaxAttSize), + couch_stream:write(OutputStream, Chunk), + Total + end, 0) end); AttLen -> + validate_attachment_size(AttName, AttLen, MaxAttSize), couch_db:with_stream(Fd, Att, fun(OutputStream) -> write_streamed_attachment(OutputStream, Fun, AttLen) end) @@ -680,6 +691,22 @@ upgrade_encoding(false) -> identity; upgrade_encoding(Encoding) -> Encoding. +max_attachment_size() -> + case config:get("couchdb", "max_attachment_size", "infinity") of + "infinity" -> + infinity; + MaxAttSize -> + list_to_integer(MaxAttSize) + end. + + +validate_attachment_size(AttName, AttSize, MaxAttSize) + when is_integer(AttSize), AttSize > MaxAttSize -> + throw({request_entity_too_large, {attachment, AttName}}); +validate_attachment_size(_AttName, _AttSize, _MAxAttSize) -> + ok. + + -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). |