Packages
nitro
4.7.1
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(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}.