mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Optimize cowboy_static:rest_init/2
This commit is contained in:
parent
87017e9699
commit
62e2635d8e
1 changed files with 39 additions and 34 deletions
|
@ -102,10 +102,10 @@
|
||||||
%% header is generated.
|
%% header is generated.
|
||||||
%%
|
%%
|
||||||
%% If a strong ETag is required a user defined function for generating the
|
%% If a strong ETag is required a user defined function for generating the
|
||||||
%% header value can be supplied. The function must accept a proplist of the
|
%% header value can be supplied. The function must accept a list of key/values
|
||||||
%% file attributes as the first argument and a second argument containing any
|
%% of the file attributes as the first argument and a second argument
|
||||||
%% additional data that the function requires. The function must return a term
|
%% containing any additional data that the function requires. The function
|
||||||
%% of the type `{weak | strong, binary()}' or `undefined'.
|
%% must return a term of the type `{weak | strong, binary()}' or `undefined'.
|
||||||
%%
|
%%
|
||||||
%% ==== Examples ====
|
%% ==== Examples ====
|
||||||
%% ```
|
%% ```
|
||||||
|
@ -202,7 +202,8 @@
|
||||||
fileinfo :: {ok, #file_info{}} | {error, _} | error,
|
fileinfo :: {ok, #file_info{}} | {error, _} | error,
|
||||||
mimetypes :: {fun((binary(), T) -> [mimedef()]), T} | undefined,
|
mimetypes :: {fun((binary(), T) -> [mimedef()]), T} | undefined,
|
||||||
etag_fun :: {fun(([etagarg()], T) ->
|
etag_fun :: {fun(([etagarg()], T) ->
|
||||||
undefined | {strong | weak, binary()}), T}}).
|
undefined | {strong | weak, binary()}), T}
|
||||||
|
}).
|
||||||
|
|
||||||
%% @private Upgrade from HTTP handler to REST handler.
|
%% @private Upgrade from HTTP handler to REST handler.
|
||||||
init({_Transport, http}, _Req, _Opts) ->
|
init({_Transport, http}, _Req, _Opts) ->
|
||||||
|
@ -211,37 +212,41 @@ init({_Transport, http}, _Req, _Opts) ->
|
||||||
%% @private Set up initial state of REST handler.
|
%% @private Set up initial state of REST handler.
|
||||||
-spec rest_init(Req, list()) -> {ok, Req, #state{}} when Req::cowboy_req:req().
|
-spec rest_init(Req, list()) -> {ok, Req, #state{}} when Req::cowboy_req:req().
|
||||||
rest_init(Req, Opts) ->
|
rest_init(Req, Opts) ->
|
||||||
Directory = proplists:get_value(directory, Opts),
|
{_, DirectoryOpt} = lists:keyfind(directory, 1, Opts),
|
||||||
Directory1 = directory_path(Directory),
|
Directory = directory_path(DirectoryOpt),
|
||||||
Mimetypes = proplists:get_value(mimetypes, Opts, []),
|
case lists:keyfind(file, 1, Opts) of
|
||||||
Mimetypes1 = case Mimetypes of
|
false ->
|
||||||
{{M, F}, E} -> {fun M:F/2, E};
|
{Filepath, Req2} = cowboy_req:path_info(Req),
|
||||||
{_, _} -> Mimetypes;
|
case check_path(Filepath) of
|
||||||
[] -> {fun path_to_mimetypes/2, []};
|
ok ->
|
||||||
[_|_] -> {fun path_to_mimetypes/2, Mimetypes}
|
Filepath2 = join_paths(Directory, Filepath),
|
||||||
|
rest_init(Req2, Opts, Filepath2);
|
||||||
|
error ->
|
||||||
|
{ok, Req2, #state{filepath=error, fileinfo=error,
|
||||||
|
mimetypes=undefined, etag_fun=undefined}}
|
||||||
|
end;
|
||||||
|
{_, FileOpt} ->
|
||||||
|
Filepath = join_paths(Directory, filepath_path(FileOpt)),
|
||||||
|
rest_init(Req, Opts, Filepath)
|
||||||
|
end.
|
||||||
|
|
||||||
|
rest_init(Req, Opts, Filepath) ->
|
||||||
|
Fileinfo = file:read_file_info(Filepath),
|
||||||
|
Mimetypes = case lists:keyfind(mimetypes, 1, Opts) of
|
||||||
|
false -> {fun path_to_mimetypes/2, []};
|
||||||
|
{_, {{M, F}, E}} -> {fun M:F/2, E};
|
||||||
|
{_, Mtypes} when is_tuple(Mtypes) -> Mtypes;
|
||||||
|
{_, Mtypes} when is_list(Mtypes) -> {fun path_to_mimetypes/2, Mtypes}
|
||||||
end,
|
end,
|
||||||
ETagFunction = case proplists:get_value(etag, Opts) of
|
EtagFun = case lists:keyfind(etag, 1, Opts) of
|
||||||
default -> {fun no_etag_function/2, undefined};
|
false -> {fun no_etag_function/2, undefined};
|
||||||
undefined -> {fun no_etag_function/2, undefined};
|
{_, default} -> {fun no_etag_function/2, undefined};
|
||||||
{attributes, []} -> {fun no_etag_function/2, undefined};
|
{_, {attributes, []}} -> {fun no_etag_function/2, undefined};
|
||||||
{attributes, Attrs} -> {fun attr_etag_function/2, Attrs};
|
{_, {attributes, Attrs}} -> {fun attr_etag_function/2, Attrs};
|
||||||
{_, _}=ETagFunction1 -> ETagFunction1
|
{_, EtagOpt} -> EtagOpt
|
||||||
end,
|
end,
|
||||||
{Filepath, Req1} = case lists:keyfind(file, 1, Opts) of
|
{ok, Req, #state{filepath=Filepath, fileinfo=Fileinfo,
|
||||||
{_, Filepath2} -> {filepath_path(Filepath2), Req};
|
mimetypes=Mimetypes, etag_fun=EtagFun}}.
|
||||||
false -> cowboy_req:path_info(Req)
|
|
||||||
end,
|
|
||||||
State = case check_path(Filepath) of
|
|
||||||
error ->
|
|
||||||
#state{filepath=error, fileinfo=error, mimetypes=undefined,
|
|
||||||
etag_fun=ETagFunction};
|
|
||||||
ok ->
|
|
||||||
Filepath1 = join_paths(Directory1, Filepath),
|
|
||||||
Fileinfo = file:read_file_info(Filepath1),
|
|
||||||
#state{filepath=Filepath1, fileinfo=Fileinfo, mimetypes=Mimetypes1,
|
|
||||||
etag_fun=ETagFunction}
|
|
||||||
end,
|
|
||||||
{ok, Req1, State}.
|
|
||||||
|
|
||||||
%% @private Only allow GET and HEAD requests on files.
|
%% @private Only allow GET and HEAD requests on files.
|
||||||
-spec allowed_methods(Req, #state{})
|
-spec allowed_methods(Req, #state{})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue