代码之家  ›  专栏  ›  技术社区  ›  Pierre-Adrien

nginx+rails+sendfile:找不到文件

  •  0
  • Pierre-Adrien  · 技术社区  · 6 年前

    最近为nginx+rails设置sendfile时遇到问题。我们有一种已经由nginx处理的文件下载,我们想添加第二个规则来处理另一个位置的另一种文件,但是到目前为止我们还没有成功。

    Ruby控制器:

    def download_file
      send_file("/srv/www/myapp/shared/tmp/directory/file.zip")
    end
    

    环境配置文件:

    Rails.application.configure do
      # ..  
      config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
      # ..
    end
    

    nginx配置:

    upstream myapp {
      server 127.0.0.1:9292;
    }
    
    server {
      listen 80;    
      server_name myapp.tld;
    
      client_max_body_size 10M;
    
      root /srv/www/myapp/current/public; 
    
      # This first block works perfectly
      location /__working_file {
        internal;
        alias /var/lib/myapp;
      }    
    
      # This second block does not work at all
      location /__new_files {
        internal;
        alias /srv/www/myapp/shared/tmp/directory;
      }
    
      location / {
        root /srv/www/myapp/current/public;
        try_files $uri @app;
      }
    
      location @app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
    
        proxy_set_header X-Sendfile-Type X-Accel-Redirect;
        # This first rule works perfectly
        proxy_set_header X-Accel-Mapping /var/lib/myapp/=/__working_file/;
        # This second rule doesn't
        proxy_set_header X-Accel-Mapping /srv/www/myapp/shared/tmp/directory/=/__new_files/;
    
        proxy_pass_header Server;
        proxy_read_timeout 300;
    
        proxy_pass http://myapp;
      }
    }
    

    结果

    访问控制器操作时, send_file 命令被触发,然后我们在浏览器中得到一个“找不到文件”,没有下载任何内容,Rails日志显示了这一点:

    Sent file /srv/www/myapp/shared/tmp/directory/file.zip (0.4ms)
    Completed 200 OK in 169ms (ActiveRecord: 37.5ms)
    Started GET "/srv/www/myapp/shared/tmp/directory/file.zip" for 109.190.197.126 at 2018-11-20 11:34:44 +0100
    
    ActionController::RoutingError (No route matches [GET] "/srv/www/myapp/shared/tmp/directory/file.zip"):
    

    文件确实存在并且可读,但nginx似乎无法访问它。有什么想法吗?

    2 回复  |  直到 6 年前
        1
  •  0
  •   ratan    6 年前

    在路由过程中,它无法获取。你必须提供适当的工作路线。

        2
  •  0
  •   Pierre-Adrien    6 年前

    问题出在这两者之间 X-Accel-Mapping 被设置。 Rack 确实能够处理多个映射,因为合并 this PR #1187 .

    但是,截至今天,此PR已在master上合并,但尚未发布(2.0.6当前是最新版本) .

    唯一的问题是,设置多个映射的正确方法是使用一个 proxy_set_header 规则,并用逗号分隔每个映射,如下所示:

    proxy_set_header X-Accel-Mapping, /var/lib/myapp/=/__working_file/,/srv/www/myapp/shared/tmp/directory/=/__new_files/
    
    推荐文章