diff options
author | Alexander Shorin <kxepal@apache.org> | 2014-06-10 19:11:45 +0400 |
---|---|---|
committer | Alexander Shorin <kxepal@apache.org> | 2015-12-03 00:52:02 +0300 |
commit | 63e5e68b6b962a2b1145bc18eeb2a5ed01342b34 (patch) | |
tree | aaae3648218e19d4c77a1273652c23607208c9b3 | |
parent | 48034db04d38f61e9676163dc4fa6f18dbb0f9ae (diff) | |
download | couchdb-63e5e68b6b962a2b1145bc18eeb2a5ed01342b34.tar.gz |
Port 231-cors.t etap test suite to eunit
Extend vhost and subresource testing for more generic code.
-rw-r--r-- | test/couchdb/Makefile.am | 1 | ||||
-rw-r--r-- | test/couchdb/couchdb_cors_tests.erl | 344 | ||||
-rw-r--r-- | test/couchdb/test_request.erl | 14 | ||||
-rw-r--r-- | test/etap/231-cors.t | 430 | ||||
-rw-r--r-- | test/etap/Makefile.am | 1 |
5 files changed, 358 insertions, 432 deletions
diff --git a/test/couchdb/Makefile.am b/test/couchdb/Makefile.am index 8eee16f3d..6859236cb 100644 --- a/test/couchdb/Makefile.am +++ b/test/couchdb/Makefile.am @@ -43,6 +43,7 @@ eunit_files = \ couch_work_queue_tests.erl \ couchdb_attachments_tests.erl \ couchdb_compaction_daemon.erl \ + couchdb_cors_tests.erl \ couchdb_file_compression_tests.erl \ couchdb_http_proxy_tests.erl \ couchdb_modules_load_tests.erl \ diff --git a/test/couchdb/couchdb_cors_tests.erl b/test/couchdb/couchdb_cors_tests.erl new file mode 100644 index 000000000..4e88ae732 --- /dev/null +++ b/test/couchdb/couchdb_cors_tests.erl @@ -0,0 +1,344 @@ +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +-module(couchdb_cors_tests). + +-include("couch_eunit.hrl"). +-include_lib("couchdb/couch_db.hrl"). + + +-define(ADMIN_USER, {user_ctx, #user_ctx{roles=[<<"_admin">>]}}). +-define(SUPPORTED_METHODS, + "GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT, COPY, OPTIONS"). +-define(TIMEOUT, 1000). + + +start() -> + {ok, Pid} = couch_server_sup:start_link(?CONFIG_CHAIN), + ok = couch_config:set("httpd", "enable_cors", "true", false), + ok = couch_config:set("vhosts", "example.com", "/", false), + Pid. + +stop(Pid) -> + couch_server_sup:stop(), + erlang:monitor(process, Pid), + receive + {'DOWN', _, _, Pid, _} -> + ok + after ?TIMEOUT -> + throw({timeout, server_stop}) + end. + +setup() -> + DbName = ?tempdb(), + {ok, Db} = couch_db:create(DbName, [?ADMIN_USER]), + couch_db:close(Db), + + couch_config:set("cors", "credentials", "false", false), + couch_config:set("cors", "origins", "http://example.com", false), + + Addr = couch_config:get("httpd", "bind_address", "127.0.0.1"), + Port = integer_to_list(mochiweb_socket_server:get(couch_httpd, port)), + Host = "http://" ++ Addr ++ ":" ++ Port, + {Host, ?b2l(DbName)}. + +setup({Mod, VHost}) -> + {Host, DbName} = setup(), + Url = case Mod of + server -> + Host; + db -> + Host ++ "/" ++ DbName + end, + DefaultHeaders = [{"Origin", "http://example.com"}] + ++ maybe_append_vhost(VHost), + {Host, DbName, Url, DefaultHeaders}. + +teardown(DbName) when is_list(DbName) -> + ok = couch_server:delete(?l2b(DbName), [?ADMIN_USER]), + ok; +teardown({_, DbName}) -> + teardown(DbName). + +teardown(_, {_, DbName, _, _}) -> + teardown(DbName). + + +cors_test_() -> + Funs = [ + fun should_not_allow_origin/2, + fun should_not_allow_origin_with_port_mismatch/2, + fun should_not_allow_origin_with_scheme_mismatch/2, + fun should_not_all_origin_due_case_mismatch/2, + fun should_make_simple_request/2, + fun should_make_preflight_request/2, + fun should_make_prefligh_request_with_port/2, + fun should_make_prefligh_request_with_scheme/2, + fun should_make_prefligh_request_with_wildcard_origin/2, + fun should_make_request_with_credentials/2, + fun should_make_origin_request_with_auth/2, + fun should_make_preflight_request_with_auth/2 + ], + { + "CORS (COUCHDB-431)", + { + setup, + fun start/0, fun stop/1, + [ + cors_tests(Funs), + vhost_cors_tests(Funs), + headers_tests() + ] + } + }. + +headers_tests() -> + { + "Various headers tests", + { + foreach, + fun setup/0, fun teardown/1, + [ + fun should_not_return_cors_headers_for_invalid_origin/1, + fun should_not_return_cors_headers_for_invalid_origin_preflight/1, + fun should_make_request_against_attachment/1, + fun should_make_range_request_against_attachment/1, + fun should_make_request_with_if_none_match_header/1 + ] + } + }. + +cors_tests(Funs) -> + { + "CORS tests", + [ + make_test_case(server, false, Funs), + make_test_case(db, false, Funs) + ] + }. + +vhost_cors_tests(Funs) -> + { + "Virtual Host CORS", + [ + make_test_case(server, true, Funs), + make_test_case(db, true, Funs) + ] + }. + +make_test_case(Mod, UseVhost, Funs) -> + { + case Mod of server -> "Server"; db -> "Database" end, + {foreachx, fun setup/1, fun teardown/2, [{{Mod, UseVhost}, Fun} + || Fun <- Funs]} + }. + + +should_not_allow_origin(_, {_, _, Url, Headers0}) -> + ?_assertEqual(undefined, + begin + couch_config:delete("cors", "origins", false), + Headers1 = proplists:delete("Origin", Headers0), + Headers = [{"Origin", "http://127.0.0.1"}] + ++ Headers1, + {ok, _, Resp, _} = test_request:get(Url, Headers), + proplists:get_value("Access-Control-Allow-Origin", Resp) + end). + +should_not_allow_origin_with_port_mismatch({_, VHost}, {_, _, Url, _}) -> + ?_assertEqual(undefined, + begin + Headers = [{"Origin", "http://example.com:5984"}, + {"Access-Control-Request-Method", "GET"}] + ++ maybe_append_vhost(VHost), + {ok, _, Resp, _} = test_request:options(Url, Headers), + proplists:get_value("Access-Control-Allow-Origin", Resp) + end). + +should_not_allow_origin_with_scheme_mismatch({_, VHost}, {_, _, Url, _}) -> + ?_assertEqual(undefined, + begin + Headers = [{"Origin", "http://example.com:5984"}, + {"Access-Control-Request-Method", "GET"}] + ++ maybe_append_vhost(VHost), + {ok, _, Resp, _} = test_request:options(Url, Headers), + proplists:get_value("Access-Control-Allow-Origin", Resp) + end). + +should_not_all_origin_due_case_mismatch({_, VHost}, {_, _, Url, _}) -> + ?_assertEqual(undefined, + begin + Headers = [{"Origin", "http://ExAmPlE.CoM"}, + {"Access-Control-Request-Method", "GET"}] + ++ maybe_append_vhost(VHost), + {ok, _, Resp, _} = test_request:options(Url, Headers), + proplists:get_value("Access-Control-Allow-Origin", Resp) + end). + +should_make_simple_request(_, {_, _, Url, DefaultHeaders}) -> + ?_test(begin + {ok, _, Resp, _} = test_request:get(Url, DefaultHeaders), + ?assertEqual( + undefined, + proplists:get_value("Access-Control-Allow-Credentials", Resp)), + ?assertEqual( + "http://example.com", + proplists:get_value("Access-Control-Allow-Origin", Resp)), + ?assertEqual( + "Cache-Control, Content-Type, Server", + proplists:get_value("Access-Control-Expose-Headers", Resp)) + end). + +should_make_preflight_request(_, {_, _, Url, DefaultHeaders}) -> + ?_assertEqual(?SUPPORTED_METHODS, + begin + Headers = DefaultHeaders + ++ [{"Access-Control-Request-Method", "GET"}], + {ok, _, Resp, _} = test_request:options(Url, Headers), + proplists:get_value("Access-Control-Allow-Methods", Resp) + end). + +should_make_prefligh_request_with_port({_, VHost}, {_, _, Url, _}) -> + ?_assertEqual("http://example.com:5984", + begin + couch_config:set("cors", "origins", "http://example.com:5984", + false), + Headers = [{"Origin", "http://example.com:5984"}, + {"Access-Control-Request-Method", "GET"}] + ++ maybe_append_vhost(VHost), + {ok, _, Resp, _} = test_request:options(Url, Headers), + proplists:get_value("Access-Control-Allow-Origin", Resp) + end). + +should_make_prefligh_request_with_scheme({_, VHost}, {_, _, Url, _}) -> + ?_assertEqual("https://example.com:5984", + begin + couch_config:set("cors", "origins", "https://example.com:5984", + false), + Headers = [{"Origin", "https://example.com:5984"}, + {"Access-Control-Request-Method", "GET"}] + ++ maybe_append_vhost(VHost), + {ok, _, Resp, _} = test_request:options(Url, Headers), + proplists:get_value("Access-Control-Allow-Origin", Resp) + end). + +should_make_prefligh_request_with_wildcard_origin({_, VHost}, {_, _, Url, _}) -> + ?_assertEqual("https://example.com:5984", + begin + couch_config:set("cors", "origins", "*", false), + Headers = [{"Origin", "https://example.com:5984"}, + {"Access-Control-Request-Method", "GET"}] + ++ maybe_append_vhost(VHost), + {ok, _, Resp, _} = test_request:options(Url, Headers), + proplists:get_value("Access-Control-Allow-Origin", Resp) + end). + +should_make_request_with_credentials(_, {_, _, Url, DefaultHeaders}) -> + ?_assertEqual("true", + begin + ok = couch_config:set("cors", "credentials", "true", false), + {ok, _, Resp, _} = test_request:options(Url, DefaultHeaders), + proplists:get_value("Access-Control-Allow-Credentials", Resp) + end). + +should_make_origin_request_with_auth(_, {_, _, Url, DefaultHeaders}) -> + ?_assertEqual("http://example.com", + begin + Hashed = couch_passwords:hash_admin_password(<<"test">>), + couch_config:set("admins", "test", Hashed, false), + {ok, _, Resp, _} = test_request:get( + Url, DefaultHeaders, [{basic_auth, {"test", "test"}}]), + couch_config:delete("admins", "test", false), + proplists:get_value("Access-Control-Allow-Origin", Resp) + end). + +should_make_preflight_request_with_auth(_, {_, _, Url, DefaultHeaders}) -> + ?_assertEqual(?SUPPORTED_METHODS, + begin + Hashed = couch_passwords:hash_admin_password(<<"test">>), + couch_config:set("admins", "test", Hashed, false), + Headers = DefaultHeaders + ++ [{"Access-Control-Request-Method", "GET"}], + {ok, _, Resp, _} = test_request:options( + Url, Headers, [{basic_auth, {"test", "test"}}]), + couch_config:delete("admins", "test", false), + proplists:get_value("Access-Control-Allow-Methods", Resp) + end). + +should_not_return_cors_headers_for_invalid_origin({Host, _}) -> + ?_assertEqual(undefined, + begin + Headers = [{"Origin", "http://127.0.0.1"}], + {ok, _, Resp, _} = test_request:get(Host, Headers), + proplists:get_value("Access-Control-Allow-Origin", Resp) + end). + +should_not_return_cors_headers_for_invalid_origin_preflight({Host, _}) -> + ?_assertEqual(undefined, + begin + Headers = [{"Origin", "http://127.0.0.1"}, + {"Access-Control-Request-Method", "GET"}], + {ok, _, Resp, _} = test_request:options(Host, Headers), + proplists:get_value("Access-Control-Allow-Origin", Resp) + end). + +should_make_request_against_attachment({Host, DbName}) -> + {"COUCHDB-1689", + ?_assertEqual(200, + begin + Url = Host ++ "/" ++ DbName, + {ok, Code0, _, _} = test_request:put( + Url ++ "/doc/file.txt", [{"Content-Type", "text/plain"}], + "hello, couch!"), + ?assert(Code0 =:= 201), + {ok, Code, _, _} = test_request:get( + Url ++ "/doc?attachments=true", + [{"Origin", "http://example.com"}]), + Code + end)}. + +should_make_range_request_against_attachment({Host, DbName}) -> + {"COUCHDB-1689", + ?_assertEqual(206, + begin + Url = Host ++ "/" ++ DbName, + {ok, Code0, _, _} = test_request:put( + Url ++ "/doc/file.txt", + [{"Content-Type", "application/octet-stream"}], + "hello, couch!"), + ?assert(Code0 =:= 201), + {ok, Code, _, _} = test_request:get( + Url ++ "/doc/file.txt", [{"Origin", "http://example.com"}, + {"Range", "bytes=0-6"}]), + Code + end)}. + +should_make_request_with_if_none_match_header({Host, DbName}) -> + {"COUCHDB-1697", + ?_assertEqual(304, + begin + Url = Host ++ "/" ++ DbName, + {ok, Code0, Headers0, _} = test_request:put( + Url ++ "/doc", [{"Content-Type", "application/json"}], "{}"), + ?assert(Code0 =:= 201), + ETag = proplists:get_value("ETag", Headers0), + {ok, Code, _, _} = test_request:get( + Url ++ "/doc", [{"Origin", "http://example.com"}, + {"If-None-Match", ETag}]), + Code + end)}. + + +maybe_append_vhost(true) -> + [{"Host", "http://example.com"}]; +maybe_append_vhost(false) -> + []. diff --git a/test/couchdb/test_request.erl b/test/couchdb/test_request.erl index 36871b4f7..68e495698 100644 --- a/test/couchdb/test_request.erl +++ b/test/couchdb/test_request.erl @@ -12,7 +12,9 @@ -module(test_request). --export([get/1, get/2, get/3, put/2, put/3]). +-export([get/1, get/2, get/3]). +-export([put/2, put/3]). +-export([options/1, options/2, options/3]). -export([request/3, request/4]). get(Url) -> @@ -31,6 +33,16 @@ put(Url, Headers, Body) -> request(put, Url, Headers, Body). +options(Url) -> + request(options, Url, []). + +options(Url, Headers) -> + request(options, Url, Headers). + +options(Url, Headers, Opts) -> + request(options, Url, Headers, [], Opts). + + request(Method, Url, Headers) -> request(Method, Url, Headers, []). diff --git a/test/etap/231-cors.t b/test/etap/231-cors.t deleted file mode 100644 index 2f420d1c4..000000000 --- a/test/etap/231-cors.t +++ /dev/null @@ -1,430 +0,0 @@ -#!/usr/bin/env escript -%% -*- erlang -*- - -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - --record(user_ctx, { - name = null, - roles = [], - handler -}). - - --define(SUPPORTED_METHODS, "GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT, COPY, OPTIONS"). -server() -> - lists:concat([ - "http://127.0.0.1:", - mochiweb_socket_server:get(couch_httpd, port), - "/" - ]). - - -main(_) -> - test_util:init_code_path(), - - etap:plan(29), - case (catch test()) of - ok -> - etap:end_tests(); - Other -> - etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), - etap:bail(Other) - end, - ok. - -dbname() -> "etap-test-db". -dbname1() -> "etap-test-db1". -dbname2() -> "etap-test-db2". - -admin_user_ctx() -> {user_ctx, #user_ctx{roles=[<<"_admin">>]}}. - -set_admin_password(UserName, Password) -> - Hashed = couch_passwords:hash_admin_password(Password), - couch_config:set("admins", UserName, Hashed, false). - -cycle_db(DbName) -> - couch_server:delete(list_to_binary(DbName), [admin_user_ctx()]), - {ok, Db} = couch_db:create(list_to_binary(DbName), [admin_user_ctx()]), - Db. - -test() -> - %% launch couchdb - couch_server_sup:start_link(test_util:config_files()), - - %% initialize db - timer:sleep(1000), - Db = cycle_db(dbname()), - Db1 = cycle_db(dbname1()), - Db2 = cycle_db(dbname2()), - - % CORS is disabled by default - test_no_headers_server(), - test_no_headers_db(), - - % Now enable CORS - ok = couch_config:set("httpd", "enable_cors", "true", false), - ok = couch_config:set("cors", "origins", "http://example.com", false), - - %% do tests - test_incorrect_origin_simple_request(), - test_incorrect_origin_preflight_request(), - - test_preflight_request(), - test_db_request(), - test_doc_with_attachment_request(), - test_doc_with_attachment_range_request(), - test_db_preflight_request(), - test_db1_origin_request(), - test_preflight_with_port1(), - test_preflight_with_scheme1(), - test_if_none_match_header(), - - ok = couch_config:set("cors", "origins", "http://example.com:5984", false), - test_preflight_with_port2(), - - ok = couch_config:set("cors", "origins", "https://example.com:5984", false), - test_preflight_with_scheme2(), - - ok = couch_config:set("cors", "origins", "*", false), - test_preflight_with_wildcard(), - - ok = couch_config:set("cors", "origins", "http://example.com", false), - test_case_sensitive_mismatch_of_allowed_origins(), - - % http://www.w3.org/TR/cors/#supports-credentials - % 6.1.3 - % If the resource supports credentials add a single - % Access-Control-Allow-Origin header, with the value - % of the Origin header as value, and add a single - % Access-Control-Allow-Credentials header with the - % case-sensitive string "true" as value. - % Otherwise, add a single Access-Control-Allow-Origin - % header, with either the value of the Origin header - % or the string "*" as value. - % Note: The string "*" cannot be used for a resource - % that supports credentials. - test_db_request_credentials_header_off(), - ok = couch_config:set("cors", "credentials", "true", false), - test_db_request_credentials_header_on(), - % We don’t test wildcards & credentials as that would - % fall into the realm of validating config values - % which we don’t do at all yet - - % test with vhosts - ok = couch_config:set("vhosts", "example.com", "/", false), - test_preflight_request(true), - test_db_request(true), - test_db_preflight_request(true), - test_db1_origin_request(true), - test_preflight_with_port1(true), - test_preflight_with_scheme1(true), - - % TBD - % test multiple per-host configuration - - %% do tests with auth - ok = set_admin_password("test", <<"test">>), - - test_db_preflight_auth_request(), - test_db_origin_auth_request(), - - - %% restart boilerplate - catch couch_db:close(Db), - catch couch_db:close(Db1), - catch couch_db:close(Db2), - - couch_server:delete(list_to_binary(dbname()), [admin_user_ctx()]), - couch_server:delete(list_to_binary(dbname1()), [admin_user_ctx()]), - couch_server:delete(list_to_binary(dbname2()), [admin_user_ctx()]), - - timer:sleep(3000), - couch_server_sup:stop(), - ok. - -test_preflight_request() -> test_preflight_request(false). -test_db_request() -> test_db_request(false). -test_db_preflight_request() -> test_db_preflight_request(false). -test_db1_origin_request() -> test_db1_origin_request(false). -test_preflight_with_port1() -> test_preflight_with_port1(false). -test_preflight_with_scheme1() -> test_preflight_with_scheme1(false). - -%% Cors is disabled, should not return Access-Control-Allow-Origin -test_no_headers_server() -> - Headers = [{"Origin", "http://127.0.0.1"}], - {ok, _, Resp, _} = ibrowse:send_req(server(), Headers, get, []), - etap:is(proplists:get_value("Access-Control-Allow-Origin", Resp), - undefined, "No CORS Headers when disabled"). - -%% Cors is disabled, should not return Access-Control-Allow-Origin -test_no_headers_db() -> - Headers = [{"Origin", "http://127.0.0.1"}], - Url = server() ++ "etap-test-db", - {ok, _, Resp, _} = ibrowse:send_req(Url, Headers, get, []), - etap:is(proplists:get_value("Access-Control-Allow-Origin", Resp), - undefined, "No CORS Headers when disabled"). - -test_incorrect_origin_simple_request() -> - Headers = [{"Origin", "http://127.0.0.1"}], - {ok, _, RespHeaders, _} = ibrowse:send_req(server(), Headers, get, []), - etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders), - undefined, - "Specified invalid origin, no Access"). - -test_incorrect_origin_preflight_request() -> - Headers = [{"Origin", "http://127.0.0.1"}, - {"Access-Control-Request-Method", "GET"}], - {ok, _, RespHeaders, _} = ibrowse:send_req(server(), Headers, options, []), - etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders), - undefined, - "invalid origin"). - -test_preflight_request(VHost) -> - Headers = [{"Origin", "http://example.com"}, - {"Access-Control-Request-Method", "GET"}] - ++ maybe_append_vhost(VHost), - - case ibrowse:send_req(server(), Headers, options, []) of - {ok, _, RespHeaders, _} -> - etap:is(proplists:get_value("Access-Control-Allow-Methods", RespHeaders), - ?SUPPORTED_METHODS, - "test_preflight_request Access-Control-Allow-Methods ok"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -test_db_request(VHost) -> - Headers = [{"Origin", "http://example.com"}] - ++ maybe_append_vhost(VHost), - Url = server() ++ "etap-test-db", - case ibrowse:send_req(Url, Headers, get, []) of - {ok, _, RespHeaders, _Body} -> - etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders), - "http://example.com", - "db Access-Control-Allow-Origin ok"), - etap:is(proplists:get_value("Access-Control-Expose-Headers", RespHeaders), - "Cache-Control, Content-Type, Server", - "db Access-Control-Expose-Headers ok"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -% COUCHDB-1689 -test_doc_with_attachment_request() -> - DocUrl = server() ++ "etap-test-db/doc1", - ibrowse:send_req(DocUrl ++ "/attachment.txt", - [{"Content-Type", "text/plain"}], put, "this is a text attachment"), - - Headers = [{"Origin", "http://example.com"}], - Url = DocUrl ++ "?attachments=true", - case ibrowse:send_req(Url, Headers, get, []) of - {ok, Code, _RespHeaders, _Body} -> - etap:is(Code, "200", "Response without errors"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -% COUCHDB-1689 -test_doc_with_attachment_range_request() -> - AttachmentUrl = server() ++ "etap-test-db/doc2/attachment.bin", - % Use a Content-Type that doesn't get compressed - ibrowse:send_req(AttachmentUrl, - [{"Content-Type", "application/octet-stream"}], put, - "this is an attachment"), - - Headers = [{"Origin", "http://example.com"}, {"Range", "bytes=0-6"}], - case ibrowse:send_req(AttachmentUrl, Headers, get, []) of - {ok, Code, _RespHeaders, _Body} -> - etap:is(Code, "206", "Response without errors"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -% COUCHDB-1697 -test_if_none_match_header() -> - Url = server() ++ "etap-test-db/doc2", - Headers = [{"Origin", "http://example.com"}], - {ok, _, _RespHeaders, _} = ibrowse:send_req(Url, Headers, get, []), - ETag = proplists:get_value("ETag", _RespHeaders), - Headers2 = [{"Origin", "http://example.com"}, {"If-None-Match", ETag}], - case ibrowse:send_req(Url, Headers2, get, []) of - {ok, Code, _RespHeaders2, _} -> - etap:is(Code, "304", "Responded with Not Modified"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -test_db_request_credentials_header_off() -> - Headers = [{"Origin", "http://example.com"}], - Url = server() ++ "etap-test-db", - case ibrowse:send_req(Url, Headers, get, []) of - {ok, _, RespHeaders, _Body} -> - etap:is(proplists:get_value("Access-Control-Allow-Credentials", RespHeaders), - undefined, - "db Access-Control-Allow-Credentials off"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -test_db_request_credentials_header_on() -> - Headers = [{"Origin", "http://example.com"}], - Url = server() ++ "etap-test-db", - case ibrowse:send_req(Url, Headers, get, []) of - {ok, _, RespHeaders, _Body} -> - etap:is(proplists:get_value("Access-Control-Allow-Credentials", RespHeaders), - "true", - "db Access-Control-Allow-Credentials ok"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -test_db_preflight_request(VHost) -> - Url = server() ++ "etap-test-db", - Headers = [{"Origin", "http://example.com"}, - {"Access-Control-Request-Method", "GET"}] - ++ maybe_append_vhost(VHost), - case ibrowse:send_req(Url, Headers, options, []) of - {ok, _, RespHeaders, _} -> - etap:is(proplists:get_value("Access-Control-Allow-Methods", RespHeaders), - ?SUPPORTED_METHODS, - "db Access-Control-Allow-Methods ok"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - - -test_db1_origin_request(VHost) -> - Headers = [{"Origin", "http://example.com"}] - ++ maybe_append_vhost(VHost), - Url = server() ++ "etap-test-db1", - case ibrowse:send_req(Url, Headers, get, [], [{host_header, "example.com"}]) of - {ok, _, RespHeaders, _Body} -> - etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders), - "http://example.com", - "db origin ok"); - _Else -> - io:format("else ~p~n", [_Else]), - etap:is(false, true, "ibrowse failed") - end. - -test_db_preflight_auth_request() -> - Url = server() ++ "etap-test-db2", - Headers = [{"Origin", "http://example.com"}, - {"Access-Control-Request-Method", "GET"}], - case ibrowse:send_req(Url, Headers, options, []) of - {ok, _Status, RespHeaders, _} -> - etap:is(proplists:get_value("Access-Control-Allow-Methods", RespHeaders), - ?SUPPORTED_METHODS, - "db Access-Control-Allow-Methods ok"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - - -test_db_origin_auth_request() -> - Headers = [{"Origin", "http://example.com"}], - Url = server() ++ "etap-test-db2", - - case ibrowse:send_req(Url, Headers, get, [], - [{basic_auth, {"test", "test"}}]) of - {ok, _, RespHeaders, _Body} -> - etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders), - "http://example.com", - "db origin ok"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -test_preflight_with_wildcard() -> - Headers = [{"Origin", "http://example.com"}, - {"Access-Control-Request-Method", "GET"}], - case ibrowse:send_req(server(), Headers, options, []) of - {ok, _, RespHeaders, _} -> - % I would either expect the current origin or a wildcard to be returned - etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders), - "http://example.com", - "db origin ok"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -test_preflight_with_port1(VHost) -> - Headers = [{"Origin", "http://example.com:5984"}, - {"Access-Control-Request-Method", "GET"}] - ++ maybe_append_vhost(VHost), - case ibrowse:send_req(server(), Headers, options, []) of - {ok, _, RespHeaders, _} -> - % I would either expect the current origin or a wildcard to be returned - etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders), - undefined, - "check non defined host:port in origin ok"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -test_preflight_with_port2() -> - Headers = [{"Origin", "http://example.com:5984"}, - {"Access-Control-Request-Method", "GET"}], - case ibrowse:send_req(server(), Headers, options, []) of - {ok, _, RespHeaders, _} -> - % I would either expect the current origin or a wildcard to be returned - etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders), - "http://example.com:5984", - "check host:port in origin ok"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -test_preflight_with_scheme1(VHost) -> - Headers = [{"Origin", "https://example.com:5984"}, - {"Access-Control-Request-Method", "GET"}] - ++ maybe_append_vhost(VHost), - case ibrowse:send_req(server(), Headers, options, []) of - {ok, _, RespHeaders, _} -> - % I would either expect the current origin or a wildcard to be returned - etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders), - undefined, - "check non defined scheme in origin ok"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -test_preflight_with_scheme2() -> - Headers = [{"Origin", "https://example.com:5984"}, - {"Access-Control-Request-Method", "GET"}], - case ibrowse:send_req(server(), Headers, options, []) of - {ok, _, RespHeaders, _} -> - % I would either expect the current origin or a wildcard to be returned - etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders), - "https://example.com:5984", - "check scheme in origin ok"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -test_case_sensitive_mismatch_of_allowed_origins() -> - Headers = [{"Origin", "http://EXAMPLE.COM"}], - Url = server() ++ "etap-test-db", - case ibrowse:send_req(Url, Headers, get, []) of - {ok, _, RespHeaders, _Body} -> - etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders), - undefined, - "db access config case mismatch"); - _ -> - etap:is(false, true, "ibrowse failed") - end. - -maybe_append_vhost(true) -> - [{"Host", "http://example.com"}]; -maybe_append_vhost(Else) -> - []. diff --git a/test/etap/Makefile.am b/test/etap/Makefile.am index a6ff3682c..743f90f08 100644 --- a/test/etap/Makefile.am +++ b/test/etap/Makefile.am @@ -32,7 +32,6 @@ fixture_files = \ fixtures/test.couch tap_files = \ - 231-cors.t \ 250-upgrade-legacy-view-files.t EXTRA_DIST = \ |