-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Error when handling HTTP requests with HTTP2 related "Upgrade: h2c" in header #6446
Copy link
Copy link
Closed
Labels
enhancementreproducer: presentThis PR or issue contains code, which reproduce the problem described or clearly understandable STRThis PR or issue contains code, which reproduce the problem described or clearly understandable STRserver
Description
Describe the bug
I'm experiencing problems when trying to handle HTTP requests sent by Qt6 clients. It looks like Qt now sends additional HTTP2 related headers by default. HTTP servers based on aiohttp 3.6 and python http.server are handling those requests just fine, but aiohttp 3.7 and 3.8 are showing irregularities in the parsed headers, are unable to read request bodies, and fail to send replies.
Test code and examples for good/bad observations are attached to this issue.
To Reproduce
Qt6 / Qt5 client test code:
#include <QtCore/QCoreApplication>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QNetworkAccessManager qnam;
QUrl requestUrl("http://localhost:9000/");
QNetworkRequest request(requestUrl);
// --- WORKAROUND: aiohttp only processes Qt6 requests with Http2Allowed set to false ---
// request.setAttribute(QNetworkRequest::Attribute::Http2AllowedAttribute, false);
request.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain;charset=UTF-8");
QByteArray queryData("Hello World");
auto* reply = qnam.post(request, queryData);
QObject::connect(reply, &QNetworkReply::finished, [&]() {
if(reply->error() == QNetworkReply::NoError) {
QString contents = QString::fromUtf8(reply->readAll());
qDebug() << "Reply Ok" << contents;
}
else {
QString err = reply->errorString();
qDebug() << "Reply Error" << err;
}
reply->deleteLater();
a.quit();
});
return a.exec();
}Aiohttp test server:
from aiohttp import web
async def post_handler(request: web.Request):
body = await request.read()
n_expected, n_read = request.headers.get('Content-Length'), len(body)
print(f"Received request, body expected {n_expected}, body read {n_read}")
headers = "\n".join(f" {k}: {v}" for k, v in request.headers.items())
print(f"Headers\n{headers}")
return web.Response(body=body)
app = web.Application()
app.add_routes([web.post('/', post_handler)])
web.run_app(app, port=9000)Expected behavior
aiohttp server should be able to handle the requests.
Logs/tracebacks
Good result with aiohttp 3.6:
Received request, body expected 11, body read 11
Headers
Host: localhost:9000
Content-Type: text/plain;charset=UTF-8
Content-Length: 11
Accept-Encoding: gzip, deflate
Accept-Language: en-US,*
User-Agent: Mozilla/5.0
Connection: Keep-Alive, Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: AAIAAAAA
Bad result with aiohttp 3.7 and 3.8:
Received request, body expected 11, body read 0
Headers
Host: localhost:9000
Content-Type: text/plain;charset=UTF-8
Content-Length: 11
Accept-Encoding: gzip, deflate
Accept-Language: en-US,*
User-Agent: Mozilla/5.0
Connection: Keep-Alive, Upgrade, HTTP2-Settings, Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: AAIAAAAA
Unhandled exception
Traceback (most recent call last):
File "/home/pwuertz/.local/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 514, in start
resp, reset = await task
File "/home/pwuertz/.local/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 460, in _handle_request
reset = await self.finish_response(request, resp, start_time)
File "/home/pwuertz/.local/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 599, in finish_response
self._request_parser.feed_data(self._message_tail)
File "aiohttp/_http_parser.pyx", line 551, in aiohttp._http_parser.HttpParser.feed_data
aiohttp.http_exceptions.BadStatusLine: 400, message="Bad status line 'Invalid method encountered'"Python Version
Python 3.9.7aiohttp Version
Version: 3.8.1multidict Version
Version: 4.7.6yarl Version
Version: 1.5.1OS
Ubuntu 21.10
Related component
Server
Additional context
No response
Code of Conduct
- I agree to follow the aio-libs Code of Conduct
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementreproducer: presentThis PR or issue contains code, which reproduce the problem described or clearly understandable STRThis PR or issue contains code, which reproduce the problem described or clearly understandable STRserver