Browse Source

n2o_multipart to n4u_multipart

221V 3 years ago
parent
commit
0923b9583f
3 changed files with 103 additions and 80 deletions
  1. 1 1
      ebin/n4u.app
  2. 0 79
      src/endpoints/cowboy/n2o_multipart.erl
  3. 102 0
      src/endpoints/cowboy/n4u_multipart.erl

+ 1 - 1
ebin/n4u.app

@@ -2,7 +2,7 @@
   {description, "N4U WebSocket Application Server"},
   {vsn, "4.4.20"},
   {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, n4u_cowboy, n2o_multipart, n4u_static, n4u_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, n4u_cowboy, n4u_multipart, n4u_static, n4u_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]},
   {mod, {n4u_app, []}},
   {env, []}

+ 0 - 79
src/endpoints/cowboy/n2o_multipart.erl

@@ -1,79 +0,0 @@
--module(n2o_multipart).
--export([init/3,handle/2,terminate/3]).
--compile([export_all, nowarn_export_all]).
--define(MAX_FILE_SIZE_LIMIT, 900*1000*1000). % 300Kb
--define(TMP_PATH,".").
-
-% test multipart
-% curl -F file=@/Users/5HT/Desktop/40.tiff http://localhost:8000/multipart
-
-init(_Type, Req, []) ->
-	{ok, Req, undefined}.
-
-handle(Req, State) ->
-    {_Method, Req2} = cowboy_req:method(Req),
-    {B, ReqU} = case multipart(Req2, ?MODULE) of
-                {ok, ReqM} -> {<<"<h1>This is a response for POST</h1>">>, ReqM};
-                {rejected, file_size_limit, ReqM} -> {<<"POST: File Size Limit">>, ReqM} end,
-    {ok, Req3} = cowboy_req:reply(200, [], B, ReqU),
-    {ok, Req3, State}.
-
-terminate(_Reason, _Req, _State) ->
-    ok.
-
-multipart(Req, C) ->
-    multipart(Req, C, ?MAX_FILE_SIZE_LIMIT).
-multipart(Req, C, MaxFileSizeLimit) when is_atom(C) and is_integer(MaxFileSizeLimit) ->
-    case cowboy_req:part(Req) of
-        {ok, Headers, Req2} ->
-            Req5 = case cow_multipart:form_data(Headers) of
-                {data, FieldName} ->
-                    {ok, Body, Req3} = cowboy_req:part_body(Req2),
-                    ok = C:data_payload(FieldName, Body),
-                    Req3;
-                {file, FieldName, Filename, _CType, _CTransferEncoding} ->
-                    TempFilename = temp_filename(),
-                    {ok, IoDevice} = file:open(TempFilename, [raw, write]),
-                    Rsf = stream_file(Req2, IoDevice, 0, MaxFileSizeLimit),
-                    ok = file:close(IoDevice),
-                    case Rsf of
-                            {ok, FileSize, Req4} ->
-                                ok = C:file_payload(FieldName, Filename, TempFilename, FileSize),
-                                Req4;
-                            {limit, Reason, Req4} ->
-                                error_logger:warning_msg("Upload limit detected! Type: ~p, FieldName: ~p, Filename: ~p,~nReq: ~p~n",
-                                    [Reason, FieldName, Filename, Req4]),
-                                ok = file:delete(TempFilename),
-                                Req4
-                    end
-            end,
-            multipart(Req5, C, MaxFileSizeLimit);
-        {done, Req2} ->
-            {ok, Req2}
-    end.
-
-stream_file(Req, IoDevice, FileSize, MaxFileSizeLimit) ->
-    {Control, Data, Req2} = cowboy_req:part_body(Req),
-    NewFileSize = byte_size(Data) + FileSize,
-    case NewFileSize > MaxFileSizeLimit of
-        true -> {limit, file_size, Req2};
-        false ->
-            ok = file:write(IoDevice, Data),
-            case Control of
-                ok -> {ok, NewFileSize, Req2};
-                more -> stream_file(Req2, IoDevice, NewFileSize, MaxFileSizeLimit)
-            end
-    end.
-
-temp_filename() ->
-    list_to_binary(filename:join([?TMP_PATH, atom_to_list(?MODULE) ++ integer_to_list(erlang:phash2(make_ref()))])).
-
-data_payload(_FieldName, _Body) ->
-    % error_logger:info_msg("DATA PAYLOAD {FieldName, Body} = {~p,~p}", [_FieldName, _Body]),
-    ok.
-
-file_payload(_FieldName, _Filename, TempFilename, _FileSize) ->
-    NewFileName = <<"/tmp/upload.jpg">>,
-    % error_logger:info_msg("FILE PAYLOAD: {~p, ~p, ~p}", [_FieldName, _Filename, TempFilename]),
-    {ok, _BytesCopied} = file:copy(TempFilename, NewFileName),
-    ok.

+ 102 - 0
src/endpoints/cowboy/n4u_multipart.erl

@@ -0,0 +1,102 @@
+-module(n4u_multipart).
+
+-export([init/3, handle/2, terminate/3]).
+
+-export([multipart/2, multipart/3, stream_file/4,
+  temp_filename/0, data_payload/2, file_payload/4]).
+
+
+-define(MAX_FILE_SIZE_LIMIT, 900 * 1000 * 1000). % 300Kb
+-define(TMP_PATH, ".").
+
+
+% test multipart
+% curl -F file=file.pdf http://localhost:8000/multipart
+
+
+init(_Type, Req, []) ->
+  {ok, Req, undefined}.
+
+
+handle(Req, State) ->
+  {_Method, Req2} = cowboy_req:method(Req),
+  {B, ReqU} = case multipart(Req2, ?MODULE) of
+    {ok, ReqM} -> {<<"<h1>This is a response for POST</h1>">>, ReqM};
+    {rejected, file_size_limit, ReqM} -> {<<"POST: File Size Limit">>, ReqM}
+  end,
+  {ok, Req3} = cowboy_req:reply(200, [], B, ReqU),
+  {ok, Req3, State}.
+
+
+terminate(_Reason, _Req, _State) ->
+  ok.
+
+
+multipart(Req, C) ->
+  multipart(Req, C, ?MAX_FILE_SIZE_LIMIT).
+
+multipart(Req, C, Max_FileSize_Limit) when erlang:is_atom(C) and erlang:is_integer(Max_FileSize_Limit) ->
+  case cowboy_req:part(Req) of % todo check cowboy changes (1.0.1 to 2.9.0)
+    {ok, Headers, Req2} ->
+      Req5 = case cow_multipart:form_data(Headers) of
+        {data, Field_Name} ->
+          {ok, Body, Req3} = cowboy_req:part_body(Req2),
+          ok = C:data_payload(Field_Name, Body),
+          Req3;
+          
+        {file, Field_Name, Filename, _CType, _CTransferEncoding} ->
+          Temp_Filename = temp_filename(),
+          {ok, IoDevice} = file:open(Temp_Filename, [raw, write]),
+          Rsf = stream_file(Req2, IoDevice, 0, Max_FileSize_Limit),
+          ok = file:close(IoDevice),
+          
+          case Rsf of
+            {ok, File_Size, Req4} ->
+              ok = C:file_payload(Field_Name, Filename, Temp_Filename, File_Size),
+              Req4;
+            
+            {limit, Reason, Req4} ->
+              error_logger:warning_msg("Upload limit detected! Type: ~p, FieldName: ~p, Filename: ~p,~nReq: ~p~n",
+                [Reason, Field_Name, Filename, Req4]),
+              ok = file:delete(Temp_Filename),
+              Req4
+          end
+      end,
+      multipart(Req5, C, Max_FileSize_Limit);
+    
+    {done, Req2} ->
+      {ok, Req2}
+  end.
+
+
+stream_file(Req, IoDevice, File_Size, Max_FileSize_Limit) ->
+  {Control, Data, Req2} = cowboy_req:part_body(Req),
+  New_FileSize = erlang:byte_size(Data) + File_Size,
+  case New_FileSize > Max_FileSize_Limit of
+    true -> {limit, file_size, Req2};
+    false ->
+      ok = file:write(IoDevice, Data),
+      case Control of
+        ok -> {ok, New_FileSize, Req2};
+        more -> stream_file(Req2, IoDevice, New_FileSize, Max_FileSize_Limit)
+      end
+  end.
+
+
+temp_filename() ->
+  erlang:list_to_binary(filename:join(
+    [?TMP_PATH, erlang:atom_to_list(?MODULE) ++
+                erlang:integer_to_list( erlang:phash2(erlang:make_ref()) ) ] )).
+
+
+data_payload(_Field_Name, _Body) ->
+  %error_logger:info_msg("DATA PAYLOAD {Field_Name, Body} = {~p, ~p}", [_Field_Name, _Body]),
+  ok.
+
+
+file_payload(_Field_Name, _File_Name, Temp_Filename, _File_Size) ->
+  New_File_Name = <<"/tmp/upload.jpg">>, % todo think and change
+  % error_logger:info_msg("FILE PAYLOAD: {~p, ~p, ~p}", [_Field_Name, _File_Name, Temp_Filename]),
+  {ok, _Bytes_Copied} = file:copy(Temp_Filename, New_File_Name),
+  ok.
+