diff options
author | Garren Smith <garren.smith@gmail.com> | 2019-02-05 16:47:39 +0200 |
---|---|---|
committer | Paul J. Davis <paul.joseph.davis@gmail.com> | 2019-02-07 11:58:33 -0600 |
commit | 7fe8bfb6a329e4e6d460d6c2ab6455c711869e98 (patch) | |
tree | 17bd04dee940deac40cfdc4d9b2395b1818f1f55 | |
parent | e702598c4f2c528a9b867a9989d814cb9f6d8311 (diff) | |
download | couchdb-7fe8bfb6a329e4e6d460d6c2ab6455c711869e98.tar.gz |
Add check for repeated `partition` definitions
This is a usability improvement. If someone specifies the a `partition`
value in the query string that is different than the `partition` value
in the URL path it is not clear which value would be used. This allows
specifying it in both places as long as the query string matches the URL
path and throws a 400 Bad Request error otherwise.
Co-Authored-By: Garren Smith <garren.smith@gmail.com>
-rw-r--r-- | src/chttpd/src/chttpd_db.erl | 8 | ||||
-rw-r--r-- | test/elixir/test/partition_view_test.exs | 10 |
2 files changed, 17 insertions, 1 deletions
diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl index 7a00d2b1b..003b0d8dc 100644 --- a/src/chttpd/src/chttpd_db.erl +++ b/src/chttpd/src/chttpd_db.erl @@ -282,7 +282,13 @@ handle_partition_req(#httpd{path_parts=[DbName, _, PartId | Rest]}=Req, Db) -> true -> couch_partition:validate_partition(PartId), QS = chttpd:qs(Req), - NewQS = lists:ukeysort(1, [{"partition", ?b2l(PartId)} | QS]), + PartIdStr = ?b2l(PartId), + QSPartIdStr = couch_util:get_value("partition", QS, PartIdStr), + if QSPartIdStr == PartIdStr -> ok; true -> + Msg = <<"Conflicting value for `partition` in query string">>, + throw({bad_request, Msg}) + end, + NewQS = lists:ukeysort(1, [{"partition", PartIdStr} | QS]), NewReq = Req#httpd{ path_parts = [DbName | Rest], qs = NewQS diff --git a/test/elixir/test/partition_view_test.exs b/test/elixir/test/partition_view_test.exs index b9fbf179f..0a55c2443 100644 --- a/test/elixir/test/partition_view_test.exs +++ b/test/elixir/test/partition_view_test.exs @@ -106,6 +106,16 @@ defmodule ViewPartitionTest do assert Enum.dedup(partitions) == ["bar"] end + test "conflicting partitions in path and query string rejected", context do + db_name = context[:db_name] + + url = "/#{db_name}/_partition/foo/_design/map/_view/some" + resp = Couch.get(url, query: %{partition: "bar"}) + assert resp.status_code == 400 + %{:body => %{"reason" => reason}} = resp + assert Regex.match?(~r/Conflicting value/, reason) + end + test "query will return zero results for wrong inputs", context do db_name = context[:db_name] |