P
P
Pavel Kaptur2019-07-04 17:47:11
linux
Pavel Kaptur, 2019-07-04 17:47:11

How to handle file upload via GET and POST requests?

Good afternoon, there was a need to make a server that accepts files via GET and POST requests and saves them to a specific folder with normal names. There is an implementation of such a server in python, but there are questions about the performance of the server and its reliability. I want to do something like this on nginx or any other industrial web server. Do I understand correctly that I need to write some kind of backend?
In general, I know nothing about this, and I ask you to direct me to the right path of excavation. I read a lot of things, but none of what I read worked, and something is very outdated.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Andrew, 2019-07-04
@drem1lin

You can get by with nginx alone (using lua-nginx-module):

nginx_upload.conf
pid        logs/nginx_upload.pid;
events {
    worker_connections  1024;
}

http {
    lua_package_path '/usr/local/lib/lua/5.1/?.lua;;';

    server {
        listen       8001;

        # download
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;

        # auth
        auth_basic "Restricted site";
        auth_basic_user_file /opt/nginx/.htpasswd;

        location /download {
            alias upload;
        }


        location ~ ^/upload_lua(/.*)?$ {
            set $store_path upload$1/;
            content_by_lua_file conf/lua/my_upload.lua;
        }

        location ~ ^/delete/(.*)$ {
            set $file_path upload/$1;
            content_by_lua_file conf/lua/my_delete.lua;
        }
    }
}

https://www.yanxurui.cc/posts/server/2017-03-21-NG...
local upload = require "resty.upload"

local function my_get_file_name(header)
    local file_name
    for i, ele in ipairs(header) do
        file_name = string.match(ele, 'filename="(.*)"')
        if file_name and file_name ~= '' then
            return file_name
        end
    end
    return nil
end

local chunk_size = 4096
local form = upload:new(chunk_size)
local file
local file_path
while true do
    local typ, res, err = form:read()

    if not typ then
         ngx.say("failed to read: ", err)
         return
    end

    if typ == "header" then
        local file_name = my_get_file_name(res)
        if file_name then
            file_path = ngx.var.store_path..file_name
            file = io.open(file_path, "w+")
            if not file then
                ngx.say("failed to open file ", file_path)
                return
            end
        end

    elseif typ == "body" then
        if file then
            file:write(res)
        end

    elseif typ == "part_end" then
        if file then
            file:close()
            file = nil
            ngx.say("upload to "..file_path.." successfully!")
        end
    elseif typ == "eof" then
        break

    else
        -- do nothing
    end
end

Used:
openresty/lua-resty-upload
lua-nginx-module
Or simple PHP example:
upload.php
<!DOCTYPE html>
<html>
<head>
  <title>Upload your files</title>
</head>
<body>
  <form enctype="multipart/form-data" action="upload.php" method="POST">
    <p>Upload your file</p>
    <input type="file" name="uploaded_file"></input><br />
    <input type="submit" value="Upload"></input>
  </form>
</body>
</html>
<?PHP
  if(!empty($_FILES['uploaded_file']))
  {
    $path = "uploads/";
    $path = $path . basename( $_FILES['uploaded_file']['name']);
    if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $path)) {
      echo "The file ".  basename( $_FILES['uploaded_file']['name']). 
      " has been uploaded";
    } else{
        echo "There was an error uploading the file, please try again!";
    }
  }
?>

A
Alexander, 2019-07-04
@NeiroNx

Yes, in any case, you will need Backend and it doesn’t matter what language it will be in, it matters how many files and what size you need to accept - you will have to set the size limit, in PHP it is 50 megabytes by default, in python it is a different value. Perhaps the Python script will have to be connected via the wsgi layer to Apache or Nginx.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question