Add CORS support
Two new options: cors_allow_origins and cors_max_age. * cors_allow_origins: list of origins allowed, for example ["http://rabbitmq.com", "http://pivotal.com"]; or ["*"] to allow everything. * cors_max_age: time in seconds that clients may cache preflight requests. It defaults to 30 minutes.
This commit is contained in:
		
							parent
							
								
									f15b26a961
								
							
						
					
					
						commit
						1ae44f86a2
					
				|  | @ -0,0 +1,88 @@ | |||
| %%   The contents of this file are subject to the Mozilla Public License | ||||
| %%   Version 1.1 (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.mozilla.org/MPL/ | ||||
| %% | ||||
| %%   Software distributed under the License is distributed on an "AS IS" | ||||
| %%   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the | ||||
| %%   License for the specific language governing rights and limitations | ||||
| %%   under the License. | ||||
| %% | ||||
| %%   The Original Code is RabbitMQ Management Plugin. | ||||
| %% | ||||
| %%   The Initial Developer of the Original Code is GoPivotal, Inc. | ||||
| %%   Copyright (c) 2007-2016 Pivotal Software, Inc.  All rights reserved. | ||||
| %% | ||||
| 
 | ||||
| %% Useful documentation about CORS: | ||||
| %% * https://tools.ietf.org/html/rfc6454 | ||||
| %% * https://www.w3.org/TR/cors/ | ||||
| %% * https://staticapps.org/articles/cross-domain-requests-with-cors/ | ||||
| -module(rabbit_mgmt_cors). | ||||
| 
 | ||||
| -export([set_headers/2]). | ||||
| 
 | ||||
| %% We don't set access-control-max-age because we currently have | ||||
| %% no way to know which headers apply to the whole resource. We | ||||
| %% only know for the next request. | ||||
| set_headers(ReqData, Module) -> | ||||
|     ReqData1 = case wrq:get_resp_header("vary", ReqData) of | ||||
|         undefined -> wrq:set_resp_header("vary", "origin", ReqData); | ||||
|         VaryValue -> wrq:set_resp_header("vary", VaryValue ++ ", origin", ReqData) | ||||
|     end, | ||||
|     case match_origin(ReqData1) of | ||||
|         false -> | ||||
|             ReqData1; | ||||
|         Origin -> | ||||
|             ReqData2 = case wrq:method(ReqData1) of | ||||
|                 'OPTIONS' -> handle_options(ReqData1, Module); | ||||
|                 _         -> ReqData1 | ||||
|             end, | ||||
|             wrq:set_resp_headers([ | ||||
|                 {"access-control-allow-origin",      Origin}, | ||||
|                 {"access-control-allow-credentials", "true"} | ||||
|             ], ReqData2) | ||||
|     end. | ||||
| 
 | ||||
| %% Set max-age from configuration (default: 30 minutes). | ||||
| %% Set allow-methods from what is defined in Module:allowed_methods/2. | ||||
| %% Set allow-headers to the same as the request (accept all headers). | ||||
| handle_options(ReqData, Module) -> | ||||
|     MaxAge = application:get_env(rabbitmq_management, cors_max_age, 1800), | ||||
|     {Methods, _, _} = Module:allowed_methods(undefined, undefined), | ||||
|     AllowMethods = string:join([atom_to_list(M) || M <- Methods], ", "), | ||||
|     ReqHeaders = wrq:get_req_header("access-control-request-headers", ReqData), | ||||
|     MaxAgeHd = case MaxAge of | ||||
|         undefined -> []; | ||||
|         _ -> {"access-control-max-age", integer_to_list(MaxAge)} | ||||
|     end, | ||||
|     MaybeAllowHeaders = case ReqHeaders of | ||||
|         undefined -> []; | ||||
|         _ -> [{"access-control-allow-headers", ReqHeaders}] | ||||
|     end, | ||||
|     wrq:set_resp_headers([MaxAgeHd, | ||||
|         {"access-control-allow-methods", AllowMethods} | ||||
|         |MaybeAllowHeaders], ReqData). | ||||
| 
 | ||||
| %% If the origin header is missing or "null", we disable CORS. | ||||
| %% Otherwise, we only enable it if the origin is found in the | ||||
| %% cors_allow_origins configuration variable, or if "*" is (it | ||||
| %% allows all origins). | ||||
| match_origin(ReqData) -> | ||||
|     case wrq:get_req_header("origin", ReqData) of | ||||
|         undefined -> false; | ||||
|         "null" -> false; | ||||
|         Origin -> | ||||
|             AllowedOrigins = application:get_env(rabbitmq_management, | ||||
|                 cors_allow_origins, []), | ||||
|             case lists:member(Origin, AllowedOrigins) of | ||||
|                 true -> | ||||
|                     Origin; | ||||
|                 false -> | ||||
|                     %% Maybe the configuration explicitly allows "*". | ||||
|                     case lists:member("*", AllowedOrigins) of | ||||
|                         true  -> Origin; | ||||
|                         false -> false | ||||
|                     end | ||||
|             end | ||||
|     end. | ||||
|  | @ -17,6 +17,7 @@ | |||
| -module(rabbit_mgmt_wm_aliveness_test). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| -export([resource_exists/2]). | ||||
| 
 | ||||
|  | @ -30,6 +31,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
|          content_types_provided/2, content_types_accepted/2, | ||||
|          is_authorized/2, allowed_methods/2, delete_resource/2, | ||||
|          args_hash/1]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -29,6 +30,9 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -40,7 +44,7 @@ content_types_accepted(ReqData, Context) -> | |||
|    {[{"application/json", accept_content}], ReqData, Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'DELETE'], ReqData, Context}. | ||||
|     {['HEAD', 'GET', 'DELETE', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| resource_exists(ReqData, Context) -> | ||||
|     Binding = binding(ReqData), | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
| -export([allowed_methods/2, post_is_create/2, create_path/2]). | ||||
| -export([content_types_accepted/2, accept_content/2, resource_exists/2]). | ||||
| -export([basic/1, augmented/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -31,6 +32,9 @@ | |||
| init([Mode]) -> | ||||
|     {ok, {Mode, #context{}}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -49,8 +53,8 @@ content_types_accepted(ReqData, Context) -> | |||
| 
 | ||||
| allowed_methods(ReqData, {Mode, Context}) -> | ||||
|     {case Mode of | ||||
|          source_destination -> ['HEAD', 'GET', 'POST']; | ||||
|          _                  -> ['HEAD', 'GET'] | ||||
|          source_destination -> ['HEAD', 'GET', 'POST', 'OPTIONS']; | ||||
|          _                  -> ['HEAD', 'GET', 'OPTIONS'] | ||||
|      end, ReqData, {Mode, Context}}. | ||||
| 
 | ||||
| post_is_create(ReqData, Context) -> | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| -module(rabbit_mgmt_wm_channel). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| -export([resource_exists/2]). | ||||
| 
 | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2, | ||||
|          augmented/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -import(rabbit_misc, [pget/2]). | ||||
|  | @ -30,6 +31,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2, | ||||
|          augmented/2, resource_exists/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -import(rabbit_misc, [pget/2]). | ||||
|  | @ -32,6 +33,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ | |||
| -export([init/1, resource_exists/2, to_json/2, | ||||
|          content_types_provided/2, content_types_accepted/2, | ||||
|          is_authorized/2, allowed_methods/2, accept_content/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -28,6 +29,9 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -39,7 +43,7 @@ content_types_accepted(ReqData, Context) -> | |||
|    {[{"application/json", accept_content}], ReqData, Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'PUT'], ReqData, Context}. | ||||
|     {['HEAD', 'GET', 'PUT', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| resource_exists(ReqData, Context) -> | ||||
|     {true, ReqData, Context}. | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, resource_exists/2, to_json/2, content_types_provided/2, | ||||
|          is_authorized/2, allowed_methods/2, delete_resource/2, conn/1]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -28,6 +29,9 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -36,7 +40,7 @@ encodings_provided(ReqData, Context) -> | |||
|      {"gzip", fun(X) -> zlib:gzip(X) end}], ReqData, Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'DELETE'], ReqData, Context}. | ||||
|     {['HEAD', 'GET', 'DELETE', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| resource_exists(ReqData, Context) -> | ||||
|     case conn(ReqData) of | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| -module(rabbit_mgmt_wm_connection_channels). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| -export([resource_exists/2]). | ||||
| 
 | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2, | ||||
|          augmented/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -import(rabbit_misc, [pget/2]). | ||||
|  | @ -30,6 +31,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2, | ||||
|          augmented/2, resource_exists/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -import(rabbit_misc, [pget/2]). | ||||
|  | @ -32,6 +33,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, resource_exists/2, | ||||
|          is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -import(rabbit_misc, [pget/2]). | ||||
|  | @ -29,6 +30,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ | |||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([content_types_accepted/2, allowed_methods/2, accept_json/2]). | ||||
| -export([post_is_create/2, create_path/2, accept_multipart/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -export([apply_defs/3]). | ||||
|  | @ -32,6 +33,9 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -44,7 +48,7 @@ content_types_accepted(ReqData, Context) -> | |||
|      {"multipart/form-data", accept_multipart}], ReqData, Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'POST'], ReqData, Context}. | ||||
|     {['HEAD', 'GET', 'POST', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| post_is_create(ReqData, Context) -> | ||||
|     {true, ReqData, Context}. | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
|          content_types_provided/2, content_types_accepted/2, | ||||
|          is_authorized/2, allowed_methods/2, accept_content/2, | ||||
|          delete_resource/2, exchange/1, exchange/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -29,6 +30,9 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -40,7 +44,7 @@ content_types_accepted(ReqData, Context) -> | |||
|    {[{"application/json", accept_content}], ReqData, Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE'], ReqData, Context}. | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| resource_exists(ReqData, Context) -> | ||||
|     {case exchange(ReqData) of | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, resource_exists/2, post_is_create/2, is_authorized/2, | ||||
|          allowed_methods/2,  content_types_provided/2, process_post/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -27,8 +28,11 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['POST'], ReqData, Context}. | ||||
|     {['POST', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2, | ||||
|          resource_exists/2, basic/1, augmented/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| -module(rabbit_mgmt_wm_extensions). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -26,6 +27,12 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ | |||
| -module(rabbit_mgmt_wm_healthchecks). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| -export([resource_exists/2]). | ||||
| 
 | ||||
|  | @ -26,6 +27,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| -module(rabbit_mgmt_wm_node). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| -export([resource_exists/2]). | ||||
| 
 | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| -module(rabbit_mgmt_wm_nodes). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([all_nodes/1, all_nodes_raw/0]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| -module(rabbit_mgmt_wm_overview). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -import(rabbit_misc, [pget/2, pget/3]). | ||||
|  | @ -29,6 +30,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, ?MODULE), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
|          content_types_provided/2, content_types_accepted/2, | ||||
|          is_authorized/2, allowed_methods/2, accept_content/2, | ||||
|          delete_resource/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -import(rabbit_misc, [pget/2]). | ||||
|  | @ -32,6 +33,9 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -43,7 +47,7 @@ content_types_accepted(ReqData, Context) -> | |||
|    {[{"application/json", accept_content}], ReqData, Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE'], ReqData, Context}. | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| resource_exists(ReqData, Context) -> | ||||
|     {case parameter(ReqData) of | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2, | ||||
|          resource_exists/2, basic/1]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
|          content_types_provided/2, content_types_accepted/2, | ||||
|          is_authorized/2, allowed_methods/2, accept_content/2, | ||||
|          delete_resource/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -29,6 +30,9 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -40,7 +44,7 @@ content_types_accepted(ReqData, Context) -> | |||
|    {[{"application/json", accept_content}], ReqData, Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE'], ReqData, Context}. | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| resource_exists(ReqData, Context) -> | ||||
|     {case perms(ReqData) of | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| -module(rabbit_mgmt_wm_permissions). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([permissions/0]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, resource_exists/2, | ||||
|          is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, resource_exists/2, | ||||
|          is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2, | ||||
|          resource_exists/2, basic/1]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
|          content_types_provided/2, content_types_accepted/2, | ||||
|          is_authorized/2, allowed_methods/2, accept_content/2, | ||||
|          delete_resource/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -import(rabbit_misc, [pget/2]). | ||||
|  | @ -32,6 +33,9 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -43,7 +47,7 @@ content_types_accepted(ReqData, Context) -> | |||
|    {[{"application/json", accept_content}], ReqData, Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE'], ReqData, Context}. | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| resource_exists(ReqData, Context) -> | ||||
|     {case policy(ReqData) of | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
|          content_types_provided/2, content_types_accepted/2, | ||||
|          is_authorized/2, allowed_methods/2, accept_content/2, | ||||
|          delete_resource/2, queue/1, queue/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -29,6 +30,9 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -40,7 +44,7 @@ content_types_accepted(ReqData, Context) -> | |||
|    {[{"application/json", accept_content}], ReqData, Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE'], ReqData, Context}. | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| resource_exists(ReqData, Context) -> | ||||
|     {case queue(ReqData) of | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, resource_exists/2, post_is_create/2, is_authorized/2, | ||||
|          allowed_methods/2, process_post/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -28,8 +29,11 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['POST'], ReqData, Context}. | ||||
|     {['POST', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| encodings_provided(ReqData, Context) -> | ||||
|     {[{"identity", fun(X) -> X end}, | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, resource_exists/2, post_is_create/2, is_authorized/2, | ||||
|   allowed_methods/2, process_post/2, content_types_provided/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -28,8 +29,11 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['POST'], ReqData, Context}. | ||||
|     {['POST', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, resource_exists/2, is_authorized/2, allowed_methods/2, | ||||
|          delete_resource/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -27,8 +28,11 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['DELETE'], ReqData, Context}. | ||||
|     {['DELETE', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| encodings_provided(ReqData, Context) -> | ||||
|     {[{"identity", fun(X) -> X end}, | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2, | ||||
|          resource_exists/2, basic/1, augmented/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
|          content_types_provided/2, content_types_accepted/2, | ||||
|          is_authorized/2, allowed_methods/2, accept_content/2, | ||||
|          delete_resource/2, user/1, put_user/1, put_user/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -import(rabbit_misc, [pget/2]). | ||||
|  | @ -31,6 +32,9 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -42,7 +46,7 @@ content_types_accepted(ReqData, Context) -> | |||
|    {[{"application/json", accept_content}], ReqData, Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE'], ReqData, Context}. | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| resource_exists(ReqData, Context) -> | ||||
|     {case user(ReqData) of | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| -module(rabbit_mgmt_wm_users). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| -export([users/0]). | ||||
| 
 | ||||
|  | @ -30,6 +31,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
|          content_types_provided/2, content_types_accepted/2, | ||||
|          is_authorized/2, allowed_methods/2, accept_content/2, | ||||
|          delete_resource/2, id/1, put_vhost/2]). | ||||
| -export([finish_request/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -import(rabbit_misc, [pget/2]). | ||||
|  | @ -31,6 +32,9 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  | @ -42,7 +46,7 @@ content_types_accepted(ReqData, Context) -> | |||
|    {[{"application/json", accept_content}], ReqData, Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE'], ReqData, Context}. | ||||
|     {['HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| resource_exists(ReqData, Context) -> | ||||
|     {rabbit_vhost:exists(id(ReqData)), ReqData, Context}. | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| -module(rabbit_mgmt_wm_vhosts). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| -export([basic/0, augmented/2]). | ||||
| 
 | ||||
|  | @ -28,6 +29,12 @@ | |||
| 
 | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| -module(rabbit_mgmt_wm_whoami). | ||||
| 
 | ||||
| -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). | ||||
| -export([finish_request/2, allowed_methods/2]). | ||||
| -export([encodings_provided/2]). | ||||
| 
 | ||||
| -include("rabbit_mgmt.hrl"). | ||||
|  | @ -26,6 +27,12 @@ | |||
| %%-------------------------------------------------------------------- | ||||
| init(_Config) -> {ok, #context{}}. | ||||
| 
 | ||||
| finish_request(ReqData, Context) -> | ||||
|     {ok, rabbit_mgmt_cors:set_headers(ReqData, Context), Context}. | ||||
| 
 | ||||
| allowed_methods(ReqData, Context) -> | ||||
|     {['HEAD', 'GET', 'OPTIONS'], ReqData, Context}. | ||||
| 
 | ||||
| content_types_provided(ReqData, Context) -> | ||||
|    {[{"application/json", to_json}], ReqData, Context}. | ||||
| 
 | ||||
|  |  | |||
|  | @ -12,7 +12,9 @@ | |||
|           %% List of {MaxAgeInSeconds, SampleEveryNSeconds} | ||||
|           [{global,   [{605, 5}, {3660, 60}, {29400, 600}, {86400, 1800}]}, | ||||
|            {basic,    [{605, 5}, {3600, 60}]}, | ||||
|            {detailed, [{10, 5}]}]} | ||||
|            {detailed, [{10, 5}]}]}, | ||||
|          {cors_allow_origins, []}, | ||||
|          {cors_max_age, 1800} | ||||
|         ]}, | ||||
|   {applications, [kernel, stdlib, rabbit, xmerl, rabbitmq_web_dispatch, | ||||
|                   amqp_client, rabbitmq_management_agent]}]}. | ||||
|  |  | |||
|  | @ -23,6 +23,48 @@ | |||
| -import(rabbit_mgmt_test_util, [assert_list/2, assert_item/2, test_item/2]). | ||||
| -import(rabbit_misc, [pget/2]). | ||||
| 
 | ||||
| cors_test() -> | ||||
|     %% With CORS disabled. No header should be received. | ||||
|     {ok, {_, HdNoCORS, _}} = req(get, "/overview", [auth_header("guest", "guest")]), | ||||
|     false = lists:keymember("access-control-allow-origin", 1, HdNoCORS), | ||||
|     %% The Vary header should include "Origin" regardless of CORS configuration. | ||||
|     {_, "Accept-Encoding, origin"} = lists:keyfind("vary", 1, HdNoCORS), | ||||
|     %% Enable CORS. | ||||
|     application:set_env(rabbitmq_management, cors_allow_origins, ["http://rabbitmq.com"]), | ||||
|     %% We should only receive allow-origin and allow-credentials from GET. | ||||
|     {ok, {_, HdGetCORS, _}} = req(get, "/overview", | ||||
|         [{"origin", "http://rabbitmq.com"}, auth_header("guest", "guest")]), | ||||
|     true = lists:keymember("access-control-allow-origin", 1, HdGetCORS), | ||||
|     true = lists:keymember("access-control-allow-credentials", 1, HdGetCORS), | ||||
|     false = lists:keymember("access-control-expose-headers", 1, HdGetCORS), | ||||
|     false = lists:keymember("access-control-max-age", 1, HdGetCORS), | ||||
|     false = lists:keymember("access-control-allow-methods", 1, HdGetCORS), | ||||
|     false = lists:keymember("access-control-allow-headers", 1, HdGetCORS), | ||||
|     %% We should receive allow-origin, allow-credentials and allow-methods from OPTIONS. | ||||
|     {ok, {_, HdOptionsCORS, _}} = req(options, "/overview", | ||||
|         [{"origin", "http://rabbitmq.com"}, auth_header("guest", "guest")]), | ||||
|     true = lists:keymember("access-control-allow-origin", 1, HdOptionsCORS), | ||||
|     true = lists:keymember("access-control-allow-credentials", 1, HdOptionsCORS), | ||||
|     false = lists:keymember("access-control-expose-headers", 1, HdOptionsCORS), | ||||
|     true = lists:keymember("access-control-max-age", 1, HdOptionsCORS), | ||||
|     true = lists:keymember("access-control-allow-methods", 1, HdOptionsCORS), | ||||
|     false = lists:keymember("access-control-allow-headers", 1, HdOptionsCORS), | ||||
|     %% We should receive allow-headers when request-headers is sent. | ||||
|     {ok, {_, HdAllowHeadersCORS, _}} = req(options, "/overview", | ||||
|         [{"origin", "http://rabbitmq.com"}, | ||||
|          auth_header("guest", "guest"), | ||||
|          {"access-control-request-headers", "x-piggy-bank"}]), | ||||
|     {_, "x-piggy-bank"} = lists:keyfind("access-control-allow-headers", 1, HdAllowHeadersCORS), | ||||
|     %% Disable preflight request caching. | ||||
|     application:set_env(rabbitmq_management, cors_max_age, undefined), | ||||
|     %% We shouldn't receive max-age anymore. | ||||
|     {ok, {_, HdNoMaxAgeCORS, _}} = req(options, "/overview", | ||||
|         [{"origin", "http://rabbitmq.com"}, auth_header("guest", "guest")]), | ||||
|     false = lists:keymember("access-control-max-age", 1, HdNoMaxAgeCORS), | ||||
|     %% Disable CORS again. | ||||
|     application:set_env(rabbitmq_management, cors_allow_origins, []), | ||||
|     ok. | ||||
| 
 | ||||
| overview_test() -> | ||||
|     %% Rather crude, but this req doesn't say much and at least this means it | ||||
|     %% didn't blow up. | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue