Browse Source

n2o 4.5 mqtt

Namdak Tonpa 8 years ago
parent
commit
76a4b3c6c0
1 changed files with 59 additions and 0 deletions
  1. 59 0
      src/nitro_static.erl

+ 59 - 0
src/nitro_static.erl

@@ -0,0 +1,59 @@
+-module(n2o_static).
+-description('N2O 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}.
+
+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(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={Path, {ok, #file_info{size=_Size}}, _}) ->
+    StringPath = nitro:to_list(unicode:characters_to_binary(Path,utf8,utf8)),
+    [_Type,Name|RestPath]=SplitPath = 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}.