Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uploaded files do not appear in the directory #145

Open
maro584 opened this issue Jan 30, 2023 · 2 comments
Open

Uploaded files do not appear in the directory #145

maro584 opened this issue Jan 30, 2023 · 2 comments

Comments

@maro584
Copy link

maro584 commented Jan 30, 2023

I used the following documentation to complete the setup:

https://www.nginx.com/resources/wiki/modules/upload/

When trying to upload via the form from the example module configuration, the file in the designated directory does not appear, the directory obviously exists and for the time of testing I gave it 777 permissions. Below are the logs generated when uploading the file:

tail -f /usr/local/nginx/logs/access.log

x.x.x.x - - [30/Jan/2023:15:50:14 +0000] "GET /upload/upload.html HTTP/1.1" 200 587 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
x.x.x.x - user [30/Jan/2023:15:50:14 +0000] "POST /upload HTTP/1.1" 301 169 "http://x.x.x.x/upload/upload.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
x.x.x.x - user [30/Jan/2023:15:50:18 +0000] "GET /upload/ HTTP/1.1" 200 277 "http://x.x.x.x/upload/upload.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"

upload.html

<title>Test upload</title>

Select files to upload







nginx.conf
#user nobody;
worker_processes 1;

error_log logs/error.log;
error_log logs/error.log notice;
error_log logs/error.log info;

#pid logs/nginx.pid;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;

#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
#                  '$status $body_bytes_sent "$http_referer" '
#                  '"$http_user_agent" "$http_x_forwarded_for"';

#access_log  logs/access.log  main;

sendfile        on;
#tcp_nopush     on;

#keepalive_timeout  0;
keepalive_timeout  65;

#gzip  on;

server {
    listen       80;
    client_max_body_size 100m;
    server_name  localhost;
    root <some_path>;
    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    location / {
        index  index.html index.htm;
        autoindex on;
        autoindex_exact_size on;
        allow x.x.x.x;
        allow x.x.x.x;

    }
    location /upload {
    # Pass altered request body to this location
       # upload_pass   @test;
        autoindex on;
        autoindex_exact_size on;
    # Store files to this directory
    # The directory is hashed, subdirectories 0 1 2 3 4 5 6 7 8 9 should exist
        upload_store /tmp/upload;

    # Allow uploaded files to be read only by user
        upload_store_access user:r;

    # Set specified fields in request body
        upload_set_form_field $upload_field_name.name "$upload_file_name";
        upload_set_form_field $upload_field_name.content_type "$upload_content_type";
        upload_set_form_field $upload_field_name.path "$upload_tmp_path";

    # Inform backend about hash and size of a file
        upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
        upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";

        upload_pass_form_field "^submit$|^description$";

        upload_cleanup 400 404 499 500-505;
    }

# Pass altered request body to a backend
    location @test {
        proxy_pass   http://localhost:8080;
    }
    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}


# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
#    listen       8000;
#    listen       somename:8080;
#    server_name  somename  alias  another.alias;

#    location / {
#        root   html;
#        index  index.html index.htm;
#    }
#}


# HTTPS server
#
#server {
#    listen       443 ssl;
#    server_name  localhost;

#    ssl_certificate      cert.pem;
#    ssl_certificate_key  cert.key;

#    ssl_session_cache    shared:SSL:1m;
#    ssl_session_timeout  5m;

#    ssl_ciphers  HIGH:!aNULL:!MD5;
#    ssl_prefer_server_ciphers  on;

#    location / {
#        root   html;
#        index  index.html index.htm;
#    }
#}

}

Directory z for files, despite using the configuration, is empty, the uploaded files are small, a few Kb.

nginx version: nginx/1.20.2

Red Hat Enterprise Linux release 8.7 (Ootpa)

@kitamiq
Copy link

kitamiq commented Feb 14, 2023

I spent whole night trying to fix the same issue. Just as @maro584, i gave up on using the default upload_store /tmp/upload 1;, because even though the subdirectories clearly exist and have the correct permissions (ended up with 777), the error.log was telling me (2: No such file or directory). Switching to upload_store /tmp stopped throwing any errors or messages at all, however the files were actually never saving in /tmp/, and trying different locations such as /var/tmp and so on didn't help. I also tried using different users in the nginx.conf's user directive, including my own working user to ensure it's not a permissions/access issue.

Things suddenly started working when I changed the line to upload_store /var/log/nginx/;, which of course is ridiculous and wrong, but it's the place nginx 100% can access, and indeed, the files started uploading. I don't know anything about nginx' inner structure and thus have no idea why it doesn't allow itself not just accessing but "seeing" any directories outside of the working dir paths defined when compiling, maybe it's the default behavior for security reasons, maybe I missed some obscure compilation flag that would allow this.

So, I guess my advice is to implement a temporary solution, save the files into one of the nginx directories and make your backend scripts instantly move them to a better location if you plan to use nginx as a fast local proxy for testing your python/ruby/php webapp, or switch to Apache if you need a production web server, that would save you a lot of time. Honestly, it's depressing how there is little to no online help about such issues in nginx and its modules.

@btingle
Copy link

btingle commented Oct 18, 2024

Hey everyone, I also came across and managed to solve this issue. The solution was not obvious!

I am assuming everyone having this issue was running NGINX through systemd- systemd does something funny, it turns out!
It remaps /tmp and /var/tmp for each service to it's own ~special~ tmp directory, of the format [/var]/tmp/systemd-private-*-nginx.service-*.
Thus, any directories you have created in your regular /tmp or /var/tmp directory will not be seen by the nginx service! This is only an issue when hashed directories are enabled by upload_store.

To make sure the files are actually saved, you can either create the hashed subdirectories in the special systemd temp folder each time the nginx service launches or just use forgo hashing entirely like so:

upload_store /tmp

Note that if you want to see the files with these methods, you will need to check the /tmp/systemd-private-*nginx*/tmp directory for them!

You can also just change your upload_store directory to a non-tmp directory like @kitamiq did!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants