Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
http2frames_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:network-protocol
4
5#ifndef HTTP2FRAMES_P_H
6#define HTTP2FRAMES_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists for the convenience
13// of the Network Access API. This header file may change from
14// version to version without notice, or even be removed.
15//
16// We mean it.
17//
18
20#include "hpack_p.h"
21
22#include <QtCore/qendian.h>
23#include <algorithm>
24#include <vector>
25
26QT_BEGIN_NAMESPACE
27
28class QHttp2ProtocolHandler;
29class QIODevice;
30
31namespace Http2
32{
33
34struct Q_AUTOTEST_EXPORT Frame
35{
36 Frame();
37 // Reading these values without first forming a valid frame (either reading
38 // it from a socket or building it) will result in undefined behavior:
39 FrameType type() const;
40 quint32 streamID() const;
41 FrameFlags flags() const;
42 quint32 payloadSize() const;
43 uchar padding() const;
44 bool supportsPaddedFlag() const;
45 bool isPadded() const;
46 // In HTTP/2 a stream's priority is specified by its weight and a stream
47 // (id) it depends on:
48 bool priority(quint32 *streamID = nullptr,
49 uchar *weight = nullptr) const;
50
53
54 // Number of payload bytes without padding and/or priority.
55 quint32 dataSize() const;
56 // HEADERS data size for HEADERS, PUSH_PROMISE and CONTINUATION streams:
57 quint32 hpackBlockSize() const;
58 // Beginning of payload without priority/padding bytes.
59 const uchar *dataBegin() const;
60 // HEADERS data beginning for HEADERS, PUSH_PROMISE and CONTINUATION streams:
61 const uchar *hpackBlockBegin() const;
62
64};
65
66class Q_AUTOTEST_EXPORT FrameReader
67{
68public:
69 FrameStatus read(QIODevice &socket);
70
71 Frame &inboundFrame()
72 {
73 return frame;
74 }
75private:
76 bool readHeader(QIODevice &socket);
77 bool readPayload(QIODevice &socket);
78 bool discardPayload(QIODevice &socket);
79
80 quint32 offset = 0;
81 Frame frame;
82};
83
84class Q_AUTOTEST_EXPORT FrameWriter
85{
86public:
87 using payload_type = std::vector<uchar>;
88 using size_type = payload_type::size_type;
89
90 FrameWriter();
91 FrameWriter(FrameType type, FrameFlags flags, quint32 streamID);
92
93 Frame &outboundFrame()
94 {
95 return frame;
96 }
97
98 void setOutboundFrame(Frame &&newFrame);
99
100 // Frame 'builders':
101 void start(FrameType type, FrameFlags flags, quint32 streamID);
102 void setPayloadSize(quint32 size);
103 void setType(FrameType type);
104 void setFlags(FrameFlags flags);
105 void addFlag(FrameFlag flag);
106
107 // All append functions also update frame's payload length.
108 template<typename ValueType>
109 void append(ValueType val)
110 {
111 uchar wired[sizeof val] = {};
112 qToBigEndian(val, wired);
113 append(wired, wired + sizeof val);
114 }
115 void append(uchar val)
116 {
117 frame.buffer.push_back(val);
118 updatePayloadSize();
119 }
120 void append(Settings identifier)
121 {
122 append(quint16(identifier));
123 }
124 void append(const payload_type &payload)
125 {
126 append(&payload[0], &payload[0] + payload.size());
127 }
128 void append(QByteArrayView payload)
129 {
130 append(reinterpret_cast<const uchar *>(payload.begin()),
131 reinterpret_cast<const uchar *>(payload.end()));
132 }
133
134 void append(const uchar *begin, const uchar *end);
135
136 // Write as a single frame:
137 bool write(QIODevice &socket) const;
138 // Two types of frames we are sending are affected by frame size limits:
139 // HEADERS and DATA. HEADERS' payload (hpacked HTTP headers, following a
140 // frame header) is always in our 'buffer', we send the initial HEADERS
141 // frame first and then CONTINUTATION frame(s) if needed:
142 bool writeHEADERS(QIODevice &socket, quint32 sizeLimit);
143 // With DATA frames the actual payload is never in our 'buffer', it's a
144 // 'readPointer' from QNonContiguousData. We split this payload as needed
145 // into DATA frames with correct payload size fitting into frame size limit:
146 bool writeDATA(QIODevice &socket, quint32 sizeLimit,
147 const uchar *src, quint32 size);
148private:
149 void updatePayloadSize();
150 Frame frame;
151};
152
153}
154
155QT_END_NAMESPACE
156
157#endif
Combined button and popup list for selecting options.
FrameStatus validateHeader() const
bool priority(quint32 *streamID=nullptr, uchar *weight=nullptr) const
FrameStatus validatePayload() const
bool supportsPaddedFlag() const
uchar padding() const
const uchar * dataBegin() const
quint32 hpackBlockSize() const
quint32 payloadSize() const
quint32 streamID() const
quint32 dataSize() const
const uchar * hpackBlockBegin() const
bool isPadded() const
std::vector< uchar > buffer
FrameType type() const
FrameFlags flags() const