Nginx + uWSGI + Flask: OSError при загрузке файла с помощью Firefox - PullRequest
0 голосов
/ 03 января 2019

Я получил установку Nginx + uWSGI + Flask, реализующую веб-приложение, в котором пользователь загружает большой файл (приблизительно 3 ГБ). Проблема в том, что иногда при использовании Firefox загрузка не начинается (панель менеджера загрузки переходит туда-сюда). Проблема не возникает с Chrome.

В журнале uWSGI отображается следующее сообщение:

uwsgi_response_write_body_do() TIMEOUT !!! 
OSError: write error

Я попытался установить uwsgi_max_temp_file_size 0; в файле конфигурации Nginx, но это не решило мою проблему.

Вот весь соответствующий код.

  • Код колбы

    def generate():
    
        # create and return your data in small parts here
        with open(os.path.abspath(app.root_path)+server_path, 'rb') as f:
            while True:
                read_data = f.read(1024)
                if not read_data:
                    break # done
                yield read_data            
    
    response = Response(stream_with_context(generate()), mimetype=mimetype)
    response.headers['Content-Disposition'] = 'attachment; filename={}'.format(file_basename)
    response.headers['Content-Length'] = os.path.getsize(os.path.abspath(app.root_path)+server_path)
    return response
    
  • uWSGI

    [uwsgi]
    
    virtualenv = /home/simone/Documents/LabDash/venv
    
    mount = /home/simone/Documents/LabDash=LabDash:app
    
    ; tell uWSGI to rewrite PATH_INFO and SCRIPT_NAME according to mount-points
    manage-script-name = true
    
    master = true
    processes = 5
    
    socket = LabDash.sock
    chmod-socket = 660
    vacuum = true
    
    die-on-term = true
    
    ; to remove in production, just used for debugging
    catch-exceptions= true
    
    ; auto-reload feature
    touch-reload = /home/simone/Documents/LabDash/app/routes.py
    
  • Nginx

        user www-data;
        worker_processes auto;
        pid /run/nginx.pid;
        include /etc/nginx/modules-enabled/*.conf;
    
        events {
            worker_connections 768;
            # multi_accept on;
        }
    
        http {
    
            ##
            # Basic Settings
            ##
    
            sendfile on;
            tcp_nopush on;
            tcp_nodelay on;
            keepalive_timeout 65;
            types_hash_max_size 2048;
            # server_tokens off;
    
            # server_names_hash_bucket_size 64;
            # server_name_in_redirect off;
    
            include /etc/nginx/mime.types;
            default_type application/octet-stream;
    
            ##
            # SSL Settings
            ##
    
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
            ssl_prefer_server_ciphers on;
    
            ##
            # Logging Settings
            ##
    
            access_log /var/log/nginx/access.log;
            error_log /var/log/nginx/error.log debug;
    
            ##
            # Gzip Settings
            ##
    
            gzip on;
    
            ##
            # Virtual Host Configs
            ##
    
            include /etc/nginx/conf.d/*.conf;
            include /etc/nginx/sites-enabled/*;
        }
    
    server {
    listen 4000;
    client_max_body_size 10G;
    server_name testdomain www.testdomain;
    
    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/simone/Documents/LabDash/LabDash.sock;
       }
    }
    

В журналах ошибок Nginx:

writev() failed (104: Connection reset by peer) while reading upstream

Если вместо потоковой передачи используется send_file Flask, проблема сохраняется, и в журнале Nginx есть:

epoll_wait() reported that client prematurely closed connection, so upstream connection is closed too
...