为什么 NGINX 对多部分文件上传请求的验证会立即关闭连接?
Why does NGINX authverify of multipart file upload request receive an immediate closed connection?
NGINX 在 8080 上为我们的网关提供服务,通过我们在 8100 上的 AAA 服务器进行身份验证,然后将经过身份验证的请求传递到 8081 上的 NGINX 进行路由。除了针对我们的文件服务器的文件上传请求(任何大小)之外,一切都可以直接开箱即用。发送到8080的Gateway,强制关闭8100到AAA的连接时出现500 Internal Server Error。发送到 8081,NGINX 路由多部分文件上传内容就好了。
改变client_max_body_size没有帮助;也不会更改 keep-alive 值。在 NGINX 中执行 multipart 验证步骤的技巧是什么?
server {
listen 8080;
listen [::]:8080;
server_name _;
access_log /var/log/nginx/api.auth.log;
location = /authverify {
internal;
proxy_pass http://127.0.0.1:8081/api/v1/aaa/authentication/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
location /api/v1/aaa/authentication {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api {
auth_request /authverify;
auth_request_set $auth_header $upstream_http_authorization;
more_set_headers "Authorization: $auth_header";
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
非常感谢任何帮助! (我们是 运行 nginx 1.6.2,没有安装额外的模块。)
更新:
似乎 WEB API 对请求 header 在内容已被抑制时仍然指示 "multipart" 不满意。我已经研究过在身份验证请求中抑制 Content-Type 但没有找到令人满意的实现方法...
2019-11-22 05:20:41.896 +00:00 [Error] The server encountered an
internal error and was unable to process your request. Try it again.
System.IO.IOException: Unexpected end of Stream, the content may have
already been read by another component. at
Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.ReadAsync(Byte[]
buffer, Int32 offset, Int32 count, CancellationToken
cancellationToken) at
Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.DrainAsync(Stream
stream, ArrayPool1 bytePool, Nullable
1 limit, CancellationToken
cancellationToken) at
Microsoft.AspNetCore.WebUtilities.MultipartReader.ReadNextSectionAsync(CancellationToken
cancellationToken) at
Microsoft.AspNetCore.Http.Features.FormFeature.InnerReadFormAsync(CancellationToken
cancellationToken) at
Microsoft.AspNetCore.Mvc.ModelBinding.FormValueProviderFactory.AddValueProviderAsync(ValueProviderFactoryContext
context) at
Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ActionContext
actionContext, IList`1 factories) at
Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ControllerContext
controllerContext) at
Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<g__Bind|0>d.MoveNext()
就我而言,重新设置 Content-Type
解决了问题:
location = /authverify {
internal;
proxy_pass http://127.0.0.1:8081/api/v1/aaa/authentication/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Content-Type "";
proxy_set_header X-Original-URI $request_uri;
}
但这可能取决于您的 API 处理请求的方式。
NGINX 在 8080 上为我们的网关提供服务,通过我们在 8100 上的 AAA 服务器进行身份验证,然后将经过身份验证的请求传递到 8081 上的 NGINX 进行路由。除了针对我们的文件服务器的文件上传请求(任何大小)之外,一切都可以直接开箱即用。发送到8080的Gateway,强制关闭8100到AAA的连接时出现500 Internal Server Error。发送到 8081,NGINX 路由多部分文件上传内容就好了。
改变client_max_body_size没有帮助;也不会更改 keep-alive 值。在 NGINX 中执行 multipart 验证步骤的技巧是什么?
server {
listen 8080;
listen [::]:8080;
server_name _;
access_log /var/log/nginx/api.auth.log;
location = /authverify {
internal;
proxy_pass http://127.0.0.1:8081/api/v1/aaa/authentication/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
location /api/v1/aaa/authentication {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api {
auth_request /authverify;
auth_request_set $auth_header $upstream_http_authorization;
more_set_headers "Authorization: $auth_header";
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
非常感谢任何帮助! (我们是 运行 nginx 1.6.2,没有安装额外的模块。)
更新: 似乎 WEB API 对请求 header 在内容已被抑制时仍然指示 "multipart" 不满意。我已经研究过在身份验证请求中抑制 Content-Type 但没有找到令人满意的实现方法...
2019-11-22 05:20:41.896 +00:00 [Error] The server encountered an internal error and was unable to process your request. Try it again. System.IO.IOException: Unexpected end of Stream, the content may have already been read by another component. at Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.DrainAsync(Stream stream, ArrayPool
1 bytePool, Nullable
1 limit, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.MultipartReader.ReadNextSectionAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Features.FormFeature.InnerReadFormAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Mvc.ModelBinding.FormValueProviderFactory.AddValueProviderAsync(ValueProviderFactoryContext context) at Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ActionContext actionContext, IList`1 factories) at Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ControllerContext controllerContext) at Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<g__Bind|0>d.MoveNext()
就我而言,重新设置 Content-Type
解决了问题:
location = /authverify {
internal;
proxy_pass http://127.0.0.1:8081/api/v1/aaa/authentication/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Content-Type "";
proxy_set_header X-Original-URI $request_uri;
}
但这可能取决于您的 API 处理请求的方式。