summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorncshaw <ncshaw@ibm.com>2021-07-19 12:36:30 -0400
committerNick Vatamaniuc <nickva@users.noreply.github.com>2021-07-19 14:49:47 -0400
commitf31e92997ab57eae0808137c6b59a8c02e3fd912 (patch)
tree9cbafe61d91635d773a431a608bc6eac22335c4c
parentc42d5b93cadd64e11170d89b06f7f60ad6c765a9 (diff)
downloadcouchdb-f31e92997ab57eae0808137c6b59a8c02e3fd912.tar.gz
Fix response code for nonexistent attachment
-rw-r--r--src/chttpd/src/chttpd_db.erl30
-rw-r--r--test/elixir/test/attachments_test.exs5
2 files changed, 27 insertions, 8 deletions
diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index 312adaed4..017c387d4 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -1442,11 +1442,8 @@ couch_doc_open(Db, DocId, Rev, Options0) ->
end
end.
-% Attachment request handlers
-
-db_attachment_req(#httpd{method='GET',mochi_req=MochiReq}=Req, Db, DocId, FileNameParts) ->
- FileName = list_to_binary(mochiweb_util:join(lists:map(fun binary_to_list/1,
- FileNameParts),"/")),
+get_attachment(Req, Db, DocId, FileName) ->
+ % Check if attachment exists
#doc_query_args{
rev=Rev,
options=Options
@@ -1455,9 +1452,21 @@ db_attachment_req(#httpd{method='GET',mochi_req=MochiReq}=Req, Db, DocId, FileNa
atts=Atts
} = Doc = couch_doc_open(Db, DocId, Rev, Options),
case [A || A <- Atts, couch_att:fetch(name, A) == FileName] of
- [] ->
+ [] ->
+ {error, missing};
+ [Att] ->
+ {ok, Doc, Att}
+ end.
+
+% Attachment request handlers
+
+db_attachment_req(#httpd{method='GET',mochi_req=MochiReq}=Req, Db, DocId, FileNameParts) ->
+ FileName = list_to_binary(mochiweb_util:join(lists:map(fun binary_to_list/1,
+ FileNameParts),"/")),
+ case get_attachment(Req, Db, DocId, FileName) of
+ {error, missing} ->
throw({not_found, "Document is missing attachment"});
- [Att] ->
+ {ok, Doc, Att} ->
[Type, Enc, DiskLen, AttLen, Md5] = couch_att:fetch([type, encoding, disk_len, att_len, md5], Att),
Refs = monitor_attachments(Att),
try
@@ -1559,7 +1568,12 @@ db_attachment_req(#httpd{method=Method, user_ctx=Ctx}=Req, Db, DocId, FileNamePa
NewAtt = case Method of
'DELETE' ->
- [];
+ case get_attachment(Req, Db, DocId, FileName) of
+ {error, missing} ->
+ throw({not_found, "Document is missing attachment"});
+ {ok, _, _} ->
+ []
+ end;
_ ->
MimeType = case couch_httpd:header_value(Req,"Content-Type") of
% We could throw an error here or guess by the FileName.
diff --git a/test/elixir/test/attachments_test.exs b/test/elixir/test/attachments_test.exs
index 020003377..fe694e21f 100644
--- a/test/elixir/test/attachments_test.exs
+++ b/test/elixir/test/attachments_test.exs
@@ -109,6 +109,11 @@ defmodule AttachmentsTest do
assert resp.status_code == 409
+ resp = Couch.delete("/#{db_name}/bin_doc/notexisting.txt", query: %{w: 3, rev: rev})
+ assert resp.status_code == 404
+ assert resp.body["error"] == "not_found"
+ assert resp.body["reason"] == "Document is missing attachment"
+
resp = Couch.delete("/#{db_name}/bin_doc/foo.txt", query: %{w: 3, rev: rev})
assert resp.status_code == 200
assert resp.headers["location"] == nil