summaryrefslogtreecommitdiffstats
path: root/src/network/access/qhttp2protocolhandler.cpp
Commit message (Collapse)AuthorAgeFilesLines
* HTTP/2 - implement the proper 'h2c' (protocol upgrade)Timur Pocheptsov2017-08-271-14/+24
| | | | | | | | | | | | | | | | | | | | | | | | | Without TLS (and thus ALPN/NPN negotiation) HTTP/2 requires a protocol upgrade procedure, as described in RFC 7540, 3.2. We start as HTTP/1.1 (and thus we create QHttpProtocolHandler first), augmenting the headers we send with 'Upgrade: h2c'. In case we receive HTTP/1.1 response with status code 101 ('Switching Protocols'), we continue as HTTP/2 session, creating QHttp2ProtocolHandler and pretending the first request we sent was HTTP/2 request on a real HTTP/2 stream. If the first response is something different from 101, we continue as HTTP/1.1. This change also required auto-test update: our toy-server now has to respond to the initial HTTP/1.1 request on a platform without ALPN/NPN. As a bonus a subtle flakyness in 'goaway' auto-test went away (well, it was fixed). [ChangeLog][QtNetwork][HTTP/2] In case of clear text HTTP/2 we now initiate a required protocol upgrade procedure instead of 'H2Direct' connection. Task-number: QTBUG-61397 Change-Id: I573fa304fdaf661490159037dc47775d97c8ea5b Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
* Use QNetworkReply::ProtocolFailure in HTTP/2 failuresThiago Macieira2017-05-081-4/+4
| | | | | | | | | ProtocolInvalidOperationError are meant for actual replies from the server indicating that the operation is not valid (HTTP 400 Bad Request). Change-Id: I9ad33fff8b634979bdbafffd14bbc57e4b21d6bf Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
* Use HTTP2WasUsedAttribute for HTTP2Timur Pocheptsov2017-03-291-0/+2
| | | | | | | | | | | Previously we were always setting SpdyWasUsedAttribute for SPDY/HTTP/2/HTTP/1.1 (true/false) which is confusing. Now if HTTP2AllowedAttribute was set to true on a request, we set HTTP2WasUsedAttribute. Otherwise, as we did before, we're setting SpdyWasUsedAttribute. Change-Id: I0c44cfb5469fef0c12719baa951197ee2accee4a Reviewed-by: Markus Goetz (Woboq GmbH) <markus@woboq.com> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
* HTTP/2 - fix SETTINGS frame validationTimur Pocheptsov2017-01-171-1/+1
| | | | | | | | | When testing peer's SETTINGS frames, namely MAX_CONCURRENT_STREAM identifier, we should test against upper limit _new_ values from these frames, not our own pre-set maxConcurrentStreams (it apparently was a typo). Change-Id: I2036e45b0f931914f75ca99142192e2f9385623e Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* qhttp2protocolhandler - handle proxies correctlyTimur Pocheptsov2017-01-111-3/+12
| | | | | | | | For requests through proxy, the Request-URI (':path' header) must contain full url. Change-Id: Ibecdf4556b0cecf731da0f89b241bb86a07fa3ad Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* HTTP/2 - fix handling of GOAWAY frameTimur Pocheptsov2017-01-111-9/+18
| | | | | | | | | | | | | | | | | | | - Fix the case when we erroneously handled stream ID == 0 in a GOAWAY frame as an invalid stream ID. - _q_receivedReply: convert do{}while() loop into to while(){} to prevent it from handling any frames after GOAWAY frame received and all active frame finished. - sendRequest - if we received GOAWAY, also clear spdyRequests in the connection channel, otherwise it keeps re-trying to send requests! - Http network connection channel never resets a protocolHandler in _q_encrypted/ _q_connected, which is BAD for HTTP/2, since HTTP/2 has unique per-connection compression context and must be reset - now we recreate the protocol handler in _q_encrypted or _q_connected (https/http). - Update autotest. Task-number: QTBUG-57600 Change-Id: Ib864ce52287bab23334ff43a83ba4b0b7cb52c60 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* HTTP/2 - fix the handling of PUSH_PROMISETimur Pocheptsov2016-10-211-75/+297
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | HTTP/2 allows a server to pre-emptively send (or "push") responses (along with corresponding "promised" requests) to a client in association with a previous client-initiated request. This can be useful when the server knows the client will need to have those responses available in order to fully process the response to the original request. Server push is semantically equivalent to a server responding to a request; however, in this case, that request is also sent by the server, as a PUSH_PROMISE frame. The PUSH_PROMISE frame includes a header block that contains a complete set of request header fields that the server attributes to the request. After sending the PUSH_PROMISE frame, the server can begin delivering the pushed response as a response on a server-initiated stream that uses the promised stream identifier. This patch: - fixes the HPACK decompression of PUSH_PROMISE frames; - allows a user to enable PUSH_PROMISE; - processes and caches pushed data for promised streams; - updates auto-test - emulates a simple PUSH_PROMISE scenario. Change-Id: Ic4850863a5e3895320baac3871a723fc091b4aca Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Refactor Http2::FrameReader/Http2::FrameWriterTimur Pocheptsov2016-08-191-78/+83
| | | | | | | | | | | | | | Introduce new entity: class Http2::Frame with accessors like payloadSize/type/flags/streamID etc. (they actually read /interpret raw bytes from a frame's buffer) instead of duplicating this functionality in reader/writer classes. Delete defaulted members and remove explicitly defined move ctors/operators (not needed actually). Update auto-test ('HTTP/2 server') to use these new classes. Change-Id: Ie3516efbd095704e212142eef9e792323678ccfa Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* HTTP/2 - do not set END_HEADERS if we have CONTINUATIONsTimur Pocheptsov2016-08-171-1/+1
| | | | | | | | | Setting END_HEADERS flag on a HEADERS frame means we do not have CONTINUATION frame(s). So do NOT set it too early, only if we fit into a single frame. Change-Id: I891a2db227cee59e4eacfe7c2f18b431cd85fe47 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Enable cleartext HTTP/2 and bring the auto-test back to lifeTimur Pocheptsov2016-08-111-2/+2
| | | | | | | | | | | | | | HTTP/2 does not require TLS connection, it can work in a cleartext mode. Plus at the moment only OpenSSL backend allows HTTP/2 negotiation via ALPN/NPN (and none of our CI configurations with OpenSSL supports these extensions, rendering HTTP/2 auto-test useless). This patch implements cleartext HTTP/2 ('h2c') in 'direct' mode - this is allowed if a client has a prior knowledge that HTTP/2 is supported by a server. Change-Id: I4978775e9732c40bc77f549b83bb4a5d1761887e Reviewed-by: Alex Trotsenko <alex1973tr@gmail.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* http2frame - do not rely on a socket's bufferTimur Pocheptsov2016-08-111-55/+51
| | | | | | | | | | | | | | | - Whenever we have a read notification, read this data, even if it's not enough for a frame's header - otherwise, QNAM can use a socket in an Ubuffered mode and FrameReader can potentially fail to read anything correctly. - Do not call/rely on bytesAvailable and do not try to invoke _q_receiveReply in Qt::QueuedConnection mode, instead try to read until we end up in an incomplete frame or some error. Change-Id: I7f44ba9e34bc64f3e26bd29080f0050da635b3ae Reviewed-by: Alex Trotsenko <alex1973tr@gmail.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Revert "Implement protocol upgrade for HTTP/2 enabled requests"Timur Pocheptsov2016-08-041-36/+15
| | | | | | | | | This reverts commit 12d71f4ea20415ff2274e1e90f9e4d5a8b935d7f. This change is breaking a build + incomplete as my test revealed. Will have to re-try later. Change-Id: I7ea089093a832aa5822caaaac56e62f5fda4df17 Reviewed-by: Liang Qi <liang.qi@qt.io>
* Implement protocol upgrade for HTTP/2 enabled requestsTimur Pocheptsov2016-08-031-15/+36
| | | | | | | | | | | | | | Without ALPN/NPN (== without OpenSSL) we can negotiate HTTP/2 using the protocol upgrade procedure as described by RFC7540. Since there is no TLS handshake, after our http channel was connected we first send an 'augmented' HTTP/1.1 request - its header contains additional 'HTTP2-Settings' and 'Upgrade' (to 'h2c') fields. If we receive reponse 101 (switch protocol) we re-create a protocol handler and switch to HTTP/2. Task-number: QTBUG-50955 Change-Id: I36e9985e06ba76edaf7fdb22bb43770f8d593c61 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* fix namespaced buildOswald Buddenhagen2016-08-011-2/+2
| | | | | Change-Id: I37b571db193d444ea60d508375fef89add467d1e Reviewed-by: Timur Pocheptsov <timur.pocheptsov@theqtcompany.com>
* Remove SSL includes from qhttpnetworkconnection_p.hFriedemann Kleint2016-07-121-2/+0
| | | | | | | | | | | | | | | | | On Windows, qsslcontext_openssl_p.h pulls in an unsanitized windows.h, causing the infamous min/max macros to be defined, requiring a #define NOMINMAX in qhttp2protocolhandler.cpp. This in turn breaks the MinGW developer build since that has NOMINMAX globally defined: access\qhttp2protocolhandler.cpp:40:0: error: "NOMINMAX" redefined [-Werror] Remove the include, adding missing forward declarations and include directives to the source files. Change-Id: Ic1c2c711d87599b15ad6e2d87eae7153a44ace47 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@theqtcompany.com>
* HTTP2 protocol handlerTimur Pocheptsov2016-07-081-0/+1219
Add HTTP2 support in QNAM - QHttp2ProtocolHandler + aux. classes. [ChangeLog][QtNetwork] Added support for HTTP/2 protocol Task-number: QTBUG-50956 Change-Id: I3a119cfbb1fb3118d9003225f5e54b46ae2829b6 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>