使用 Azure Web 应用和 Web API 的 HTTP2 请求



我们最近在 azure 网站和 web API 之间启用了 HTTP2 流量。 这是通过 Azure 门户中的开关启用的。 从 Web 应用到 Web API 的第一个请求失败,并显示:(失败( 网络::ERR_SPDY_PROTOCOL_ERROR

并且看起来请求从未进入 api。 我们已尝试将这两个应用升级到 .NET 4.6.1,假设旧版本不支持新的 HTTP2 协议。 我正在努力在 chrome 中的开发工具或使用 chrome 中的高级跟踪工具中找到任何有用的东西。 以下是我们在使用高级 Chrome 网络工具 (chrome://net-internals/#events( 检查对 api 的请求的详细 HTTP2 会话事件跟踪时看到的错误:

t=314214 [st=  0] +HTTP2_SESSION  [dt=?]
--> host = "autoservice.compareunittest.com:443"
--> proxy = "DIRECT"
t=314214 [st=  0]    HTTP2_SESSION_INITIALIZED
--> protocol = "h2"
--> source_dependency = 129205 (SOCKET)
t=314214 [st=  0]    HTTP2_SESSION_SEND_SETTINGS
--> settings = ["[id:1 (SETTINGS_HEADER_TABLE_SIZE) value:65536]","[id:3 (SETTINGS_MAX_CONCURRENT_STREAMS) value:1000]","[id:4 (SETTINGS_INITIAL_WINDOW_SIZE) value:6291456]"]
t=314214 [st=  0]    HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 15663105
--> window_size = 15728640
t=314214 [st=  0]    HTTP2_SESSION_SEND_WINDOW_UPDATE
--> delta = 15663105
--> stream_id = 0
t=314214 [st=  0]    HTTP2_SESSION_SEND_HEADERS
--> exclusive = true
--> fin = true
--> has_priority = true
--> :method: OPTIONS
:authority: autoservice.compareunittest.com
:scheme: https
:path: /api/mi/abtestlogbatch
access-control-request-method: POST
origin: https://motor.compareunittest.com
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36
access-control-request-headers: __requestverificationtoken,authorization,content-type,correlationid
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-GB,en-US;q=0.9,en;q=0.8
--> parent_stream_id = 0
--> source_dependency = 129202 (HTTP_STREAM_JOB)
--> stream_id = 1
--> weight = 220
t=314424 [st=210]    HTTP2_SESSION_RECV_SETTINGS
t=314424 [st=210]    HTTP2_SESSION_SEND_SETTINGS_ACK
t=314424 [st=210]    HTTP2_SESSION_RECV_SETTING
--> id = "3 (SETTINGS_MAX_CONCURRENT_STREAMS)"
--> value = 100
t=314424 [st=210]    HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE
--> delta_window_size = 983041
t=314424 [st=210]    HTTP2_SESSION_RECV_SETTING
--> id = "4 (SETTINGS_INITIAL_WINDOW_SIZE)"
--> value = 1048576
t=314424 [st=210]    HTTP2_SESSION_RECV_WINDOW_UPDATE
--> delta = 983041
--> stream_id = 0
t=314424 [st=210]    HTTP2_SESSION_UPDATE_SEND_WINDOW
--> delta = 983041
--> window_size = 1048576
t=314424 [st=210]    HTTP2_SESSION_RECV_SETTINGS_ACK
t=314424 [st=210]    HTTP2_SESSION_RECV_HEADERS
--> fin = false
--> :status: 200
allow: OPTIONS, TRACE, GET, HEAD, POST
server: Microsoft-IIS/10.0
public: OPTIONS, TRACE, GET, HEAD, POST
x-powered-by: ASP.NET
access-control-allow-origin: *
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control, __RequestVerificationToken, CorrelationId
x-frame-options: SAMEORIGIN
date: Thu, 03 May 2018 14:48:24 GMT
content-length: 0
--> stream_id = 1
t=314424 [st=210]    HTTP2_SESSION_RECV_DATA
--> fin = true
--> size = 0
--> stream_id = 1
t=314535 [st=321]    HTTP2_SESSION_SEND_HEADERS
--> exclusive = true
--> fin = false
--> has_priority = true
--> :method: POST
:authority: autoservice.compareunittest.com
:scheme: https
:path: /api/mi/abtestlogbatch
content-length: 311
correlationid: 72b3a477-1129-4ca4-a373-3bd6cdc2c5b0
origin: https://motor.compareunittest.com
authorization: 48iFi3wa47u4yT46TfwRj3dcC651N275Cn=
content-type: application/json;charset=UTF-8
accept: application/json, text/plain, */*
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36
__requestverificationtoken: GmI53U-AOKgq8RZ92Qf59kazIktqpOEPVZ4LzF_uL562FYPOz2ylxk94VYG3dJwZm-ZwhrfMOYjvfPWovI37OJ4mI3yDG6Do2DaBGY0HkC41:kE5Uxfh3fNgktZIhW1XG84nflggp3EULxtJbu_NCHiBwPxrOMeOAxiI7CoBWMGH3o8HlHU7Cz3ISWhC3cxapm_IfuzB-YF4GpU0NsqPvynA1
referer: https://motor.compareunittest.com/
accept-encoding: gzip, deflate, br
accept-language: en-GB,en-US;q=0.9,en;q=0.8
--> parent_stream_id = 0
--> source_dependency = 129229 (HTTP_STREAM_JOB)
--> stream_id = 3
--> weight = 220
t=314535 [st=321]    HTTP2_SESSION_SEND_DATA
--> fin = true
--> size = 311
--> stream_id = 3
t=314535 [st=321]    HTTP2_SESSION_UPDATE_SEND_WINDOW
--> delta = -311
--> window_size = 1048265
t=314542 [st=328]    HTTP2_SESSION_RECV_RST_STREAM
--> error_code = "1 (PROTOCOL_ERROR)"
--> stream_id = 3
t=314653 [st=439]    HTTP2_SESSION_SEND_HEADERS
--> exclusive = true
--> fin = true
--> has_priority = true
--> :method: OPTIONS
:authority: autoservice.compareunittest.com
:scheme: https
:path: /api/mi/pagevisit
access-control-request-method: POST
origin: https://motor.compareunittest.com
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36
access-control-request-headers: __requestverificationtoken,authorization,content-type,correlationid
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-GB,en-US;q=0.9,en;q=0.8
--> parent_stream_id = 0
--> source_dependency = 129239 (HTTP_STREAM_JOB)
--> stream_id = 5
--> weight = 220
t=314654 [st=440]    HTTP2_SESSION_RECV_WINDOW_UPDATE
--> delta = 311
--> stream_id = 0
t=314654 [st=440]    HTTP2_SESSION_UPDATE_SEND_WINDOW
--> delta = 311
--> window_size = 1048576
t=314913 [st=699]    HTTP2_SESSION_RECV_HEADERS
--> fin = false
--> :status: 200
allow: OPTIONS, TRACE, GET, HEAD, POST
server: Microsoft-IIS/10.0
public: OPTIONS, TRACE, GET, HEAD, POST
x-powered-by: ASP.NET
access-control-allow-origin: *
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control, __RequestVerificationToken, CorrelationId
x-frame-options: SAMEORIGIN
date: Thu, 03 May 2018 14:48:25 GMT
content-length: 0
--> stream_id = 5
t=314914 [st=700]    HTTP2_SESSION_RECV_DATA
--> fin = true
--> size = 0
--> stream_id = 5
t=314925 [st=711]    HTTP2_SESSION_SEND_HEADERS
--> exclusive = true
--> fin = false
--> has_priority = true
--> :method: POST
:authority: autoservice.compareunittest.com
:scheme: https
:path: /api/mi/pagevisit
content-length: 364
correlationid: 72b3a477-1129-4ca4-a373-3bd6cdc2c5b0
origin: https://motor.compareunittest.com
authorization: 48iFi3wa47u4yT46TfwRj3dcC651N275Cn=
content-type: application/json;charset=UTF-8
accept: application/json, text/plain, */*
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36
__requestverificationtoken: GmI53U-AOKgq8RZ92Qf59kazIktqpOEPVZ4LzF_uL562FYPOz2ylxk94VYG3dJwZm-ZwhrfMOYjvfPWovI37OJ4mI3yDG6Do2DaBGY0HkC41:kE5Uxfh3fNgktZIhW1XG84nflggp3EULxtJbu_NCHiBwPxrOMeOAxiI7CoBWMGH3o8HlHU7Cz3ISWhC3cxapm_IfuzB-YF4GpU0NsqPvynA1
referer: https://motor.compareunittest.com/
accept-encoding: gzip, deflate, br
accept-language: en-GB,en-US;q=0.9,en;q=0.8
--> parent_stream_id = 0
--> source_dependency = 129259 (HTTP_STREAM_JOB)
--> stream_id = 7
--> weight = 220
t=314925 [st=711]    HTTP2_SESSION_SEND_DATA
--> fin = true
--> size = 364
--> stream_id = 7
t=314925 [st=711]    HTTP2_SESSION_UPDATE_SEND_WINDOW
--> delta = -364
--> window_size = 1048212
t=314933 [st=719]    HTTP2_SESSION_RECV_RST_STREAM
--> error_code = "1 (PROTOCOL_ERROR)"
--> stream_id = 7
t=315213 [st=999]    HTTP2_SESSION_RECV_WINDOW_UPDATE
--> delta = 364
--> stream_id = 0
t=315213 [st=999]    HTTP2_SESSION_UPDATE_SEND_WINDOW
--> delta = 364
--> window_size = 1048576

我觉得网上应该有更多关于如何使您的应用程序使用 http2 进行通信的信息,但我们没有找到任何东西。

任何帮助不胜感激!

谢谢

编辑

我还包含了我们正在发出的 HTTP2 请求,该请求是从 chrome 中的 HAR 文件保存的:

"request": {
"method": "OPTIONS",
"url": "https://autoservice.compareunittest.com/api/mi/pagevisit",
"httpVersion": "http/2.0",
"headers": [
{
"name": ":path",
"value": "/api/mi/pagevisit"
},
{
"name": "access-control-request-method",
"value": "POST"
},
{
"name": "origin",
"value": "https://motor.compareunittest.com"
},
{
"name": "accept-encoding",
"value": "gzip, deflate, br"
},
{
"name": "accept-language",
"value": "en-GB,en-US;q=0.9,en;q=0.8"
},
{
"name": "user-agent",
"value": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"
},
{
"name": "accept",
"value": "*/*"
},
{
"name": ":authority",
"value": "autoservice.compareunittest.com"
},
{
"name": ":scheme",
"value": "https"
},
{
"name": ":method",
"value": "OPTIONS"
},
{
"name": "access-control-request-headers",
"value": "__requestverificationtoken,authorization,content-type,correlationid"
}
],

这是我切换回 HTTP1 时来自 API 的响应,它响应正确:

"response": {
"status": 200,
"statusText": "OK",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Date",
"value": "Thu, 03 May 2018 16:33:19 GMT"
},
{
"name": "Server",
"value": "Microsoft-IIS/10.0"
},
{
"name": "X-Frame-Options",
"value": "SAMEORIGIN"
},
{
"name": "X-Powered-By",
"value": "ASP.NET"
},
{
"name": "Allow",
"value": "OPTIONS, TRACE, GET, HEAD, POST"
},
{
"name": "Access-Control-Allow-Origin",
"value": "*"
},
{
"name": "Public",
"value": "OPTIONS, TRACE, GET, HEAD, POST"
},
{
"name": "Access-Control-Allow-Headers",
"value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control, __RequestVerificationToken, CorrelationId"
},
{
"name": "Content-Length",
"value": "0"
}
],

错误发生在HTTP_TRANSACTION_READ_HEADERS之后的事实很有趣。

HTTP/2 对 HTTP 标头要严格得多,而 HTTP/1 对无效标头非常宽容。因此,如果您的 HTTP 标头中有冒号或空格,这可能是原因。

通常,您会在chrome://net-internals/#events中看到比显示的信息更多的信息,如果这是原因,这应该有助于查明导致问题的标头。尝试转到chrome://net-internals/#http2,看看您是否获得了更多信息。

有关详细信息,请参阅此博客文章。或者,如果您将HTTP标头(来自HTTP/1请求(添加到问题中,那么我们可能能够发现一些东西。

因此,在尝试了上述所有方法,从标头中删除所有小写字符串,从请求令牌中删除"__"之后,没有任何效果。 我们在防伪请求中连接了两个令牌,并在 API 端将它们拆分出来。 我注意到第二个静态字符串在字符串的末尾有一个"="。 我们从所有应用程序中删除了它,它现在适用于所有 HTTP1 和 2 请求!

感谢您的帮助!检查标题中的字符是我从中学到的。

最新更新