summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul J. Davis <paul.joseph.davis@gmail.com>2017-05-30 13:42:47 -0500
committerPaul J. Davis <paul.joseph.davis@gmail.com>2017-05-30 13:42:47 -0500
commit85a163a114adba1249dbe5ea5c2048cfd5157390 (patch)
tree8d6604f2d033bb4d1c0e8468534d4653572c40d6
parent68c3008b8909c53d610ee839593b60c0912b636f (diff)
downloadcouchdb-85a163a114adba1249dbe5ea5c2048cfd5157390.tar.gz
Reject unknown engines in chttpd
-rw-r--r--src/chttpd/src/chttpd_db.erl21
-rw-r--r--src/chttpd/test/chttpd_db_test.erl16
-rw-r--r--src/couch/src/couch_server.erl1
3 files changed, 32 insertions, 6 deletions
diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index efb2f6f27..af05f35b9 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -284,13 +284,12 @@ create_db_req(#httpd{}=Req, DbName) ->
N = chttpd:qs_value(Req, "n", config:get("cluster", "n", "3")),
Q = chttpd:qs_value(Req, "q", config:get("cluster", "q", "8")),
P = chttpd:qs_value(Req, "placement", config:get("cluster", "placement")),
- E = iolist_to_binary(chttpd:qs_value(Req, "engine", "couch")),
+ EngineOpt = parse_engine_opt(Req),
Options = [
{n, N},
{q, Q},
- {placement, P},
- {engine, E}
- ],
+ {placement, P}
+ ] ++ EngineOpt,
DocUrl = absolute_uri(Req, "/" ++ couch_util:url_encode(DbName)),
case fabric:create_db(DbName, Options) of
ok ->
@@ -1359,6 +1358,20 @@ get_md5_header(Req) ->
parse_doc_query(Req) ->
lists:foldl(fun parse_doc_query/2, #doc_query_args{}, chttpd:qs(Req)).
+parse_engine_opt(Req) ->
+ case chttpd:qs_value(Req, "engine") of
+ undefined ->
+ [];
+ Extension ->
+ Available = couch_server:get_engine_extensions(),
+ case lists:member(Extension, Available) of
+ true ->
+ [{engine, iolist_to_binary(Extension)}];
+ false ->
+ throw({bad_request, invalid_engine_extension})
+ end
+ end.
+
parse_doc_query({Key, Value}, Args) ->
case {Key, Value} of
{"attachments", "true"} ->
diff --git a/src/chttpd/test/chttpd_db_test.erl b/src/chttpd/test/chttpd_db_test.erl
index b7ea7f006..f153b1032 100644
--- a/src/chttpd/test/chttpd_db_test.erl
+++ b/src/chttpd/test/chttpd_db_test.erl
@@ -60,7 +60,8 @@ all_test_() ->
fun should_accept_live_as_an_alias_for_continuous/1,
fun should_return_404_for_delete_att_on_notadoc/1,
fun should_return_409_for_del_att_without_rev/1,
- fun should_return_200_for_del_att_with_rev/1
+ fun should_return_200_for_del_att_with_rev/1,
+ fun should_return_400_for_bad_engine/1
]
}
}
@@ -92,7 +93,7 @@ should_accept_live_as_an_alias_for_continuous(Url) ->
LastSeqNum = list_to_integer(binary_to_list(LastSeqNum0)),
{ok, _, _, _} = create_doc(Url, "testdoc2"),
- {ok, _, _, ResultBody2} =
+ {ok, _, _, ResultBody2} =
test_request:get(Url ++ "/_changes?feed=live&timeout=1", [?AUTH]),
[_, CleanedResult] = binary:split(ResultBody2, <<"\n">>),
{[{_, Seq}, _]} = ?JSON_DECODE(CleanedResult),
@@ -179,3 +180,14 @@ should_return_200_for_del_att_with_rev(Url) ->
),
?assertEqual(200, RC1)
end).
+
+should_return_400_for_bad_engine(_) ->
+ ?_test(begin
+ TmpDb = ?tempdb(),
+ Addr = config:get("chttpd", "bind_address", "127.0.0.1"),
+ Port = mochiweb_socket_server:get(chttpd, port),
+ BaseUrl = lists:concat(["http://", Addr, ":", Port, "/", ?b2l(TmpDb)]),
+ Url = BaseUrl ++ "?engine=cowabunga",
+ {ok, Status, _, _} = test_request:put(Url, [?CONTENT_JSON, ?AUTH], "{}"),
+ ?assertEqual(400, Status)
+ end).
diff --git a/src/couch/src/couch_server.erl b/src/couch/src/couch_server.erl
index 1ad033411..9c1521660 100644
--- a/src/couch/src/couch_server.erl
+++ b/src/couch/src/couch_server.erl
@@ -23,6 +23,7 @@
-export([close_lru/0]).
-export([delete_compaction_files/1]).
-export([exists/1]).
+-export([get_engine_extensions/0]).
% config_listener api
-export([handle_config_change/5, handle_config_terminate/3]).