diff options
author | Paul J. Davis <paul.joseph.davis@gmail.com> | 2017-05-30 13:42:47 -0500 |
---|---|---|
committer | Paul J. Davis <paul.joseph.davis@gmail.com> | 2017-05-30 13:42:47 -0500 |
commit | 85a163a114adba1249dbe5ea5c2048cfd5157390 (patch) | |
tree | 8d6604f2d033bb4d1c0e8468534d4653572c40d6 | |
parent | 68c3008b8909c53d610ee839593b60c0912b636f (diff) | |
download | couchdb-85a163a114adba1249dbe5ea5c2048cfd5157390.tar.gz |
Reject unknown engines in chttpd
-rw-r--r-- | src/chttpd/src/chttpd_db.erl | 21 | ||||
-rw-r--r-- | src/chttpd/test/chttpd_db_test.erl | 16 | ||||
-rw-r--r-- | src/couch/src/couch_server.erl | 1 |
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]). |