mirror of
https://github.com/valitydev/url-shortener.git
synced 2024-11-06 01:55:19 +00:00
MSPF-396: update to erlang 21 (#13)
* MSPF-396: update to erlang 21 (#12) * Setup to run on local machine * Migrated to new erlang/cowboy with dependencies * Updated dependecies & fixed wrong error handling * Removed redundant dependecy and hid generated apps * Removed extra cors module, added Options to handler * Fixed middleware misplacement, and properly implemented handler behaviour * cleaned up * returned to url instead of http in private repos * Returned to using cowboy_cors as CORS app, fixed typing, added epic branches rules for Jenkins * added missing dependency, divided net_opts option * Updated cors policy, added cors tests * Reverted unnessesary Jenkinsfile changes * Suppresed jesse warnings * Updated build image tag * Switched to using new jesse and parse_trans * Bumped utils and image tags, updated registry * bumped base image * bumped build_utils, removed registry redefinition * Refreshed outdated config (#14) * bumped erlang-health, fixed lager crash * Upgraded lager, restored redirection, refreshed config * Refreshed deprecated ranch opts passing * Switched to master branches * Bumped build image
This commit is contained in:
parent
ba71536ebc
commit
1b31deb9f7
4
Jenkinsfile
vendored
4
Jenkinsfile
vendored
@ -33,7 +33,7 @@ build('url-shortener', 'docker-host', finalHook) {
|
|||||||
sh 'make wc_xref'
|
sh 'make wc_xref'
|
||||||
}
|
}
|
||||||
runStage('dialyze') {
|
runStage('dialyze') {
|
||||||
withWsCache("_build/default/rebar3_19.1_plt") {
|
withWsCache("_build/default/rebar3_21.1.1_plt") {
|
||||||
sh 'make wc_dialyze'
|
sh 'make wc_dialyze'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,4 +62,4 @@ build('url-shortener', 'docker-host', finalHook) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
Makefile
6
Makefile
@ -13,11 +13,11 @@ SERVICE_IMAGE_TAG ?= $(shell git rev-parse HEAD)
|
|||||||
SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG)
|
SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG)
|
||||||
|
|
||||||
# Base image for the service
|
# Base image for the service
|
||||||
BASE_IMAGE_NAME := service_erlang
|
BASE_IMAGE_NAME := service-erlang
|
||||||
BASE_IMAGE_TAG := 16e2b3ef17e5fdefac8554ced9c2c74e5c6e9e11
|
BASE_IMAGE_TAG := bdb3e60ddc70044bae1aa581d260d3a9803a2477
|
||||||
|
|
||||||
# Build image tag to be used
|
# Build image tag to be used
|
||||||
BUILD_IMAGE_TAG := eee42f2ca018c313190bc350fe47d4dea70b6d27
|
BUILD_IMAGE_TAG := a166721af4f3454345d443bc681b91962d259d40
|
||||||
|
|
||||||
CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean
|
CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean
|
||||||
|
|
||||||
|
@ -51,11 +51,12 @@ get_processor_childspecs(Opts, HealthCheckers) ->
|
|||||||
[woody_server:child_spec(
|
[woody_server:child_spec(
|
||||||
?MODULE,
|
?MODULE,
|
||||||
#{
|
#{
|
||||||
ip => IP,
|
ip => IP,
|
||||||
port => maps:get(port, Opts, 8022),
|
port => maps:get(port, Opts, 8022),
|
||||||
net_opts => maps:get(net_opts, Opts, []),
|
protocol_opts => maps:get(protocol_opts, Opts, #{}),
|
||||||
event_handler => scoper_woody_event_handler,
|
transport_opts => maps:get(transport_opts, Opts, #{}),
|
||||||
handlers => [
|
event_handler => scoper_woody_event_handler,
|
||||||
|
handlers => [
|
||||||
{"/v1/stateproc", {
|
{"/v1/stateproc", {
|
||||||
{mg_proto_state_processing_thrift, 'Processor'},
|
{mg_proto_state_processing_thrift, 'Processor'},
|
||||||
shortener_slug
|
shortener_slug
|
||||||
|
@ -144,7 +144,7 @@ derive_kid_from_public_key_pem_entry(JWK) ->
|
|||||||
}.
|
}.
|
||||||
|
|
||||||
-spec store_key(keyname(), {pem_file, file:filename()}, store_opts()) ->
|
-spec store_key(keyname(), {pem_file, file:filename()}, store_opts()) ->
|
||||||
ok | {error, file:posix() | {unknown_key, _}}.
|
{ok, keyinfo()} | {error, file:posix() | {unknown_key, _}}.
|
||||||
|
|
||||||
store_key(Keyname, {pem_file, Filename}, Opts) ->
|
store_key(Keyname, {pem_file, Filename}, Opts) ->
|
||||||
case jose_jwk:from_pem_file(Filename) of
|
case jose_jwk:from_pem_file(Filename) of
|
||||||
|
@ -11,25 +11,24 @@
|
|||||||
policy_init(Req) ->
|
policy_init(Req) ->
|
||||||
{ok, Req, undefined}.
|
{ok, Req, undefined}.
|
||||||
|
|
||||||
-spec allowed_origins(cowboy_req:req(), any()) -> {'*', cowboy_req:req(), any()}.
|
-spec allowed_origins(cowboy_req:req(), any()) -> {'*', any()}.
|
||||||
|
|
||||||
allowed_origins(Req, State) ->
|
allowed_origins(_, State) ->
|
||||||
{'*', Req, State}.
|
{'*', State}.
|
||||||
|
|
||||||
-spec allowed_headers(cowboy_req:req(), any()) -> {[binary()], cowboy_req:req(), any()}.
|
-spec allowed_headers(cowboy_req:req(), any()) -> {[binary()], any()}.
|
||||||
|
|
||||||
allowed_headers(Req, State) ->
|
allowed_headers(_, State) ->
|
||||||
{[
|
{[
|
||||||
<<"accept">>,
|
<<"accept">>,
|
||||||
<<"access-control-allow-headers">>,
|
<<"access-control-allow-headers">>,
|
||||||
<<"authorization">>,
|
<<"authorization">>,
|
||||||
<<"content-type">>,
|
<<"content-type">>,
|
||||||
<<"origin">>,
|
|
||||||
<<"x-request-id">>,
|
<<"x-request-id">>,
|
||||||
<<"x-requested-with">>
|
<<"x-requested-with">>
|
||||||
], Req, State}.
|
], State}.
|
||||||
|
|
||||||
-spec allowed_methods(cowboy_req:req(), any()) -> {[binary()], cowboy_req:req(), any()}.
|
-spec allowed_methods(cowboy_req:req(), any()) -> {[binary()], any()}.
|
||||||
|
|
||||||
allowed_methods(Req, State) ->
|
allowed_methods(_, State) ->
|
||||||
{[<<"GET">>, <<"POST">>, <<"PUT">>, <<"DELETE">>, <<"OPTIONS">>], Req, State}.
|
{[<<"GET">>, <<"POST">>, <<"PUT">>, <<"DELETE">>, <<"OPTIONS">>], State}.
|
||||||
|
@ -3,14 +3,13 @@
|
|||||||
%% Swagger handler
|
%% Swagger handler
|
||||||
|
|
||||||
-behaviour(swag_server_logic_handler).
|
-behaviour(swag_server_logic_handler).
|
||||||
-export([authorize_api_key/2]).
|
-export([authorize_api_key/3]).
|
||||||
-export([handle_request/3]).
|
-export([handle_request/4]).
|
||||||
|
|
||||||
%% Cowboy http handler
|
%% Cowboy http handler
|
||||||
|
|
||||||
-behaviour(cowboy_http_handler).
|
-behaviour(cowboy_handler).
|
||||||
-export([init/3]).
|
-export([init/2]).
|
||||||
-export([handle/2]).
|
|
||||||
-export([terminate/3]).
|
-export([terminate/3]).
|
||||||
|
|
||||||
%%
|
%%
|
||||||
@ -23,17 +22,17 @@
|
|||||||
-type request_data() :: #{atom() | binary() => term()}.
|
-type request_data() :: #{atom() | binary() => term()}.
|
||||||
-type subject_id() :: woody_user_identity:id().
|
-type subject_id() :: woody_user_identity:id().
|
||||||
|
|
||||||
-spec authorize_api_key(operation_id(), swag_server:api_key()) ->
|
-spec authorize_api_key(operation_id(), swag_server:api_key(), swag_server:handler_opts(_)) ->
|
||||||
Result :: false | {true, shortener_auth:context()}.
|
Result :: false | {true, shortener_auth:context()}.
|
||||||
|
|
||||||
authorize_api_key(OperationID, ApiKey) ->
|
authorize_api_key(OperationID, ApiKey, _Opts) ->
|
||||||
ok = scoper:add_scope('swag.server', #{operation => OperationID}),
|
ok = scoper:add_scope('swag.server', #{operation => OperationID}),
|
||||||
shortener_auth:authorize_api_key(OperationID, ApiKey).
|
shortener_auth:authorize_api_key(OperationID, ApiKey).
|
||||||
|
|
||||||
-spec handle_request(operation_id(), request_data(), request_ctx()) ->
|
-spec handle_request(operation_id(), request_data(), request_ctx(), any()) ->
|
||||||
{ok | error, swag_server_logic_handler:response()}.
|
{ok | error, swag_server:response()}.
|
||||||
|
|
||||||
handle_request(OperationID, Req, Context) ->
|
handle_request(OperationID, Req, Context, _Opts) ->
|
||||||
try
|
try
|
||||||
AuthContext = get_auth_context(Context),
|
AuthContext = get_auth_context(Context),
|
||||||
WoodyCtx = create_woody_ctx(Req, AuthContext),
|
WoodyCtx = create_woody_ctx(Req, AuthContext),
|
||||||
@ -43,7 +42,7 @@ handle_request(OperationID, Req, Context) ->
|
|||||||
SubjectID = get_subject_id(AuthContext),
|
SubjectID = get_subject_id(AuthContext),
|
||||||
process_request(OperationID, Req, Slug, SubjectID, WoodyCtx);
|
process_request(OperationID, Req, Slug, SubjectID, WoodyCtx);
|
||||||
{error, forbidden} ->
|
{error, forbidden} ->
|
||||||
{ok, {403, [], undefined}}
|
{ok, {403, #{}, undefined}}
|
||||||
end
|
end
|
||||||
catch
|
catch
|
||||||
error:{woody_error, {Source, Class, Details}} ->
|
error:{woody_error, {Source, Class, Details}} ->
|
||||||
@ -87,16 +86,16 @@ get_auth_context(#{auth_context := AuthContext}) ->
|
|||||||
AuthContext.
|
AuthContext.
|
||||||
|
|
||||||
handle_woody_error(_Source, result_unexpected, _Details) ->
|
handle_woody_error(_Source, result_unexpected, _Details) ->
|
||||||
{500, [], <<>>};
|
{500, #{}, <<>>};
|
||||||
handle_woody_error(_Source, resource_unavailable, _Details) ->
|
handle_woody_error(_Source, resource_unavailable, _Details) ->
|
||||||
{503, [], <<>>};
|
{503, #{}, <<>>};
|
||||||
handle_woody_error(_Source, result_unknown, _Details) ->
|
handle_woody_error(_Source, result_unknown, _Details) ->
|
||||||
{504, [], <<>>}.
|
{504, #{}, <<>>}.
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
-spec process_request(operation_id(), request_data(), shortener_slug:slug(), subject_id(), woody_context:ctx()) ->
|
-spec process_request(operation_id(), request_data(), shortener_slug:slug(), subject_id(), woody_context:ctx()) ->
|
||||||
{ok | error, swag_server_logic_handler:response()}.
|
{ok | error, swag_server:response()}.
|
||||||
|
|
||||||
process_request(
|
process_request(
|
||||||
'ShortenUrl',
|
'ShortenUrl',
|
||||||
@ -111,9 +110,9 @@ process_request(
|
|||||||
case validate_source_url(SourceUrl) of
|
case validate_source_url(SourceUrl) of
|
||||||
true ->
|
true ->
|
||||||
Slug = shortener_slug:create(SourceUrl, parse_timestamp(ExpiresAt), SubjectID, WoodyCtx),
|
Slug = shortener_slug:create(SourceUrl, parse_timestamp(ExpiresAt), SubjectID, WoodyCtx),
|
||||||
{ok, {201, [], construct_shortened_url(Slug)}};
|
{ok, {201, #{}, construct_shortened_url(Slug)}};
|
||||||
false ->
|
false ->
|
||||||
{ok, {400, [], #{
|
{ok, {400, #{}, #{
|
||||||
<<"code">> => <<"forbidden_source_url">>,
|
<<"code">> => <<"forbidden_source_url">>,
|
||||||
<<"message">> => <<"Source URL is forbidden">>
|
<<"message">> => <<"Source URL is forbidden">>
|
||||||
}}}
|
}}}
|
||||||
@ -126,7 +125,7 @@ process_request(
|
|||||||
_SubjectID,
|
_SubjectID,
|
||||||
_WoodyCtx
|
_WoodyCtx
|
||||||
) ->
|
) ->
|
||||||
{error, {404, [], undefined}};
|
{error, {404, #{}, undefined}};
|
||||||
process_request(
|
process_request(
|
||||||
'GetShortenedUrl',
|
'GetShortenedUrl',
|
||||||
_Req,
|
_Req,
|
||||||
@ -134,7 +133,7 @@ process_request(
|
|||||||
_SubjectID,
|
_SubjectID,
|
||||||
_WoodyCtx
|
_WoodyCtx
|
||||||
) ->
|
) ->
|
||||||
{ok, {200, [], construct_shortened_url(Slug)}};
|
{ok, {200, #{}, construct_shortened_url(Slug)}};
|
||||||
|
|
||||||
process_request(
|
process_request(
|
||||||
'DeleteShortenedUrl',
|
'DeleteShortenedUrl',
|
||||||
@ -145,9 +144,9 @@ process_request(
|
|||||||
) ->
|
) ->
|
||||||
case shortener_slug:remove(ID, WoodyCtx) of
|
case shortener_slug:remove(ID, WoodyCtx) of
|
||||||
ok ->
|
ok ->
|
||||||
{ok, {204, [], undefined}};
|
{ok, {204, #{}, undefined}};
|
||||||
{error, notfound} ->
|
{error, notfound} ->
|
||||||
{error, {404, [], undefined}}
|
{error, {404, #{}, undefined}}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
validate_source_url(SourceUrl) ->
|
validate_source_url(SourceUrl) ->
|
||||||
@ -214,30 +213,24 @@ get_source_url_whitelist() ->
|
|||||||
-type request() :: cowboy_req:req().
|
-type request() :: cowboy_req:req().
|
||||||
-type terminate_reason() :: {normal, shutdown} | {error, atom()}.
|
-type terminate_reason() :: {normal, shutdown} | {error, atom()}.
|
||||||
|
|
||||||
-spec init({atom(), http}, request(), _) ->
|
-spec init(request(), _) ->
|
||||||
{ok, request(), state()}.
|
{ok, request(), state()}.
|
||||||
|
|
||||||
init({_, http}, Req, _Opts) ->
|
init(Req, Opts) ->
|
||||||
{ok, Req, undefined}.
|
ID = cowboy_req:binding('shortenedUrlID', Req),
|
||||||
|
Req1 = case shortener_slug:get(ID, woody_context:new()) of
|
||||||
-spec handle(request(), state()) ->
|
|
||||||
{ok, request(), state()}.
|
|
||||||
|
|
||||||
handle(Req1, St) ->
|
|
||||||
{ID, Req2} = cowboy_req:binding('shortenedUrlID', Req1),
|
|
||||||
{ok, Req3} = case shortener_slug:get(ID, woody_context:new()) of
|
|
||||||
{ok, #{source := Source, expires_at := ExpiresAt}} ->
|
{ok, #{source := Source, expires_at := ExpiresAt}} ->
|
||||||
{ok, {Date, Time, _, _UndefinedButDialyzerDisagrees}} = rfc3339:parse(ExpiresAt),
|
{ok, {Date, Time, _, _UndefinedButDialyzerDisagrees}} = rfc3339:parse(ExpiresAt),
|
||||||
Headers = [
|
Headers = #{
|
||||||
{<<"location">> , Source},
|
<<"location">> => Source,
|
||||||
{<<"expires">> , cowboy_clock:rfc1123({Date, Time})},
|
<<"expires">> => cowboy_clock:rfc1123({Date, Time}),
|
||||||
{<<"cache-control">> , <<"must-revalidate">>}
|
<<"cache-control">> => <<"must-revalidate">>
|
||||||
],
|
},
|
||||||
cowboy_req:reply(301, Headers, Req2);
|
cowboy_req:reply(301, Headers, Req);
|
||||||
{error, notfound} ->
|
{error, notfound} ->
|
||||||
cowboy_req:reply(404, Req2)
|
cowboy_req:reply(404, Req)
|
||||||
end,
|
end,
|
||||||
{ok, Req3, St}.
|
{ok, Req1, Opts}.
|
||||||
|
|
||||||
-spec terminate(terminate_reason(), request(), state()) ->
|
-spec terminate(terminate_reason(), request(), state()) ->
|
||||||
ok.
|
ok.
|
||||||
|
@ -16,7 +16,7 @@ child_spec(LogicHandler, Opts, AdditionalRoutes) ->
|
|||||||
?MODULE,
|
?MODULE,
|
||||||
Transport,
|
Transport,
|
||||||
TransportOpts,
|
TransportOpts,
|
||||||
cowboy_protocol,
|
cowboy_clear,
|
||||||
CowboyOpts
|
CowboyOpts
|
||||||
).
|
).
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ get_socket_transport(Opts) ->
|
|||||||
{ok, IP} = inet:parse_address(maps:get(ip, Opts, ?DEFAULT_IP_ADDR)),
|
{ok, IP} = inet:parse_address(maps:get(ip, Opts, ?DEFAULT_IP_ADDR)),
|
||||||
Port = maps:get(port, Opts, ?DEFAULT_PORT),
|
Port = maps:get(port, Opts, ?DEFAULT_PORT),
|
||||||
Acceptors = maps:get(acceptors, Opts, ?DEFAULT_ACCEPTORS_POOLSIZE),
|
Acceptors = maps:get(acceptors, Opts, ?DEFAULT_ACCEPTORS_POOLSIZE),
|
||||||
{ranch_tcp, [{ip, IP}, {port, Port}, {num_acceptors, Acceptors}]}.
|
{ranch_tcp, #{socket_opts => [{ip, IP}, {port, Port}], num_acceptors => Acceptors}}.
|
||||||
|
|
||||||
get_cowboy_config(LogicHandler, AdditionalRoutes, Opts) ->
|
get_cowboy_config(LogicHandler, AdditionalRoutes, Opts) ->
|
||||||
ShortUrlTemplate = maps:get(short_url_template, Opts),
|
ShortUrlTemplate = maps:get(short_url_template, Opts),
|
||||||
@ -34,19 +34,19 @@ get_cowboy_config(LogicHandler, AdditionalRoutes, Opts) ->
|
|||||||
swag_server_router:get_paths(LogicHandler) ++
|
swag_server_router:get_paths(LogicHandler) ++
|
||||||
[{'_', [{genlib:to_list(ShortUrlPath) ++ ":shortenedUrlID", shortener_handler, #{}}]}]
|
[{'_', [{genlib:to_list(ShortUrlPath) ++ ":shortenedUrlID", shortener_handler, #{}}]}]
|
||||||
),
|
),
|
||||||
[
|
#{
|
||||||
{env, [
|
env => #{
|
||||||
{dispatch, cowboy_router:compile(Routes)},
|
dispatch => cowboy_router:compile(Routes),
|
||||||
{cors_policy, shortener_cors_policy}
|
cors_policy => shortener_cors_policy
|
||||||
]},
|
},
|
||||||
{middlewares, [
|
middlewares => [
|
||||||
cowboy_router,
|
cowboy_router,
|
||||||
cowboy_cors,
|
cowboy_cors,
|
||||||
cowboy_handler
|
cowboy_handler
|
||||||
]},
|
],
|
||||||
{onrequest, cowboy_access_log:get_request_hook()},
|
stream_handlers => [cowboy_stream_h, cowboy_access_log_h],
|
||||||
{onresponse, cowboy_access_log:get_response_hook(shortener_access_lager_event)}
|
sink => shortener_access_lager_event
|
||||||
].
|
}.
|
||||||
|
|
||||||
squash_routes(Routes) ->
|
squash_routes(Routes) ->
|
||||||
orddict:to_list(lists:foldl(
|
orddict:to_list(lists:foldl(
|
||||||
|
@ -22,6 +22,11 @@
|
|||||||
|
|
||||||
-export([woody_timeout_test/1]).
|
-export([woody_timeout_test/1]).
|
||||||
|
|
||||||
|
-export([unsupported_cors_method/1]).
|
||||||
|
-export([supported_cors_method/1]).
|
||||||
|
-export([unsupported_cors_header/1]).
|
||||||
|
-export([supported_cors_header/1]).
|
||||||
|
|
||||||
%% tests descriptions
|
%% tests descriptions
|
||||||
|
|
||||||
-type config() :: [{atom(), term()}].
|
-type config() :: [{atom(), term()}].
|
||||||
@ -33,7 +38,7 @@
|
|||||||
all() ->
|
all() ->
|
||||||
[
|
[
|
||||||
{group, general},
|
{group, general},
|
||||||
|
{group, cors},
|
||||||
woody_timeout_test
|
woody_timeout_test
|
||||||
].
|
].
|
||||||
|
|
||||||
@ -53,6 +58,12 @@ groups() ->
|
|||||||
fordidden_source_url,
|
fordidden_source_url,
|
||||||
url_expired,
|
url_expired,
|
||||||
always_unique_url
|
always_unique_url
|
||||||
|
]},
|
||||||
|
{cors, [], [
|
||||||
|
unsupported_cors_method,
|
||||||
|
supported_cors_method,
|
||||||
|
unsupported_cors_header,
|
||||||
|
supported_cors_header
|
||||||
]}
|
]}
|
||||||
].
|
].
|
||||||
|
|
||||||
@ -87,7 +98,7 @@ init_per_suite(C) ->
|
|||||||
|
|
||||||
-spec init_per_group(atom(), config()) -> config().
|
-spec init_per_group(atom(), config()) -> config().
|
||||||
|
|
||||||
init_per_group(general, C) ->
|
init_per_group(_Group, C) ->
|
||||||
ShortenerApp =
|
ShortenerApp =
|
||||||
genlib_app:start_application_with(shortener, get_app_config(
|
genlib_app:start_application_with(shortener, get_app_config(
|
||||||
?config(port, C),
|
?config(port, C),
|
||||||
@ -101,7 +112,7 @@ init_per_group(general, C) ->
|
|||||||
|
|
||||||
-spec end_per_group(atom(), config()) -> _.
|
-spec end_per_group(atom(), config()) -> _.
|
||||||
|
|
||||||
end_per_group(general, C) ->
|
end_per_group(_Group, C) ->
|
||||||
genlib_app:stop_unload_applications(?config(shortener_app, C)).
|
genlib_app:stop_unload_applications(?config(shortener_app, C)).
|
||||||
|
|
||||||
get_keysource(Key, C) ->
|
get_keysource(Key, C) ->
|
||||||
@ -220,6 +231,57 @@ always_unique_url(C) ->
|
|||||||
N = length(lists:usort(IDs)),
|
N = length(lists:usort(IDs)),
|
||||||
N = length(lists:usort(ShortUrls)).
|
N = length(lists:usort(ShortUrls)).
|
||||||
|
|
||||||
|
|
||||||
|
%% cors
|
||||||
|
-spec unsupported_cors_method(config()) -> _.
|
||||||
|
-spec supported_cors_method(config()) -> _.
|
||||||
|
-spec unsupported_cors_header(config()) -> _.
|
||||||
|
-spec supported_cors_header(config()) -> _.
|
||||||
|
|
||||||
|
unsupported_cors_method(C) ->
|
||||||
|
SourceUrl = <<"https://oops.io/">>,
|
||||||
|
Params = construct_params(SourceUrl),
|
||||||
|
C1 = set_api_auth_token(unsupported_cors_method, [read, write], C),
|
||||||
|
{ok, 201, _, #{<<"shortenedUrl">> := ShortUrl}} = shorten_url(Params, C1),
|
||||||
|
ReqHeaders = [{<<"origin">>, <<"localhost">>}, {<<"access-control-request-method">>, <<"PATCH">>}],
|
||||||
|
{ok, 200, Headers, _} = hackney:request(options, ShortUrl, ReqHeaders),
|
||||||
|
false = lists:member(<<"access-control-allow-methods">>, Headers).
|
||||||
|
|
||||||
|
supported_cors_method(C) ->
|
||||||
|
SourceUrl = <<"https://oops.io/">>,
|
||||||
|
Params = construct_params(SourceUrl),
|
||||||
|
C1 = set_api_auth_token(supported_cors_method, [read, write], C),
|
||||||
|
{ok, 201, _, #{<<"shortenedUrl">> := ShortUrl}} = shorten_url(Params, C1),
|
||||||
|
ReqHeaders = [{<<"origin">>, <<"localhost">>}, {<<"access-control-request-method">>, <<"GET">>}],
|
||||||
|
{ok, 200, Headers, _} = hackney:request(options, ShortUrl, ReqHeaders),
|
||||||
|
{Allowed, _} = shortener_cors_policy:allowed_methods(undefined, undefined),
|
||||||
|
{_, Returned} = lists:keyfind(<<"access-control-allow-methods">>, 1, Headers),
|
||||||
|
Allowed = binary:split(Returned, <<",">>, [global]).
|
||||||
|
|
||||||
|
|
||||||
|
supported_cors_header(C) ->
|
||||||
|
SourceUrl = <<"https://oops.io/">>,
|
||||||
|
Params = construct_params(SourceUrl),
|
||||||
|
C1 = set_api_auth_token(supported_cors_header, [read, write], C),
|
||||||
|
{ok, 201, _, #{<<"shortenedUrl">> := ShortUrl}} = shorten_url(Params, C1),
|
||||||
|
ReqHeaders = [{<<"origin">>, <<"localhost">>}, {<<"access-control-request-method">>, <<"GET">>}, {<<"access-control-request-headers">>, <<"content-type,authorization">>}],
|
||||||
|
{ok, 200, Headers, _} = hackney:request(options, ShortUrl, ReqHeaders),
|
||||||
|
{Allowed, _} = shortener_cors_policy:allowed_headers(undefined, undefined),
|
||||||
|
{_, Returned} = lists:keyfind(<<"access-control-allow-headers">>, 1, Headers),
|
||||||
|
[_ | Allowed] = binary:split(Returned, <<",">>, [global]). % truncate origin
|
||||||
|
|
||||||
|
unsupported_cors_header(C) ->
|
||||||
|
SourceUrl = <<"https://oops.io/">>,
|
||||||
|
Params = construct_params(SourceUrl),
|
||||||
|
C1 = set_api_auth_token(unsupported_cors_header, [read, write], C),
|
||||||
|
{ok, 201, _, #{<<"shortenedUrl">> := ShortUrl}} = shorten_url(Params, C1),
|
||||||
|
ReqHeaders = [{<<"origin">>, <<"localhost">>}, {<<"access-control-request-method">>, <<"GET">>}, {<<"access-control-request-headers">>, <<"content-type,42">>}],
|
||||||
|
{ok, 200, Headers, _} = hackney:request(options, ShortUrl, ReqHeaders),
|
||||||
|
false = lists:member(<<"access-control-allow-headers">>, Headers),
|
||||||
|
false = lists:member(<<"access-control-allow-credentials">>, Headers),
|
||||||
|
false = lists:member(<<"access-control-allow-methods">>, Headers),
|
||||||
|
false = lists:member(<<"access-control-allow-origin">>, Headers).
|
||||||
|
|
||||||
construct_params(SourceUrl) ->
|
construct_params(SourceUrl) ->
|
||||||
construct_params(SourceUrl, 3600).
|
construct_params(SourceUrl, 3600).
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 8dd1d30e97e4db20c9da98a5ddb261b199402bc0
|
Subproject commit 870b70a63af18fc7a02c9ff26b06132d2b1993cb
|
@ -4,7 +4,7 @@
|
|||||||
{error_logger_hwm, 600},
|
{error_logger_hwm, 600},
|
||||||
{log_root, "/var/log/shortener"},
|
{log_root, "/var/log/shortener"},
|
||||||
{handlers, [
|
{handlers, [
|
||||||
{lager_console_backend, debug},
|
{lager_console_backend, [{level, debug}]},
|
||||||
{lager_file_backend, [
|
{lager_file_backend, [
|
||||||
{file, "console.json"},
|
{file, "console.json"},
|
||||||
{level, debug},
|
{level, debug},
|
||||||
@ -51,9 +51,9 @@
|
|||||||
{processor, #{
|
{processor, #{
|
||||||
ip => "::",
|
ip => "::",
|
||||||
port => 8022,
|
port => 8022,
|
||||||
net_opts => [
|
protocol_opts => #{
|
||||||
{timeout , 60000}
|
request_timeout => 60000
|
||||||
]
|
}
|
||||||
}},
|
}},
|
||||||
{service_clients, #{
|
{service_clients, #{
|
||||||
automaton => #{
|
automaton => #{
|
||||||
|
16
rebar.config
16
rebar.config
@ -28,9 +28,9 @@
|
|||||||
|
|
||||||
% Common project dependencies.
|
% Common project dependencies.
|
||||||
{deps, [
|
{deps, [
|
||||||
{cowboy, "1.0.4"},
|
{lager, "3.6.4"},
|
||||||
|
{cowboy, "2.5.0"},
|
||||||
{jose, "1.7.9"},
|
{jose, "1.7.9"},
|
||||||
{lager, "3.5.2"},
|
|
||||||
{genlib,
|
{genlib,
|
||||||
{git, "https://github.com/rbkmoney/genlib.git",
|
{git, "https://github.com/rbkmoney/genlib.git",
|
||||||
{branch, "master"}
|
{branch, "master"}
|
||||||
@ -46,11 +46,6 @@
|
|||||||
{branch, "master"}
|
{branch, "master"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{cowboy_cors,
|
|
||||||
{git, "https://github.com/danielwhite/cowboy_cors.git",
|
|
||||||
{branch, "master"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{woody,
|
{woody,
|
||||||
{git, "git@github.com:rbkmoney/woody_erlang.git",
|
{git, "git@github.com:rbkmoney/woody_erlang.git",
|
||||||
{branch, "master"}
|
{branch, "master"}
|
||||||
@ -73,7 +68,12 @@
|
|||||||
},
|
},
|
||||||
{erl_health,
|
{erl_health,
|
||||||
{git, "https://github.com/rbkmoney/erlang-health.git",
|
{git, "https://github.com/rbkmoney/erlang-health.git",
|
||||||
{branch, master}
|
{branch, "master"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{cowboy_cors,
|
||||||
|
{git, "https://github.com/rbkmoney/cowboy_cors.git",
|
||||||
|
{branch, "master"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]}.
|
]}.
|
||||||
|
62
rebar.lock
62
rebar.lock
@ -1,38 +1,44 @@
|
|||||||
{"1.1.0",
|
{"1.1.0",
|
||||||
[{<<"base64url">>,{pkg,<<"base64url">>,<<"0.0.1">>},1},
|
[{<<"base64url">>,{pkg,<<"base64url">>,<<"0.0.1">>},1},
|
||||||
{<<"certifi">>,{pkg,<<"certifi">>,<<"0.7.0">>},1},
|
{<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1},
|
||||||
|
{<<"certifi">>,{pkg,<<"certifi">>,<<"2.3.1">>},1},
|
||||||
{<<"cg_mon">>,
|
{<<"cg_mon">>,
|
||||||
{git,"https://github.com/rbkmoney/cg_mon.git",
|
{git,"https://github.com/rbkmoney/cg_mon.git",
|
||||||
{ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}},
|
{ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}},
|
||||||
1},
|
1},
|
||||||
{<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},0},
|
{<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.5.0">>},0},
|
||||||
{<<"cowboy_access_log">>,
|
{<<"cowboy_access_log">>,
|
||||||
{git,"git@github.com:rbkmoney/cowboy_access_log.git",
|
{git,"git@github.com:rbkmoney/cowboy_access_log.git",
|
||||||
{ref,"c91ae2316f3daf5465ec12e9fdd0ae37082885c0"}},
|
{ref,"b6e9f5cdd0990c756ace0267983226abaf137bd0"}},
|
||||||
0},
|
0},
|
||||||
{<<"cowboy_cors">>,
|
{<<"cowboy_cors">>,
|
||||||
{git,"https://github.com/danielwhite/cowboy_cors.git",
|
{git,"https://github.com/rbkmoney/cowboy_cors.git",
|
||||||
{ref,"392f5804b63fff2bd0fda67671d5b2fbe0badd37"}},
|
{ref,"4cac7528845a8610d471b6fbb92321f79d93f0b8"}},
|
||||||
0},
|
0},
|
||||||
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},1},
|
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},1},
|
||||||
{<<"erl_health">>,
|
{<<"erl_health">>,
|
||||||
{git,"https://github.com/rbkmoney/erlang-health.git",
|
{git,"https://github.com/rbkmoney/erlang-health.git",
|
||||||
{ref,"ab3ca1ccab6e77905810aa270eb936dbe70e02f8"}},
|
{ref,"2575c7b63d82a92de54d2d27e504413675e64811"}},
|
||||||
0},
|
0},
|
||||||
{<<"genlib">>,
|
{<<"genlib">>,
|
||||||
{git,"https://github.com/rbkmoney/genlib.git",
|
{git,"https://github.com/rbkmoney/genlib.git",
|
||||||
{ref,"7fc1ca1a57dbe2b8b837951095e314c32afd6c9a"}},
|
{ref,"7fc1ca1a57dbe2b8b837951095e314c32afd6c9a"}},
|
||||||
0},
|
0},
|
||||||
{<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1},
|
{<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1},
|
||||||
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.6.2">>},0},
|
{<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1},
|
||||||
{<<"idna">>,{pkg,<<"idna">>,<<"1.2.0">>},1},
|
{<<"gun">>,
|
||||||
|
{git,"https://github.com/ninenines/gun.git",
|
||||||
|
{ref,"e7dd9f227e46979d8073e71c683395a809b78cb4"}},
|
||||||
|
1},
|
||||||
|
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.0">>},0},
|
||||||
|
{<<"idna">>,{pkg,<<"idna">>,<<"5.1.2">>},1},
|
||||||
{<<"jesse">>,
|
{<<"jesse">>,
|
||||||
{git,"https://github.com/rbkmoney/jesse.git",
|
{git,"https://github.com/rbkmoney/jesse.git",
|
||||||
{ref,"39105922d1ce5834383d8e8aa877c60319b9834a"}},
|
{ref,"723e835708a022bbce9e57807ecf220b00fb771a"}},
|
||||||
0},
|
0},
|
||||||
{<<"jose">>,{pkg,<<"jose">>,<<"1.7.9">>},0},
|
{<<"jose">>,{pkg,<<"jose">>,<<"1.7.9">>},0},
|
||||||
{<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.2">>},0},
|
{<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.2">>},0},
|
||||||
{<<"lager">>,{pkg,<<"lager">>,<<"3.5.2">>},0},
|
{<<"lager">>,{pkg,<<"lager">>,<<"3.6.4">>},0},
|
||||||
{<<"lager_logstash_formatter">>,
|
{<<"lager_logstash_formatter">>,
|
||||||
{git,"git@github.com:rbkmoney/lager_logstash_formatter.git",
|
{git,"git@github.com:rbkmoney/lager_logstash_formatter.git",
|
||||||
{ref,"24527c15c47749866f2d427b333fa1333a46b8af"}},
|
{ref,"24527c15c47749866f2d427b333fa1333a46b8af"}},
|
||||||
@ -44,15 +50,14 @@
|
|||||||
0},
|
0},
|
||||||
{<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},1},
|
{<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},1},
|
||||||
{<<"parse_trans">>,
|
{<<"parse_trans">>,
|
||||||
{git,"https://github.com/rbkmoney/parse_trans.git",
|
{git,"https://github.com/uwiger/parse_trans.git",
|
||||||
{ref,"5ee45f5bfa6c04329bea3281977b774f04c89f11"}},
|
{ref,"76abb347c3c1d00fb0ccf9e4b43e22b3d2288484"}},
|
||||||
0},
|
0},
|
||||||
{<<"pooler">>,{pkg,<<"pooler">>,<<"1.5.0">>},0},
|
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.6.2">>},1},
|
||||||
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.4.0">>},1},
|
|
||||||
{<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0},
|
{<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0},
|
||||||
{<<"scoper">>,
|
{<<"scoper">>,
|
||||||
{git,"git@github.com:rbkmoney/scoper.git",
|
{git,"git@github.com:rbkmoney/scoper.git",
|
||||||
{ref,"802057089bac258f45e35263eb2223961618468d"}},
|
{ref,"206f76e006207f75828c1df3dde0deaa8554f332"}},
|
||||||
0},
|
0},
|
||||||
{<<"snowflake">>,
|
{<<"snowflake">>,
|
||||||
{git,"https://github.com/rbkmoney/snowflake.git",
|
{git,"https://github.com/rbkmoney/snowflake.git",
|
||||||
@ -63,30 +68,33 @@
|
|||||||
{git,"https://github.com/rbkmoney/thrift_erlang.git",
|
{git,"https://github.com/rbkmoney/thrift_erlang.git",
|
||||||
{ref,"240bbc842f6e9b90d01bd07838778cf48752b510"}},
|
{ref,"240bbc842f6e9b90d01bd07838778cf48752b510"}},
|
||||||
1},
|
1},
|
||||||
|
{<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.3.1">>},2},
|
||||||
{<<"woody">>,
|
{<<"woody">>,
|
||||||
{git,"git@github.com:rbkmoney/woody_erlang.git",
|
{git,"git@github.com:rbkmoney/woody_erlang.git",
|
||||||
{ref,"354ac7664529ddecc07376bdaf4408cd8022fb61"}},
|
{ref,"c396f927b5149d1b5589262773a9e6a39cb68d33"}},
|
||||||
0},
|
0},
|
||||||
{<<"woody_user_identity">>,
|
{<<"woody_user_identity">>,
|
||||||
{git,"git@github.com:rbkmoney/woody_erlang_user_identity.git",
|
{git,"git@github.com:rbkmoney/woody_erlang_user_identity.git",
|
||||||
{ref,"9c7ad2b8beac9c88c54594b264743dec7b9cf696"}},
|
{ref,"fe973ab27fee9fc1cc39281e88816c7b6dce84c6"}},
|
||||||
0}]}.
|
0}]}.
|
||||||
[
|
[
|
||||||
{pkg_hash,[
|
{pkg_hash,[
|
||||||
{<<"base64url">>, <<"36A90125F5948E3AFD7BE97662A1504B934DD5DAC78451CA6E9ABF85A10286BE">>},
|
{<<"base64url">>, <<"36A90125F5948E3AFD7BE97662A1504B934DD5DAC78451CA6E9ABF85A10286BE">>},
|
||||||
{<<"certifi">>, <<"861A57F3808F7EB0C2D1802AFEAAE0FA5DE813B0DF0979153CBAFCD853ABABAF">>},
|
{<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>},
|
||||||
{<<"cowboy">>, <<"A324A8DF9F2316C833A470D918AAF73AE894278B8AA6226CE7A9BF699388F878">>},
|
{<<"certifi">>, <<"D0F424232390BF47D82DA8478022301C561CF6445B5B5FB6A84D49A9E76D2639">>},
|
||||||
{<<"cowlib">>, <<"9D769A1D062C9C3AC753096F868CA121E2730B9A377DE23DEC0F7E08B1DF84EE">>},
|
{<<"cowboy">>, <<"4EF3AE066EE10FE01EA3272EDC8F024347A0D3EB95F6FBB9AED556DACBFC1337">>},
|
||||||
|
{<<"cowlib">>, <<"8AA629F81A0FC189F261DC98A42243FA842625FEEA3C7EC56C48F4CCDB55490F">>},
|
||||||
{<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>},
|
{<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>},
|
||||||
{<<"hackney">>, <<"96A0A5E7E65B7ACAD8031D231965718CC70A9B4131A8B033B7543BBD673B8210">>},
|
{<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>},
|
||||||
{<<"idna">>, <<"AC62EE99DA068F43C50DC69ACF700E03A62A348360126260E87F2B54ECED86B2">>},
|
{<<"hackney">>, <<"287A5D2304D516F63E56C469511C42B016423BCB167E61B611F6BAD47E3CA60E">>},
|
||||||
|
{<<"idna">>, <<"E21CB58A09F0228A9E0B95EAA1217F1BCFC31A1AAA6E1FDF2F53A33F7DBD9494">>},
|
||||||
{<<"jose">>, <<"9DC5A14AB62DB4E41677FCC97993752562FB57AD0B8BA062589682EDD3ACB91F">>},
|
{<<"jose">>, <<"9DC5A14AB62DB4E41677FCC97993752562FB57AD0B8BA062589682EDD3ACB91F">>},
|
||||||
{<<"jsx">>, <<"7ACC7D785B5ABE8A6E9ADBDE926A24E481F29956DD8B4DF49E3E4E7BCC92A018">>},
|
{<<"jsx">>, <<"7ACC7D785B5ABE8A6E9ADBDE926A24E481F29956DD8B4DF49E3E4E7BCC92A018">>},
|
||||||
{<<"lager">>, <<"614A8C8F67BF99B69EB264EA22121AD25511C055AAEC09B086773D5108C6767F">>},
|
{<<"lager">>, <<"CED6E98070FB4E58EE93174D006D46479C79844DF7FC17FA4FEFC1049A320D88">>},
|
||||||
{<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>},
|
{<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>},
|
||||||
{<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>},
|
{<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>},
|
||||||
{<<"pooler">>, <<"0FD4BE5D2976E6A2E9A1617623031758C26F200C1FCA89E4A3C542747BEC6371">>},
|
{<<"ranch">>, <<"6DB93C78F411EE033DBB18BA8234C5574883ACB9A75AF0FB90A9B82EA46AFA00">>},
|
||||||
{<<"ranch">>, <<"10272F95DA79340FA7E8774BA7930B901713D272905D0012B06CA6D994F8826B">>},
|
|
||||||
{<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>},
|
{<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>},
|
||||||
{<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}]}
|
{<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>},
|
||||||
|
{<<"unicode_util_compat">>, <<"A1F612A7B512638634A603C8F401892AFBF99B8CE93A45041F8AACA99CADB85E">>}]}
|
||||||
].
|
].
|
||||||
|
Loading…
Reference in New Issue
Block a user