.net 核心 nginx 托管套接字不允许 http post

Posted

技术标签:

【中文标题】.net 核心 nginx 托管套接字不允许 http post【英文标题】:.net core nginx hosting sockets doesn't allow http post 【发布时间】:2018-03-06 08:57:30 【问题描述】:

我正在尝试创建一个具有 http 功能的网站,包括 http post 功能,以及 web 套接字(例如 signalR)。我正在尝试使用 nginx 在 ubuntu 服务器上托管这个网站。通常在 nginx 上的设置是这样的:

server 
 listen 80;
 location / 
    proxy_pass http://localhost:5000;
    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 Connection "upgrade";才能使用websockets。但是,在 .net 核心项目中添加此行会导致所有 http post 请求显示 400 错误,如400 status error when posting form data in ASP.Net Core 所示。是否有允许帖子和网络套接字的设置?

【问题讨论】:

【参考方案1】:

使用 $http_connection 代替 keep-alive 或升级

proxy_set_header Connection $http_connection;

【讨论】:

完美!有用!您能否简要解释一下此更改的作用? 这部分适用于我。 Websocket 有效,POST 请求有效,但现在我遇到了一个新问题,在使用 Identity Server 记录后,它会将我重定向到没有任何参数的回调页面。【参考方案2】:

这不能解决您的问题,但可能是一种解决方法。我通过在 nginx 中设置 2 个代理位置到单个 asp.net 核心 kestrel 站点来解决这个问题。一个用于带有

的 websocket
proxy_cache_bypass $http_upgrade;

一个用于其他一切。看起来像这样。最上面的是除 websockets 之外的所有东西,下面是 websockets。注意我也有重写。

location /n/ 
        proxy_pass http://localhost:5001/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;


location /nsock/ 
        proxy_pass http://localhost:5001/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";

【讨论】:

你为什么要重写每个请求? 使用***配置,它基本上从 URL 中删除“n/”,因为它代理了 asp.net 核心站点。例如,此 URL hostname/n/api/entries 以 hostname:5001/api/entries 代理到 5001 端口。注意没有“n/”。我这样做是因为有几个 kestrel 实例在不同的端口上运行,我从常规 80/443 nginx 端口中的不同“子 Web 文件夹”代理它们。 不需要重写,这会导致 Nginx 重新处理请求。您只需将您的代理通行证更改为proxy_pass http://localhost:5001/;,与第二个指令相同 谢谢!我不知道结尾的斜杠会像在 proxy_pass 上那样工作。完全按照您所说的工作,无需重写。这是在 Pi 上运行的,因此感谢您没有在 nginx 中处理每个请求两次。我在上面编辑了我的 sn-p,以防有人偶然发现它。 它的工作原理是这样的:proxy_pass 到一个裸 url,即在 domain/ip/port 和完整的客户端请求 url 被传递给代理之后什么都没有。添加任何内容,即使只是对 proxy_pass 的斜线,并且添加的任何内容都会替换与该位置块匹配的客户端请求 url 的部分。因此,如果您有location /foo proxy_pass http://example.com/bar;,那么对example.com/foo/baz 的客户端请求将被代理到example.com/bar/baz【参考方案3】:

这是我使用 nginx 对 .Net Core API 的配置:

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_http_version 1.1;
    proxy_set_header X-NginX-Proxy true;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_cache_bypass $http_upgrade;
    proxy_redirect off;
    proxy_set_header X-Forwarded-Proto $scheme;

主要思想是删除这些行(如果有的话)

proxy_set_header Connection "upgrade";
proxy_set_header Connection keep-alive;

并在您的配置中插入这一行

proxy_set_header Connection $http_connection;

希望对你有帮助。

【讨论】:

以上是关于.net 核心 nginx 托管套接字不允许 http post的主要内容,如果未能解决你的问题,请参考以下文章

在.net核心应用程序中自托管HTTP(s)端点而不使用asp.net?

.NET 中 GC 的模式与风格

如何将 slug 添加到 asp.net 核心网站中的所有链接生成?

如何让自托管 HTTPS asp.net 核心站点自动使用绑定到端口的证书

从 Azure 中托管的 ASP.NET Core 5.0 MVC 站点调用 API/服务的间歇性套接字异常

Aurelia 的 Oauth2 托管在 asp .net 核心中