Browse Source

n2o_static to n4u_static

221V 3 years ago
parent
commit
716f3962de
3 changed files with 113 additions and 71 deletions
  1. 1 1
      ebin/n4u.app
  2. 0 70
      src/endpoints/cowboy/n2o_static.erl
  3. 112 0
      src/endpoints/cowboy/n4u_static.erl

+ 1 - 1
ebin/n4u.app

@@ -2,7 +2,7 @@
   {description, "N4U WebSocket Application Server"},
   {description, "N4U WebSocket Application Server"},
   {vsn, "4.4.20"},
   {vsn, "4.4.20"},
   {applications, [kernel, stdlib, asn1, public_key, ssl, crypto, ranch, cowboy, fs, active, sh, gproc, nitro]},
   {applications, [kernel, stdlib, asn1, public_key, ssl, crypto, ranch, cowboy, fs, active, sh, gproc, nitro]},
-  {modules, [n2o, n4u_app, n4u_sup, n4u_async, n4u_xhr, n4u_cx, n2o_cowboy, n2o_multipart, n2o_static, n2o_stream, n4u_document, n4u_proto, n4u_relay, n4u_error, n4u_io, n4u_log, n4u_mq, n4u_pickle, n4u_query, n4u_secret, n4u_session, n4u_syn, n4u_client, n4u_file, n4u_heart, n4u_http, n4u_nitrogen, n4u_text, wf, wf_convert, wf_utils]},
+  {modules, [n2o, n4u_app, n4u_sup, n4u_async, n4u_xhr, n4u_cx, n2o_cowboy, n2o_multipart, n4u_static, n2o_stream, n4u_document, n4u_proto, n4u_relay, n4u_error, n4u_io, n4u_log, n4u_mq, n4u_pickle, n4u_query, n4u_secret, n4u_session, n4u_syn, n4u_client, n4u_file, n4u_heart, n4u_http, n4u_nitrogen, n4u_text, wf, wf_convert, wf_utils]},
   {registered, [n4u_sup]},
   {registered, [n4u_sup]},
   {mod, {n4u_app, []}},
   {mod, {n4u_app, []}},
   {env, []}
   {env, []}

+ 0 - 70
src/endpoints/cowboy/n2o_static.erl

@@ -1,70 +0,0 @@
--module(n2o_static).
--description('N4U Static Bridge to files in LING image, MAD bundle or OS').
--compile([export_all, nowarn_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]),
-	wf:info(?MODULE,"Rest Init: ~p~n\r",[FileName]),
-    {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}) ->
-    wf:info(?MODULE,"Content Type Provided: ~p~n\r",[Path]),
-	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 = wf:to_list(unicode:characters_to_binary(Path,utf8,utf8)),
-    [_Type,Name|RestPath]=SplitPath = filename:split(StringPath),
-    wf:info(?MODULE,"Split Path: ~p~n\r",[SplitPath]),
-    %wf:info(?MODULE,"Code Path: ~p~n\r",[filename:join([code:lib_dir(Name)|RestPath])]),
-	FileName = filename:absname(StringPath),
-    wf:info(?MODULE,"Abs Name: ~p~n\r",[FileName]),
-    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,
-    wf:info(?MODULE,"Cowboy Requested Static File: ~p~n\r ~p~n\r",[Raw,filename:absname(StringPath)]),
-	Sendfile = fun (Socket, Transport) ->
-		case Transport:send(Socket, Raw) of
-			{ok, _} -> ok;
-			{error, closed} -> ok;
-			{error, etimedout} -> ok;
-			_ -> ok end end,
-	{{stream, size(Raw), Sendfile}, Req, State}.

+ 112 - 0
src/endpoints/cowboy/n4u_static.erl

@@ -0,0 +1,112 @@
+-module(n4u_static).
+-include_lib("kernel/include/file.hrl").
+
+-export([init/3, rest_init/2, forbidden/2, malformed_request/2,
+  content_types_provided/2, resource_exists/2, generate_etag/2,
+  last_modified/2, get_file/2, mad_load_file/1]). % todo check last func - maybe needs outside this module
+
+
+% N4U Static Bridge to files
+
+init(_, _, _) -> {upgrade, protocol, cowboy_rest}.
+
+
+rest_init(Req, {dir, Path, Extra}) when erlang:is_binary(Path) ->
+  rest_init(Req, {dir, erlang:binary_to_list(Path), Extra});
+
+rest_init(Req, {dir, Path, Extra}) ->
+  {PathInfo, Req2} = cowboy_req:path_info(Req), %% todo check - replace with cowboy bridge func
+  Info = {ok, #file_info{type = regular, 'size' = 0}},
+  FileName = filename:join([Path|PathInfo]),
+  wf:info(?MODULE, "Rest Init: ~p~n", [FileName]),
+  {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}) ->
+  wf:info(?MODULE,"Content Type Provided: ~p~n",[Path]),
+  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, erlang:list_to_binary(erlang: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),
+  wf:info(?MODULE, "Split Path: ~p~n", [SplitPath]),
+  %wf:info(?MODULE, "Code Path: ~p~n", [filename:join([code:lib_dir(Name)|RestPath])]),
+  FileName = filename:absname(StringPath),
+  wf:info(?MODULE, "Abs Name: ~p~n", [FileName]),
+  Raw = case file:read_file(FileName) of
+    {ok, Bin}  -> Bin;
+    {error, _} ->
+      case ?MODULE:mad_load_file(StringPath) of % todo check how it works
+        {ok, ETSFile} -> ETSFile;
+        {error, _} ->
+          case file:read_file( filename:join( [code:lib_dir(Name)|RestPath] ) ) of
+            {ok, ReleaseFile} -> ReleaseFile;
+            {error, _} -> <<>>
+          end
+      end
+  end,
+  wf:info(?MODULE, "Cowboy Requested Static File: ~p~n", [FileName]),
+  Sendfile = fun(Socket, Transport) ->
+    case Transport:send(Socket, Raw) of
+      {ok, _} -> ok;
+      {error, closed} -> ok;
+      {error, etimedout} -> ok;
+      _ -> ok
+    end
+  end,
+  {{stream, erlang:size(Raw), Sendfile}, Req, State}.
+
+
+ets_created() ->
+  case ets:info(filesystem) of
+    undefined ->
+      ets:new(filesystem, [set, named_table, {keypos, 1}, public]);
+    _ ->
+      skip
+  end.
+
+
+mad_load_file(Name)  ->
+  ets_created(),
+  case ets:lookup(filesystem, Name) of
+    [{Name, Bin}] -> {ok, Bin};
+    _ -> {error, etsfs}
+  end.
+