Packages
nitro
7.2.0
11.4.16
11.4.15
11.4.14
9.9.7
9.9.6
8.2.4
8.2.3
8.2.2
8.2.1
8.2.0
7.12.1
7.10.0
7.9.3
7.9.2
7.9.1
7.9.0
7.8.3
7.8.2
7.8.0
7.7.1
7.7.0
7.6.2
7.6.1
7.6.0
7.5.0
7.4.2
7.4.1
7.4.0
7.2.1
7.2.0
7.1.1
7.1.0
6.12.0
6.11.11
6.11.10
6.11.9
6.11.8
6.11.7
6.11.6
6.11.4
6.11.2
6.11.1
6.10.9
6.10.8
6.10.7
6.10.6
6.10.5
6.10.4
6.10.3
6.10.2
6.10.1
6.9.1
6.6.1
6.5.0
6.4.4
6.4.3
6.4.2
6.4.1
6.4.0
5.12.4
5.12.3
5.12.2
5.12.1
5.12.0
5.11.1
5.11.0
5.9.2
5.9.1
5.8.5
5.8.4
5.8.3
5.8.1
5.8.0
5.6.1
5.5.1
5.4.3
5.4.2
5.4.1
5.3.1
5.3.0
5.2.1
5.1.7
5.1.6
5.1.5
5.1.4
5.1.3
5.1.2
5.1.1
4.12.11
4.12.10
4.12.9
4.12.8
4.12.7
4.12.6
4.12.5
4.12.4
4.12.3
4.12.2
4.12.1
4.12.0
4.11.13
4.11.12
4.11.11
4.11.10
4.11.9
4.11.8
4.11.7
4.11.6
4.11.5
4.11.4
4.11.3
4.11.2
4.11.1
4.11.0
4.10.9
4.10.8
4.10.7
4.10.6
4.10.5
4.10.4
4.10.3
4.10.2
4.10.1
4.10.0
4.7.7
4.7.4
4.7.3
4.7.2
4.7.1
4.7.0
4.4.1
4.4.0
1.4.0
NITRO Nitrogen Web Framework
Current section
Files
Jump to
Current section
Files
src/nitro_static.erl
-module(nitro_static).
-description('NITRO Static bridge for MAD containers').
-author('Maxim Sokhatsky').
-compile(export_all).
-include_lib("kernel/include/file.hrl").
init(_, _, _) -> {upgrade, protocol, cowboy_rest}.
rest_init(Req, {dir, Path, Extra})
when is_binary(Path) ->
rest_init(Req, {dir, binary_to_list(Path), Extra});
rest_init(Req, {dir, Path, Extra}) ->
{PathInfo, Req2} = cowboy_req:path_info(Req),
Info = {ok, #file_info{type = regular, size = 0}},
FileName = filename:join([Path | PathInfo]),
{ok, Req2, {FileName, Info, Extra}}.
malformed_request(Req, State) ->
{State =:= error, Req, State}.
forbidden(Req,
State = {_, {ok, #file_info{type = directory}}, _}) ->
{true, Req, State};
forbidden(Req, State = {_, {error, eacces}, _}) ->
{true, Req, State};
forbidden(Req,
State = {_, {ok, #file_info{access = Access}}, _})
when Access =:= write; Access =:= none ->
{true, Req, State};
forbidden(Req, State) -> {false, Req, State}.
fixpath(Path) ->
{Module, Fun} = application:get_env(n2o,
fixpath,
{nitro_static, fix}),
Module:Fun(Path).
fix(A) -> A.
content_types_provided(Req, State = {Path, _, Extra}) ->
case lists:keyfind(mimetypes, 1, Extra) of
false ->
{[{cow_mimetypes:web(Path), get_file}], Req, State};
{mimetypes, Module, Function} ->
{[{Module:Function(fixpath(Path)), get_file}],
Req,
State};
{mimetypes, Type} -> {[{Type, get_file}], Req, State}
end.
resource_exists(Req,
State = {_, {ok, #file_info{type = regular}}, _}) ->
{true, Req, State};
resource_exists(Req, State) -> {false, Req, State}.
generate_etag(Req,
State = {Path,
{ok, #file_info{size = Size, mtime = Mtime}},
Extra}) ->
case lists:keyfind(etag, 1, Extra) of
false ->
{generate_default_etag(Size, Mtime), Req, State};
{etag, Module, Function} ->
{Module:Function(Path, Size, Mtime), Req, State};
{etag, false} -> {undefined, Req, State}
end.
generate_default_etag(Size, Mtime) ->
{strong,
list_to_binary(integer_to_list(erlang:phash2({Size,
Mtime},
16#ffffffff)))}.
last_modified(Req,
State = {_, {ok, #file_info{mtime = Modified}}, _}) ->
{Modified, Req, State}.
get_file(Req,
State = {P, {ok, #file_info{size = _Size}}, _}) ->
Path = fixpath(P),
StringPath =
nitro:to_list(unicode:characters_to_binary(Path,
utf8,
utf8)),
[_Type, Name | RestPath] = filename:split(StringPath),
FileName = filename:absname(StringPath),
Raw = case file:read_file(FileName) of
{ok, Bin} -> Bin;
{error, _} ->
case mad_repl:load_file(StringPath) of
{ok, ETSFile} -> ETSFile;
{error, _} ->
case
file:read_file(filename:join([code:lib_dir(list_to_atom(Name))
| RestPath]))
of
{ok, ReleaseFile} -> ReleaseFile;
{error, _} -> <<>>
end
end
end,
Sendfile = fun (Socket, Transport) ->
Transport:send(Socket, Raw)
end,
{{stream, size(Raw), Sendfile}, Req, State}.