使用查询字符串的文件请求在NGINX后面的ASP.NET Core中失败

时间:2017-05-05 16:30:30

标签: json nginx proxy asp.net-core kestrel

我在Linux上运行NGINX反向代理后面有一个ASP.NET核心站点。我遇到了一个问题,如果我通过附加了查询字符串的代理执行文件请求(即用于缓存清除),我会收到404错误,但如果我直接请求完全相同的URL从应用程序(而不是通过NGINX),它工作正常,如果我删除查询字符串,它也可以正常工作。

下面的示例(NGINX代理正在侦听端口5000,应用程序正在侦听端口5002)...

如果我使用的网址如下: http://host-name:5000/path/file.json

我正确地得到了结果,这就是应用程序控制台输出中出现的结果:

[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://host-name:5000/path/file.json  
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://host-name:5000/path/file.json  
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
      Sending file. Request path: '/path/file.json'. Physical path: '/home/coreuser/debug/wwwroot/path/file.json'
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware:Information: Sending file. Request path: '/path/file.json'. Physical path: '/home/coreuser/debug/wwwroot/path/file.json'
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 400.9508ms 200 application/json

如果我使用的网址如下: http://host-name:5002/path/file.json

我正确地得到了结果,这就是应用程序控制台输出中出现的结果:

[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://host-name:5002/path/file.json  
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://host-name:5002/path/file.json  
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
      Sending file. Request path: '/path/file.json'. Physical path: '/home/coreuser/debug/wwwroot/path/file.json'
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware:Information: Sending file. Request path: '/path/file.json'. Physical path: '/home/coreuser/debug/wwwroot/path/file.json'
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 28.2031ms 200 application/json
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 28.2031ms 200 application/json

如果我使用的网址如下: http://host-name:5002/path/file.json?_dc=1020

我正确地得到了结果,这就是应用程序控制台输出中出现的结果:

[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://host-name:5002/path/bootstrap.json?_dc=1020  
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://host-name:5002/path/bootstrap.json?_dc=1020  
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
      Sending file. Request path: '/path/file.json'. Physical path: '/home/coreuser/debug/wwwroot/path/file.json'
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware:Information: Sending file. Request path: '/path/file.json'. Physical path:     '/home/coreuser/debug/wwwroot/path/file.json'
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 146.8157ms 200 application/json
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 146.8157ms 200 application/json

如果我使用的网址如下: http://host-name:5000/path/file.json?_dc=1020

我收到404错误,这就是应用程序控制台输出中出现的错误:

[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://host-name:5000/path/file.json?_dc=1020  
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://host-name:5000/path/file.json?_dc=1020  
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 379.4175ms 404 
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 379.4175ms 404 

现在,我不清楚NGINX是否存在与它转发到ASP.NET核心应用程序的问题相关的问题,或者它不仅仅是ASP.NET核心的一个问题应用程序(和/或Kestrel)因查询字符串和请求中显示的代理端口号的组合而被抛弃。

NGINX配置的相关部分如下所示:

server {
    server_name host-name;
    listen 5000 default_server;
    listen [::]:5000 default_server;
    location / {
        proxy_pass http://localhost:5002;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $http_host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Path $request_uri;
    }
}

有什么想法吗?

修改

我修改了我的服务器块后看起来像这样:

server {
    server_name host-name;
    listen 5000 default_server;
    listen [::]:5000 default_server;
    root /var/www/path-to-debug/wwwroot;
    location / {
        if ($query_string ~ "^(.*)_dc=(.*)$") {
          rewrite ^(.*)$ $uri?;
        }
        try_files $uri @proxy;
    }
    location @proxy {
        proxy_pass http://localhost:5002;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $http_host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Path $request_uri;
    }
}

现在正在正确获取特定文件(完全绕过Kestrel),但这似乎弄乱了我的一个控制器调用,它还附加了_dc = XXXX。

1 个答案:

答案 0 :(得分:0)

我已经通过修改我的服务器代理块来使这部分工作如下......这对我来说感觉像是一个黑客,但我还没有找到更好的解决方案。我还有其他问题,但如果我不能解决这些问题,我会发布单独的问题。

server {
    server_name host-name;
    listen 5000 default_server;
    listen [::]:5000 default_server;
    root /var/www/path-to-debug/wwwroot;
    location / {
        if ($query_string ~ "^(.*)_dc=(.*)$") {
          rewrite ^(.*)$ $uri?;
        }
        try_files $uri @proxy;
    }
    location @proxy {
        proxy_pass http://localhost:5002;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $http_host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Path $uri;
    }
}