mirror of
https://github.com/NohamR/RMHook-Win.git
synced 2026-05-25 19:59:46 +00:00
Add Qt libs and headers
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
// Copyright (C) 2018 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef BITSTREAMS_P_H
|
||||
#define BITSTREAMS_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QByteArray;
|
||||
|
||||
namespace HPack
|
||||
{
|
||||
|
||||
// BitOStream works with an external buffer,
|
||||
// for example, HEADERS frame.
|
||||
class Q_AUTOTEST_EXPORT BitOStream
|
||||
{
|
||||
public:
|
||||
BitOStream(std::vector<uchar> &buffer);
|
||||
|
||||
// Write 'bitLength' bits from the least significant
|
||||
// bits in 'bits' to bitstream:
|
||||
void writeBits(uchar bits, quint8 bitLength);
|
||||
// HPACK data format, we support:
|
||||
// * 32-bit integers
|
||||
// * strings
|
||||
void write(quint32 src);
|
||||
void write(QByteArrayView src, bool compressed);
|
||||
|
||||
quint64 bitLength() const;
|
||||
quint64 byteLength() const;
|
||||
const uchar *begin() const;
|
||||
const uchar *end() const;
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(BitOStream);
|
||||
|
||||
std::vector<uchar> &buffer;
|
||||
quint64 bitsSet;
|
||||
};
|
||||
|
||||
class Q_AUTOTEST_EXPORT BitIStream
|
||||
{
|
||||
public:
|
||||
// Error is set by 'read' functions.
|
||||
// 'peek' does not set the error,
|
||||
// since it just peeks some bits
|
||||
// without the notion of wrong/right.
|
||||
// 'read' functions only change 'streamOffset'
|
||||
// on success.
|
||||
enum class Error
|
||||
{
|
||||
NoError,
|
||||
NotEnoughData,
|
||||
CompressionError,
|
||||
InvalidInteger
|
||||
};
|
||||
|
||||
BitIStream();
|
||||
BitIStream(const uchar *f, const uchar *l);
|
||||
|
||||
quint64 bitLength() const;
|
||||
bool hasMoreBits() const;
|
||||
|
||||
// peekBits tries to read 'length' bits from the bitstream into
|
||||
// 'dst' ('length' must be <= sizeof(dst) * 8), packing them
|
||||
// starting from the most significant bit of the most significant
|
||||
// byte. It's a template so that we can use it with different
|
||||
// integer types. Returns the number of bits actually read.
|
||||
// Does not change stream's offset.
|
||||
|
||||
template<class T>
|
||||
quint64 peekBits(quint64 from, quint64 length, T *dstPtr) const
|
||||
{
|
||||
static_assert(std::is_unsigned<T>::value, "peekBits: unsigned integer type expected");
|
||||
|
||||
Q_ASSERT(dstPtr);
|
||||
Q_ASSERT(length <= sizeof(T) * 8);
|
||||
|
||||
if (from >= bitLength() || !length)
|
||||
return 0;
|
||||
|
||||
T &dst = *dstPtr;
|
||||
dst = T();
|
||||
length = std::min(length, bitLength() - from);
|
||||
|
||||
const uchar *srcByte = first + from / 8;
|
||||
auto bitsToRead = length + from % 8;
|
||||
|
||||
while (bitsToRead > 8) {
|
||||
dst = (dst << 8) | *srcByte;
|
||||
bitsToRead -= 8;
|
||||
++srcByte;
|
||||
}
|
||||
|
||||
dst <<= bitsToRead;
|
||||
dst |= *srcByte >> (8 - bitsToRead);
|
||||
dst <<= sizeof(T) * 8 - length;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
quint64 streamOffset() const
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
bool skipBits(quint64 nBits);
|
||||
bool rewindOffset(quint64 nBits);
|
||||
|
||||
bool read(quint32 *dstPtr);
|
||||
bool read(QByteArray *dstPtr);
|
||||
|
||||
Error error() const;
|
||||
|
||||
private:
|
||||
void setError(Error newState);
|
||||
|
||||
const uchar *first;
|
||||
const uchar *last;
|
||||
quint64 offset;
|
||||
Error streamError;
|
||||
};
|
||||
|
||||
} // namespace HPack
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef HPACK_P_H
|
||||
#define HPACK_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "hpacktable_p.h"
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QByteArray;
|
||||
|
||||
namespace HPack
|
||||
{
|
||||
|
||||
using HttpHeader = std::vector<HeaderField>;
|
||||
HeaderSize header_size(const HttpHeader &header);
|
||||
|
||||
class Q_AUTOTEST_EXPORT Encoder
|
||||
{
|
||||
public:
|
||||
Encoder(quint32 maxTableSize, bool compressStrings);
|
||||
|
||||
quint32 dynamicTableSize() const;
|
||||
|
||||
bool encodeRequest(class BitOStream &outputStream,
|
||||
const HttpHeader &header);
|
||||
bool encodeResponse(BitOStream &outputStream,
|
||||
const HttpHeader &header);
|
||||
|
||||
bool encodeSizeUpdate(BitOStream &outputStream,
|
||||
quint32 newSize);
|
||||
|
||||
void setMaxDynamicTableSize(quint32 size);
|
||||
void setCompressStrings(bool compress);
|
||||
|
||||
private:
|
||||
bool encodeRequestPseudoHeaders(BitOStream &outputStream,
|
||||
const HttpHeader &header);
|
||||
bool encodeHeaderField(BitOStream &outputStream,
|
||||
const HeaderField &field);
|
||||
bool encodeMethod(BitOStream &outputStream,
|
||||
const HeaderField &field);
|
||||
|
||||
bool encodeResponsePseudoHeaders(BitOStream &outputStream,
|
||||
const HttpHeader &header);
|
||||
|
||||
bool encodeIndexedField(BitOStream &outputStream, quint32 index) const;
|
||||
|
||||
|
||||
bool encodeLiteralField(BitOStream &outputStream,
|
||||
const struct BitPattern &fieldType,
|
||||
quint32 nameIndex,
|
||||
const QByteArray &value,
|
||||
bool withCompression);
|
||||
|
||||
bool encodeLiteralField(BitOStream &outputStream,
|
||||
const BitPattern &fieldType,
|
||||
const QByteArray &name,
|
||||
const QByteArray &value,
|
||||
bool withCompression);
|
||||
|
||||
FieldLookupTable lookupTable;
|
||||
bool compressStrings;
|
||||
};
|
||||
|
||||
class Q_AUTOTEST_EXPORT Decoder
|
||||
{
|
||||
public:
|
||||
Decoder(quint32 maxTableSize);
|
||||
|
||||
bool decodeHeaderFields(class BitIStream &inputStream);
|
||||
|
||||
const HttpHeader &decodedHeader() const
|
||||
{
|
||||
return header;
|
||||
}
|
||||
|
||||
quint32 dynamicTableSize() const;
|
||||
|
||||
void setMaxDynamicTableSize(quint32 size);
|
||||
|
||||
private:
|
||||
|
||||
bool decodeIndexedField(BitIStream &inputStream);
|
||||
bool decodeSizeUpdate(BitIStream &inputStream);
|
||||
bool decodeLiteralField(const BitPattern &fieldType,
|
||||
BitIStream &inputStream);
|
||||
|
||||
bool processDecodedField(const BitPattern &fieldType,
|
||||
const QByteArray &name,
|
||||
const QByteArray &value);
|
||||
|
||||
void handleStreamError(BitIStream &inputStream);
|
||||
|
||||
HttpHeader header;
|
||||
FieldLookupTable lookupTable;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
// Copyright (C) 2019 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef HPACKTABLE_P_H
|
||||
#define HPACKTABLE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
#include <QtCore/qpair.h>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <deque>
|
||||
#include <set>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace HPack
|
||||
{
|
||||
|
||||
struct Q_AUTOTEST_EXPORT HeaderField
|
||||
{
|
||||
HeaderField()
|
||||
{
|
||||
}
|
||||
|
||||
HeaderField(const QByteArray &n, const QByteArray &v)
|
||||
: name(n),
|
||||
value(v)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const HeaderField &rhs) const
|
||||
{
|
||||
return name == rhs.name && value == rhs.value;
|
||||
}
|
||||
|
||||
QByteArray name;
|
||||
QByteArray value;
|
||||
};
|
||||
|
||||
using HeaderSize = QPair<bool, quint32>;
|
||||
|
||||
HeaderSize entry_size(QByteArrayView name, QByteArrayView value);
|
||||
|
||||
inline HeaderSize entry_size(const HeaderField &entry)
|
||||
{
|
||||
return entry_size(entry.name, entry.value);
|
||||
}
|
||||
|
||||
/*
|
||||
Lookup table consists of two parts (HPACK, 2.3):
|
||||
the immutable static table (pre-defined by HPACK's specs)
|
||||
and dynamic table which is updated while
|
||||
compressing/decompressing headers.
|
||||
|
||||
Table must provide/implement:
|
||||
1. Fast random access - we read fields' indices from
|
||||
HPACK's bit stream.
|
||||
2. FIFO for dynamic part - to push new items to the front
|
||||
and evict them from the back (HPACK, 2.3.2).
|
||||
3. Fast lookup - encoder receives pairs of strings
|
||||
(name|value) and it has to find an index for a pair
|
||||
as the whole or for a name at least (if it's already
|
||||
in either static or dynamic table).
|
||||
|
||||
Static table is an immutable vector.
|
||||
|
||||
Dynamic part is implemented in a way similar to std::deque -
|
||||
it's a vector of pointers to chunks. Each chunk is a vector of
|
||||
(name|value) pairs. Once allocated with a fixed size, chunk
|
||||
never re-allocates its data, so entries' addresses do not change.
|
||||
We add new chunks prepending them to the front of a vector,
|
||||
in each chunk we fill (name|value) pairs starting from the back
|
||||
of the chunk (this simplifies item eviction/FIFO).
|
||||
Given a 'linear' index we can find a chunk number and
|
||||
offset in this chunk - random access.
|
||||
|
||||
Lookup in a static part is straightforward:
|
||||
it's an (immutable) vector, data is sorted,
|
||||
contains no duplicates, we use binary search comparing string values.
|
||||
|
||||
To provide a lookup in dynamic table faster than a linear search,
|
||||
we have an std::set of 'SearchEntries', where each entry contains:
|
||||
- a pointer to a (name|value) pair (to compare
|
||||
name|value strings).
|
||||
- a pointer to a chunk containing this pair and
|
||||
- an offset within this chunk - to calculate a
|
||||
'linear' index.
|
||||
|
||||
Entries in a table can be duplicated (HPACK, 2.3.2),
|
||||
if we evict an entry, we must update our index removing
|
||||
the exactly right key, thus keys in this set are sorted
|
||||
by name|value pairs first, and then by chunk index/offset
|
||||
(so that NewSearchEntryKey < OldSearchEntry even if strings
|
||||
are equal).
|
||||
*/
|
||||
|
||||
class Q_AUTOTEST_EXPORT FieldLookupTable
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
ChunkSize = 16,
|
||||
DefaultSize = 4096 // Recommended by HTTP2.
|
||||
};
|
||||
|
||||
FieldLookupTable(quint32 maxTableSize, bool useIndex);
|
||||
|
||||
bool prependField(const QByteArray &name, const QByteArray &value);
|
||||
void evictEntry();
|
||||
|
||||
quint32 numberOfEntries() const;
|
||||
quint32 numberOfStaticEntries() const;
|
||||
quint32 numberOfDynamicEntries() const;
|
||||
quint32 dynamicDataSize() const;
|
||||
void clearDynamicTable();
|
||||
|
||||
bool indexIsValid(quint32 index) const;
|
||||
quint32 indexOf(const QByteArray &name, const QByteArray &value) const;
|
||||
quint32 indexOf(const QByteArray &name) const;
|
||||
bool field(quint32 index, QByteArray *name, QByteArray *value) const;
|
||||
bool fieldName(quint32 index, QByteArray *dst) const;
|
||||
bool fieldValue(quint32 index, QByteArray *dst) const;
|
||||
|
||||
bool updateDynamicTableSize(quint32 size);
|
||||
void setMaxDynamicTableSize(quint32 size);
|
||||
|
||||
static const std::vector<HeaderField> &staticPart();
|
||||
|
||||
private:
|
||||
// Table's maximum size is controlled
|
||||
// by SETTINGS_HEADER_TABLE_SIZE (HTTP/2, 6.5.2).
|
||||
quint32 maxTableSize;
|
||||
// The tableCapacity is how many bytes the table
|
||||
// can currently hold. It cannot exceed maxTableSize.
|
||||
// It can be modified by a special message in
|
||||
// the HPACK bit stream (HPACK, 6.3).
|
||||
quint32 tableCapacity;
|
||||
|
||||
using Chunk = std::vector<HeaderField>;
|
||||
using ChunkPtr = std::unique_ptr<Chunk>;
|
||||
std::deque<ChunkPtr> chunks;
|
||||
using size_type = std::deque<ChunkPtr>::size_type;
|
||||
|
||||
struct SearchEntry;
|
||||
friend struct SearchEntry;
|
||||
|
||||
struct SearchEntry
|
||||
{
|
||||
SearchEntry();
|
||||
SearchEntry(const HeaderField *f, const Chunk *c,
|
||||
quint32 o, const FieldLookupTable *t);
|
||||
|
||||
const HeaderField *field;
|
||||
const Chunk *chunk;
|
||||
const quint32 offset;
|
||||
const FieldLookupTable *table;
|
||||
|
||||
bool operator < (const SearchEntry &rhs) const;
|
||||
};
|
||||
|
||||
bool useIndex;
|
||||
std::set<SearchEntry> searchIndex;
|
||||
|
||||
SearchEntry frontKey() const;
|
||||
SearchEntry backKey() const;
|
||||
|
||||
bool fieldAt(quint32 index, HeaderField *field) const;
|
||||
|
||||
const HeaderField &front() const;
|
||||
HeaderField &front();
|
||||
const HeaderField &back() const;
|
||||
|
||||
quint32 nDynamic;
|
||||
quint32 begin;
|
||||
quint32 end;
|
||||
quint32 dataSize;
|
||||
|
||||
quint32 indexOfChunk(const Chunk *chunk) const;
|
||||
quint32 keyToIndex(const SearchEntry &key) const;
|
||||
|
||||
enum class CompareMode {
|
||||
nameOnly,
|
||||
nameAndValue
|
||||
};
|
||||
|
||||
static std::vector<HeaderField>::const_iterator findInStaticPart(const HeaderField &field, CompareMode mode);
|
||||
|
||||
mutable QByteArray dummyDst;
|
||||
|
||||
Q_DISABLE_COPY_MOVE(FieldLookupTable)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef HTTP2FRAMES_P_H
|
||||
#define HTTP2FRAMES_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "http2protocol_p.h"
|
||||
#include "hpack_p.h"
|
||||
|
||||
#include <QtCore/qendian.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttp2ProtocolHandler;
|
||||
class QAbstractSocket;
|
||||
|
||||
namespace Http2
|
||||
{
|
||||
|
||||
struct Q_AUTOTEST_EXPORT Frame
|
||||
{
|
||||
Frame();
|
||||
// Reading these values without first forming a valid frame (either reading
|
||||
// it from a socket or building it) will result in undefined behavior:
|
||||
FrameType type() const;
|
||||
quint32 streamID() const;
|
||||
FrameFlags flags() const;
|
||||
quint32 payloadSize() const;
|
||||
uchar padding() const;
|
||||
// In HTTP/2 a stream's priority is specified by its weight and a stream
|
||||
// (id) it depends on:
|
||||
bool priority(quint32 *streamID = nullptr,
|
||||
uchar *weight = nullptr) const;
|
||||
|
||||
FrameStatus validateHeader() const;
|
||||
FrameStatus validatePayload() const;
|
||||
|
||||
// Number of payload bytes without padding and/or priority.
|
||||
quint32 dataSize() const;
|
||||
// HEADERS data size for HEADERS, PUSH_PROMISE and CONTINUATION streams:
|
||||
quint32 hpackBlockSize() const;
|
||||
// Beginning of payload without priority/padding bytes.
|
||||
const uchar *dataBegin() const;
|
||||
// HEADERS data beginning for HEADERS, PUSH_PROMISE and CONTINUATION streams:
|
||||
const uchar *hpackBlockBegin() const;
|
||||
|
||||
std::vector<uchar> buffer;
|
||||
};
|
||||
|
||||
class Q_AUTOTEST_EXPORT FrameReader
|
||||
{
|
||||
public:
|
||||
FrameStatus read(QAbstractSocket &socket);
|
||||
|
||||
Frame &inboundFrame()
|
||||
{
|
||||
return frame;
|
||||
}
|
||||
private:
|
||||
bool readHeader(QAbstractSocket &socket);
|
||||
bool readPayload(QAbstractSocket &socket);
|
||||
|
||||
quint32 offset = 0;
|
||||
Frame frame;
|
||||
};
|
||||
|
||||
class Q_AUTOTEST_EXPORT FrameWriter
|
||||
{
|
||||
public:
|
||||
using payload_type = std::vector<uchar>;
|
||||
using size_type = payload_type::size_type;
|
||||
|
||||
FrameWriter();
|
||||
FrameWriter(FrameType type, FrameFlags flags, quint32 streamID);
|
||||
|
||||
Frame &outboundFrame()
|
||||
{
|
||||
return frame;
|
||||
}
|
||||
|
||||
void setOutboundFrame(Frame &&newFrame);
|
||||
|
||||
// Frame 'builders':
|
||||
void start(FrameType type, FrameFlags flags, quint32 streamID);
|
||||
void setPayloadSize(quint32 size);
|
||||
void setType(FrameType type);
|
||||
void setFlags(FrameFlags flags);
|
||||
void addFlag(FrameFlag flag);
|
||||
|
||||
// All append functions also update frame's payload length.
|
||||
template<typename ValueType>
|
||||
void append(ValueType val)
|
||||
{
|
||||
uchar wired[sizeof val] = {};
|
||||
qToBigEndian(val, wired);
|
||||
append(wired, wired + sizeof val);
|
||||
}
|
||||
void append(uchar val)
|
||||
{
|
||||
frame.buffer.push_back(val);
|
||||
updatePayloadSize();
|
||||
}
|
||||
void append(Settings identifier)
|
||||
{
|
||||
append(quint16(identifier));
|
||||
}
|
||||
void append(const payload_type &payload)
|
||||
{
|
||||
append(&payload[0], &payload[0] + payload.size());
|
||||
}
|
||||
|
||||
void append(const uchar *begin, const uchar *end);
|
||||
|
||||
// Write as a single frame:
|
||||
bool write(QAbstractSocket &socket) const;
|
||||
// Two types of frames we are sending are affected by frame size limits:
|
||||
// HEADERS and DATA. HEADERS' payload (hpacked HTTP headers, following a
|
||||
// frame header) is always in our 'buffer', we send the initial HEADERS
|
||||
// frame first and then CONTINUTATION frame(s) if needed:
|
||||
bool writeHEADERS(QAbstractSocket &socket, quint32 sizeLimit);
|
||||
// With DATA frames the actual payload is never in our 'buffer', it's a
|
||||
// 'readPointer' from QNonContiguousData. We split this payload as needed
|
||||
// into DATA frames with correct payload size fitting into frame size limit:
|
||||
bool writeDATA(QAbstractSocket &socket, quint32 sizeLimit,
|
||||
const uchar *src, quint32 size);
|
||||
private:
|
||||
void updatePayloadSize();
|
||||
Frame frame;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,170 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef HTTP2PROTOCOL_P_H
|
||||
#define HTTP2PROTOCOL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/qnetworkreply.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
#include <QtCore/qmap.h>
|
||||
|
||||
// Different HTTP/2 constants/values as defined by RFC 7540.
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpNetworkRequest;
|
||||
class QHttp2Configuration;
|
||||
class QHttpNetworkReply;
|
||||
class QByteArray;
|
||||
class QString;
|
||||
|
||||
namespace Http2
|
||||
{
|
||||
|
||||
enum class Settings : quint16
|
||||
{
|
||||
HEADER_TABLE_SIZE_ID = 0x1,
|
||||
ENABLE_PUSH_ID = 0x2,
|
||||
MAX_CONCURRENT_STREAMS_ID = 0x3,
|
||||
INITIAL_WINDOW_SIZE_ID = 0x4,
|
||||
MAX_FRAME_SIZE_ID = 0x5,
|
||||
MAX_HEADER_LIST_SIZE_ID = 0x6
|
||||
};
|
||||
|
||||
enum class FrameType : uchar
|
||||
{
|
||||
DATA = 0x0,
|
||||
HEADERS = 0x1,
|
||||
PRIORITY = 0x2,
|
||||
RST_STREAM = 0x3,
|
||||
SETTINGS = 0x4,
|
||||
PUSH_PROMISE = 0x5,
|
||||
PING = 0x6,
|
||||
GOAWAY = 0x7,
|
||||
WINDOW_UPDATE = 0x8,
|
||||
CONTINUATION = 0x9,
|
||||
// ATTENTION: enumerators must be sorted.
|
||||
// We use LAST_FRAME_TYPE to check if
|
||||
// frame type is known, if not - this frame
|
||||
// must be ignored, HTTP/2 5.1).
|
||||
LAST_FRAME_TYPE
|
||||
};
|
||||
|
||||
enum class FrameFlag : uchar
|
||||
{
|
||||
EMPTY = 0x0, // Valid for any frame type.
|
||||
ACK = 0x1, // Valid for PING, SETTINGS
|
||||
END_STREAM = 0x1, // Valid for HEADERS, DATA
|
||||
END_HEADERS = 0x4, // Valid for PUSH_PROMISE, HEADERS,
|
||||
PADDED = 0x8, // Valid for PUSH_PROMISE, HEADERS, DATA
|
||||
PRIORITY = 0x20 // Valid for HEADERS,
|
||||
};
|
||||
|
||||
Q_DECLARE_FLAGS(FrameFlags, FrameFlag)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(FrameFlags)
|
||||
|
||||
enum Http2PredefinedParameters
|
||||
{
|
||||
// Old-style enum, so we
|
||||
// can use as Http2::frameHeaderSize for example.
|
||||
clientPrefaceLength = 24, // HTTP/2, 3.5
|
||||
connectionStreamID = 0, // HTTP/2, 5.1.1
|
||||
frameHeaderSize = 9, // HTTP/2, 4.1
|
||||
|
||||
// The initial allowed payload size. We would use it as an
|
||||
// upper limit for a frame payload we send, until our peer
|
||||
// updates us with a larger SETTINGS_MAX_FRAME_SIZE.
|
||||
|
||||
// The initial maximum payload size that an HTTP/2 frame
|
||||
// can contain is 16384. It's also the minimal size that
|
||||
// can be advertised via 'SETTINGS' frames. A real frame
|
||||
// can have a payload smaller than 16384.
|
||||
minPayloadLimit = 16384, // HTTP/2 6.5.2
|
||||
// The maximum allowed payload size.
|
||||
maxPayloadSize = (1 << 24) - 1, // HTTP/2 6.5.2
|
||||
|
||||
defaultSessionWindowSize = 65535, // HTTP/2 6.5.2
|
||||
maxConcurrentStreams = 100 // HTTP/2, 6.5.2
|
||||
};
|
||||
|
||||
// These are ints, const, they have internal linkage, it's ok to have them in
|
||||
// headers - no ODR violation.
|
||||
const quint32 lastValidStreamID((quint32(1) << 31) - 1); // HTTP/2, 5.1.1
|
||||
|
||||
// The default size of 64K is too small and limiting: if we use it, we end up
|
||||
// sending WINDOW_UPDATE frames on a stream/session all the time, for each
|
||||
// 2 DATE frames of size 16K (also default) we'll send a WINDOW_UPDATE frame
|
||||
// for a given stream and have a download speed order of magnitude lower than
|
||||
// our own HTTP/1.1 protocol handler. We choose a bigger window size: normally,
|
||||
// HTTP/2 servers are not afraid to immediately set it to the possible max,
|
||||
// we do the same and split this window size between our concurrent streams.
|
||||
const qint32 maxSessionReceiveWindowSize((quint32(1) << 31) - 1);
|
||||
// Presumably, we never use up to 100 streams so let it be 10 simultaneous:
|
||||
const qint32 qtDefaultStreamReceiveWindowSize = maxSessionReceiveWindowSize / 10;
|
||||
|
||||
struct Frame configurationToSettingsFrame(const QHttp2Configuration &configuration);
|
||||
QByteArray settingsFrameToBase64(const Frame &settingsFrame);
|
||||
void appendProtocolUpgradeHeaders(const QHttp2Configuration &configuration, QHttpNetworkRequest *request);
|
||||
|
||||
extern const Q_AUTOTEST_EXPORT char Http2clientPreface[clientPrefaceLength];
|
||||
|
||||
enum class FrameStatus
|
||||
{
|
||||
protocolError,
|
||||
sizeError,
|
||||
incompleteFrame,
|
||||
goodFrame
|
||||
};
|
||||
|
||||
enum Http2Error
|
||||
{
|
||||
// Old-style enum to avoid excessive name
|
||||
// qualification ...
|
||||
// NB:
|
||||
// I use the last enumerator to check
|
||||
// that errorCode (quint32) is valid,
|
||||
// so it needs to be the highest-numbered!
|
||||
// HTTP/2 7:
|
||||
HTTP2_NO_ERROR = 0x0,
|
||||
PROTOCOL_ERROR = 0x1,
|
||||
INTERNAL_ERROR = 0x2,
|
||||
FLOW_CONTROL_ERROR = 0x3,
|
||||
SETTINGS_TIMEOUT = 0x4,
|
||||
STREAM_CLOSED = 0x5,
|
||||
FRAME_SIZE_ERROR = 0x6,
|
||||
REFUSE_STREAM = 0x7,
|
||||
CANCEL = 0x8,
|
||||
COMPRESSION_ERROR = 0x9,
|
||||
CONNECT_ERROR = 0xa,
|
||||
ENHANCE_YOUR_CALM = 0xb,
|
||||
INADEQUATE_SECURITY = 0xc,
|
||||
HTTP_1_1_REQUIRED = 0xd
|
||||
};
|
||||
|
||||
void qt_error(quint32 errorCode, QNetworkReply::NetworkError &error, QString &errorString);
|
||||
QString qt_error_string(quint32 errorCode);
|
||||
QNetworkReply::NetworkError qt_error(quint32 errorCode);
|
||||
bool is_protocol_upgraded(const QHttpNetworkReply &reply);
|
||||
|
||||
} // namespace Http2
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(QT_HTTP2)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_DECL_METATYPE_EXTERN_TAGGED(Http2::Settings, Http2__Settings, Q_NETWORK_EXPORT)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef HTTP2STREAMS_P_H
|
||||
#define HTTP2STREAMS_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "http2frames_p.h"
|
||||
#include "hpack_p.h"
|
||||
|
||||
#include <private/qhttpnetworkconnectionchannel_p.h>
|
||||
#include <private/qhttpnetworkrequest_p.h>
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNonContiguousByteDevice;
|
||||
|
||||
namespace Http2
|
||||
{
|
||||
|
||||
struct Q_AUTOTEST_EXPORT Stream
|
||||
{
|
||||
enum StreamState {
|
||||
idle,
|
||||
open,
|
||||
halfClosedLocal,
|
||||
halfClosedRemote,
|
||||
remoteReserved,
|
||||
closed
|
||||
};
|
||||
|
||||
Stream();
|
||||
// That's a ctor for a client-initiated stream:
|
||||
Stream(const HttpMessagePair &message, quint32 streamID, qint32 sendSize,
|
||||
qint32 recvSize);
|
||||
// That's a reserved stream, created by PUSH_PROMISE from a server:
|
||||
Stream(const QString &key, quint32 streamID, qint32 recvSize);
|
||||
|
||||
QHttpNetworkReply *reply() const;
|
||||
const QHttpNetworkRequest &request() const;
|
||||
QHttpNetworkRequest &request();
|
||||
QHttpNetworkRequest::Priority priority() const;
|
||||
uchar weight() const;
|
||||
|
||||
QNonContiguousByteDevice *data() const;
|
||||
|
||||
HttpMessagePair httpPair;
|
||||
quint32 streamID = 0;
|
||||
// Signed as window sizes can become negative:
|
||||
qint32 sendWindow = 65535;
|
||||
qint32 recvWindow = 65535;
|
||||
|
||||
StreamState state = idle;
|
||||
QString key; // for PUSH_PROMISE
|
||||
};
|
||||
|
||||
struct PushPromise
|
||||
{
|
||||
quint32 reservedID = 0;
|
||||
// PUSH_PROMISE has its own HEADERS,
|
||||
// usually similar to what request has:
|
||||
HPack::HttpHeader pushHeader;
|
||||
// Response has its own (normal) HEADERS:
|
||||
HPack::HttpHeader responseHeader;
|
||||
// DATA frames on a promised stream:
|
||||
std::vector<Frame> dataFrames;
|
||||
};
|
||||
|
||||
} // namespace Http2
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef HUFFMAN_P_H
|
||||
#define HUFFMAN_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QByteArray;
|
||||
|
||||
namespace HPack
|
||||
{
|
||||
|
||||
struct CodeEntry
|
||||
{
|
||||
quint32 byteValue;
|
||||
quint32 huffmanCode;
|
||||
quint32 bitLength;
|
||||
};
|
||||
|
||||
class BitOStream;
|
||||
|
||||
quint64 huffman_encoded_bit_length(QByteArrayView inputData);
|
||||
void huffman_encode_string(QByteArrayView inputData, BitOStream &outputStream);
|
||||
|
||||
// PrefixTable:
|
||||
// Huffman codes with a small bit length
|
||||
// fit into a table (these are 'terminal' symbols),
|
||||
// codes with longer codes require additional
|
||||
// tables, so several symbols will have the same index
|
||||
// in a table - pointing into the next table.
|
||||
// Every table has an 'indexLength' - that's
|
||||
// how many bits can fit in table's indices +
|
||||
// 'prefixLength' - how many bits were addressed
|
||||
// by its 'parent' table(s).
|
||||
// All PrefixTables are kept in 'prefixTables' array.
|
||||
// PrefixTable itself does not have any entries,
|
||||
// it just holds table's prefix/index + 'offset' -
|
||||
// there table's data starts in an array of all
|
||||
// possible entries ('tableData').
|
||||
|
||||
struct PrefixTable
|
||||
{
|
||||
PrefixTable()
|
||||
: prefixLength(),
|
||||
indexLength(),
|
||||
offset()
|
||||
{
|
||||
}
|
||||
|
||||
PrefixTable(quint32 prefix, quint32 index)
|
||||
: prefixLength(prefix),
|
||||
indexLength(index),
|
||||
offset()
|
||||
{
|
||||
}
|
||||
|
||||
quint32 size()const
|
||||
{
|
||||
// Number of entries table contains:
|
||||
return 1 << indexLength;
|
||||
}
|
||||
|
||||
quint32 prefixLength;
|
||||
quint32 indexLength;
|
||||
quint32 offset;
|
||||
};
|
||||
|
||||
// Table entry is either a terminal entry (thus probably the code found)
|
||||
// or points into another table ('nextTable' - index into
|
||||
// 'prefixTables' array). If it's a terminal, 'nextTable' index
|
||||
// refers to the same table.
|
||||
|
||||
struct PrefixTableEntry
|
||||
{
|
||||
PrefixTableEntry()
|
||||
: bitLength(),
|
||||
nextTable(),
|
||||
byteValue()
|
||||
{
|
||||
}
|
||||
|
||||
quint32 bitLength;
|
||||
quint32 nextTable;
|
||||
quint32 byteValue;
|
||||
};
|
||||
|
||||
class BitIStream;
|
||||
|
||||
class HuffmanDecoder
|
||||
{
|
||||
public:
|
||||
enum class BitConstants
|
||||
{
|
||||
rootPrefix = 9,
|
||||
childPrefix = 6
|
||||
};
|
||||
|
||||
HuffmanDecoder();
|
||||
|
||||
bool decodeStream(BitIStream &inputStream, QByteArray &outputBuffer);
|
||||
|
||||
private:
|
||||
quint32 addTable(quint32 prefixLength, quint32 indexLength);
|
||||
PrefixTableEntry tableEntry(const PrefixTable &table, quint32 index);
|
||||
void setTableEntry(const PrefixTable &table, quint32 index, const PrefixTableEntry &entry);
|
||||
|
||||
std::vector<PrefixTable> prefixTables;
|
||||
std::vector<PrefixTableEntry> tableData;
|
||||
quint32 minCodeLength;
|
||||
};
|
||||
|
||||
bool huffman_decode_string(BitIStream &inputStream, QByteArray *outputBuffer);
|
||||
|
||||
} // namespace HPack
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QABSTRACTNETWORKCACHE_P_H
|
||||
#define QABSTRACTNETWORKCACHE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access framework. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "private/qobject_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAbstractNetworkCachePrivate: public QObjectPrivate
|
||||
{
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2014 BlackBerry Limited. All rights reserved.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QABSTRACTPROTOCOLHANDLER_H
|
||||
#define QABSTRACTPROTOCOLHANDLER_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpNetworkConnectionChannel;
|
||||
class QHttpNetworkReply;
|
||||
class QAbstractSocket;
|
||||
class QHttpNetworkConnection;
|
||||
|
||||
class QAbstractProtocolHandler {
|
||||
public:
|
||||
QAbstractProtocolHandler(QHttpNetworkConnectionChannel *channel);
|
||||
virtual ~QAbstractProtocolHandler();
|
||||
|
||||
virtual void _q_receiveReply() = 0;
|
||||
virtual void _q_readyRead() = 0;
|
||||
virtual bool sendRequest() = 0;
|
||||
void setReply(QHttpNetworkReply *reply);
|
||||
|
||||
protected:
|
||||
QHttpNetworkConnectionChannel *m_channel;
|
||||
QHttpNetworkReply *m_reply;
|
||||
QAbstractSocket *m_socket;
|
||||
QHttpNetworkConnection *m_connection;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QABSTRACTPROTOCOLHANDLER_H
|
||||
@@ -0,0 +1,137 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QABSTRACTSOCKET_P_H
|
||||
#define QABSTRACTSOCKET_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the QAbstractSocket class. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "QtNetwork/qabstractsocket.h"
|
||||
#include "QtCore/qbytearray.h"
|
||||
#include "QtCore/qlist.h"
|
||||
#include "QtCore/qtimer.h"
|
||||
#include "private/qiodevice_p.h"
|
||||
#include "private/qabstractsocketengine_p.h"
|
||||
#include "qnetworkproxy.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHostInfo;
|
||||
|
||||
class QAbstractSocketPrivate : public QIODevicePrivate, public QAbstractSocketEngineReceiver
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QAbstractSocket)
|
||||
public:
|
||||
QAbstractSocketPrivate();
|
||||
virtual ~QAbstractSocketPrivate();
|
||||
|
||||
// from QAbstractSocketEngineReceiver
|
||||
inline void readNotification() override { canReadNotification(); }
|
||||
inline void writeNotification() override { canWriteNotification(); }
|
||||
inline void exceptionNotification() override {}
|
||||
inline void closeNotification() override { canCloseNotification(); }
|
||||
void connectionNotification() override;
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
inline void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator) override {
|
||||
Q_Q(QAbstractSocket);
|
||||
emit q->proxyAuthenticationRequired(proxy, authenticator);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual bool bind(const QHostAddress &address, quint16 port, QAbstractSocket::BindMode mode);
|
||||
|
||||
virtual bool canReadNotification();
|
||||
bool canWriteNotification();
|
||||
void canCloseNotification();
|
||||
|
||||
// slots
|
||||
void _q_connectToNextAddress();
|
||||
void _q_startConnecting(const QHostInfo &hostInfo);
|
||||
void _q_testConnection();
|
||||
void _q_abortConnectionAttempt();
|
||||
|
||||
bool emittedReadyRead = false;
|
||||
bool emittedBytesWritten = false;
|
||||
|
||||
bool abortCalled = false;
|
||||
bool pendingClose = false;
|
||||
|
||||
QAbstractSocket::PauseModes pauseMode = QAbstractSocket::PauseNever;
|
||||
|
||||
QString hostName;
|
||||
quint16 port = 0;
|
||||
QHostAddress host;
|
||||
QList<QHostAddress> addresses;
|
||||
|
||||
quint16 localPort = 0;
|
||||
quint16 peerPort = 0;
|
||||
QHostAddress localAddress;
|
||||
QHostAddress peerAddress;
|
||||
QString peerName;
|
||||
|
||||
QAbstractSocketEngine *socketEngine = nullptr;
|
||||
qintptr cachedSocketDescriptor = -1;
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
QNetworkProxy proxy;
|
||||
QNetworkProxy proxyInUse;
|
||||
QString protocolTag;
|
||||
void resolveProxy(const QString &hostName, quint16 port);
|
||||
#else
|
||||
inline void resolveProxy(const QString &, quint16) { }
|
||||
#endif
|
||||
inline void resolveProxy(quint16 port) { resolveProxy(QString(), port); }
|
||||
|
||||
void resetSocketLayer();
|
||||
virtual bool flush();
|
||||
|
||||
bool initSocketLayer(QAbstractSocket::NetworkLayerProtocol protocol);
|
||||
virtual void configureCreatedSocket();
|
||||
void startConnectingByName(const QString &host);
|
||||
void fetchConnectionParameters();
|
||||
bool readFromSocket();
|
||||
virtual bool writeToSocket();
|
||||
void emitReadyRead(int channel = 0);
|
||||
void emitBytesWritten(qint64 bytes, int channel = 0);
|
||||
|
||||
void setError(QAbstractSocket::SocketError errorCode, const QString &errorString);
|
||||
void setErrorAndEmit(QAbstractSocket::SocketError errorCode, const QString &errorString);
|
||||
|
||||
qint64 readBufferMaxSize = 0;
|
||||
bool isBuffered = false;
|
||||
bool hasPendingData = false;
|
||||
|
||||
QTimer *connectTimer = nullptr;
|
||||
|
||||
int hostLookupId = -1;
|
||||
|
||||
QAbstractSocket::SocketType socketType = QAbstractSocket::UnknownSocketType;
|
||||
QAbstractSocket::SocketState state = QAbstractSocket::UnconnectedState;
|
||||
|
||||
// Must be kept in sync with QIODevicePrivate::errorString.
|
||||
QAbstractSocket::SocketError socketError = QAbstractSocket::UnknownSocketError;
|
||||
|
||||
QAbstractSocket::NetworkLayerProtocol preferredNetworkLayerProtocol =
|
||||
QAbstractSocket::UnknownNetworkLayerProtocol;
|
||||
|
||||
bool prePauseReadSocketNotifierState = false;
|
||||
bool prePauseWriteSocketNotifierState = false;
|
||||
bool prePauseExceptionSocketNotifierState = false;
|
||||
static void pauseSocketNotifiers(QAbstractSocket*);
|
||||
static void resumeSocketNotifiers(QAbstractSocket*);
|
||||
static QAbstractSocketEngine* getSocketEngine(QAbstractSocket*);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QABSTRACTSOCKET_P_H
|
||||
@@ -0,0 +1,225 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QABSTRACTSOCKETENGINE_P_H
|
||||
#define QABSTRACTSOCKETENGINE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "QtNetwork/qhostaddress.h"
|
||||
#include "QtNetwork/qabstractsocket.h"
|
||||
#include "private/qobject_p.h"
|
||||
#include "private/qnetworkdatagram_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAuthenticator;
|
||||
class QAbstractSocketEnginePrivate;
|
||||
#ifndef QT_NO_NETWORKINTERFACE
|
||||
class QNetworkInterface;
|
||||
#endif
|
||||
class QNetworkProxy;
|
||||
|
||||
class QAbstractSocketEngineReceiver {
|
||||
public:
|
||||
virtual ~QAbstractSocketEngineReceiver(){}
|
||||
virtual void readNotification()= 0;
|
||||
virtual void writeNotification()= 0;
|
||||
virtual void closeNotification()= 0;
|
||||
virtual void exceptionNotification()= 0;
|
||||
virtual void connectionNotification()= 0;
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
virtual void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)= 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
class Q_AUTOTEST_EXPORT QAbstractSocketEngine : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_MOC_INCLUDE(<QtNetwork/qauthenticator.h>)
|
||||
public:
|
||||
|
||||
static QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType, const QNetworkProxy &, QObject *parent);
|
||||
static QAbstractSocketEngine *createSocketEngine(qintptr socketDescriptor, QObject *parent);
|
||||
|
||||
QAbstractSocketEngine(QObject *parent = nullptr);
|
||||
|
||||
enum SocketOption {
|
||||
NonBlockingSocketOption,
|
||||
BroadcastSocketOption,
|
||||
ReceiveBufferSocketOption,
|
||||
SendBufferSocketOption,
|
||||
AddressReusable,
|
||||
BindExclusively,
|
||||
ReceiveOutOfBandData,
|
||||
LowDelayOption,
|
||||
KeepAliveOption,
|
||||
MulticastTtlOption,
|
||||
MulticastLoopbackOption,
|
||||
TypeOfServiceOption,
|
||||
ReceivePacketInformation,
|
||||
ReceiveHopLimit,
|
||||
MaxStreamsSocketOption,
|
||||
PathMtuInformation
|
||||
};
|
||||
|
||||
enum PacketHeaderOption {
|
||||
WantNone = 0,
|
||||
WantDatagramSender = 0x01,
|
||||
WantDatagramDestination = 0x02,
|
||||
WantDatagramHopLimit = 0x04,
|
||||
WantStreamNumber = 0x08,
|
||||
WantEndOfRecord = 0x10,
|
||||
|
||||
WantAll = 0xff
|
||||
};
|
||||
Q_DECLARE_FLAGS(PacketHeaderOptions, PacketHeaderOption)
|
||||
|
||||
virtual bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) = 0;
|
||||
|
||||
virtual bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) = 0;
|
||||
|
||||
virtual qintptr socketDescriptor() const = 0;
|
||||
|
||||
virtual bool isValid() const = 0;
|
||||
|
||||
virtual bool connectToHost(const QHostAddress &address, quint16 port) = 0;
|
||||
virtual bool connectToHostByName(const QString &name, quint16 port) = 0;
|
||||
virtual bool bind(const QHostAddress &address, quint16 port) = 0;
|
||||
virtual bool listen(int backlog) = 0;
|
||||
virtual qintptr accept() = 0;
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual qint64 bytesAvailable() const = 0;
|
||||
|
||||
virtual qint64 read(char *data, qint64 maxlen) = 0;
|
||||
virtual qint64 write(const char *data, qint64 len) = 0;
|
||||
|
||||
#ifndef QT_NO_UDPSOCKET
|
||||
#ifndef QT_NO_NETWORKINTERFACE
|
||||
virtual bool joinMulticastGroup(const QHostAddress &groupAddress,
|
||||
const QNetworkInterface &iface) = 0;
|
||||
virtual bool leaveMulticastGroup(const QHostAddress &groupAddress,
|
||||
const QNetworkInterface &iface) = 0;
|
||||
virtual QNetworkInterface multicastInterface() const = 0;
|
||||
virtual bool setMulticastInterface(const QNetworkInterface &iface) = 0;
|
||||
#endif // QT_NO_NETWORKINTERFACE
|
||||
|
||||
virtual bool hasPendingDatagrams() const = 0;
|
||||
virtual qint64 pendingDatagramSize() const = 0;
|
||||
#endif // QT_NO_UDPSOCKET
|
||||
|
||||
virtual qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader *header = nullptr,
|
||||
PacketHeaderOptions = WantNone) = 0;
|
||||
virtual qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &header) = 0;
|
||||
virtual qint64 bytesToWrite() const = 0;
|
||||
|
||||
virtual int option(SocketOption option) const = 0;
|
||||
virtual bool setOption(SocketOption option, int value) = 0;
|
||||
|
||||
virtual bool waitForRead(int msecs = 30000, bool *timedOut = nullptr) = 0;
|
||||
virtual bool waitForWrite(int msecs = 30000, bool *timedOut = nullptr) = 0;
|
||||
virtual bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
|
||||
bool checkRead, bool checkWrite,
|
||||
int msecs = 30000, bool *timedOut = nullptr) = 0;
|
||||
|
||||
QAbstractSocket::SocketError error() const;
|
||||
QString errorString() const;
|
||||
QAbstractSocket::SocketState state() const;
|
||||
QAbstractSocket::SocketType socketType() const;
|
||||
QAbstractSocket::NetworkLayerProtocol protocol() const;
|
||||
|
||||
QHostAddress localAddress() const;
|
||||
quint16 localPort() const;
|
||||
QHostAddress peerAddress() const;
|
||||
quint16 peerPort() const;
|
||||
int inboundStreamCount() const;
|
||||
int outboundStreamCount() const;
|
||||
|
||||
virtual bool isReadNotificationEnabled() const = 0;
|
||||
virtual void setReadNotificationEnabled(bool enable) = 0;
|
||||
virtual bool isWriteNotificationEnabled() const = 0;
|
||||
virtual void setWriteNotificationEnabled(bool enable) = 0;
|
||||
virtual bool isExceptionNotificationEnabled() const = 0;
|
||||
virtual void setExceptionNotificationEnabled(bool enable) = 0;
|
||||
|
||||
public Q_SLOTS:
|
||||
void readNotification();
|
||||
void writeNotification();
|
||||
void closeNotification();
|
||||
void exceptionNotification();
|
||||
void connectionNotification();
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
|
||||
#endif
|
||||
|
||||
public:
|
||||
void setReceiver(QAbstractSocketEngineReceiver *receiver);
|
||||
protected:
|
||||
QAbstractSocketEngine(QAbstractSocketEnginePrivate &dd, QObject* parent = nullptr);
|
||||
|
||||
void setError(QAbstractSocket::SocketError error, const QString &errorString) const;
|
||||
void setState(QAbstractSocket::SocketState state);
|
||||
void setSocketType(QAbstractSocket::SocketType socketType);
|
||||
void setProtocol(QAbstractSocket::NetworkLayerProtocol protocol);
|
||||
void setLocalAddress(const QHostAddress &address);
|
||||
void setLocalPort(quint16 port);
|
||||
void setPeerAddress(const QHostAddress &address);
|
||||
void setPeerPort(quint16 port);
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QAbstractSocketEngine)
|
||||
Q_DISABLE_COPY_MOVE(QAbstractSocketEngine)
|
||||
};
|
||||
|
||||
class QAbstractSocketEnginePrivate : public QObjectPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QAbstractSocketEngine)
|
||||
public:
|
||||
QAbstractSocketEnginePrivate();
|
||||
|
||||
mutable QAbstractSocket::SocketError socketError;
|
||||
mutable bool hasSetSocketError;
|
||||
mutable QString socketErrorString;
|
||||
QAbstractSocket::SocketState socketState;
|
||||
QAbstractSocket::SocketType socketType;
|
||||
QAbstractSocket::NetworkLayerProtocol socketProtocol;
|
||||
QHostAddress localAddress;
|
||||
quint16 localPort;
|
||||
QHostAddress peerAddress;
|
||||
quint16 peerPort;
|
||||
int inboundStreamCount;
|
||||
int outboundStreamCount;
|
||||
QAbstractSocketEngineReceiver *receiver;
|
||||
};
|
||||
|
||||
|
||||
class Q_AUTOTEST_EXPORT QSocketEngineHandler
|
||||
{
|
||||
protected:
|
||||
QSocketEngineHandler();
|
||||
virtual ~QSocketEngineHandler();
|
||||
virtual QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType,
|
||||
const QNetworkProxy &, QObject *parent) = 0;
|
||||
virtual QAbstractSocketEngine *createSocketEngine(qintptr socketDescriptor, QObject *parent) = 0;
|
||||
|
||||
private:
|
||||
friend class QAbstractSocketEngine;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractSocketEngine::PacketHeaderOptions)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QABSTRACTSOCKETENGINE_P_H
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QAUTHENTICATOR_P_H
|
||||
#define QAUTHENTICATOR_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <qhash.h>
|
||||
#include <qbytearray.h>
|
||||
#include <qscopedpointer.h>
|
||||
#include <qstring.h>
|
||||
#include <qauthenticator.h>
|
||||
#include <qvariant.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpResponseHeader;
|
||||
#if QT_CONFIG(sspi) // SSPI
|
||||
class QSSPIWindowsHandles;
|
||||
#elif QT_CONFIG(gssapi) // GSSAPI
|
||||
class QGssApiHandles;
|
||||
#endif
|
||||
|
||||
class Q_AUTOTEST_EXPORT QAuthenticatorPrivate
|
||||
{
|
||||
public:
|
||||
enum Method { None, Basic, Negotiate, Ntlm, DigestMd5, };
|
||||
QAuthenticatorPrivate();
|
||||
~QAuthenticatorPrivate();
|
||||
|
||||
QString user;
|
||||
QString extractedUser;
|
||||
QString password;
|
||||
QVariantHash options;
|
||||
Method method;
|
||||
QString realm;
|
||||
QByteArray challenge;
|
||||
#if QT_CONFIG(sspi) // SSPI
|
||||
QScopedPointer<QSSPIWindowsHandles> sspiWindowsHandles;
|
||||
#elif QT_CONFIG(gssapi) // GSSAPI
|
||||
QScopedPointer<QGssApiHandles> gssApiHandles;
|
||||
#endif
|
||||
bool hasFailed; //credentials have been tried but rejected by server.
|
||||
|
||||
enum Phase {
|
||||
Start,
|
||||
Phase1,
|
||||
Phase2,
|
||||
Done,
|
||||
Invalid
|
||||
};
|
||||
Phase phase;
|
||||
|
||||
// digest specific
|
||||
QByteArray cnonce;
|
||||
int nonceCount;
|
||||
|
||||
// ntlm specific
|
||||
QString workstation;
|
||||
QString userDomain;
|
||||
|
||||
QByteArray calculateResponse(QByteArrayView method, QByteArrayView path, QStringView host);
|
||||
|
||||
inline static QAuthenticatorPrivate *getPrivate(QAuthenticator &auth) { return auth.d; }
|
||||
inline static const QAuthenticatorPrivate *getPrivate(const QAuthenticator &auth) { return auth.d; }
|
||||
|
||||
QByteArray digestMd5Response(QByteArrayView challenge, QByteArrayView method,
|
||||
QByteArrayView path);
|
||||
static QHash<QByteArray, QByteArray>
|
||||
parseDigestAuthenticationChallenge(QByteArrayView challenge);
|
||||
|
||||
void parseHttpResponse(const QList<QPair<QByteArray, QByteArray>> &, bool isProxy,
|
||||
QStringView host);
|
||||
void updateCredentials();
|
||||
|
||||
static bool isMethodSupported(QByteArrayView method);
|
||||
};
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef DECOMPRESS_HELPER_P_H
|
||||
#define DECOMPRESS_HELPER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QtCore/private/qbytedata_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIODevice;
|
||||
class Q_AUTOTEST_EXPORT QDecompressHelper
|
||||
{
|
||||
public:
|
||||
enum ContentEncoding {
|
||||
None,
|
||||
Deflate,
|
||||
GZip,
|
||||
Brotli,
|
||||
Zstandard,
|
||||
};
|
||||
|
||||
QDecompressHelper() = default;
|
||||
~QDecompressHelper();
|
||||
|
||||
bool setEncoding(const QByteArray &contentEncoding);
|
||||
|
||||
bool isCountingBytes() const;
|
||||
void setCountingBytesEnabled(bool shouldCount);
|
||||
|
||||
qint64 uncompressedSize() const;
|
||||
|
||||
bool hasData() const;
|
||||
void feed(const QByteArray &data);
|
||||
void feed(QByteArray &&data);
|
||||
void feed(const QByteDataBuffer &buffer);
|
||||
void feed(QByteDataBuffer &&buffer);
|
||||
qsizetype read(char *data, qsizetype maxSize);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
void clear();
|
||||
|
||||
void setDecompressedSafetyCheckThreshold(qint64 threshold);
|
||||
|
||||
static bool isSupportedEncoding(const QByteArray &encoding);
|
||||
static QByteArrayList acceptedEncoding();
|
||||
|
||||
QString errorString() const;
|
||||
|
||||
private:
|
||||
bool isPotentialArchiveBomb() const;
|
||||
bool hasDataInternal() const;
|
||||
qsizetype readInternal(char *data, qsizetype maxSize);
|
||||
|
||||
bool countInternal();
|
||||
bool countInternal(const QByteArray &data);
|
||||
bool countInternal(const QByteDataBuffer &buffer);
|
||||
|
||||
bool setEncoding(ContentEncoding ce);
|
||||
qint64 encodedBytesAvailable() const;
|
||||
|
||||
qsizetype readZLib(char *data, qsizetype maxSize);
|
||||
qsizetype readBrotli(char *data, qsizetype maxSize);
|
||||
qsizetype readZstandard(char *data, qsizetype maxSize);
|
||||
|
||||
QByteDataBuffer compressedDataBuffer;
|
||||
QByteDataBuffer decompressedDataBuffer;
|
||||
const qsizetype MaxDecompressedDataBufferSize = 10 * 1024 * 1024;
|
||||
bool decoderHasData = false;
|
||||
|
||||
bool countDecompressed = false;
|
||||
std::unique_ptr<QDecompressHelper> countHelper;
|
||||
|
||||
QString errorStr;
|
||||
|
||||
// Used for calculating the ratio
|
||||
qint64 archiveBombCheckThreshold = 10 * 1024 * 1024;
|
||||
qint64 totalUncompressedBytes = 0;
|
||||
qint64 totalCompressedBytes = 0;
|
||||
qint64 totalBytesRead = 0;
|
||||
|
||||
ContentEncoding contentEncoding = None;
|
||||
|
||||
void *decoderPointer = nullptr;
|
||||
#if QT_CONFIG(brotli)
|
||||
const uint8_t *brotliUnconsumedDataPtr = nullptr;
|
||||
size_t brotliUnconsumedAmount = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // DECOMPRESS_HELPER_P_H
|
||||
@@ -0,0 +1,206 @@
|
||||
// Copyright (C) 2012 Jeremy Lainé <jeremy.laine@m4x.org>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QDNSLOOKUP_P_H
|
||||
#define QDNSLOOKUP_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the QDnsLookup class. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "QtCore/qmutex.h"
|
||||
#include "QtCore/qrunnable.h"
|
||||
#include "QtCore/qsharedpointer.h"
|
||||
#if QT_CONFIG(thread)
|
||||
#include "QtCore/qthreadpool.h"
|
||||
#endif
|
||||
#include "QtNetwork/qdnslookup.h"
|
||||
#include "QtNetwork/qhostaddress.h"
|
||||
#include "private/qobject_p.h"
|
||||
|
||||
QT_REQUIRE_CONFIG(dnslookup);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
//#define QDNSLOOKUP_DEBUG
|
||||
|
||||
constexpr qsizetype MaxDomainNameLength = 255;
|
||||
class QDnsLookupRunnable;
|
||||
|
||||
class QDnsLookupReply
|
||||
{
|
||||
public:
|
||||
QDnsLookupReply()
|
||||
: error(QDnsLookup::NoError)
|
||||
{ }
|
||||
|
||||
QDnsLookup::Error error;
|
||||
QString errorString;
|
||||
|
||||
QList<QDnsDomainNameRecord> canonicalNameRecords;
|
||||
QList<QDnsHostAddressRecord> hostAddressRecords;
|
||||
QList<QDnsMailExchangeRecord> mailExchangeRecords;
|
||||
QList<QDnsDomainNameRecord> nameServerRecords;
|
||||
QList<QDnsDomainNameRecord> pointerRecords;
|
||||
QList<QDnsServiceRecord> serviceRecords;
|
||||
QList<QDnsTextRecord> textRecords;
|
||||
};
|
||||
|
||||
class QDnsLookupPrivate : public QObjectPrivate
|
||||
{
|
||||
public:
|
||||
QDnsLookupPrivate()
|
||||
: isFinished(false)
|
||||
, type(QDnsLookup::A)
|
||||
, runnable(nullptr)
|
||||
{ }
|
||||
|
||||
void _q_lookupFinished(const QDnsLookupReply &reply);
|
||||
|
||||
static const char *msgNoIpV6NameServerAdresses;
|
||||
|
||||
bool isFinished;
|
||||
|
||||
void nameChanged()
|
||||
{
|
||||
emit q_func()->nameChanged(name);
|
||||
}
|
||||
Q_OBJECT_BINDABLE_PROPERTY(QDnsLookupPrivate, QString, name,
|
||||
&QDnsLookupPrivate::nameChanged);
|
||||
|
||||
void typeChanged()
|
||||
{
|
||||
emit q_func()->typeChanged(type);
|
||||
}
|
||||
|
||||
Q_OBJECT_BINDABLE_PROPERTY(QDnsLookupPrivate, QDnsLookup::Type,
|
||||
type, &QDnsLookupPrivate::typeChanged);
|
||||
|
||||
void nameserverChanged()
|
||||
{
|
||||
emit q_func()->nameserverChanged(nameserver);
|
||||
}
|
||||
Q_OBJECT_BINDABLE_PROPERTY(QDnsLookupPrivate, QHostAddress, nameserver,
|
||||
&QDnsLookupPrivate::nameserverChanged);
|
||||
|
||||
QDnsLookupReply reply;
|
||||
QDnsLookupRunnable *runnable;
|
||||
|
||||
Q_DECLARE_PUBLIC(QDnsLookup)
|
||||
};
|
||||
|
||||
class QDnsLookupRunnable : public QObject, public QRunnable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QDnsLookupRunnable(QDnsLookup::Type type, const QByteArray &name, const QHostAddress &nameserver)
|
||||
: requestType(type)
|
||||
, requestName(name)
|
||||
, nameserver(nameserver)
|
||||
{ }
|
||||
void run() override;
|
||||
|
||||
signals:
|
||||
void finished(const QDnsLookupReply &reply);
|
||||
|
||||
private:
|
||||
static void query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply);
|
||||
QDnsLookup::Type requestType;
|
||||
QByteArray requestName;
|
||||
QHostAddress nameserver;
|
||||
};
|
||||
|
||||
#if QT_CONFIG(thread)
|
||||
class QDnsLookupThreadPool : public QThreadPool
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QDnsLookupThreadPool();
|
||||
void start(QRunnable *runnable);
|
||||
|
||||
private slots:
|
||||
void _q_applicationDestroyed();
|
||||
|
||||
private:
|
||||
QMutex signalsMutex;
|
||||
bool signalsConnected;
|
||||
};
|
||||
#endif // QT_CONFIG(thread)
|
||||
|
||||
class QDnsRecordPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
QDnsRecordPrivate()
|
||||
: timeToLive(0)
|
||||
{ }
|
||||
|
||||
QString name;
|
||||
quint32 timeToLive;
|
||||
};
|
||||
|
||||
class QDnsDomainNameRecordPrivate : public QDnsRecordPrivate
|
||||
{
|
||||
public:
|
||||
QDnsDomainNameRecordPrivate()
|
||||
{ }
|
||||
|
||||
QString value;
|
||||
};
|
||||
|
||||
class QDnsHostAddressRecordPrivate : public QDnsRecordPrivate
|
||||
{
|
||||
public:
|
||||
QDnsHostAddressRecordPrivate()
|
||||
{ }
|
||||
|
||||
QHostAddress value;
|
||||
};
|
||||
|
||||
class QDnsMailExchangeRecordPrivate : public QDnsRecordPrivate
|
||||
{
|
||||
public:
|
||||
QDnsMailExchangeRecordPrivate()
|
||||
: preference(0)
|
||||
{ }
|
||||
|
||||
QString exchange;
|
||||
quint16 preference;
|
||||
};
|
||||
|
||||
class QDnsServiceRecordPrivate : public QDnsRecordPrivate
|
||||
{
|
||||
public:
|
||||
QDnsServiceRecordPrivate()
|
||||
: port(0),
|
||||
priority(0),
|
||||
weight(0)
|
||||
{ }
|
||||
|
||||
QString target;
|
||||
quint16 port;
|
||||
quint16 priority;
|
||||
quint16 weight;
|
||||
};
|
||||
|
||||
class QDnsTextRecordPrivate : public QDnsRecordPrivate
|
||||
{
|
||||
public:
|
||||
QDnsTextRecordPrivate()
|
||||
{ }
|
||||
|
||||
QList<QByteArray> values;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDNSLOOKUP_P_H
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QDTLS_P_H
|
||||
#define QDTLS_P_H
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qtlsbackend_p.h"
|
||||
|
||||
#include <QtCore/private/qobject_p.h>
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
QT_REQUIRE_CONFIG(dtls);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHostAddress;
|
||||
|
||||
class QDtlsClientVerifierPrivate : public QObjectPrivate
|
||||
{
|
||||
public:
|
||||
QDtlsClientVerifierPrivate();
|
||||
~QDtlsClientVerifierPrivate();
|
||||
std::unique_ptr<QTlsPrivate::DtlsCookieVerifier> backend;
|
||||
};
|
||||
|
||||
class QDtlsPrivate : public QObjectPrivate
|
||||
{
|
||||
public:
|
||||
QDtlsPrivate();
|
||||
~QDtlsPrivate();
|
||||
std::unique_ptr<QTlsPrivate::DtlsCryptograph> backend;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDTLS_P_H
|
||||
@@ -0,0 +1,99 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHOSTADDRESSPRIVATE_H
|
||||
#define QHOSTADDRESSPRIVATE_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the QHostAddress and QNetworkInterface classes. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qhostaddress.h"
|
||||
#include "qabstractsocket.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
enum AddressClassification {
|
||||
LoopbackAddress = 1,
|
||||
LocalNetAddress, // RFC 1122
|
||||
LinkLocalAddress, // RFC 4291 (v6), RFC 3927 (v4)
|
||||
MulticastAddress, // RFC 4291 (v6), RFC 3171 (v4)
|
||||
BroadcastAddress, // RFC 919, 922
|
||||
|
||||
GlobalAddress = 16,
|
||||
TestNetworkAddress, // RFC 3849 (v6), RFC 5737 (v4),
|
||||
PrivateNetworkAddress, // RFC 1918
|
||||
UniqueLocalAddress, // RFC 4193
|
||||
SiteLocalAddress, // RFC 4291 (deprecated by RFC 3879, should be treated as global)
|
||||
|
||||
UnknownAddress = 0 // unclassified or reserved
|
||||
};
|
||||
|
||||
class QNetmask
|
||||
{
|
||||
// stores 0-32 for IPv4, 0-128 for IPv6, or 255 for invalid
|
||||
quint8 length;
|
||||
public:
|
||||
constexpr QNetmask() : length(255) {}
|
||||
|
||||
bool setAddress(const QHostAddress &address);
|
||||
QHostAddress address(QAbstractSocket::NetworkLayerProtocol protocol) const;
|
||||
|
||||
int prefixLength() const { return length == 255 ? -1 : length; }
|
||||
void setPrefixLength(QAbstractSocket::NetworkLayerProtocol proto, int len)
|
||||
{
|
||||
int maxlen = -1;
|
||||
if (proto == QAbstractSocket::IPv4Protocol)
|
||||
maxlen = 32;
|
||||
else if (proto == QAbstractSocket::IPv6Protocol)
|
||||
maxlen = 128;
|
||||
if (len > maxlen || len < 0)
|
||||
length = 255U;
|
||||
else
|
||||
length = unsigned(len);
|
||||
}
|
||||
|
||||
friend bool operator==(QNetmask n1, QNetmask n2)
|
||||
{ return n1.length == n2.length; }
|
||||
};
|
||||
|
||||
class QHostAddressPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
QHostAddressPrivate();
|
||||
|
||||
void setAddress(quint32 a_ = 0);
|
||||
void setAddress(const quint8 *a_);
|
||||
void setAddress(const Q_IPV6ADDR &a_);
|
||||
|
||||
bool parse(const QString &ipString);
|
||||
void clear();
|
||||
|
||||
QString scopeId;
|
||||
|
||||
union {
|
||||
Q_IPV6ADDR a6; // IPv6 address
|
||||
struct { quint64 c[2]; } a6_64;
|
||||
struct { quint32 c[4]; } a6_32;
|
||||
};
|
||||
quint32 a; // IPv4 address
|
||||
qint8 protocol;
|
||||
|
||||
AddressClassification classify() const;
|
||||
static AddressClassification classify(const QHostAddress &address)
|
||||
{ return address.d->classify(); }
|
||||
|
||||
friend class QHostAddress;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,194 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHOSTINFO_P_H
|
||||
#define QHOSTINFO_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the QHostInfo class. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "QtCore/qcoreapplication.h"
|
||||
#include "private/qcoreapplication_p.h"
|
||||
#include "private/qmetaobject_p.h"
|
||||
#include "QtNetwork/qhostinfo.h"
|
||||
#include "QtCore/qmutex.h"
|
||||
#include "QtCore/qwaitcondition.h"
|
||||
#include "QtCore/qobject.h"
|
||||
#include "QtCore/qpointer.h"
|
||||
#include "QtCore/qthread.h"
|
||||
#if QT_CONFIG(thread)
|
||||
#include "QtCore/qthreadpool.h"
|
||||
#endif
|
||||
#include "QtCore/qrunnable.h"
|
||||
#include "QtCore/qlist.h"
|
||||
#include "QtCore/qqueue.h"
|
||||
#include <QElapsedTimer>
|
||||
#include <QCache>
|
||||
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class QHostInfoResult : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QHostInfoResult(const QObject *receiver, QtPrivate::SlotObjUniquePtr slot);
|
||||
~QHostInfoResult() override;
|
||||
|
||||
void postResultsReady(const QHostInfo &info);
|
||||
|
||||
Q_SIGNALS:
|
||||
void resultsReady(const QHostInfo &info);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
private:
|
||||
QHostInfoResult(const QHostInfoResult *other)
|
||||
: receiver(other->receiver), slotObj{copy(other->slotObj)},
|
||||
withContextObject(other->withContextObject)
|
||||
{
|
||||
// cleanup if the application terminates before results are delivered
|
||||
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
|
||||
this, &QObject::deleteLater);
|
||||
// maintain thread affinity
|
||||
moveToThread(other->thread());
|
||||
}
|
||||
|
||||
QPointer<const QObject> receiver = nullptr;
|
||||
QtPrivate::SlotObjUniquePtr slotObj;
|
||||
const bool withContextObject = false;
|
||||
};
|
||||
|
||||
class QHostInfoAgent
|
||||
{
|
||||
public:
|
||||
static QHostInfo fromName(const QString &hostName);
|
||||
static QHostInfo lookup(const QString &hostName);
|
||||
static QHostInfo reverseLookup(const QHostAddress &address);
|
||||
};
|
||||
|
||||
class QHostInfoPrivate
|
||||
{
|
||||
public:
|
||||
inline QHostInfoPrivate()
|
||||
: err(QHostInfo::NoError),
|
||||
errorStr(QLatin1StringView(QT_TRANSLATE_NOOP("QHostInfo", "Unknown error"))),
|
||||
lookupId(0)
|
||||
{
|
||||
}
|
||||
static int lookupHostImpl(const QString &name,
|
||||
const QObject *receiver,
|
||||
QtPrivate::QSlotObjectBase *slotObj,
|
||||
const char *member);
|
||||
|
||||
QHostInfo::HostInfoError err;
|
||||
QString errorStr;
|
||||
QList<QHostAddress> addrs;
|
||||
QString hostName;
|
||||
int lookupId;
|
||||
};
|
||||
|
||||
// These functions are outside of the QHostInfo class and strictly internal.
|
||||
// Do NOT use them outside of QAbstractSocket.
|
||||
QHostInfo Q_NETWORK_EXPORT qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id);
|
||||
void Q_AUTOTEST_EXPORT qt_qhostinfo_clear_cache();
|
||||
void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e);
|
||||
void Q_AUTOTEST_EXPORT qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution);
|
||||
|
||||
class QHostInfoCache
|
||||
{
|
||||
public:
|
||||
QHostInfoCache();
|
||||
const int max_age; // seconds
|
||||
|
||||
QHostInfo get(const QString &name, bool *valid);
|
||||
void put(const QString &name, const QHostInfo &info);
|
||||
void clear();
|
||||
|
||||
bool isEnabled() { return enabled.load(std::memory_order_relaxed); }
|
||||
// this function is currently only used for the auto tests
|
||||
// and not usable by public API
|
||||
void setEnabled(bool e) { enabled.store(e, std::memory_order_relaxed); }
|
||||
private:
|
||||
std::atomic<bool> enabled;
|
||||
struct QHostInfoCacheElement {
|
||||
QHostInfo info;
|
||||
QElapsedTimer age;
|
||||
};
|
||||
QCache<QString,QHostInfoCacheElement> cache;
|
||||
QMutex mutex;
|
||||
};
|
||||
|
||||
// the following classes are used for the (normal) case: We use multiple threads to lookup DNS
|
||||
|
||||
class QHostInfoRunnable : public QRunnable
|
||||
{
|
||||
public:
|
||||
explicit QHostInfoRunnable(const QString &hn, int i, const QObject *receiver,
|
||||
QtPrivate::SlotObjUniquePtr slotObj);
|
||||
~QHostInfoRunnable() override;
|
||||
|
||||
void run() override;
|
||||
|
||||
QString toBeLookedUp;
|
||||
int id;
|
||||
QHostInfoResult resultEmitter;
|
||||
};
|
||||
|
||||
|
||||
class QHostInfoLookupManager
|
||||
{
|
||||
public:
|
||||
QHostInfoLookupManager();
|
||||
~QHostInfoLookupManager();
|
||||
|
||||
void clear();
|
||||
|
||||
// called from QHostInfo
|
||||
void scheduleLookup(QHostInfoRunnable *r);
|
||||
void abortLookup(int id);
|
||||
|
||||
// called from QHostInfoRunnable
|
||||
void lookupFinished(QHostInfoRunnable *r);
|
||||
bool wasAborted(int id);
|
||||
|
||||
QHostInfoCache cache;
|
||||
|
||||
friend class QHostInfoRunnable;
|
||||
protected:
|
||||
#if QT_CONFIG(thread)
|
||||
QList<QHostInfoRunnable*> currentLookups; // in progress
|
||||
QList<QHostInfoRunnable*> postponedLookups; // postponed because in progress for same host
|
||||
#endif
|
||||
QQueue<QHostInfoRunnable*> scheduledLookups; // not yet started
|
||||
QList<QHostInfoRunnable*> finishedLookups; // recently finished
|
||||
QList<int> abortedLookups; // ids of aborted lookups
|
||||
|
||||
#if QT_CONFIG(thread)
|
||||
QThreadPool threadPool;
|
||||
#endif
|
||||
QMutex mutex;
|
||||
|
||||
bool wasDeleted;
|
||||
|
||||
private:
|
||||
void rescheduleWithMutexHeld();
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHOSTINFO_P_H
|
||||
@@ -0,0 +1,117 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHSTS_P_H
|
||||
#define QHSTS_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <QtNetwork/qhstspolicy.h>
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qdatetime.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qpair.h>
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtCore/qcontainerfwd.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_AUTOTEST_EXPORT QHstsCache
|
||||
{
|
||||
public:
|
||||
|
||||
void updateFromHeaders(const QList<QPair<QByteArray, QByteArray>> &headers,
|
||||
const QUrl &url);
|
||||
void updateFromPolicies(const QList<QHstsPolicy> &hosts);
|
||||
void updateKnownHost(const QUrl &url, const QDateTime &expires,
|
||||
bool includeSubDomains);
|
||||
bool isKnownHost(const QUrl &url) const;
|
||||
void clear();
|
||||
|
||||
QList<QHstsPolicy> policies() const;
|
||||
|
||||
#if QT_CONFIG(settings)
|
||||
void setStore(class QHstsStore *store);
|
||||
#endif // QT_CONFIG(settings)
|
||||
|
||||
private:
|
||||
|
||||
void updateKnownHost(const QString &hostName, const QDateTime &expires,
|
||||
bool includeSubDomains);
|
||||
|
||||
struct HostName
|
||||
{
|
||||
explicit HostName(const QString &n) : name(n) { }
|
||||
explicit HostName(QStringView r) : fragment(r) { }
|
||||
|
||||
bool operator < (const HostName &rhs) const
|
||||
{
|
||||
if (fragment.size()) {
|
||||
if (rhs.fragment.size())
|
||||
return fragment < rhs.fragment;
|
||||
return fragment < QStringView{rhs.name};
|
||||
}
|
||||
|
||||
if (rhs.fragment.size())
|
||||
return QStringView{name} < rhs.fragment;
|
||||
return name < rhs.name;
|
||||
}
|
||||
|
||||
// We use 'name' for a HostName object contained in our dictionary;
|
||||
// we use 'fragment' only during lookup, when chopping the complete host
|
||||
// name, removing subdomain names (such HostName object is 'transient', it
|
||||
// must not outlive the original QString object.
|
||||
QString name;
|
||||
QStringView fragment;
|
||||
};
|
||||
|
||||
mutable std::map<HostName, QHstsPolicy> knownHosts;
|
||||
#if QT_CONFIG(settings)
|
||||
QHstsStore *hstsStore = nullptr;
|
||||
#endif // QT_CONFIG(settings)
|
||||
};
|
||||
|
||||
class Q_AUTOTEST_EXPORT QHstsHeaderParser
|
||||
{
|
||||
public:
|
||||
|
||||
bool parse(const QList<QPair<QByteArray, QByteArray>> &headers);
|
||||
|
||||
QDateTime expirationDate() const { return expiry; }
|
||||
bool includeSubDomains() const { return subDomainsFound; }
|
||||
|
||||
private:
|
||||
|
||||
bool parseSTSHeader();
|
||||
bool parseDirective();
|
||||
bool processDirective(const QByteArray &name, const QByteArray &value);
|
||||
bool nextToken();
|
||||
|
||||
QByteArray header;
|
||||
QByteArray token;
|
||||
|
||||
QDateTime expiry;
|
||||
int tokenPos = 0;
|
||||
bool maxAgeFound = false;
|
||||
qint64 maxAge = 0;
|
||||
bool subDomainsFound = false;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHSTSSTORE_P_H
|
||||
#define QHSTSSTORE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(settings);
|
||||
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qsettings.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHstsPolicy;
|
||||
class QByteArray;
|
||||
class QString;
|
||||
|
||||
class Q_AUTOTEST_EXPORT QHstsStore
|
||||
{
|
||||
public:
|
||||
explicit QHstsStore(const QString &dirName);
|
||||
~QHstsStore();
|
||||
|
||||
QList<QHstsPolicy> readPolicies();
|
||||
void addToObserved(const QHstsPolicy &policy);
|
||||
void synchronize();
|
||||
|
||||
bool isWritable() const;
|
||||
|
||||
static QString absoluteFilePath(const QString &dirName);
|
||||
private:
|
||||
void beginHstsGroups();
|
||||
bool serializePolicy(const QString &key, const QHstsPolicy &policy);
|
||||
bool deserializePolicy(const QString &key, QHstsPolicy &policy);
|
||||
void evictPolicy(const QString &key);
|
||||
void endHstsGroups();
|
||||
|
||||
QList<QHstsPolicy> observedPolicies;
|
||||
QSettings store;
|
||||
|
||||
Q_DISABLE_COPY_MOVE(QHstsStore)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHSTSSTORE_P_H
|
||||
@@ -0,0 +1,203 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTP2PROTOCOLHANDLER_P_H
|
||||
#define QHTTP2PROTOCOLHANDLER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qhttpnetworkconnectionchannel_p.h>
|
||||
#include <private/qabstractprotocolhandler_p.h>
|
||||
#include <private/qhttpnetworkrequest_p.h>
|
||||
|
||||
#include <access/qhttp2configuration.h>
|
||||
|
||||
#include <private/http2protocol_p.h>
|
||||
#include <private/http2streams_p.h>
|
||||
#include <private/http2frames_p.h>
|
||||
#include <private/hpacktable_p.h>
|
||||
#include <private/hpack_p.h>
|
||||
|
||||
#include <QtCore/qnamespace.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qflags.h>
|
||||
#include <QtCore/qhash.h>
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <deque>
|
||||
#include <set>
|
||||
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttp2ProtocolHandler : public QObject, public QAbstractProtocolHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *channel);
|
||||
|
||||
QHttp2ProtocolHandler(const QHttp2ProtocolHandler &rhs) = delete;
|
||||
QHttp2ProtocolHandler(QHttp2ProtocolHandler &&rhs) = delete;
|
||||
|
||||
QHttp2ProtocolHandler &operator = (const QHttp2ProtocolHandler &rhs) = delete;
|
||||
QHttp2ProtocolHandler &operator = (QHttp2ProtocolHandler &&rhs) = delete;
|
||||
|
||||
Q_INVOKABLE void handleConnectionClosure();
|
||||
Q_INVOKABLE void ensureClientPrefaceSent();
|
||||
|
||||
private slots:
|
||||
void _q_uploadDataReadyRead();
|
||||
void _q_replyDestroyed(QObject* reply);
|
||||
void _q_uploadDataDestroyed(QObject* uploadData);
|
||||
|
||||
private:
|
||||
using Stream = Http2::Stream;
|
||||
|
||||
void _q_readyRead() override;
|
||||
Q_INVOKABLE void _q_receiveReply() override;
|
||||
Q_INVOKABLE bool sendRequest() override;
|
||||
|
||||
bool sendClientPreface();
|
||||
bool sendSETTINGS_ACK();
|
||||
bool sendHEADERS(Stream &stream);
|
||||
bool sendDATA(Stream &stream);
|
||||
Q_INVOKABLE bool sendWINDOW_UPDATE(quint32 streamID, quint32 delta);
|
||||
bool sendRST_STREAM(quint32 streamID, quint32 errorCoder);
|
||||
bool sendGOAWAY(quint32 errorCode);
|
||||
|
||||
void handleDATA();
|
||||
void handleHEADERS();
|
||||
void handlePRIORITY();
|
||||
void handleRST_STREAM();
|
||||
void handleSETTINGS();
|
||||
void handlePUSH_PROMISE();
|
||||
void handlePING();
|
||||
void handleGOAWAY();
|
||||
void handleWINDOW_UPDATE();
|
||||
void handleCONTINUATION();
|
||||
|
||||
void handleContinuedHEADERS();
|
||||
|
||||
bool acceptSetting(Http2::Settings identifier, quint32 newValue);
|
||||
|
||||
void updateStream(Stream &stream, const HPack::HttpHeader &headers,
|
||||
Qt::ConnectionType connectionType = Qt::DirectConnection);
|
||||
void updateStream(Stream &stream, const Http2::Frame &dataFrame,
|
||||
Qt::ConnectionType connectionType = Qt::DirectConnection);
|
||||
void finishStream(Stream &stream, Qt::ConnectionType connectionType = Qt::DirectConnection);
|
||||
// Error code send by a peer (GOAWAY/RST_STREAM):
|
||||
void finishStreamWithError(Stream &stream, quint32 errorCode);
|
||||
// Locally encountered error:
|
||||
void finishStreamWithError(Stream &stream, QNetworkReply::NetworkError error,
|
||||
const QString &message);
|
||||
|
||||
// Stream's lifecycle management:
|
||||
quint32 createNewStream(const HttpMessagePair &message, bool uploadDone = false);
|
||||
void addToSuspended(Stream &stream);
|
||||
void markAsReset(quint32 streamID);
|
||||
quint32 popStreamToResume();
|
||||
void removeFromSuspended(quint32 streamID);
|
||||
void deleteActiveStream(quint32 streamID);
|
||||
bool streamWasReset(quint32 streamID) const;
|
||||
|
||||
bool prefaceSent = false;
|
||||
// In the current implementation we send
|
||||
// SETTINGS only once, immediately after
|
||||
// the client's preface 24-byte message.
|
||||
bool waitingForSettingsACK = false;
|
||||
|
||||
static const quint32 maxAcceptableTableSize = 16 * HPack::FieldLookupTable::DefaultSize;
|
||||
// HTTP/2 4.3: Header compression is stateful. One compression context and
|
||||
// one decompression context are used for the entire connection.
|
||||
HPack::Decoder decoder;
|
||||
HPack::Encoder encoder;
|
||||
|
||||
QHash<QObject *, int> streamIDs;
|
||||
QHash<quint32, Stream> activeStreams;
|
||||
std::deque<quint32> suspendedStreams[3]; // 3 for priorities: High, Normal, Low.
|
||||
static const std::deque<quint32>::size_type maxRecycledStreams;
|
||||
std::deque<quint32> recycledStreams;
|
||||
|
||||
// Peer's max frame size (this min is the default value
|
||||
// we start with, that can be updated by SETTINGS frame):
|
||||
quint32 maxFrameSize = Http2::minPayloadLimit;
|
||||
|
||||
Http2::FrameReader frameReader;
|
||||
Http2::Frame inboundFrame;
|
||||
Http2::FrameWriter frameWriter;
|
||||
// Temporary storage to assemble HEADERS' block
|
||||
// from several CONTINUATION frames ...
|
||||
bool continuationExpected = false;
|
||||
std::vector<Http2::Frame> continuedFrames;
|
||||
|
||||
// Control flow:
|
||||
|
||||
// This is how many concurrent streams our peer allows us, 100 is the
|
||||
// initial value, can be updated by the server's SETTINGS frame(s):
|
||||
quint32 maxConcurrentStreams = Http2::maxConcurrentStreams;
|
||||
// While we allow sending SETTTINGS_MAX_CONCURRENT_STREAMS to limit our peer,
|
||||
// it's just a hint and we do not actually enforce it (and we can continue
|
||||
// sending requests and creating streams while maxConcurrentStreams allows).
|
||||
|
||||
// This is our (client-side) maximum possible receive window size, we set
|
||||
// it in a ctor from QHttp2Configuration, it does not change after that.
|
||||
// The default is 64Kb:
|
||||
qint32 maxSessionReceiveWindowSize = Http2::defaultSessionWindowSize;
|
||||
|
||||
// Our session current receive window size, updated in a ctor from
|
||||
// QHttp2Configuration. Signed integer since it can become negative
|
||||
// (it's still a valid window size).
|
||||
qint32 sessionReceiveWindowSize = Http2::defaultSessionWindowSize;
|
||||
// Our per-stream receive window size, default is 64 Kb, will be updated
|
||||
// from QHttp2Configuration. Again, signed - can become negative.
|
||||
qint32 streamInitialReceiveWindowSize = Http2::defaultSessionWindowSize;
|
||||
|
||||
// These are our peer's receive window sizes, they will be updated by the
|
||||
// peer's SETTINGS and WINDOW_UPDATE frames, defaults presumed to be 64Kb.
|
||||
qint32 sessionSendWindowSize = Http2::defaultSessionWindowSize;
|
||||
qint32 streamInitialSendWindowSize = Http2::defaultSessionWindowSize;
|
||||
|
||||
// Our peer's header size limitations. It's unlimited by default, but can
|
||||
// be changed via peer's SETTINGS frame.
|
||||
quint32 maxHeaderListSize = (std::numeric_limits<quint32>::max)();
|
||||
// While we can send SETTINGS_MAX_HEADER_LIST_SIZE value (our limit on
|
||||
// the headers size), we never enforce it, it's just a hint to our peer.
|
||||
|
||||
Q_INVOKABLE void resumeSuspendedStreams();
|
||||
// Our stream IDs (all odd), the first valid will be 1.
|
||||
quint32 nextID = 1;
|
||||
quint32 allocateStreamID();
|
||||
bool validPeerStreamID() const;
|
||||
bool goingAway = false;
|
||||
bool pushPromiseEnabled = false;
|
||||
quint32 lastPromisedID = Http2::connectionStreamID;
|
||||
QHash<QString, Http2::PushPromise> promisedData;
|
||||
bool tryReserveStream(const Http2::Frame &pushPromiseFrame,
|
||||
const HPack::HttpHeader &requestHeader);
|
||||
void resetPromisedStream(const Http2::Frame &pushPromiseFrame,
|
||||
Http2::Http2Error reason);
|
||||
void initReplyFromPushPromise(const HttpMessagePair &message,
|
||||
const QString &cacheKey);
|
||||
// Errors:
|
||||
void connectionError(Http2::Http2Error errorCode,
|
||||
const char *message);
|
||||
void closeSession();
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTPHEADERPARSER_H
|
||||
#define QHTTPHEADERPARSER_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QString>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace HeaderConstants {
|
||||
|
||||
// We previously used 8K, which is common on server side, but it turned out to
|
||||
// not be enough for various uses. Historically Firefox used 10K as the limit of
|
||||
// a single field, but some Location headers and Authorization challenges can
|
||||
// get even longer. Other browsers, such as Chrome, instead have a limit on the
|
||||
// total size of all the headers (as well as extra limits on some of the
|
||||
// individual fields). We'll use 100K as our default limit, which would be a ridiculously large
|
||||
// header, with the possibility to override it where we need to.
|
||||
static constexpr int MAX_HEADER_FIELD_SIZE = 100 * 1024;
|
||||
// Taken from http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestfields
|
||||
static constexpr int MAX_HEADER_FIELDS = 100;
|
||||
// Chromium has a limit on the total size of the header set to 256KB,
|
||||
// which is a reasonable default for QNetworkAccessManager.
|
||||
// https://stackoverflow.com/a/3436155
|
||||
static constexpr int MAX_TOTAL_HEADER_SIZE = 256 * 1024;
|
||||
|
||||
}
|
||||
|
||||
class Q_NETWORK_PRIVATE_EXPORT QHttpHeaderParser
|
||||
{
|
||||
public:
|
||||
QHttpHeaderParser();
|
||||
|
||||
void clear();
|
||||
bool parseHeaders(QByteArrayView headers);
|
||||
bool parseStatus(QByteArrayView status);
|
||||
|
||||
const QList<QPair<QByteArray, QByteArray> >& headers() const;
|
||||
void setStatusCode(int code);
|
||||
int getStatusCode() const;
|
||||
int getMajorVersion() const;
|
||||
void setMajorVersion(int version);
|
||||
int getMinorVersion() const;
|
||||
void setMinorVersion(int version);
|
||||
QString getReasonPhrase() const;
|
||||
void setReasonPhrase(const QString &reason);
|
||||
|
||||
QByteArray firstHeaderField(const QByteArray &name,
|
||||
const QByteArray &defaultValue = QByteArray()) const;
|
||||
QByteArray combinedHeaderValue(const QByteArray &name,
|
||||
const QByteArray &defaultValue = QByteArray()) const;
|
||||
QList<QByteArray> headerFieldValues(const QByteArray &name) const;
|
||||
void setHeaderField(const QByteArray &name, const QByteArray &data);
|
||||
void prependHeaderField(const QByteArray &name, const QByteArray &data);
|
||||
void appendHeaderField(const QByteArray &name, const QByteArray &data);
|
||||
void removeHeaderField(const QByteArray &name);
|
||||
void clearHeaders();
|
||||
|
||||
void setMaxHeaderFieldSize(qsizetype size) { maxFieldSize = size; }
|
||||
qsizetype maxHeaderFieldSize() const { return maxFieldSize; }
|
||||
|
||||
void setMaxTotalHeaderSize(qsizetype size) { maxTotalSize = size; }
|
||||
qsizetype maxTotalHeaderSize() const { return maxTotalSize; }
|
||||
|
||||
void setMaxHeaderFields(qsizetype count) { maxFieldCount = count; }
|
||||
qsizetype maxHeaderFields() const { return maxFieldCount; }
|
||||
|
||||
private:
|
||||
QList<QPair<QByteArray, QByteArray> > fields;
|
||||
QString reasonPhrase;
|
||||
int statusCode;
|
||||
int majorVersion;
|
||||
int minorVersion;
|
||||
|
||||
qsizetype maxFieldSize = HeaderConstants::MAX_HEADER_FIELD_SIZE;
|
||||
qsizetype maxTotalSize = HeaderConstants::MAX_TOTAL_HEADER_SIZE;
|
||||
qsizetype maxFieldCount = HeaderConstants::MAX_HEADER_FIELDS;
|
||||
};
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPHEADERPARSER_H
|
||||
@@ -0,0 +1,149 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTPMULTIPART_P_H
|
||||
#define QHTTPMULTIPART_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "QtCore/qshareddata.h"
|
||||
#include "qnetworkrequest_p.h" // for deriving QHttpPartPrivate from QNetworkHeadersPrivate
|
||||
#include "private/qobject_p.h"
|
||||
|
||||
#ifndef Q_OS_WASM
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class QHttpPartPrivate: public QSharedData, public QNetworkHeadersPrivate
|
||||
{
|
||||
public:
|
||||
inline QHttpPartPrivate() : bodyDevice(nullptr), headerCreated(false), readPointer(0)
|
||||
{
|
||||
}
|
||||
~QHttpPartPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QHttpPartPrivate(const QHttpPartPrivate &other)
|
||||
: QSharedData(other), QNetworkHeadersPrivate(other), body(other.body),
|
||||
header(other.header), headerCreated(other.headerCreated), readPointer(other.readPointer)
|
||||
{
|
||||
bodyDevice = other.bodyDevice;
|
||||
}
|
||||
|
||||
inline bool operator==(const QHttpPartPrivate &other) const
|
||||
{
|
||||
return rawHeaders == other.rawHeaders && body == other.body &&
|
||||
bodyDevice == other.bodyDevice && readPointer == other.readPointer;
|
||||
}
|
||||
|
||||
void setBodyDevice(QIODevice *device) {
|
||||
bodyDevice = device;
|
||||
readPointer = 0;
|
||||
}
|
||||
void setBody(const QByteArray &newBody) {
|
||||
body = newBody;
|
||||
readPointer = 0;
|
||||
}
|
||||
|
||||
// QIODevice-style methods called by QHttpMultiPartIODevice (but this class is
|
||||
// not a QIODevice):
|
||||
qint64 bytesAvailable() const;
|
||||
qint64 readData(char *data, qint64 maxSize);
|
||||
qint64 size() const;
|
||||
bool reset();
|
||||
|
||||
QByteArray body;
|
||||
QIODevice *bodyDevice;
|
||||
|
||||
private:
|
||||
void checkHeaderCreated() const;
|
||||
|
||||
mutable QByteArray header;
|
||||
mutable bool headerCreated;
|
||||
qint64 readPointer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class QHttpMultiPartPrivate;
|
||||
|
||||
class Q_AUTOTEST_EXPORT QHttpMultiPartIODevice : public QIODevice
|
||||
{
|
||||
public:
|
||||
QHttpMultiPartIODevice(QHttpMultiPartPrivate *parentMultiPart) :
|
||||
QIODevice(), multiPart(parentMultiPart), readPointer(0), deviceSize(-1) {
|
||||
}
|
||||
|
||||
~QHttpMultiPartIODevice() {
|
||||
}
|
||||
|
||||
virtual bool atEnd() const override {
|
||||
return readPointer == size();
|
||||
}
|
||||
|
||||
virtual qint64 bytesAvailable() const override {
|
||||
return size() - readPointer;
|
||||
}
|
||||
|
||||
virtual void close() override {
|
||||
readPointer = 0;
|
||||
partOffsets.clear();
|
||||
deviceSize = -1;
|
||||
QIODevice::close();
|
||||
}
|
||||
|
||||
virtual qint64 bytesToWrite() const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual qint64 size() const override;
|
||||
virtual bool isSequential() const override;
|
||||
virtual bool reset() override;
|
||||
virtual qint64 readData(char *data, qint64 maxSize) override;
|
||||
virtual qint64 writeData(const char *data, qint64 maxSize) override;
|
||||
|
||||
QHttpMultiPartPrivate *multiPart;
|
||||
qint64 readPointer;
|
||||
mutable QList<qint64> partOffsets;
|
||||
mutable qint64 deviceSize;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class QHttpMultiPartPrivate: public QObjectPrivate
|
||||
{
|
||||
public:
|
||||
|
||||
QHttpMultiPartPrivate();
|
||||
|
||||
~QHttpMultiPartPrivate()
|
||||
{
|
||||
delete device;
|
||||
}
|
||||
|
||||
QList<QHttpPart> parts;
|
||||
QByteArray boundary;
|
||||
QHttpMultiPart::ContentType contentType;
|
||||
QHttpMultiPartIODevice *device;
|
||||
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
#endif // QHTTPMULTIPART_P_H
|
||||
@@ -0,0 +1,271 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTPNETWORKCONNECTION_H
|
||||
#define QHTTPNETWORKCONNECTION_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/qnetworkrequest.h>
|
||||
#include <QtNetwork/qnetworkreply.h>
|
||||
#include <QtNetwork/qabstractsocket.h>
|
||||
|
||||
#include <qhttp2configuration.h>
|
||||
|
||||
#include <private/qobject_p.h>
|
||||
#include <qauthenticator.h>
|
||||
#include <qnetworkproxy.h>
|
||||
#include <qbuffer.h>
|
||||
#include <qtimer.h>
|
||||
#include <qsharedpointer.h>
|
||||
|
||||
#include <private/qhttpnetworkheader_p.h>
|
||||
#include <private/qhttpnetworkrequest_p.h>
|
||||
#include <private/qhttpnetworkreply_p.h>
|
||||
#include <private/qnetconmonitor_p.h>
|
||||
#include <private/http2protocol_p.h>
|
||||
|
||||
#include <private/qhttpnetworkconnectionchannel_p.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpNetworkRequest;
|
||||
class QHttpNetworkReply;
|
||||
class QHttpThreadDelegate;
|
||||
class QByteArray;
|
||||
class QHostInfo;
|
||||
#ifndef QT_NO_SSL
|
||||
class QSslConfiguration;
|
||||
class QSslContext;
|
||||
#endif // !QT_NO_SSL
|
||||
|
||||
class QHttpNetworkConnectionPrivate;
|
||||
class Q_AUTOTEST_EXPORT QHttpNetworkConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum ConnectionType {
|
||||
ConnectionTypeHTTP,
|
||||
ConnectionTypeHTTP2,
|
||||
ConnectionTypeHTTP2Direct
|
||||
};
|
||||
|
||||
explicit QHttpNetworkConnection(const QString &hostName, quint16 port = 80, bool encrypt = false,
|
||||
ConnectionType connectionType = ConnectionTypeHTTP,
|
||||
QObject *parent = nullptr);
|
||||
QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80,
|
||||
bool encrypt = false, QObject *parent = nullptr,
|
||||
ConnectionType connectionType = ConnectionTypeHTTP);
|
||||
~QHttpNetworkConnection();
|
||||
|
||||
//The hostname to which this is connected to.
|
||||
QString hostName() const;
|
||||
//The HTTP port in use.
|
||||
quint16 port() const;
|
||||
|
||||
//add a new HTTP request through this connection
|
||||
QHttpNetworkReply* sendRequest(const QHttpNetworkRequest &request);
|
||||
void fillHttp2Queue();
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
//set the proxy for this connection
|
||||
void setCacheProxy(const QNetworkProxy &networkProxy);
|
||||
QNetworkProxy cacheProxy() const;
|
||||
void setTransparentProxy(const QNetworkProxy &networkProxy);
|
||||
QNetworkProxy transparentProxy() const;
|
||||
#endif
|
||||
|
||||
bool isSsl() const;
|
||||
|
||||
QHttpNetworkConnectionChannel *channels() const;
|
||||
|
||||
ConnectionType connectionType();
|
||||
void setConnectionType(ConnectionType type);
|
||||
|
||||
QHttp2Configuration http2Parameters() const;
|
||||
void setHttp2Parameters(const QHttp2Configuration ¶ms);
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
void setSslConfiguration(const QSslConfiguration &config);
|
||||
void ignoreSslErrors(int channel = -1);
|
||||
void ignoreSslErrors(const QList<QSslError> &errors, int channel = -1);
|
||||
std::shared_ptr<QSslContext> sslContext();
|
||||
void setSslContext(std::shared_ptr<QSslContext> context);
|
||||
#endif
|
||||
|
||||
void preConnectFinished();
|
||||
|
||||
QString peerVerifyName() const;
|
||||
void setPeerVerifyName(const QString &peerName);
|
||||
|
||||
public slots:
|
||||
void onlineStateChanged(bool isOnline);
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QHttpNetworkConnection)
|
||||
Q_DISABLE_COPY_MOVE(QHttpNetworkConnection)
|
||||
friend class QHttpThreadDelegate;
|
||||
friend class QHttpNetworkReply;
|
||||
friend class QHttpNetworkReplyPrivate;
|
||||
friend class QHttpNetworkConnectionChannel;
|
||||
friend class QHttp2ProtocolHandler;
|
||||
friend class QHttpProtocolHandler;
|
||||
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_hostLookupFinished(QHostInfo))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_connectDelayedChannel())
|
||||
};
|
||||
|
||||
|
||||
// private classes
|
||||
typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair;
|
||||
|
||||
|
||||
class QHttpNetworkConnectionPrivate : public QObjectPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QHttpNetworkConnection)
|
||||
public:
|
||||
static const int defaultHttpChannelCount;
|
||||
static const int defaultPipelineLength;
|
||||
static const int defaultRePipelineLength;
|
||||
|
||||
enum ConnectionState {
|
||||
RunningState = 0,
|
||||
PausedState = 1
|
||||
};
|
||||
|
||||
enum NetworkLayerPreferenceState {
|
||||
Unknown,
|
||||
HostLookupPending,
|
||||
IPv4,
|
||||
IPv6,
|
||||
IPv4or6
|
||||
};
|
||||
|
||||
QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt,
|
||||
QHttpNetworkConnection::ConnectionType type);
|
||||
QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt,
|
||||
QHttpNetworkConnection::ConnectionType type);
|
||||
~QHttpNetworkConnectionPrivate();
|
||||
void init();
|
||||
|
||||
void pauseConnection();
|
||||
void resumeConnection();
|
||||
ConnectionState state;
|
||||
NetworkLayerPreferenceState networkLayerState;
|
||||
|
||||
enum { ChunkSize = 4096 };
|
||||
|
||||
int indexOf(QAbstractSocket *socket) const;
|
||||
|
||||
QHttpNetworkReply *queueRequest(const QHttpNetworkRequest &request);
|
||||
void requeueRequest(const HttpMessagePair &pair); // e.g. after pipeline broke
|
||||
void fillHttp2Queue();
|
||||
bool dequeueRequest(QAbstractSocket *socket);
|
||||
void prepareRequest(HttpMessagePair &request);
|
||||
void updateChannel(int i, const HttpMessagePair &messagePair);
|
||||
QHttpNetworkRequest predictNextRequest() const;
|
||||
QHttpNetworkReply* predictNextRequestsReply() const;
|
||||
|
||||
void fillPipeline(QAbstractSocket *socket);
|
||||
bool fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel);
|
||||
|
||||
// read more HTTP body after the next event loop spin
|
||||
void readMoreLater(QHttpNetworkReply *reply);
|
||||
|
||||
void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy);
|
||||
|
||||
void startHostInfoLookup();
|
||||
void startNetworkLayerStateLookup();
|
||||
void networkLayerDetected(QAbstractSocket::NetworkLayerProtocol protocol);
|
||||
|
||||
// private slots
|
||||
void _q_startNextRequest(); // send the next request from the queue
|
||||
|
||||
void _q_hostLookupFinished(const QHostInfo &info);
|
||||
void _q_connectDelayedChannel();
|
||||
|
||||
void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request);
|
||||
|
||||
QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket,
|
||||
const QString &extraDetail = QString());
|
||||
|
||||
void removeReply(QHttpNetworkReply *reply);
|
||||
|
||||
QString hostName;
|
||||
quint16 port;
|
||||
bool encrypt;
|
||||
bool delayIpv4;
|
||||
|
||||
// Number of channels we are trying to use at the moment:
|
||||
int activeChannelCount;
|
||||
// The total number of channels we reserved:
|
||||
const int channelCount;
|
||||
QTimer delayedConnectionTimer;
|
||||
QHttpNetworkConnectionChannel *channels; // parallel connections to the server
|
||||
bool shouldEmitChannelError(QAbstractSocket *socket);
|
||||
|
||||
qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const;
|
||||
qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const;
|
||||
|
||||
|
||||
void emitReplyError(QAbstractSocket *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode);
|
||||
bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend);
|
||||
struct ParseRedirectResult {
|
||||
QUrl redirectUrl;
|
||||
QNetworkReply::NetworkError errorCode;
|
||||
};
|
||||
ParseRedirectResult parseRedirectResponse(QHttpNetworkReply *reply);
|
||||
// Used by the HTTP1 code-path
|
||||
QUrl parseRedirectResponse(QAbstractSocket *socket, QHttpNetworkReply *reply);
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
QNetworkProxy networkProxy;
|
||||
void emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth);
|
||||
#endif
|
||||
|
||||
//The request queues
|
||||
QList<HttpMessagePair> highPriorityQueue;
|
||||
QList<HttpMessagePair> lowPriorityQueue;
|
||||
|
||||
int preConnectRequests;
|
||||
|
||||
QHttpNetworkConnection::ConnectionType connectionType;
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
std::shared_ptr<QSslContext> sslContext;
|
||||
#endif
|
||||
|
||||
QHttp2Configuration http2Parameters;
|
||||
|
||||
QString peerVerifyName;
|
||||
// If network status monitoring is enabled, we activate connectionMonitor
|
||||
// as soons as one of channels managed to connect to host (and we
|
||||
// have a pair of addresses (us,peer).
|
||||
// NETMONTODO: consider activating a monitor on a change from
|
||||
// HostLookUp state to ConnectingState (means we have both
|
||||
// local/remote addresses known and can start monitoring this
|
||||
// early).
|
||||
QNetworkConnectionMonitor connectionMonitor;
|
||||
|
||||
friend class QHttpNetworkConnectionChannel;
|
||||
};
|
||||
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,178 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTPNETWORKCONNECTIONCHANNEL_H
|
||||
#define QHTTPNETWORKCONNECTIONCHANNEL_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/qnetworkrequest.h>
|
||||
#include <QtNetwork/qnetworkreply.h>
|
||||
#include <QtNetwork/qabstractsocket.h>
|
||||
|
||||
#include <private/qobject_p.h>
|
||||
#include <qauthenticator.h>
|
||||
#include <qnetworkproxy.h>
|
||||
#include <qbuffer.h>
|
||||
|
||||
#include <private/qhttpnetworkheader_p.h>
|
||||
#include <private/qhttpnetworkrequest_p.h>
|
||||
#include <private/qhttpnetworkreply_p.h>
|
||||
|
||||
#include <private/qhttpnetworkconnection_p.h>
|
||||
#include <private/qabstractprotocolhandler_p.h>
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
# include <QtNetwork/qsslsocket.h>
|
||||
# include <QtNetwork/qsslerror.h>
|
||||
# include <QtNetwork/qsslconfiguration.h>
|
||||
#else
|
||||
# include <QtNetwork/qtcpsocket.h>
|
||||
#endif
|
||||
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpNetworkRequest;
|
||||
class QHttpNetworkReply;
|
||||
class QByteArray;
|
||||
|
||||
#ifndef HttpMessagePair
|
||||
typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair;
|
||||
#endif
|
||||
|
||||
class QHttpNetworkConnectionChannel : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
// TODO: Refactor this to add an EncryptingState (and remove pendingEncrypt).
|
||||
// Also add an Unconnected state so IdleState does not have double meaning.
|
||||
enum ChannelState {
|
||||
IdleState = 0, // ready to send request
|
||||
ConnectingState = 1, // connecting to host
|
||||
WritingState = 2, // writing the data
|
||||
WaitingState = 4, // waiting for reply
|
||||
ReadingState = 8, // reading the reply
|
||||
ClosingState = 16,
|
||||
BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|ClosingState)
|
||||
};
|
||||
QAbstractSocket *socket;
|
||||
bool ssl;
|
||||
bool isInitialized;
|
||||
ChannelState state;
|
||||
QHttpNetworkRequest request; // current request, only used for HTTP
|
||||
QHttpNetworkReply *reply; // current reply for this request, only used for HTTP
|
||||
qint64 written;
|
||||
qint64 bytesTotal;
|
||||
bool resendCurrent;
|
||||
int lastStatus; // last status received on this channel
|
||||
bool pendingEncrypt; // for https (send after encrypted)
|
||||
int reconnectAttempts; // maximum 2 reconnection attempts
|
||||
QAuthenticator authenticator;
|
||||
QAuthenticator proxyAuthenticator;
|
||||
bool authenticationCredentialsSent;
|
||||
bool proxyCredentialsSent;
|
||||
std::unique_ptr<QAbstractProtocolHandler> protocolHandler;
|
||||
QMultiMap<int, HttpMessagePair> h2RequestsToSend;
|
||||
bool switchedToHttp2 = false;
|
||||
#ifndef QT_NO_SSL
|
||||
bool ignoreAllSslErrors;
|
||||
QList<QSslError> ignoreSslErrorsList;
|
||||
QScopedPointer<QSslConfiguration> sslConfiguration;
|
||||
void ignoreSslErrors();
|
||||
void ignoreSslErrors(const QList<QSslError> &errors);
|
||||
void setSslConfiguration(const QSslConfiguration &config);
|
||||
void requeueHttp2Requests(); // when we wanted HTTP/2 but got HTTP/1.1
|
||||
#endif
|
||||
// to emit the signal for all in-flight replies:
|
||||
void emitFinishedWithError(QNetworkReply::NetworkError error, const char *message);
|
||||
|
||||
// HTTP pipelining -> http://en.wikipedia.org/wiki/Http_pipelining
|
||||
enum PipeliningSupport {
|
||||
PipeliningSupportUnknown, // default for a new connection
|
||||
PipeliningProbablySupported, // after having received a server response that indicates support
|
||||
PipeliningNotSupported // currently not used
|
||||
};
|
||||
PipeliningSupport pipeliningSupported;
|
||||
QList<HttpMessagePair> alreadyPipelinedRequests;
|
||||
QByteArray pipeline; // temporary buffer that gets sent to socket in pipelineFlush
|
||||
void pipelineInto(HttpMessagePair &pair);
|
||||
void pipelineFlush();
|
||||
void requeueCurrentlyPipelinedRequests();
|
||||
void detectPipeliningSupport();
|
||||
|
||||
QHttpNetworkConnectionChannel();
|
||||
|
||||
QAbstractSocket::NetworkLayerProtocol networkLayerPreference;
|
||||
|
||||
void setConnection(QHttpNetworkConnection *c);
|
||||
QPointer<QHttpNetworkConnection> connection;
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
QNetworkProxy proxy;
|
||||
void setProxy(const QNetworkProxy &networkProxy);
|
||||
#endif
|
||||
|
||||
void init();
|
||||
void close();
|
||||
void abort();
|
||||
|
||||
bool sendRequest();
|
||||
void sendRequestDelayed();
|
||||
|
||||
bool ensureConnection();
|
||||
|
||||
void allDone(); // reply header + body have been read
|
||||
void handleStatus(); // called from allDone()
|
||||
|
||||
bool resetUploadData(); // return true if resetting worked or there is no upload data
|
||||
|
||||
void handleUnexpectedEOF();
|
||||
void closeAndResendCurrentRequest();
|
||||
void resendCurrentRequest();
|
||||
|
||||
bool isSocketBusy() const;
|
||||
bool isSocketWriting() const;
|
||||
bool isSocketWaiting() const;
|
||||
bool isSocketReading() const;
|
||||
|
||||
protected slots:
|
||||
void _q_receiveReply();
|
||||
void _q_bytesWritten(qint64 bytes); // proceed sending
|
||||
void _q_readyRead(); // pending data to read
|
||||
void _q_disconnected(); // disconnected from host
|
||||
void _q_connected(); // start sending request
|
||||
void _q_error(QAbstractSocket::SocketError); // error from socket
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy
|
||||
#endif
|
||||
|
||||
void _q_uploadDataReadyRead();
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
void _q_encrypted(); // start sending request (https)
|
||||
void _q_sslErrors(const QList<QSslError> &errors); // ssl errors from the socket
|
||||
void _q_preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*); // tls-psk auth necessary
|
||||
void _q_encryptedBytesWritten(qint64 bytes); // proceed sending
|
||||
#endif
|
||||
|
||||
friend class QHttpProtocolHandler;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTPNETWORKHEADER_H
|
||||
#define QHTTPNETWORKHEADER_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qhttpheaderparser_p.h>
|
||||
|
||||
#include <qshareddata.h>
|
||||
#include <qurl.h>
|
||||
|
||||
#ifndef Q_OS_WASM
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_AUTOTEST_EXPORT QHttpNetworkHeader
|
||||
{
|
||||
public:
|
||||
virtual ~QHttpNetworkHeader() {}
|
||||
virtual QUrl url() const = 0;
|
||||
virtual void setUrl(const QUrl &url) = 0;
|
||||
|
||||
virtual int majorVersion() const = 0;
|
||||
virtual int minorVersion() const = 0;
|
||||
|
||||
virtual qint64 contentLength() const = 0;
|
||||
virtual void setContentLength(qint64 length) = 0;
|
||||
|
||||
virtual QList<QPair<QByteArray, QByteArray> > header() const = 0;
|
||||
virtual QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const = 0;
|
||||
virtual void setHeaderField(const QByteArray &name, const QByteArray &data) = 0;
|
||||
};
|
||||
|
||||
class Q_AUTOTEST_EXPORT QHttpNetworkHeaderPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
QUrl url;
|
||||
QHttpHeaderParser parser;
|
||||
|
||||
QHttpNetworkHeaderPrivate(const QUrl &newUrl = QUrl());
|
||||
QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other) = default;
|
||||
qint64 contentLength() const;
|
||||
void setContentLength(qint64 length);
|
||||
|
||||
QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const;
|
||||
QList<QByteArray> headerFieldValues(const QByteArray &name) const;
|
||||
void setHeaderField(const QByteArray &name, const QByteArray &data);
|
||||
void prependHeaderField(const QByteArray &name, const QByteArray &data);
|
||||
void clearHeaders();
|
||||
QList<QPair<QByteArray, QByteArray> > headers() const;
|
||||
bool operator==(const QHttpNetworkHeaderPrivate &other) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPNETWORKHEADER_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTPNETWORKREPLY_H
|
||||
#define QHTTPNETWORKREPLY_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <qplatformdefs.h>
|
||||
|
||||
#include <QtNetwork/qtcpsocket.h>
|
||||
// it's safe to include these even if SSL support is not enabled
|
||||
#include <QtNetwork/qsslsocket.h>
|
||||
#include <QtNetwork/qsslerror.h>
|
||||
|
||||
#include <QtNetwork/qnetworkrequest.h>
|
||||
#include <QtNetwork/qnetworkreply.h>
|
||||
#include <qbuffer.h>
|
||||
|
||||
#include <private/qobject_p.h>
|
||||
#include <private/qhttpnetworkheader_p.h>
|
||||
#include <private/qhttpnetworkrequest_p.h>
|
||||
#include <private/qauthenticator_p.h>
|
||||
#include <private/qringbuffer_p.h>
|
||||
#include <private/qbytedata_p.h>
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
Q_MOC_INCLUDE(<QtNetwork/QNetworkProxy>)
|
||||
#endif
|
||||
Q_MOC_INCLUDE(<QtNetwork/QAuthenticator>)
|
||||
|
||||
#include <private/qdecompresshelper_p.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpNetworkConnection;
|
||||
class QHttpNetworkConnectionChannel;
|
||||
class QHttpNetworkRequest;
|
||||
class QHttpNetworkConnectionPrivate;
|
||||
class QHttpNetworkReplyPrivate;
|
||||
class Q_AUTOTEST_EXPORT QHttpNetworkReply : public QObject, public QHttpNetworkHeader
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit QHttpNetworkReply(const QUrl &url = QUrl(), QObject *parent = nullptr);
|
||||
virtual ~QHttpNetworkReply();
|
||||
|
||||
QUrl url() const override;
|
||||
void setUrl(const QUrl &url) override;
|
||||
|
||||
int majorVersion() const override;
|
||||
int minorVersion() const override;
|
||||
void setMajorVersion(int version);
|
||||
void setMinorVersion(int version);
|
||||
|
||||
qint64 contentLength() const override;
|
||||
void setContentLength(qint64 length) override;
|
||||
|
||||
QList<QPair<QByteArray, QByteArray> > header() const override;
|
||||
QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const override;
|
||||
void setHeaderField(const QByteArray &name, const QByteArray &data) override;
|
||||
void appendHeaderField(const QByteArray &name, const QByteArray &data);
|
||||
void parseHeader(const QByteArray &header); // used for testing
|
||||
|
||||
QHttpNetworkRequest request() const;
|
||||
void setRequest(const QHttpNetworkRequest &request);
|
||||
|
||||
int statusCode() const;
|
||||
void setStatusCode(int code);
|
||||
|
||||
QString errorString() const;
|
||||
void setErrorString(const QString &error);
|
||||
|
||||
QNetworkReply::NetworkError errorCode() const;
|
||||
|
||||
QString reasonPhrase() const;
|
||||
void setReasonPhrase(const QString &reason);
|
||||
|
||||
qint64 bytesAvailable() const;
|
||||
qint64 bytesAvailableNextBlock() const;
|
||||
bool readAnyAvailable() const;
|
||||
QByteArray readAny();
|
||||
QByteArray readAll();
|
||||
QByteArray read(qint64 amount);
|
||||
qint64 sizeNextBlock();
|
||||
void setDownstreamLimited(bool t);
|
||||
void setReadBufferSize(qint64 size);
|
||||
|
||||
bool supportsUserProvidedDownloadBuffer();
|
||||
void setUserProvidedDownloadBuffer(char*);
|
||||
char* userProvidedDownloadBuffer();
|
||||
|
||||
void abort();
|
||||
|
||||
bool isAborted() const;
|
||||
bool isFinished() const;
|
||||
|
||||
bool isPipeliningUsed() const;
|
||||
bool isHttp2Used() const;
|
||||
void setHttp2WasUsed(bool h2Used);
|
||||
qint64 removedContentLength() const;
|
||||
|
||||
bool isRedirecting() const;
|
||||
|
||||
QHttpNetworkConnection* connection();
|
||||
|
||||
QUrl redirectUrl() const;
|
||||
void setRedirectUrl(const QUrl &url);
|
||||
|
||||
static bool isHttpRedirect(int statusCode);
|
||||
|
||||
bool isCompressed() const;
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
QSslConfiguration sslConfiguration() const;
|
||||
void setSslConfiguration(const QSslConfiguration &config);
|
||||
void ignoreSslErrors();
|
||||
void ignoreSslErrors(const QList<QSslError> &errors);
|
||||
|
||||
Q_SIGNALS:
|
||||
void encrypted();
|
||||
void sslErrors(const QList<QSslError> &errors);
|
||||
void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator);
|
||||
#endif
|
||||
|
||||
Q_SIGNALS:
|
||||
void socketStartedConnecting();
|
||||
void requestSent();
|
||||
void readyRead();
|
||||
void finished();
|
||||
void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
|
||||
void headerChanged();
|
||||
void dataReadProgress(qint64 done, qint64 total);
|
||||
void dataSendProgress(qint64 done, qint64 total);
|
||||
void cacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
|
||||
#endif
|
||||
void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
|
||||
void redirected(const QUrl &url, int httpStatus, int maxRedirectsRemaining);
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QHttpNetworkReply)
|
||||
friend class QHttpSocketEngine;
|
||||
friend class QHttpNetworkConnection;
|
||||
friend class QHttpNetworkConnectionPrivate;
|
||||
friend class QHttpNetworkConnectionChannel;
|
||||
friend class QHttp2ProtocolHandler;
|
||||
friend class QHttpProtocolHandler;
|
||||
friend class QSpdyProtocolHandler;
|
||||
};
|
||||
|
||||
|
||||
class Q_AUTOTEST_EXPORT QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate
|
||||
{
|
||||
public:
|
||||
QHttpNetworkReplyPrivate(const QUrl &newUrl = QUrl());
|
||||
~QHttpNetworkReplyPrivate();
|
||||
qint64 readStatus(QAbstractSocket *socket);
|
||||
bool parseStatus(const QByteArray &status);
|
||||
qint64 readHeader(QAbstractSocket *socket);
|
||||
void parseHeader(const QByteArray &header);
|
||||
void appendHeaderField(const QByteArray &name, const QByteArray &data);
|
||||
qint64 readBody(QAbstractSocket *socket, QByteDataBuffer *out);
|
||||
qint64 readBodyVeryFast(QAbstractSocket *socket, char *b);
|
||||
qint64 readBodyFast(QAbstractSocket *socket, QByteDataBuffer *rb);
|
||||
bool findChallenge(bool forProxy, QByteArray &challenge) const;
|
||||
void clear();
|
||||
void clearHttpLayerInformation();
|
||||
|
||||
qint64 readReplyBodyRaw(QAbstractSocket *in, QByteDataBuffer *out, qint64 size);
|
||||
qint64 readReplyBodyChunked(QAbstractSocket *in, QByteDataBuffer *out);
|
||||
qint64 getChunkSize(QAbstractSocket *in, qint64 *chunkSize);
|
||||
|
||||
bool isRedirecting() const;
|
||||
bool shouldEmitSignals();
|
||||
bool expectContent();
|
||||
void eraseData();
|
||||
|
||||
qint64 bytesAvailable() const;
|
||||
bool isChunked();
|
||||
bool isConnectionCloseEnabled();
|
||||
|
||||
bool isCompressed() const;
|
||||
void removeAutoDecompressHeader();
|
||||
|
||||
enum ReplyState {
|
||||
NothingDoneState,
|
||||
ReadingStatusState,
|
||||
ReadingHeaderState,
|
||||
ReadingDataState,
|
||||
AllDoneState,
|
||||
SPDYSYNSent,
|
||||
SPDYUploading,
|
||||
SPDYHalfClosed,
|
||||
SPDYClosed,
|
||||
Aborted
|
||||
} state;
|
||||
|
||||
QHttpNetworkRequest request;
|
||||
bool ssl;
|
||||
QString errorString;
|
||||
qint64 bodyLength;
|
||||
qint64 contentRead;
|
||||
qint64 totalProgress;
|
||||
QByteArray fragment; // used for header, status, chunk header etc, not for reply data
|
||||
bool chunkedTransferEncoding;
|
||||
bool connectionCloseEnabled;
|
||||
bool forceConnectionCloseEnabled;
|
||||
bool lastChunkRead;
|
||||
qint64 currentChunkSize;
|
||||
qint64 currentChunkRead;
|
||||
qint64 readBufferMaxSize;
|
||||
qint64 totallyUploadedData; // HTTP/2
|
||||
qint64 removedContentLength;
|
||||
QPointer<QHttpNetworkConnection> connection;
|
||||
QPointer<QHttpNetworkConnectionChannel> connectionChannel;
|
||||
QNetworkReply::NetworkError httpErrorCode = QNetworkReply::NoError;
|
||||
|
||||
bool autoDecompress;
|
||||
|
||||
QByteDataBuffer responseData; // uncompressed body
|
||||
bool requestIsPrepared;
|
||||
|
||||
bool pipeliningUsed;
|
||||
bool h2Used;
|
||||
bool downstreamLimited;
|
||||
|
||||
char* userProvidedDownloadBuffer;
|
||||
QUrl redirectUrl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPNETWORKREPLY_H
|
||||
@@ -0,0 +1,164 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTPNETWORKREQUEST_H
|
||||
#define QHTTPNETWORKREQUEST_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <private/qhttpnetworkheader_p.h>
|
||||
#include <QtNetwork/qnetworkrequest.h>
|
||||
#include <qmetatype.h>
|
||||
|
||||
#ifndef Q_OS_WASM
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNonContiguousByteDevice;
|
||||
|
||||
class QHttpNetworkRequestPrivate;
|
||||
class Q_AUTOTEST_EXPORT QHttpNetworkRequest: public QHttpNetworkHeader
|
||||
{
|
||||
public:
|
||||
enum Operation {
|
||||
Options,
|
||||
Get,
|
||||
Head,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Trace,
|
||||
Connect,
|
||||
Custom
|
||||
};
|
||||
|
||||
enum Priority {
|
||||
HighPriority,
|
||||
NormalPriority,
|
||||
LowPriority
|
||||
};
|
||||
|
||||
explicit QHttpNetworkRequest(const QUrl &url = QUrl(), Operation operation = Get, Priority priority = NormalPriority);
|
||||
QHttpNetworkRequest(const QHttpNetworkRequest &other);
|
||||
virtual ~QHttpNetworkRequest();
|
||||
QHttpNetworkRequest &operator=(const QHttpNetworkRequest &other);
|
||||
bool operator==(const QHttpNetworkRequest &other) const;
|
||||
|
||||
QUrl url() const override;
|
||||
void setUrl(const QUrl &url) override;
|
||||
|
||||
int majorVersion() const override;
|
||||
int minorVersion() const override;
|
||||
|
||||
qint64 contentLength() const override;
|
||||
void setContentLength(qint64 length) override;
|
||||
|
||||
QList<QPair<QByteArray, QByteArray> > header() const override;
|
||||
QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const override;
|
||||
void setHeaderField(const QByteArray &name, const QByteArray &data) override;
|
||||
void prependHeaderField(const QByteArray &name, const QByteArray &data);
|
||||
void clearHeaders();
|
||||
|
||||
Operation operation() const;
|
||||
void setOperation(Operation operation);
|
||||
|
||||
QByteArray customVerb() const;
|
||||
void setCustomVerb(const QByteArray &customOperation);
|
||||
|
||||
Priority priority() const;
|
||||
void setPriority(Priority priority);
|
||||
|
||||
bool isPipeliningAllowed() const;
|
||||
void setPipeliningAllowed(bool b);
|
||||
|
||||
bool isHTTP2Allowed() const;
|
||||
void setHTTP2Allowed(bool b);
|
||||
|
||||
bool isHTTP2Direct() const;
|
||||
void setHTTP2Direct(bool b);
|
||||
|
||||
bool isH2cAllowed() const;
|
||||
void setH2cAllowed(bool b);
|
||||
|
||||
bool withCredentials() const;
|
||||
void setWithCredentials(bool b);
|
||||
|
||||
bool isSsl() const;
|
||||
void setSsl(bool);
|
||||
|
||||
bool isPreConnect() const;
|
||||
void setPreConnect(bool preConnect);
|
||||
|
||||
bool isFollowRedirects() const;
|
||||
void setRedirectPolicy(QNetworkRequest::RedirectPolicy policy);
|
||||
QNetworkRequest::RedirectPolicy redirectPolicy() const;
|
||||
|
||||
int redirectCount() const;
|
||||
void setRedirectCount(int count);
|
||||
|
||||
void setUploadByteDevice(QNonContiguousByteDevice *bd);
|
||||
QNonContiguousByteDevice* uploadByteDevice() const;
|
||||
|
||||
QByteArray methodName() const;
|
||||
QByteArray uri(bool throughProxy) const;
|
||||
|
||||
QString peerVerifyName() const;
|
||||
void setPeerVerifyName(const QString &peerName);
|
||||
|
||||
private:
|
||||
QSharedDataPointer<QHttpNetworkRequestPrivate> d;
|
||||
friend class QHttpNetworkRequestPrivate;
|
||||
friend class QHttpNetworkConnectionPrivate;
|
||||
friend class QHttpNetworkConnectionChannel;
|
||||
friend class QHttpProtocolHandler;
|
||||
friend class QHttp2ProtocolHandler;
|
||||
friend class QSpdyProtocolHandler;
|
||||
};
|
||||
|
||||
class QHttpNetworkRequestPrivate : public QHttpNetworkHeaderPrivate
|
||||
{
|
||||
public:
|
||||
QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op,
|
||||
QHttpNetworkRequest::Priority pri, const QUrl &newUrl = QUrl());
|
||||
QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other);
|
||||
~QHttpNetworkRequestPrivate();
|
||||
bool operator==(const QHttpNetworkRequestPrivate &other) const;
|
||||
|
||||
static QByteArray header(const QHttpNetworkRequest &request, bool throughProxy);
|
||||
|
||||
QHttpNetworkRequest::Operation operation;
|
||||
QByteArray customVerb;
|
||||
QHttpNetworkRequest::Priority priority;
|
||||
mutable QNonContiguousByteDevice* uploadByteDevice;
|
||||
bool autoDecompress;
|
||||
bool pipeliningAllowed;
|
||||
bool http2Allowed;
|
||||
bool http2Direct;
|
||||
bool h2cAllowed = false;
|
||||
bool withCredentials;
|
||||
bool ssl;
|
||||
bool preConnect;
|
||||
bool needResendWithCredentials = false;
|
||||
int redirectCount;
|
||||
QNetworkRequest::RedirectPolicy redirectPolicy;
|
||||
QString peerVerifyName;
|
||||
};
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_DECL_METATYPE_EXTERN(QHttpNetworkRequest, Q_AUTOTEST_EXPORT)
|
||||
|
||||
#endif // QHTTPNETWORKREQUEST_H
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// Copyright (C) 2014 BlackBerry Limited. All rights reserved.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTPPROTOCOLHANDLER_H
|
||||
#define QHTTPPROTOCOLHANDLER_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <private/qabstractprotocolhandler_p.h>
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpProtocolHandler : public QAbstractProtocolHandler {
|
||||
public:
|
||||
QHttpProtocolHandler(QHttpNetworkConnectionChannel *channel);
|
||||
|
||||
private:
|
||||
virtual void _q_receiveReply() override;
|
||||
virtual void _q_readyRead() override;
|
||||
virtual bool sendRequest() override;
|
||||
|
||||
QByteArray m_header;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,166 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTPSOCKETENGINE_P_H
|
||||
#define QHTTPSOCKETENGINE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "private/qabstractsocketengine_p.h"
|
||||
#include "qabstractsocket.h"
|
||||
#include "qnetworkproxy.h"
|
||||
#include "private/qauthenticator_p.h"
|
||||
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if !defined(QT_NO_NETWORKPROXY)
|
||||
|
||||
class QTcpSocket;
|
||||
class QHttpNetworkReply;
|
||||
class QHttpSocketEnginePrivate;
|
||||
|
||||
class Q_AUTOTEST_EXPORT QHttpSocketEngine : public QAbstractSocketEngine
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum HttpState {
|
||||
None,
|
||||
ConnectSent,
|
||||
Connected,
|
||||
SendAuthentication,
|
||||
ReadResponseContent,
|
||||
ReadResponseHeader
|
||||
};
|
||||
QHttpSocketEngine(QObject *parent = nullptr);
|
||||
~QHttpSocketEngine();
|
||||
|
||||
bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) override;
|
||||
bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) override;
|
||||
|
||||
void setProxy(const QNetworkProxy &networkProxy);
|
||||
|
||||
qintptr socketDescriptor() const override;
|
||||
|
||||
bool isValid() const override;
|
||||
|
||||
bool connectInternal();
|
||||
bool connectToHost(const QHostAddress &address, quint16 port) override;
|
||||
bool connectToHostByName(const QString &name, quint16 port) override;
|
||||
bool bind(const QHostAddress &address, quint16 port) override;
|
||||
bool listen(int backlog) override;
|
||||
qintptr accept() override;
|
||||
void close() override;
|
||||
|
||||
qint64 bytesAvailable() const override;
|
||||
|
||||
qint64 read(char *data, qint64 maxlen) override;
|
||||
qint64 write(const char *data, qint64 len) override;
|
||||
|
||||
#ifndef QT_NO_UDPSOCKET
|
||||
#ifndef QT_NO_NETWORKINTERFACE
|
||||
bool joinMulticastGroup(const QHostAddress &groupAddress,
|
||||
const QNetworkInterface &interface) override;
|
||||
bool leaveMulticastGroup(const QHostAddress &groupAddress,
|
||||
const QNetworkInterface &interface) override;
|
||||
QNetworkInterface multicastInterface() const override;
|
||||
bool setMulticastInterface(const QNetworkInterface &iface) override;
|
||||
#endif // QT_NO_NETWORKINTERFACE
|
||||
|
||||
bool hasPendingDatagrams() const override;
|
||||
qint64 pendingDatagramSize() const override;
|
||||
#endif // QT_NO_UDPSOCKET
|
||||
|
||||
qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader *,
|
||||
PacketHeaderOptions) override;
|
||||
qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) override;
|
||||
qint64 bytesToWrite() const override;
|
||||
|
||||
int option(SocketOption option) const override;
|
||||
bool setOption(SocketOption option, int value) override;
|
||||
|
||||
bool waitForRead(int msecs = 30000, bool *timedOut = nullptr) override;
|
||||
bool waitForWrite(int msecs = 30000, bool *timedOut = nullptr) override;
|
||||
bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
|
||||
bool checkRead, bool checkWrite,
|
||||
int msecs = 30000, bool *timedOut = nullptr) override;
|
||||
|
||||
bool isReadNotificationEnabled() const override;
|
||||
void setReadNotificationEnabled(bool enable) override;
|
||||
bool isWriteNotificationEnabled() const override;
|
||||
void setWriteNotificationEnabled(bool enable) override;
|
||||
bool isExceptionNotificationEnabled() const override;
|
||||
void setExceptionNotificationEnabled(bool enable) override;
|
||||
|
||||
public slots:
|
||||
void slotSocketConnected();
|
||||
void slotSocketDisconnected();
|
||||
void slotSocketReadNotification();
|
||||
void slotSocketBytesWritten();
|
||||
void slotSocketError(QAbstractSocket::SocketError error);
|
||||
void slotSocketStateChanged(QAbstractSocket::SocketState state);
|
||||
|
||||
private slots:
|
||||
void emitPendingReadNotification();
|
||||
void emitPendingWriteNotification();
|
||||
void emitPendingConnectionNotification();
|
||||
|
||||
private:
|
||||
void emitReadNotification();
|
||||
void emitWriteNotification();
|
||||
void emitConnectionNotification();
|
||||
|
||||
bool readHttpHeader();
|
||||
|
||||
Q_DECLARE_PRIVATE(QHttpSocketEngine)
|
||||
Q_DISABLE_COPY_MOVE(QHttpSocketEngine)
|
||||
|
||||
};
|
||||
|
||||
|
||||
class QHttpSocketEnginePrivate : public QAbstractSocketEnginePrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QHttpSocketEngine)
|
||||
public:
|
||||
QHttpSocketEnginePrivate();
|
||||
~QHttpSocketEnginePrivate();
|
||||
|
||||
QNetworkProxy proxy;
|
||||
QString peerName;
|
||||
QTcpSocket *socket;
|
||||
QHttpNetworkReply *reply; // only used for parsing the proxy response
|
||||
QHttpSocketEngine::HttpState state;
|
||||
QAuthenticator authenticator;
|
||||
bool readNotificationEnabled;
|
||||
bool writeNotificationEnabled;
|
||||
bool exceptNotificationEnabled;
|
||||
bool readNotificationPending;
|
||||
bool writeNotificationPending;
|
||||
bool connectionNotificationPending;
|
||||
bool credentialsSent;
|
||||
uint pendingResponseData;
|
||||
};
|
||||
|
||||
class Q_AUTOTEST_EXPORT QHttpSocketEngineHandler : public QSocketEngineHandler
|
||||
{
|
||||
public:
|
||||
virtual QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType,
|
||||
const QNetworkProxy &, QObject *parent) override;
|
||||
virtual QAbstractSocketEngine *createSocketEngine(qintptr socketDescripter, QObject *parent) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSOCKETENGINE_H
|
||||
@@ -0,0 +1,299 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTPTHREADDELEGATE_H
|
||||
#define QHTTPTHREADDELEGATE_H
|
||||
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QObject>
|
||||
#include <QThreadStorage>
|
||||
#include <QNetworkProxy>
|
||||
#include <QSslConfiguration>
|
||||
#include <QSslError>
|
||||
#include <QList>
|
||||
#include <QNetworkReply>
|
||||
#include "qhttpnetworkrequest_p.h"
|
||||
#include "qhttpnetworkconnection_p.h"
|
||||
#include "qhttp1configuration.h"
|
||||
#include "qhttp2configuration.h"
|
||||
#include <QSharedPointer>
|
||||
#include <QScopedPointer>
|
||||
#include "private/qnoncontiguousbytedevice_p.h"
|
||||
#include "qnetworkaccessauthenticationmanager_p.h"
|
||||
#include <QtNetwork/private/http2protocol_p.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAuthenticator;
|
||||
class QHttpNetworkReply;
|
||||
class QEventLoop;
|
||||
class QNetworkAccessCache;
|
||||
class QNetworkAccessCachedHttpConnection;
|
||||
|
||||
class QHttpThreadDelegate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QHttpThreadDelegate(QObject *parent = nullptr);
|
||||
|
||||
~QHttpThreadDelegate();
|
||||
|
||||
// incoming
|
||||
bool ssl;
|
||||
#ifndef QT_NO_SSL
|
||||
QScopedPointer<QSslConfiguration> incomingSslConfiguration;
|
||||
#endif
|
||||
QHttpNetworkRequest httpRequest;
|
||||
qint64 downloadBufferMaximumSize;
|
||||
qint64 readBufferMaxSize;
|
||||
qint64 bytesEmitted;
|
||||
// From backend, modified by us for signal compression
|
||||
std::shared_ptr<QAtomicInt> pendingDownloadData;
|
||||
std::shared_ptr<QAtomicInt> pendingDownloadProgress;
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
QNetworkProxy cacheProxy;
|
||||
QNetworkProxy transparentProxy;
|
||||
#endif
|
||||
std::shared_ptr<QNetworkAccessAuthenticationManager> authenticationManager;
|
||||
bool synchronous;
|
||||
qint64 connectionCacheExpiryTimeoutSeconds;
|
||||
|
||||
// outgoing, Retrieved in the synchronous HTTP case
|
||||
QByteArray synchronousDownloadData;
|
||||
QList<QPair<QByteArray,QByteArray> > incomingHeaders;
|
||||
int incomingStatusCode;
|
||||
QString incomingReasonPhrase;
|
||||
bool isPipeliningUsed;
|
||||
bool isHttp2Used;
|
||||
qint64 incomingContentLength;
|
||||
qint64 removedContentLength;
|
||||
QNetworkReply::NetworkError incomingErrorCode;
|
||||
QString incomingErrorDetail;
|
||||
QHttp1Configuration http1Parameters;
|
||||
QHttp2Configuration http2Parameters;
|
||||
|
||||
bool isCompressed;
|
||||
|
||||
protected:
|
||||
// The zerocopy download buffer, if used:
|
||||
QSharedPointer<char> downloadBuffer;
|
||||
// The QHttpNetworkConnection that is used
|
||||
QNetworkAccessCachedHttpConnection *httpConnection;
|
||||
QByteArray cacheKey;
|
||||
QHttpNetworkReply *httpReply;
|
||||
|
||||
// Used for implementing the synchronous HTTP, see startRequestSynchronously()
|
||||
QEventLoop *synchronousRequestLoop;
|
||||
|
||||
signals:
|
||||
void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *);
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
|
||||
#endif
|
||||
#ifndef QT_NO_SSL
|
||||
void encrypted();
|
||||
void sslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
|
||||
void sslConfigurationChanged(const QSslConfiguration &);
|
||||
void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *);
|
||||
#endif
|
||||
void socketStartedConnecting();
|
||||
void requestSent();
|
||||
void downloadMetaData(const QList<QPair<QByteArray,QByteArray> > &, int, const QString &, bool,
|
||||
QSharedPointer<char>, qint64, qint64, bool, bool);
|
||||
void downloadProgress(qint64, qint64);
|
||||
void downloadData(const QByteArray &);
|
||||
void error(QNetworkReply::NetworkError, const QString &);
|
||||
void downloadFinished();
|
||||
void redirected(const QUrl &url, int httpStatus, int maxRedirectsRemainig);
|
||||
|
||||
public slots:
|
||||
// This are called via QueuedConnection from user thread
|
||||
void startRequest();
|
||||
void abortRequest();
|
||||
void readBufferSizeChanged(qint64 size);
|
||||
void readBufferFreed(qint64 size);
|
||||
|
||||
// This is called with a BlockingQueuedConnection from user thread
|
||||
void startRequestSynchronously();
|
||||
protected slots:
|
||||
// From QHttp*
|
||||
void readyReadSlot();
|
||||
void finishedSlot();
|
||||
void finishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
|
||||
void synchronousFinishedSlot();
|
||||
void synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
|
||||
void headerChangedSlot();
|
||||
void synchronousHeaderChangedSlot();
|
||||
void dataReadProgressSlot(qint64 done, qint64 total);
|
||||
void cacheCredentialsSlot(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
|
||||
#ifndef QT_NO_SSL
|
||||
void encryptedSlot();
|
||||
void sslErrorsSlot(const QList<QSslError> &errors);
|
||||
void preSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator *authenticator);
|
||||
#endif
|
||||
|
||||
void synchronousAuthenticationRequiredSlot(const QHttpNetworkRequest &request, QAuthenticator *);
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void synchronousProxyAuthenticationRequiredSlot(const QNetworkProxy &, QAuthenticator *);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// Cache for all the QHttpNetworkConnection objects.
|
||||
// This is per thread.
|
||||
static QThreadStorage<QNetworkAccessCache *> connections;
|
||||
|
||||
};
|
||||
|
||||
// This QNonContiguousByteDevice is connected to the QNetworkAccessHttpBackend
|
||||
// and represents the PUT/POST data.
|
||||
class QNonContiguousByteDeviceThreadForwardImpl : public QNonContiguousByteDevice
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
bool wantDataPending;
|
||||
qint64 m_amount;
|
||||
char *m_data;
|
||||
QByteArray m_dataArray;
|
||||
bool m_atEnd;
|
||||
qint64 m_size;
|
||||
qint64 m_pos; // to match calls of haveDataSlot with the expected position
|
||||
public:
|
||||
QNonContiguousByteDeviceThreadForwardImpl(bool aE, qint64 s)
|
||||
: QNonContiguousByteDevice(),
|
||||
wantDataPending(false),
|
||||
m_amount(0),
|
||||
m_data(nullptr),
|
||||
m_atEnd(aE),
|
||||
m_size(s),
|
||||
m_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
~QNonContiguousByteDeviceThreadForwardImpl()
|
||||
{
|
||||
}
|
||||
|
||||
qint64 pos() const override
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
const char* readPointer(qint64 maximumLength, qint64 &len) override
|
||||
{
|
||||
if (m_amount > 0) {
|
||||
len = m_amount;
|
||||
return m_data;
|
||||
}
|
||||
|
||||
if (m_atEnd) {
|
||||
len = -1;
|
||||
} else if (!wantDataPending) {
|
||||
len = 0;
|
||||
wantDataPending = true;
|
||||
emit wantData(maximumLength);
|
||||
} else {
|
||||
// Do nothing, we already sent a wantData signal and wait for results
|
||||
len = 0;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool advanceReadPointer(qint64 a) override
|
||||
{
|
||||
if (m_data == nullptr)
|
||||
return false;
|
||||
|
||||
m_amount -= a;
|
||||
m_data += a;
|
||||
m_pos += a;
|
||||
|
||||
// To main thread to inform about our state. The m_pos will be sent as a sanity check.
|
||||
emit processedData(m_pos, a);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool atEnd() const override
|
||||
{
|
||||
if (m_amount > 0)
|
||||
return false;
|
||||
else
|
||||
return m_atEnd;
|
||||
}
|
||||
|
||||
bool reset() override
|
||||
{
|
||||
m_amount = 0;
|
||||
m_data = nullptr;
|
||||
m_dataArray.clear();
|
||||
|
||||
if (wantDataPending) {
|
||||
// had requested the user thread to send some data (only 1 in-flight at any moment)
|
||||
wantDataPending = false;
|
||||
}
|
||||
|
||||
// Communicate as BlockingQueuedConnection
|
||||
bool b = false;
|
||||
emit resetData(&b);
|
||||
if (b) {
|
||||
// the reset succeeded, we're at pos 0 again
|
||||
m_pos = 0;
|
||||
// the HTTP code will anyway abort the request if !b.
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
qint64 size() const override
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
public slots:
|
||||
// From user thread:
|
||||
void haveDataSlot(qint64 pos, const QByteArray &dataArray, bool dataAtEnd, qint64 dataSize)
|
||||
{
|
||||
if (pos != m_pos) {
|
||||
// Sometimes when re-sending a request in the qhttpnetwork* layer there is a pending haveData from the
|
||||
// user thread on the way to us. We need to ignore it since it is the data for the wrong(later) chunk.
|
||||
return;
|
||||
}
|
||||
wantDataPending = false;
|
||||
|
||||
m_dataArray = dataArray;
|
||||
m_data = const_cast<char*>(m_dataArray.constData());
|
||||
m_amount = dataArray.size();
|
||||
|
||||
m_atEnd = dataAtEnd;
|
||||
m_size = dataSize;
|
||||
|
||||
// This will tell the HTTP code (QHttpNetworkConnectionChannel) that we have data available now
|
||||
emit readyRead();
|
||||
}
|
||||
|
||||
signals:
|
||||
// void readyRead(); in parent class
|
||||
// void readProgress(qint64 current, qint64 total); happens in the main thread with the real bytedevice
|
||||
|
||||
// to main thread:
|
||||
void wantData(qint64);
|
||||
void processedData(qint64 pos, qint64 amount);
|
||||
void resetData(bool *b);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPTHREADDELEGATE_H
|
||||
@@ -0,0 +1,102 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QLOCALSERVER_P_H
|
||||
#define QLOCALSERVER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the QLocalServer class. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qlocalserver.h"
|
||||
#include "private/qobject_p.h"
|
||||
#include <qqueue.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(localserver);
|
||||
|
||||
#if defined(QT_LOCALSOCKET_TCP)
|
||||
# include <qtcpserver.h>
|
||||
# include <QtCore/qmap.h>
|
||||
#elif defined(Q_OS_WIN)
|
||||
# include <qt_windows.h>
|
||||
# include <qwineventnotifier.h>
|
||||
#else
|
||||
# include <private/qabstractsocketengine_p.h>
|
||||
# include <qsocketnotifier.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QLocalServerPrivate : public QObjectPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QLocalServer)
|
||||
|
||||
public:
|
||||
QLocalServerPrivate() :
|
||||
#if !defined(QT_LOCALSOCKET_TCP) && !defined(Q_OS_WIN)
|
||||
listenSocket(-1), socketNotifier(nullptr),
|
||||
#endif
|
||||
maxPendingConnections(30), error(QAbstractSocket::UnknownSocketError),
|
||||
socketOptions(QLocalServer::NoOptions)
|
||||
{
|
||||
}
|
||||
|
||||
void init();
|
||||
bool listen(const QString &name);
|
||||
bool listen(qintptr socketDescriptor);
|
||||
static bool removeServer(const QString &name);
|
||||
void closeServer();
|
||||
void waitForNewConnection(int msec, bool *timedOut);
|
||||
void _q_onNewConnection();
|
||||
|
||||
#if defined(QT_LOCALSOCKET_TCP)
|
||||
|
||||
QTcpServer tcpServer;
|
||||
QMap<quintptr, QTcpSocket*> socketMap;
|
||||
#elif defined(Q_OS_WIN)
|
||||
struct Listener {
|
||||
Listener() = default;
|
||||
HANDLE handle = nullptr;
|
||||
OVERLAPPED overlapped;
|
||||
bool connected = false;
|
||||
private:
|
||||
Q_DISABLE_COPY(Listener)
|
||||
};
|
||||
|
||||
void setError(const QString &function);
|
||||
bool addListener();
|
||||
|
||||
std::vector<std::unique_ptr<Listener>> listeners;
|
||||
HANDLE eventHandle;
|
||||
QWinEventNotifier *connectionEventNotifier;
|
||||
#else
|
||||
void setError(const QString &function);
|
||||
|
||||
int listenSocket;
|
||||
QSocketNotifier *socketNotifier;
|
||||
#endif
|
||||
|
||||
QString serverName;
|
||||
QString fullServerName;
|
||||
int maxPendingConnections;
|
||||
QQueue<QLocalSocket*> pendingConnections;
|
||||
QString errorString;
|
||||
QAbstractSocket::SocketError error;
|
||||
int listenBacklog = 50;
|
||||
|
||||
Q_OBJECT_BINDABLE_PROPERTY(QLocalServerPrivate, QLocalServer::SocketOptions, socketOptions)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QLOCALSERVER_P_H
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QLOCALSOCKET_P_H
|
||||
#define QLOCALSOCKET_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the QLocalSocket class. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qlocalsocket.h"
|
||||
#include "private/qiodevice_p.h"
|
||||
|
||||
#include <qtimer.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(localserver);
|
||||
|
||||
#if defined(QT_LOCALSOCKET_TCP)
|
||||
# include "qtcpsocket.h"
|
||||
#elif defined(Q_OS_WIN)
|
||||
# include "private/qwindowspipereader_p.h"
|
||||
# include "private/qwindowspipewriter_p.h"
|
||||
# include <qwineventnotifier.h>
|
||||
#else
|
||||
# include "private/qabstractsocketengine_p.h"
|
||||
# include <qtcpsocket.h>
|
||||
# include <qsocketnotifier.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
struct sockaddr_un;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if !defined(Q_OS_WIN) || defined(QT_LOCALSOCKET_TCP)
|
||||
|
||||
class QLocalUnixSocket : public QTcpSocket
|
||||
{
|
||||
|
||||
public:
|
||||
QLocalUnixSocket() : QTcpSocket()
|
||||
{
|
||||
};
|
||||
|
||||
inline void setSocketState(QAbstractSocket::SocketState state)
|
||||
{
|
||||
QTcpSocket::setSocketState(state);
|
||||
};
|
||||
|
||||
inline void setErrorString(const QString &string)
|
||||
{
|
||||
QTcpSocket::setErrorString(string);
|
||||
}
|
||||
|
||||
inline void setSocketError(QAbstractSocket::SocketError error)
|
||||
{
|
||||
QTcpSocket::setSocketError(error);
|
||||
}
|
||||
|
||||
inline qint64 readData(char *data, qint64 maxSize) override
|
||||
{
|
||||
return QTcpSocket::readData(data, maxSize);
|
||||
}
|
||||
|
||||
inline qint64 writeData(const char *data, qint64 maxSize) override
|
||||
{
|
||||
return QTcpSocket::writeData(data, maxSize);
|
||||
}
|
||||
};
|
||||
#endif //#if !defined(Q_OS_WIN) || defined(QT_LOCALSOCKET_TCP)
|
||||
|
||||
class QLocalSocketPrivate : public QIODevicePrivate
|
||||
{
|
||||
public:
|
||||
Q_DECLARE_PUBLIC(QLocalSocket)
|
||||
|
||||
QLocalSocketPrivate();
|
||||
void init();
|
||||
|
||||
#if defined(QT_LOCALSOCKET_TCP)
|
||||
QLocalUnixSocket* tcpSocket;
|
||||
bool ownsTcpSocket;
|
||||
void setSocket(QLocalUnixSocket*);
|
||||
QString generateErrorString(QLocalSocket::LocalSocketError, const QString &function) const;
|
||||
void setErrorAndEmit(QLocalSocket::LocalSocketError, const QString &function);
|
||||
void _q_stateChanged(QAbstractSocket::SocketState newState);
|
||||
void _q_errorOccurred(QAbstractSocket::SocketError newError);
|
||||
#elif defined(Q_OS_WIN)
|
||||
~QLocalSocketPrivate();
|
||||
qint64 pipeWriterBytesToWrite() const;
|
||||
void _q_canRead();
|
||||
void _q_bytesWritten(qint64 bytes);
|
||||
void _q_pipeClosed();
|
||||
void _q_winError(ulong windowsError, const QString &function);
|
||||
void _q_writeFailed();
|
||||
HANDLE handle;
|
||||
QWindowsPipeWriter *pipeWriter;
|
||||
QWindowsPipeReader *pipeReader;
|
||||
QLocalSocket::LocalSocketError error;
|
||||
#else
|
||||
QLocalUnixSocket unixSocket;
|
||||
QString generateErrorString(QLocalSocket::LocalSocketError, const QString &function) const;
|
||||
void setErrorAndEmit(QLocalSocket::LocalSocketError, const QString &function);
|
||||
void _q_stateChanged(QAbstractSocket::SocketState newState);
|
||||
void _q_errorOccurred(QAbstractSocket::SocketError newError);
|
||||
void _q_connectToSocket();
|
||||
void _q_abortConnectionAttempt();
|
||||
void cancelDelayedConnect();
|
||||
void describeSocket(qintptr socketDescriptor);
|
||||
static bool parseSockaddr(const sockaddr_un &addr, uint len,
|
||||
QString &fullServerName, QString &serverName, bool &abstractNamespace);
|
||||
QSocketNotifier *delayConnect;
|
||||
QTimer *connectTimer;
|
||||
QString connectingName;
|
||||
int connectingSocket;
|
||||
QIODevice::OpenMode connectingOpenMode;
|
||||
#endif
|
||||
QLocalSocket::LocalSocketState state;
|
||||
QString serverName;
|
||||
QString fullServerName;
|
||||
#if defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)
|
||||
bool emittedReadyRead;
|
||||
bool emittedBytesWritten;
|
||||
#endif
|
||||
|
||||
Q_OBJECT_BINDABLE_PROPERTY(QLocalSocketPrivate, QLocalSocket::SocketOptions, socketOptions)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QLOCALSOCKET_P_H
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNATIVESOCKETENGINE_P_H
|
||||
#define QNATIVESOCKETENGINE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "QtNetwork/qhostaddress.h"
|
||||
#include "QtNetwork/qnetworkinterface.h"
|
||||
#include "private/qabstractsocketengine_p.h"
|
||||
#ifndef Q_OS_WIN
|
||||
# include "qplatformdefs.h"
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
# define QT_SOCKLEN_T int
|
||||
# define QT_SOCKOPTLEN_T int
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
namespace SetSALen {
|
||||
template <typename T> void set(T *sa, typename std::enable_if<(&T::sa_len, true), QT_SOCKLEN_T>::type len)
|
||||
{ sa->sa_len = len; }
|
||||
template <typename T> void set(T *sin6, typename std::enable_if<(&T::sin6_len, true), QT_SOCKLEN_T>::type len)
|
||||
{ sin6->sin6_len = len; }
|
||||
template <typename T> void set(T *, ...) {}
|
||||
}
|
||||
}
|
||||
|
||||
class QNativeSocketEnginePrivate;
|
||||
#ifndef QT_NO_NETWORKINTERFACE
|
||||
class QNetworkInterface;
|
||||
#endif
|
||||
|
||||
class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QNativeSocketEngine(QObject *parent = nullptr);
|
||||
~QNativeSocketEngine();
|
||||
|
||||
bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) override;
|
||||
bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) override;
|
||||
|
||||
qintptr socketDescriptor() const override;
|
||||
|
||||
bool isValid() const override;
|
||||
|
||||
bool connectToHost(const QHostAddress &address, quint16 port) override;
|
||||
bool connectToHostByName(const QString &name, quint16 port) override;
|
||||
bool bind(const QHostAddress &address, quint16 port) override;
|
||||
bool listen(int backlog) override;
|
||||
qintptr accept() override;
|
||||
void close() override;
|
||||
|
||||
qint64 bytesAvailable() const override;
|
||||
|
||||
qint64 read(char *data, qint64 maxlen) override;
|
||||
qint64 write(const char *data, qint64 len) override;
|
||||
|
||||
#ifndef QT_NO_UDPSOCKET
|
||||
#ifndef QT_NO_NETWORKINTERFACE
|
||||
bool joinMulticastGroup(const QHostAddress &groupAddress,
|
||||
const QNetworkInterface &iface) override;
|
||||
bool leaveMulticastGroup(const QHostAddress &groupAddress,
|
||||
const QNetworkInterface &iface) override;
|
||||
QNetworkInterface multicastInterface() const override;
|
||||
bool setMulticastInterface(const QNetworkInterface &iface) override;
|
||||
#endif
|
||||
|
||||
bool hasPendingDatagrams() const override;
|
||||
qint64 pendingDatagramSize() const override;
|
||||
#endif // QT_NO_UDPSOCKET
|
||||
|
||||
qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = nullptr,
|
||||
PacketHeaderOptions = WantNone) override;
|
||||
qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) override;
|
||||
qint64 bytesToWrite() const override;
|
||||
|
||||
#if 0 // currently unused
|
||||
qint64 receiveBufferSize() const;
|
||||
void setReceiveBufferSize(qint64 bufferSize);
|
||||
|
||||
qint64 sendBufferSize() const;
|
||||
void setSendBufferSize(qint64 bufferSize);
|
||||
#endif
|
||||
|
||||
int option(SocketOption option) const override;
|
||||
bool setOption(SocketOption option, int value) override;
|
||||
|
||||
bool waitForRead(int msecs = 30000, bool *timedOut = nullptr) override;
|
||||
bool waitForWrite(int msecs = 30000, bool *timedOut = nullptr) override;
|
||||
bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
|
||||
bool checkRead, bool checkWrite,
|
||||
int msecs = 30000, bool *timedOut = nullptr) override;
|
||||
|
||||
bool isReadNotificationEnabled() const override;
|
||||
void setReadNotificationEnabled(bool enable) override;
|
||||
bool isWriteNotificationEnabled() const override;
|
||||
void setWriteNotificationEnabled(bool enable) override;
|
||||
bool isExceptionNotificationEnabled() const override;
|
||||
void setExceptionNotificationEnabled(bool enable) override;
|
||||
|
||||
public Q_SLOTS:
|
||||
// non-virtual override;
|
||||
void connectionNotification();
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QNativeSocketEngine)
|
||||
Q_DISABLE_COPY_MOVE(QNativeSocketEngine)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QNATIVESOCKETENGINE_P_H
|
||||
@@ -0,0 +1,197 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNATIVESOCKETENGINE_P_P_H
|
||||
#define QNATIVESOCKETENGINE_P_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "private/qabstractsocketengine_p.h"
|
||||
#include "private/qnativesocketengine_p.h"
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
# include <netinet/in.h>
|
||||
#else
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
# include <mswsock.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
// The following definitions are copied from the MinGW header mswsock.h which
|
||||
// was placed in the public domain. The WSASendMsg and WSARecvMsg functions
|
||||
// were introduced with Windows Vista, so some Win32 headers are lacking them.
|
||||
// There are no known versions of Windows CE or Embedded that contain them.
|
||||
# ifndef WSAID_WSARECVMSG
|
||||
typedef INT (WINAPI *LPFN_WSARECVMSG)(SOCKET s, LPWSAMSG lpMsg,
|
||||
LPDWORD lpdwNumberOfBytesRecvd,
|
||||
LPWSAOVERLAPPED lpOverlapped,
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
|
||||
# define WSAID_WSARECVMSG {0xf689d7c8,0x6f1f,0x436b,{0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22}}
|
||||
# endif // !WSAID_WSARECVMSG
|
||||
# ifndef WSAID_WSASENDMSG
|
||||
typedef struct {
|
||||
LPWSAMSG lpMsg;
|
||||
DWORD dwFlags;
|
||||
LPDWORD lpNumberOfBytesSent;
|
||||
LPWSAOVERLAPPED lpOverlapped;
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine;
|
||||
} WSASENDMSG, *LPWSASENDMSG;
|
||||
|
||||
typedef INT (WSAAPI *LPFN_WSASENDMSG)(SOCKET s, LPWSAMSG lpMsg, DWORD dwFlags,
|
||||
LPDWORD lpNumberOfBytesSent,
|
||||
LPWSAOVERLAPPED lpOverlapped,
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
|
||||
|
||||
# define WSAID_WSASENDMSG {0xa441e712,0x754f,0x43ca,{0x84,0xa7,0x0d,0xee,0x44,0xcf,0x60,0x6d}}
|
||||
# endif // !WSAID_WSASENDMSG
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
union qt_sockaddr {
|
||||
sockaddr a;
|
||||
sockaddr_in a4;
|
||||
sockaddr_in6 a6;
|
||||
};
|
||||
|
||||
class QSocketNotifier;
|
||||
|
||||
class QNativeSocketEnginePrivate : public QAbstractSocketEnginePrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QNativeSocketEngine)
|
||||
public:
|
||||
QNativeSocketEnginePrivate();
|
||||
~QNativeSocketEnginePrivate();
|
||||
|
||||
qintptr socketDescriptor;
|
||||
|
||||
QSocketNotifier *readNotifier, *writeNotifier, *exceptNotifier;
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
LPFN_WSASENDMSG sendmsg;
|
||||
LPFN_WSARECVMSG recvmsg;
|
||||
# endif
|
||||
enum ErrorString {
|
||||
NonBlockingInitFailedErrorString,
|
||||
BroadcastingInitFailedErrorString,
|
||||
NoIpV6ErrorString,
|
||||
RemoteHostClosedErrorString,
|
||||
TimeOutErrorString,
|
||||
ResourceErrorString,
|
||||
OperationUnsupportedErrorString,
|
||||
ProtocolUnsupportedErrorString,
|
||||
InvalidSocketErrorString,
|
||||
HostUnreachableErrorString,
|
||||
NetworkUnreachableErrorString,
|
||||
AccessErrorString,
|
||||
ConnectionTimeOutErrorString,
|
||||
ConnectionRefusedErrorString,
|
||||
AddressInuseErrorString,
|
||||
AddressNotAvailableErrorString,
|
||||
AddressProtectedErrorString,
|
||||
DatagramTooLargeErrorString,
|
||||
SendDatagramErrorString,
|
||||
ReceiveDatagramErrorString,
|
||||
WriteErrorString,
|
||||
ReadErrorString,
|
||||
PortInuseErrorString,
|
||||
NotSocketErrorString,
|
||||
InvalidProxyTypeString,
|
||||
TemporaryErrorString,
|
||||
NetworkDroppedConnectionErrorString,
|
||||
ConnectionResetErrorString,
|
||||
|
||||
UnknownSocketErrorString = -1
|
||||
};
|
||||
|
||||
void setError(QAbstractSocket::SocketError error, ErrorString errorString) const;
|
||||
QHostAddress adjustAddressProtocol(const QHostAddress &address) const;
|
||||
|
||||
// native functions
|
||||
int option(QNativeSocketEngine::SocketOption option) const;
|
||||
bool setOption(QNativeSocketEngine::SocketOption option, int value);
|
||||
|
||||
bool createNewSocket(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol &protocol);
|
||||
|
||||
bool nativeConnect(const QHostAddress &address, quint16 port);
|
||||
bool nativeBind(const QHostAddress &address, quint16 port);
|
||||
bool nativeListen(int backlog);
|
||||
qintptr nativeAccept();
|
||||
#ifndef QT_NO_NETWORKINTERFACE
|
||||
bool nativeJoinMulticastGroup(const QHostAddress &groupAddress,
|
||||
const QNetworkInterface &iface);
|
||||
bool nativeLeaveMulticastGroup(const QHostAddress &groupAddress,
|
||||
const QNetworkInterface &iface);
|
||||
QNetworkInterface nativeMulticastInterface() const;
|
||||
bool nativeSetMulticastInterface(const QNetworkInterface &iface);
|
||||
#endif
|
||||
qint64 nativeBytesAvailable() const;
|
||||
|
||||
bool nativeHasPendingDatagrams() const;
|
||||
qint64 nativePendingDatagramSize() const;
|
||||
qint64 nativeReceiveDatagram(char *data, qint64 maxLength, QIpPacketHeader *header,
|
||||
QAbstractSocketEngine::PacketHeaderOptions options);
|
||||
qint64 nativeSendDatagram(const char *data, qint64 length, const QIpPacketHeader &header);
|
||||
qint64 nativeRead(char *data, qint64 maxLength);
|
||||
qint64 nativeWrite(const char *data, qint64 length);
|
||||
int nativeSelect(int timeout, bool selectForRead) const;
|
||||
int nativeSelect(int timeout, bool checkRead, bool checkWrite,
|
||||
bool *selectForRead, bool *selectForWrite) const;
|
||||
|
||||
void nativeClose();
|
||||
|
||||
bool checkProxy(const QHostAddress &address);
|
||||
bool fetchConnectionParameters();
|
||||
|
||||
#if QT_CONFIG(networkinterface)
|
||||
static uint scopeIdFromString(const QString &scopeid)
|
||||
{ return QNetworkInterface::interfaceIndexFromName(scopeid); }
|
||||
#endif
|
||||
|
||||
/*! \internal
|
||||
Sets \a address and \a port in the \a aa sockaddr structure and the size in \a sockAddrSize.
|
||||
The address \a is converted to IPv6 if the current socket protocol is also IPv6.
|
||||
*/
|
||||
void setPortAndAddress(quint16 port, const QHostAddress &address, qt_sockaddr *aa, QT_SOCKLEN_T *sockAddrSize)
|
||||
{
|
||||
if (address.protocol() == QAbstractSocket::IPv6Protocol
|
||||
|| address.protocol() == QAbstractSocket::AnyIPProtocol
|
||||
|| socketProtocol == QAbstractSocket::IPv6Protocol
|
||||
|| socketProtocol == QAbstractSocket::AnyIPProtocol) {
|
||||
memset(&aa->a6, 0, sizeof(sockaddr_in6));
|
||||
aa->a6.sin6_family = AF_INET6;
|
||||
#if QT_CONFIG(networkinterface)
|
||||
aa->a6.sin6_scope_id = scopeIdFromString(address.scopeId());
|
||||
#endif
|
||||
aa->a6.sin6_port = htons(port);
|
||||
Q_IPV6ADDR tmp = address.toIPv6Address();
|
||||
memcpy(&aa->a6.sin6_addr, &tmp, sizeof(tmp));
|
||||
*sockAddrSize = sizeof(sockaddr_in6);
|
||||
SetSALen::set(&aa->a, sizeof(sockaddr_in6));
|
||||
} else {
|
||||
memset(&aa->a, 0, sizeof(sockaddr_in));
|
||||
aa->a4.sin_family = AF_INET;
|
||||
aa->a4.sin_port = htons(port);
|
||||
aa->a4.sin_addr.s_addr = htonl(address.toIPv4Address());
|
||||
*sockAddrSize = sizeof(sockaddr_in);
|
||||
SetSALen::set(&aa->a, sizeof(sockaddr_in));
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QNATIVESOCKETENGINE_P_P_H
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright (C) 2019 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETCONMONITOR_P_H
|
||||
#define QNETCONMONITOR_P_H
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qobject.h>
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNetworkConnectionMonitorPrivate;
|
||||
class Q_NETWORK_EXPORT QNetworkConnectionMonitor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QNetworkConnectionMonitor();
|
||||
QNetworkConnectionMonitor(const QHostAddress &local, const QHostAddress &remote = {});
|
||||
~QNetworkConnectionMonitor();
|
||||
|
||||
bool setTargets(const QHostAddress &local, const QHostAddress &remote);
|
||||
bool isReachable();
|
||||
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
bool isWwan() const;
|
||||
#endif
|
||||
|
||||
// Important: on Darwin you should not call isReachable/isWwan() after
|
||||
// startMonitoring(), you have to listen to reachabilityChanged()
|
||||
// signal instead.
|
||||
bool startMonitoring();
|
||||
bool isMonitoring() const;
|
||||
void stopMonitoring();
|
||||
|
||||
static bool isEnabled();
|
||||
|
||||
Q_SIGNALS:
|
||||
// Important: connect to this using QueuedConnection. On Darwin
|
||||
// callback is coming on a special dispatch queue.
|
||||
void reachabilityChanged(bool isOnline);
|
||||
|
||||
#ifdef QT_PLATFORM_UIKIT
|
||||
void isWwanChanged(bool isWwan);
|
||||
#endif
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QNetworkConnectionMonitor)
|
||||
Q_DISABLE_COPY_MOVE(QNetworkConnectionMonitor)
|
||||
};
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcNetMon)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QNETCONMONITOR_P_H
|
||||
@@ -0,0 +1,73 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKACCESSAUTHENTICATIONMANAGER_P_H
|
||||
#define QNETWORKACCESSAUTHENTICATIONMANAGER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qnetworkaccessmanager.h"
|
||||
#include "qnetworkaccesscache_p.h"
|
||||
#include "QtNetwork/qnetworkproxy.h"
|
||||
#include "QtCore/QMutex"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAuthenticator;
|
||||
class QAbstractNetworkCache;
|
||||
class QNetworkAuthenticationCredential;
|
||||
class QNetworkCookieJar;
|
||||
|
||||
class QNetworkAuthenticationCredential
|
||||
{
|
||||
public:
|
||||
QString domain;
|
||||
QString user;
|
||||
QString password;
|
||||
bool isNull() const {
|
||||
return domain.isNull() && user.isNull() && password.isNull();
|
||||
}
|
||||
};
|
||||
Q_DECLARE_TYPEINFO(QNetworkAuthenticationCredential, Q_RELOCATABLE_TYPE);
|
||||
inline bool operator<(const QNetworkAuthenticationCredential &t1, const QString &t2)
|
||||
{ return t1.domain < t2; }
|
||||
inline bool operator<(const QString &t1, const QNetworkAuthenticationCredential &t2)
|
||||
{ return t1 < t2.domain; }
|
||||
inline bool operator<(const QNetworkAuthenticationCredential &t1, const QNetworkAuthenticationCredential &t2)
|
||||
{ return t1.domain < t2.domain; }
|
||||
|
||||
class QNetworkAccessAuthenticationManager
|
||||
{
|
||||
public:
|
||||
QNetworkAccessAuthenticationManager() {}
|
||||
|
||||
void cacheCredentials(const QUrl &url, const QAuthenticator *auth);
|
||||
QNetworkAuthenticationCredential fetchCachedCredentials(const QUrl &url,
|
||||
const QAuthenticator *auth = nullptr);
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void cacheProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth);
|
||||
QNetworkAuthenticationCredential fetchCachedProxyCredentials(const QNetworkProxy &proxy,
|
||||
const QAuthenticator *auth = nullptr);
|
||||
#endif
|
||||
|
||||
void clearCache();
|
||||
|
||||
protected:
|
||||
QNetworkAccessCache authenticationCache;
|
||||
QMutex mutex;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,157 @@
|
||||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKACCESSBACKEND_P_H
|
||||
#define QNETWORKACCESSBACKEND_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/qtnetworkglobal.h>
|
||||
|
||||
#include <QtNetwork/qnetworkrequest.h>
|
||||
#include <QtNetwork/qnetworkaccessmanager.h>
|
||||
#include <QtNetwork/qnetworkreply.h>
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qflags.h>
|
||||
#include <QtCore/qbytearrayview.h>
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
|
||||
#if QT_CONFIG(ssl)
|
||||
#include <QtNetwork/qsslconfiguration.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNetworkReplyImplPrivate;
|
||||
class QNetworkAccessManagerPrivate;
|
||||
class QNetworkAccessBackendPrivate;
|
||||
class Q_NETWORK_EXPORT QNetworkAccessBackend : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(QNetworkAccessBackend);
|
||||
|
||||
public:
|
||||
enum class TargetType {
|
||||
Networked = 0x1, // We need to query for proxy in case it is needed
|
||||
Local = 0x2, // Local file, generated data or local device
|
||||
};
|
||||
Q_ENUM(TargetType)
|
||||
Q_DECLARE_FLAGS(TargetTypes, TargetType)
|
||||
|
||||
enum class SecurityFeature {
|
||||
None = 0x0,
|
||||
TLS = 0x1, // We need to set QSslConfiguration
|
||||
};
|
||||
Q_ENUM(SecurityFeature)
|
||||
Q_DECLARE_FLAGS(SecurityFeatures, SecurityFeature)
|
||||
|
||||
enum class IOFeature {
|
||||
None = 0x0,
|
||||
ZeroCopy = 0x1, // readPointer and advanceReadPointer() is available!
|
||||
NeedResetableUpload = 0x2, // Need to buffer upload data
|
||||
SupportsSynchronousMode = 0x4, // Used for XMLHttpRequest
|
||||
};
|
||||
Q_ENUM(IOFeature)
|
||||
Q_DECLARE_FLAGS(IOFeatures, IOFeature)
|
||||
|
||||
QNetworkAccessBackend(TargetTypes targetTypes, SecurityFeatures securityFeatures,
|
||||
IOFeatures ioFeatures);
|
||||
QNetworkAccessBackend(TargetTypes targetTypes);
|
||||
QNetworkAccessBackend(TargetTypes targetTypes, SecurityFeatures securityFeatures);
|
||||
QNetworkAccessBackend(TargetTypes targetTypes, IOFeatures ioFeatures);
|
||||
virtual ~QNetworkAccessBackend();
|
||||
|
||||
SecurityFeatures securityFeatures() const noexcept;
|
||||
TargetTypes targetTypes() const noexcept;
|
||||
IOFeatures ioFeatures() const noexcept;
|
||||
|
||||
inline bool needsResetableUploadData() const noexcept
|
||||
{
|
||||
return ioFeatures() & IOFeature::NeedResetableUpload;
|
||||
}
|
||||
|
||||
virtual bool start();
|
||||
virtual void open() = 0;
|
||||
virtual void close() = 0;
|
||||
#if QT_CONFIG(ssl)
|
||||
virtual void setSslConfiguration(const QSslConfiguration &configuration);
|
||||
virtual QSslConfiguration sslConfiguration() const;
|
||||
#endif
|
||||
virtual void ignoreSslErrors();
|
||||
virtual void ignoreSslErrors(const QList<QSslError> &errors);
|
||||
virtual qint64 bytesAvailable() const = 0;
|
||||
virtual QByteArrayView readPointer();
|
||||
virtual void advanceReadPointer(qint64 distance);
|
||||
virtual qint64 read(char *data, qint64 maxlen);
|
||||
virtual bool wantToRead();
|
||||
|
||||
#if QT_CONFIG(networkproxy)
|
||||
QList<QNetworkProxy> proxyList() const;
|
||||
#endif
|
||||
QUrl url() const;
|
||||
void setUrl(const QUrl &url);
|
||||
QVariant header(QNetworkRequest::KnownHeaders header) const;
|
||||
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value);
|
||||
QByteArray rawHeader(const QByteArray &header) const;
|
||||
void setRawHeader(const QByteArray &header, const QByteArray &value);
|
||||
QNetworkAccessManager::Operation operation() const;
|
||||
|
||||
bool isCachingEnabled() const;
|
||||
void setCachingEnabled(bool canCache);
|
||||
|
||||
void setAttribute(QNetworkRequest::Attribute attribute, const QVariant &value);
|
||||
|
||||
QIODevice *createUploadByteDevice();
|
||||
QIODevice *uploadByteDevice();
|
||||
|
||||
QAbstractNetworkCache *networkCache() const;
|
||||
|
||||
public slots:
|
||||
void readyRead();
|
||||
protected slots:
|
||||
void finished();
|
||||
void error(QNetworkReply::NetworkError code, const QString &errorString);
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth);
|
||||
#endif
|
||||
void authenticationRequired(QAuthenticator *auth);
|
||||
void metaDataChanged();
|
||||
void redirectionRequested(const QUrl &destination);
|
||||
|
||||
private:
|
||||
void setReplyPrivate(QNetworkReplyImplPrivate *reply);
|
||||
void setManagerPrivate(QNetworkAccessManagerPrivate *manager);
|
||||
bool isSynchronous() const;
|
||||
void setSynchronous(bool synchronous);
|
||||
|
||||
friend class QNetworkAccessManager; // for setReplyPrivate
|
||||
friend class QNetworkAccessManagerPrivate; // for setManagerPrivate
|
||||
friend class QNetworkReplyImplPrivate; // for {set,is}Synchronous()
|
||||
};
|
||||
|
||||
class Q_NETWORK_EXPORT QNetworkAccessBackendFactory : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QNetworkAccessBackendFactory();
|
||||
virtual ~QNetworkAccessBackendFactory();
|
||||
virtual QStringList supportedSchemes() const = 0;
|
||||
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
|
||||
const QNetworkRequest &request) const = 0;
|
||||
};
|
||||
|
||||
#define QNetworkAccessBackendFactory_iid "org.qt-project.Qt.NetworkAccessBackendFactory"
|
||||
Q_DECLARE_INTERFACE(QNetworkAccessBackendFactory, QNetworkAccessBackendFactory_iid);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKACCESSCACHE_P_H
|
||||
#define QNETWORKACCESSCACHE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "QtCore/qobject.h"
|
||||
#include "QtCore/qbasictimer.h"
|
||||
#include "QtCore/qbytearray.h"
|
||||
#include "QtCore/qhash.h"
|
||||
#include "QtCore/qmetatype.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNetworkRequest;
|
||||
class QUrl;
|
||||
|
||||
// this class is not about caching files but about
|
||||
// caching objects used by QNetworkAccessManager, e.g. existing TCP connections
|
||||
// or credentials.
|
||||
class QNetworkAccessCache: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
struct Node;
|
||||
typedef QHash<QByteArray, Node *> NodeHash;
|
||||
|
||||
class CacheableObject
|
||||
{
|
||||
friend class QNetworkAccessCache;
|
||||
QByteArray key;
|
||||
bool expires;
|
||||
bool shareable;
|
||||
qint64 expiryTimeoutSeconds;
|
||||
public:
|
||||
CacheableObject();
|
||||
virtual ~CacheableObject();
|
||||
virtual void dispose() = 0;
|
||||
inline QByteArray cacheKey() const { return key; }
|
||||
|
||||
protected:
|
||||
void setExpires(bool enable);
|
||||
void setShareable(bool enable);
|
||||
};
|
||||
|
||||
~QNetworkAccessCache();
|
||||
|
||||
void clear();
|
||||
|
||||
void addEntry(const QByteArray &key, CacheableObject *entry, qint64 connectionCacheExpiryTimeoutSeconds = -1);
|
||||
bool hasEntry(const QByteArray &key) const;
|
||||
CacheableObject *requestEntryNow(const QByteArray &key);
|
||||
void releaseEntry(const QByteArray &key);
|
||||
void removeEntry(const QByteArray &key);
|
||||
|
||||
signals:
|
||||
void entryReady(QNetworkAccessCache::CacheableObject *);
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *) override;
|
||||
|
||||
private:
|
||||
// idea copied from qcache.h
|
||||
NodeHash hash;
|
||||
Node *firstExpiringNode = nullptr;
|
||||
Node *lastExpiringNode = nullptr;
|
||||
|
||||
QBasicTimer timer;
|
||||
|
||||
void linkEntry(const QByteArray &key);
|
||||
bool unlinkEntry(const QByteArray &key);
|
||||
void updateTimer();
|
||||
bool emitEntryReady(Node *node, QObject *target, const char *member);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKACCESSCACHEBACKEND_P_H
|
||||
#define QNETWORKACCESSCACHEBACKEND_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qnetworkaccessbackend_p.h"
|
||||
#include "qnetworkrequest.h"
|
||||
#include "qnetworkreply.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNetworkAccessCacheBackend : public QNetworkAccessBackend
|
||||
{
|
||||
|
||||
public:
|
||||
QNetworkAccessCacheBackend();
|
||||
~QNetworkAccessCacheBackend();
|
||||
|
||||
void open() override;
|
||||
void close() override;
|
||||
bool start() override;
|
||||
qint64 bytesAvailable() const override;
|
||||
qint64 read(char *data, qint64 maxlen) override;
|
||||
|
||||
private:
|
||||
bool sendCacheContents();
|
||||
|
||||
QIODevice *device = nullptr;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QNETWORKACCESSCACHEBACKEND_P_H
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKACCESSFILEBACKEND_P_H
|
||||
#define QNETWORKACCESSFILEBACKEND_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qnetworkaccessbackend_p.h"
|
||||
#include "qnetworkrequest.h"
|
||||
#include "qnetworkreply.h"
|
||||
#include "QtCore/qfile.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNetworkAccessFileBackend: public QNetworkAccessBackend
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QNetworkAccessFileBackend();
|
||||
virtual ~QNetworkAccessFileBackend();
|
||||
|
||||
void open() override;
|
||||
void close() override;
|
||||
|
||||
qint64 bytesAvailable() const override;
|
||||
qint64 read(char *data, qint64 maxlen) override;
|
||||
|
||||
public slots:
|
||||
void uploadReadyReadSlot();
|
||||
private:
|
||||
QFile file;
|
||||
qint64 totalBytes;
|
||||
bool hasUploadFinished;
|
||||
|
||||
bool loadFileInfo();
|
||||
};
|
||||
|
||||
class QNetworkAccessFileBackendFactory: public QNetworkAccessBackendFactory
|
||||
{
|
||||
public:
|
||||
virtual QStringList supportedSchemes() const override;
|
||||
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
|
||||
const QNetworkRequest &request) const override;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,141 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKACCESSMANAGER_P_H
|
||||
#define QNETWORKACCESSMANAGER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qnetworkaccessmanager.h"
|
||||
#include "qnetworkaccesscache_p.h"
|
||||
#include "qnetworkaccessbackend_p.h"
|
||||
#include "private/qnetconmonitor_p.h"
|
||||
#include "qnetworkrequest.h"
|
||||
#include "qhsts_p.h"
|
||||
#include "private/qobject_p.h"
|
||||
#include "QtNetwork/qnetworkproxy.h"
|
||||
#include "qnetworkaccessauthenticationmanager_p.h"
|
||||
|
||||
#if QT_CONFIG(settings)
|
||||
#include "qhstsstore_p.h"
|
||||
#endif // QT_CONFIG(settings)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAuthenticator;
|
||||
class QAbstractNetworkCache;
|
||||
class QNetworkAuthenticationCredential;
|
||||
class QNetworkCookieJar;
|
||||
|
||||
class QNetworkAccessManagerPrivate: public QObjectPrivate
|
||||
{
|
||||
public:
|
||||
QNetworkAccessManagerPrivate()
|
||||
: networkCache(nullptr),
|
||||
cookieJar(nullptr),
|
||||
thread(nullptr),
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
proxyFactory(nullptr),
|
||||
#endif
|
||||
cookieJarCreated(false),
|
||||
defaultAccessControl(true),
|
||||
redirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy),
|
||||
authenticationManager(std::make_shared<QNetworkAccessAuthenticationManager>())
|
||||
{
|
||||
}
|
||||
~QNetworkAccessManagerPrivate();
|
||||
|
||||
QThread * createThread();
|
||||
void destroyThread();
|
||||
|
||||
void _q_replyFinished(QNetworkReply *reply);
|
||||
void _q_replyEncrypted(QNetworkReply *reply);
|
||||
void _q_replySslErrors(const QList<QSslError> &errors);
|
||||
void _q_replyPreSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator);
|
||||
QNetworkReply *postProcess(QNetworkReply *reply);
|
||||
void createCookieJar() const;
|
||||
|
||||
void authenticationRequired(QAuthenticator *authenticator,
|
||||
QNetworkReply *reply,
|
||||
bool synchronous,
|
||||
QUrl &url,
|
||||
QUrl *urlForLastAuthentication,
|
||||
bool allowAuthenticationReuse = true);
|
||||
void cacheCredentials(const QUrl &url, const QAuthenticator *auth);
|
||||
QNetworkAuthenticationCredential *fetchCachedCredentials(const QUrl &url,
|
||||
const QAuthenticator *auth = nullptr);
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void proxyAuthenticationRequired(const QUrl &url,
|
||||
const QNetworkProxy &proxy,
|
||||
bool synchronous,
|
||||
QAuthenticator *authenticator,
|
||||
QNetworkProxy *lastProxyAuthentication);
|
||||
void cacheProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth);
|
||||
QNetworkAuthenticationCredential *fetchCachedProxyCredentials(const QNetworkProxy &proxy,
|
||||
const QAuthenticator *auth = nullptr);
|
||||
QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query);
|
||||
#endif
|
||||
|
||||
QNetworkAccessBackend *findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request);
|
||||
QStringList backendSupportedSchemes() const;
|
||||
|
||||
#if QT_CONFIG(http) || defined(Q_OS_WASM)
|
||||
QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart);
|
||||
#endif
|
||||
|
||||
void ensureBackendPluginsLoaded();
|
||||
|
||||
// this is the cache for storing downloaded files
|
||||
QAbstractNetworkCache *networkCache;
|
||||
|
||||
QNetworkCookieJar *cookieJar;
|
||||
|
||||
QThread *thread;
|
||||
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
QNetworkProxy proxy;
|
||||
QNetworkProxyFactory *proxyFactory;
|
||||
#endif
|
||||
|
||||
bool cookieJarCreated;
|
||||
bool defaultAccessControl;
|
||||
QNetworkRequest::RedirectPolicy redirectPolicy = QNetworkRequest::NoLessSafeRedirectPolicy;
|
||||
|
||||
// The cache with authorization data:
|
||||
std::shared_ptr<QNetworkAccessAuthenticationManager> authenticationManager;
|
||||
|
||||
// this cache can be used by individual backends to cache e.g. their TCP connections to a server
|
||||
// and use the connections for multiple requests.
|
||||
QNetworkAccessCache objectCache;
|
||||
|
||||
Q_AUTOTEST_EXPORT static void clearAuthenticationCache(QNetworkAccessManager *manager);
|
||||
Q_AUTOTEST_EXPORT static void clearConnectionCache(QNetworkAccessManager *manager);
|
||||
|
||||
QHstsCache stsCache;
|
||||
#if QT_CONFIG(settings)
|
||||
QScopedPointer<QHstsStore> stsStore;
|
||||
#endif // QT_CONFIG(settings)
|
||||
bool stsEnabled = false;
|
||||
|
||||
bool autoDeleteReplies = false;
|
||||
|
||||
int transferTimeout = 0;
|
||||
|
||||
Q_DECLARE_PUBLIC(QNetworkAccessManager)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKCOOKIE_P_H
|
||||
#define QNETWORKCOOKIE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access framework. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "QtCore/qdatetime.h"
|
||||
#include "QtNetwork/qnetworkcookie.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNetworkCookiePrivate: public QSharedData
|
||||
{
|
||||
public:
|
||||
QNetworkCookiePrivate() = default;
|
||||
static QList<QNetworkCookie> parseSetCookieHeaderLine(const QByteArray &cookieString);
|
||||
|
||||
QDateTime expirationDate;
|
||||
QString domain;
|
||||
QString path;
|
||||
QString comment;
|
||||
QByteArray name;
|
||||
QByteArray value;
|
||||
QNetworkCookie::SameSite sameSite = QNetworkCookie::SameSite::Default;
|
||||
bool secure = false;
|
||||
bool httpOnly = false;
|
||||
};
|
||||
|
||||
static inline bool isLWS(char c)
|
||||
{
|
||||
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
|
||||
}
|
||||
|
||||
static int nextNonWhitespace(const QByteArray &text, int from)
|
||||
{
|
||||
// RFC 2616 defines linear whitespace as:
|
||||
// LWS = [CRLF] 1*( SP | HT )
|
||||
// We ignore the fact that CRLF must come as a pair at this point
|
||||
// It's an invalid HTTP header if that happens.
|
||||
while (from < text.size()) {
|
||||
if (isLWS(text.at(from)))
|
||||
++from;
|
||||
else
|
||||
return from; // non-whitespace
|
||||
}
|
||||
|
||||
// reached the end
|
||||
return text.size();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKCOOKIEJAR_P_H
|
||||
#define QNETWORKCOOKIEJAR_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access framework. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "private/qobject_p.h"
|
||||
#include "qnetworkcookie.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNetworkCookieJarPrivate: public QObjectPrivate
|
||||
{
|
||||
public:
|
||||
QList<QNetworkCookie> allCookies;
|
||||
|
||||
Q_DECLARE_PUBLIC(QNetworkCookieJar)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright (C) 2015 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKDATAGRAM_P_H
|
||||
#define QNETWORKDATAGRAM_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIpPacketHeader
|
||||
{
|
||||
public:
|
||||
QIpPacketHeader(const QHostAddress &dstAddr = QHostAddress(), quint16 port = 0)
|
||||
: destinationAddress(dstAddr), ifindex(0), hopLimit(-1), streamNumber(-1),
|
||||
destinationPort(port), endOfRecord(false)
|
||||
{}
|
||||
|
||||
void clear()
|
||||
{
|
||||
senderAddress.clear();
|
||||
destinationAddress.clear();
|
||||
ifindex = 0;
|
||||
hopLimit = -1;
|
||||
streamNumber = -1;
|
||||
endOfRecord = false;
|
||||
}
|
||||
|
||||
QHostAddress senderAddress;
|
||||
QHostAddress destinationAddress;
|
||||
|
||||
uint ifindex;
|
||||
int hopLimit;
|
||||
int streamNumber;
|
||||
quint16 senderPort;
|
||||
quint16 destinationPort;
|
||||
bool endOfRecord;
|
||||
};
|
||||
|
||||
class QNetworkDatagramPrivate
|
||||
{
|
||||
public:
|
||||
QNetworkDatagramPrivate(const QByteArray &data = QByteArray(),
|
||||
const QHostAddress &dstAddr = QHostAddress(), quint16 port = 0)
|
||||
: data(data), header(dstAddr, port)
|
||||
{}
|
||||
QNetworkDatagramPrivate(const QByteArray &data, const QIpPacketHeader &header)
|
||||
: data(data), header(header)
|
||||
{}
|
||||
|
||||
QByteArray data;
|
||||
QIpPacketHeader header;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QNETWORKDATAGRAM_P_H
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKDISKCACHE_P_H
|
||||
#define QNETWORKDISKCACHE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "private/qabstractnetworkcache_p.h"
|
||||
|
||||
#include <qbuffer.h>
|
||||
#include <qhash.h>
|
||||
#include <qsavefile.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(networkdiskcache);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QCacheItem
|
||||
{
|
||||
public:
|
||||
QCacheItem() = default;
|
||||
~QCacheItem()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
QNetworkCacheMetaData metaData;
|
||||
QBuffer data;
|
||||
QSaveFile *file = nullptr;
|
||||
inline qint64 size() const
|
||||
{ return file ? file->size() : data.size(); }
|
||||
|
||||
inline void reset() {
|
||||
metaData = QNetworkCacheMetaData();
|
||||
data.close();
|
||||
delete file;
|
||||
file = nullptr;
|
||||
}
|
||||
void writeHeader(QFileDevice *device) const;
|
||||
void writeCompressedData(QFileDevice *device) const;
|
||||
bool read(QFileDevice *device, bool readData);
|
||||
|
||||
bool canCompress() const;
|
||||
};
|
||||
|
||||
class QNetworkDiskCachePrivate : public QAbstractNetworkCachePrivate
|
||||
{
|
||||
public:
|
||||
QNetworkDiskCachePrivate()
|
||||
: QAbstractNetworkCachePrivate()
|
||||
, maximumCacheSize(1024 * 1024 * 50)
|
||||
, currentCacheSize(-1)
|
||||
{}
|
||||
|
||||
static QString uniqueFileName(const QUrl &url);
|
||||
QString cacheFileName(const QUrl &url) const;
|
||||
bool removeFile(const QString &file);
|
||||
void storeItem(QCacheItem *item);
|
||||
void prepareLayout();
|
||||
static quint32 crc32(const char *data, uint len);
|
||||
|
||||
mutable QCacheItem lastItem;
|
||||
QString cacheDirectory;
|
||||
QString dataDirectory;
|
||||
qint64 maximumCacheSize;
|
||||
qint64 currentCacheSize;
|
||||
|
||||
QHash<QIODevice*, QCacheItem*> inserting;
|
||||
Q_DECLARE_PUBLIC(QNetworkDiskCache)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QNETWORKDISKCACHE_P_H
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKFILE_H
|
||||
#define QNETWORKFILE_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QFile>
|
||||
#include <qnetworkreply.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNetworkFile : public QFile
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QNetworkFile();
|
||||
QNetworkFile(const QString &name);
|
||||
using QFile::open;
|
||||
|
||||
public Q_SLOTS:
|
||||
void open();
|
||||
void close() override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void finished(bool ok);
|
||||
void headerRead(QNetworkRequest::KnownHeaders header, const QVariant &value);
|
||||
void error(QNetworkReply::NetworkError error, const QString &message);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QNETWORKFILE_H
|
||||
@@ -0,0 +1,127 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKINFORMATION_P_H
|
||||
#define QNETWORKINFORMATION_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Information API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <QtNetwork/qnetworkinformation.h>
|
||||
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_NETWORK_EXPORT QNetworkInformationBackend : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using Reachability = QNetworkInformation::Reachability;
|
||||
using TransportMedium = QNetworkInformation::TransportMedium;
|
||||
|
||||
public:
|
||||
static inline const char16_t PluginNames[4][22] = {
|
||||
{ u"networklistmanager" },
|
||||
{ u"scnetworkreachability" },
|
||||
{ u"android" },
|
||||
{ u"networkmanager" },
|
||||
};
|
||||
static constexpr int PluginNamesWindowsIndex = 0;
|
||||
static constexpr int PluginNamesAppleIndex = 1;
|
||||
static constexpr int PluginNamesAndroidIndex = 2;
|
||||
static constexpr int PluginNamesLinuxIndex = 3;
|
||||
|
||||
QNetworkInformationBackend() = default;
|
||||
~QNetworkInformationBackend() override;
|
||||
|
||||
virtual QString name() const = 0;
|
||||
virtual QNetworkInformation::Features featuresSupported() const = 0;
|
||||
|
||||
Reachability reachability() const { return m_reachability; }
|
||||
bool behindCaptivePortal() const { return m_behindCaptivePortal; }
|
||||
TransportMedium transportMedium() const { return m_transportMedium; }
|
||||
bool isMetered() const { return m_metered; }
|
||||
|
||||
Q_SIGNALS:
|
||||
void reachabilityChanged(Reachability reachability);
|
||||
void behindCaptivePortalChanged(bool behindPortal);
|
||||
void transportMediumChanged(TransportMedium medium);
|
||||
void isMeteredChanged(bool isMetered);
|
||||
|
||||
protected:
|
||||
void setReachability(QNetworkInformation::Reachability reachability)
|
||||
{
|
||||
if (m_reachability != reachability) {
|
||||
m_reachability = reachability;
|
||||
emit reachabilityChanged(reachability);
|
||||
}
|
||||
}
|
||||
|
||||
void setBehindCaptivePortal(bool behindPortal)
|
||||
{
|
||||
if (m_behindCaptivePortal != behindPortal) {
|
||||
m_behindCaptivePortal = behindPortal;
|
||||
emit behindCaptivePortalChanged(behindPortal);
|
||||
}
|
||||
}
|
||||
|
||||
void setTransportMedium(TransportMedium medium)
|
||||
{
|
||||
if (m_transportMedium != medium) {
|
||||
m_transportMedium = medium;
|
||||
emit transportMediumChanged(medium);
|
||||
}
|
||||
}
|
||||
|
||||
void setMetered(bool isMetered)
|
||||
{
|
||||
if (m_metered != isMetered) {
|
||||
m_metered = isMetered;
|
||||
emit isMeteredChanged(isMetered);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Reachability m_reachability = Reachability::Unknown;
|
||||
TransportMedium m_transportMedium = TransportMedium::Unknown;
|
||||
bool m_behindCaptivePortal = false;
|
||||
bool m_metered = false;
|
||||
|
||||
Q_DISABLE_COPY_MOVE(QNetworkInformationBackend)
|
||||
friend class QNetworkInformation;
|
||||
friend class QNetworkInformationPrivate;
|
||||
};
|
||||
|
||||
class Q_NETWORK_EXPORT QNetworkInformationBackendFactory : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using Features = QNetworkInformation::Features;
|
||||
|
||||
public:
|
||||
QNetworkInformationBackendFactory();
|
||||
virtual ~QNetworkInformationBackendFactory();
|
||||
virtual QString name() const = 0;
|
||||
virtual QNetworkInformationBackend *create(Features requiredFeatures) const = 0;
|
||||
virtual Features featuresSupported() const = 0;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(QNetworkInformationBackendFactory)
|
||||
};
|
||||
#define QNetworkInformationBackendFactory_iid "org.qt-project.Qt.NetworkInformationBackendFactory"
|
||||
Q_DECLARE_INTERFACE(QNetworkInformationBackendFactory, QNetworkInformationBackendFactory_iid);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,112 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKINTERFACEPRIVATE_H
|
||||
#define QNETWORKINTERFACEPRIVATE_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/qnetworkinterface.h>
|
||||
#include <QtCore/qatomic.h>
|
||||
#include <QtCore/qdeadlinetimer.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
#include <QtNetwork/qabstractsocket.h>
|
||||
#include <private/qhostaddress_p.h>
|
||||
|
||||
#ifndef QT_NO_NETWORKINTERFACE
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNetworkAddressEntryPrivate
|
||||
{
|
||||
public:
|
||||
QHostAddress address;
|
||||
QHostAddress broadcast;
|
||||
QDeadlineTimer preferredLifetime = QDeadlineTimer::Forever;
|
||||
QDeadlineTimer validityLifetime = QDeadlineTimer::Forever;
|
||||
|
||||
QNetmask netmask;
|
||||
bool lifetimeKnown = false;
|
||||
QNetworkAddressEntry::DnsEligibilityStatus dnsEligibility = QNetworkAddressEntry::DnsEligibilityUnknown;
|
||||
};
|
||||
|
||||
class QNetworkInterfacePrivate: public QSharedData
|
||||
{
|
||||
public:
|
||||
QNetworkInterfacePrivate() : index(0)
|
||||
{ }
|
||||
~QNetworkInterfacePrivate()
|
||||
{ }
|
||||
|
||||
int index; // interface index, if know
|
||||
int mtu = 0;
|
||||
QNetworkInterface::InterfaceFlags flags;
|
||||
QNetworkInterface::InterfaceType type = QNetworkInterface::Unknown;
|
||||
|
||||
QString name;
|
||||
QString friendlyName;
|
||||
QString hardwareAddress;
|
||||
|
||||
QList<QNetworkAddressEntry> addressEntries;
|
||||
|
||||
static QString makeHwAddress(int len, uchar *data);
|
||||
static void calculateDnsEligibility(QNetworkAddressEntry *entry, bool isTemporary,
|
||||
bool isDeprecated)
|
||||
{
|
||||
// this implements an algorithm that yields the same results as Windows
|
||||
// produces, for the same input (as far as I can test)
|
||||
if (isTemporary || isDeprecated) {
|
||||
entry->setDnsEligibility(QNetworkAddressEntry::DnsIneligible);
|
||||
} else {
|
||||
AddressClassification cl = QHostAddressPrivate::classify(entry->ip());
|
||||
if (cl == LoopbackAddress || cl == LinkLocalAddress)
|
||||
entry->setDnsEligibility(QNetworkAddressEntry::DnsIneligible);
|
||||
else
|
||||
entry->setDnsEligibility(QNetworkAddressEntry::DnsEligible);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// disallow copying -- avoid detaching
|
||||
QNetworkInterfacePrivate &operator=(const QNetworkInterfacePrivate &other);
|
||||
QNetworkInterfacePrivate(const QNetworkInterfacePrivate &other);
|
||||
};
|
||||
|
||||
class QNetworkInterfaceManager
|
||||
{
|
||||
public:
|
||||
QNetworkInterfaceManager();
|
||||
~QNetworkInterfaceManager();
|
||||
|
||||
QSharedDataPointer<QNetworkInterfacePrivate> interfaceFromName(const QString &name);
|
||||
QSharedDataPointer<QNetworkInterfacePrivate> interfaceFromIndex(int index);
|
||||
QList<QSharedDataPointer<QNetworkInterfacePrivate> > allInterfaces();
|
||||
|
||||
static uint interfaceIndexFromName(const QString &name);
|
||||
static QString interfaceNameFromIndex(uint index);
|
||||
|
||||
// convenience:
|
||||
QSharedDataPointer<QNetworkInterfacePrivate> empty;
|
||||
|
||||
private:
|
||||
QList<QNetworkInterfacePrivate *> scan();
|
||||
};
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_NETWORKINTERFACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2017 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKINTERFACE_UNIX_P_H
|
||||
#define QNETWORKINTERFACE_UNIX_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qnetworkinterface_p.h"
|
||||
#include "private/qnet_unix_p.h"
|
||||
|
||||
#ifndef QT_NO_NETWORKINTERFACE
|
||||
|
||||
#define IP_MULTICAST // make AIX happy and define IFF_MULTICAST
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef Q_OS_SOLARIS
|
||||
# include <sys/sockio.h>
|
||||
#endif
|
||||
#ifdef Q_OS_HAIKU
|
||||
# include <sys/sockio.h>
|
||||
# define IFF_RUNNING 0x0001
|
||||
#endif
|
||||
#if QT_CONFIG(linux_netlink)
|
||||
// Same as net/if.h but contains other things we need in
|
||||
// qnetworkinterface_linux.cpp.
|
||||
# include <linux/if.h>
|
||||
#else
|
||||
# include <net/if.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static QNetworkInterface::InterfaceFlags convertFlags(uint rawFlags)
|
||||
{
|
||||
QNetworkInterface::InterfaceFlags flags;
|
||||
flags |= (rawFlags & IFF_UP) ? QNetworkInterface::IsUp : QNetworkInterface::InterfaceFlag(0);
|
||||
flags |= (rawFlags & IFF_RUNNING) ? QNetworkInterface::IsRunning : QNetworkInterface::InterfaceFlag(0);
|
||||
flags |= (rawFlags & IFF_BROADCAST) ? QNetworkInterface::CanBroadcast : QNetworkInterface::InterfaceFlag(0);
|
||||
flags |= (rawFlags & IFF_LOOPBACK) ? QNetworkInterface::IsLoopBack : QNetworkInterface::InterfaceFlag(0);
|
||||
#ifdef IFF_POINTOPOINT //cygwin doesn't define IFF_POINTOPOINT
|
||||
flags |= (rawFlags & IFF_POINTOPOINT) ? QNetworkInterface::IsPointToPoint : QNetworkInterface::InterfaceFlag(0);
|
||||
#endif
|
||||
|
||||
#ifdef IFF_MULTICAST
|
||||
flags |= (rawFlags & IFF_MULTICAST) ? QNetworkInterface::CanMulticast : QNetworkInterface::InterfaceFlag(0);
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_NETWORKINTERFACE
|
||||
|
||||
#endif // QNETWORKINTERFACE_UNIX_P_H
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKREPLY_P_H
|
||||
#define QNETWORKREPLY_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qnetworkrequest.h"
|
||||
#include "qnetworkrequest_p.h"
|
||||
#include "qnetworkreply.h"
|
||||
#include "QtCore/qpointer.h"
|
||||
#include <QtCore/QElapsedTimer>
|
||||
#include "private/qiodevice_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNetworkReplyPrivate: public QIODevicePrivate, public QNetworkHeadersPrivate
|
||||
{
|
||||
public:
|
||||
enum State {
|
||||
Idle, // The reply is idle.
|
||||
Buffering, // The reply is buffering outgoing data.
|
||||
Working, // The reply is uploading/downloading data.
|
||||
Finished, // The reply has finished.
|
||||
Aborted, // The reply has been aborted.
|
||||
};
|
||||
|
||||
QNetworkReplyPrivate();
|
||||
QNetworkRequest request;
|
||||
QNetworkRequest originalRequest;
|
||||
QUrl url;
|
||||
QPointer<QNetworkAccessManager> manager;
|
||||
qint64 readBufferMaxSize;
|
||||
QElapsedTimer downloadProgressSignalChoke;
|
||||
QElapsedTimer uploadProgressSignalChoke;
|
||||
bool emitAllUploadProgressSignals;
|
||||
const static int progressSignalInterval;
|
||||
QNetworkAccessManager::Operation operation;
|
||||
QNetworkReply::NetworkError errorCode;
|
||||
bool isFinished;
|
||||
|
||||
static inline void setManager(QNetworkReply *reply, QNetworkAccessManager *manager)
|
||||
{ reply->d_func()->manager = manager; }
|
||||
|
||||
Q_DECLARE_PUBLIC(QNetworkReply)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKREPLYDATAIMPL_H
|
||||
#define QNETWORKREPLYDATAIMPL_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qnetworkreply.h"
|
||||
#include "qnetworkreply_p.h"
|
||||
#include "qnetworkaccessmanager.h"
|
||||
#include <QBuffer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class QNetworkReplyDataImplPrivate;
|
||||
class QNetworkReplyDataImpl: public QNetworkReply
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QNetworkReplyDataImpl(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op);
|
||||
~QNetworkReplyDataImpl();
|
||||
virtual void abort() override;
|
||||
|
||||
// reimplemented from QNetworkReply
|
||||
virtual void close() override;
|
||||
virtual qint64 bytesAvailable() const override;
|
||||
virtual bool isSequential () const override;
|
||||
qint64 size() const override;
|
||||
|
||||
virtual qint64 readData(char *data, qint64 maxlen) override;
|
||||
|
||||
Q_DECLARE_PRIVATE(QNetworkReplyDataImpl)
|
||||
};
|
||||
|
||||
class QNetworkReplyDataImplPrivate: public QNetworkReplyPrivate
|
||||
{
|
||||
public:
|
||||
QNetworkReplyDataImplPrivate();
|
||||
~QNetworkReplyDataImplPrivate();
|
||||
|
||||
QBuffer decodedData;
|
||||
|
||||
Q_DECLARE_PUBLIC(QNetworkReplyDataImpl)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QNETWORKREPLYDATAIMPL_H
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKREPLYFILEIMPL_P_H
|
||||
#define QNETWORKREPLYFILEIMPL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qnetworkreply.h"
|
||||
#include "qnetworkreply_p.h"
|
||||
#include "qnetworkaccessmanager.h"
|
||||
#include <QFile>
|
||||
#include <private/qabstractfileengine_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNetworkReplyFileImplPrivate;
|
||||
class QNetworkReplyFileImpl: public QNetworkReply
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QNetworkReplyFileImpl(QNetworkAccessManager *manager, const QNetworkRequest &req, const QNetworkAccessManager::Operation op);
|
||||
~QNetworkReplyFileImpl();
|
||||
virtual void abort() override;
|
||||
|
||||
// reimplemented from QNetworkReply
|
||||
virtual void close() override;
|
||||
virtual qint64 bytesAvailable() const override;
|
||||
virtual bool isSequential () const override;
|
||||
qint64 size() const override;
|
||||
|
||||
virtual qint64 readData(char *data, qint64 maxlen) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void fileOpenFinished(bool isOpen);
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QNetworkReplyFileImpl)
|
||||
};
|
||||
|
||||
class QNetworkReplyFileImplPrivate: public QNetworkReplyPrivate
|
||||
{
|
||||
public:
|
||||
QNetworkReplyFileImplPrivate();
|
||||
|
||||
QNetworkAccessManagerPrivate *managerPrivate;
|
||||
QPointer<QFile> realFile;
|
||||
|
||||
Q_DECLARE_PUBLIC(QNetworkReplyFileImpl)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
// ### move to qnetworkrequest.h
|
||||
QT_DECL_METATYPE_EXTERN_TAGGED(QNetworkRequest::KnownHeaders,
|
||||
QNetworkRequest__KnownHeaders, Q_NETWORK_EXPORT)
|
||||
|
||||
#endif // QNETWORKREPLYFILEIMPL_P_H
|
||||
@@ -0,0 +1,275 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKREPLYHTTPIMPL_P_H
|
||||
#define QNETWORKREPLYHTTPIMPL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qnetworkrequest.h"
|
||||
#include "qnetworkreply.h"
|
||||
|
||||
#include "QtCore/qpointer.h"
|
||||
#include "QtCore/qdatetime.h"
|
||||
#include "QtCore/qsharedpointer.h"
|
||||
#include "QtCore/qscopedpointer.h"
|
||||
#include "QtCore/qtimer.h"
|
||||
#include "qatomic.h"
|
||||
|
||||
#include <QtNetwork/QNetworkCacheMetaData>
|
||||
#include <private/qhttpnetworkrequest_p.h>
|
||||
#include <private/qnetworkreply_p.h>
|
||||
#include <QtNetwork/QNetworkProxy>
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
#include <QtNetwork/QSslConfiguration>
|
||||
#endif
|
||||
|
||||
Q_MOC_INCLUDE(<QtNetwork/QAuthenticator>)
|
||||
|
||||
#include <private/qdecompresshelper_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_REQUIRE_CONFIG(http);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIODevice;
|
||||
|
||||
class QNetworkReplyHttpImplPrivate;
|
||||
class QNetworkReplyHttpImpl: public QNetworkReply
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QNetworkReplyHttpImpl(QNetworkAccessManager* const, const QNetworkRequest&, QNetworkAccessManager::Operation&, QIODevice* outgoingData);
|
||||
virtual ~QNetworkReplyHttpImpl();
|
||||
|
||||
void close() override;
|
||||
void abort() override;
|
||||
qint64 bytesAvailable() const override;
|
||||
bool isSequential () const override;
|
||||
qint64 size() const override;
|
||||
qint64 readData(char*, qint64) override;
|
||||
void setReadBufferSize(qint64 size) override;
|
||||
bool canReadLine () const override;
|
||||
|
||||
Q_DECLARE_PRIVATE(QNetworkReplyHttpImpl)
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_startOperation())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_cacheLoadReadyRead())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_transferTimedOut())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_finished())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_error(QNetworkReply::NetworkError, const QString &))
|
||||
|
||||
// From reply
|
||||
Q_PRIVATE_SLOT(d_func(), void replyDownloadData(QByteArray))
|
||||
Q_PRIVATE_SLOT(d_func(), void replyFinished())
|
||||
Q_PRIVATE_SLOT(d_func(), void replyDownloadProgressSlot(qint64,qint64))
|
||||
Q_PRIVATE_SLOT(d_func(), void httpAuthenticationRequired(const QHttpNetworkRequest &, QAuthenticator *))
|
||||
Q_PRIVATE_SLOT(d_func(), void httpError(QNetworkReply::NetworkError, const QString &))
|
||||
#ifndef QT_NO_SSL
|
||||
Q_PRIVATE_SLOT(d_func(), void replyEncrypted())
|
||||
Q_PRIVATE_SLOT(d_func(), void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *))
|
||||
Q_PRIVATE_SLOT(d_func(), void replySslConfigurationChanged(const QSslConfiguration&))
|
||||
Q_PRIVATE_SLOT(d_func(), void replyPreSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator *))
|
||||
#endif
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
Q_PRIVATE_SLOT(d_func(), void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth))
|
||||
#endif
|
||||
|
||||
Q_PRIVATE_SLOT(d_func(), void resetUploadDataSlot(bool *r))
|
||||
Q_PRIVATE_SLOT(d_func(), void wantUploadDataSlot(qint64))
|
||||
Q_PRIVATE_SLOT(d_func(), void sentUploadDataSlot(qint64,qint64))
|
||||
Q_PRIVATE_SLOT(d_func(), void uploadByteDeviceReadyReadSlot())
|
||||
Q_PRIVATE_SLOT(d_func(), void emitReplyUploadProgress(qint64, qint64))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_cacheSaveDeviceAboutToClose())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_metaDataChanged())
|
||||
Q_PRIVATE_SLOT(d_func(), void onRedirected(const QUrl &, int, int))
|
||||
Q_PRIVATE_SLOT(d_func(), void followRedirect())
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
protected:
|
||||
void ignoreSslErrors() override;
|
||||
void ignoreSslErrorsImplementation(const QList<QSslError> &errors) override;
|
||||
void setSslConfigurationImplementation(const QSslConfiguration &configuration) override;
|
||||
void sslConfigurationImplementation(QSslConfiguration &configuration) const override;
|
||||
#endif
|
||||
|
||||
signals:
|
||||
// To HTTP thread:
|
||||
void startHttpRequest();
|
||||
void abortHttpRequest();
|
||||
void readBufferSizeChanged(qint64 size);
|
||||
void readBufferFreed(qint64 size);
|
||||
|
||||
void startHttpRequestSynchronously();
|
||||
|
||||
void haveUploadData(const qint64 pos, const QByteArray &dataArray, bool dataAtEnd, qint64 dataSize);
|
||||
};
|
||||
|
||||
class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate
|
||||
{
|
||||
public:
|
||||
|
||||
static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& prio);
|
||||
|
||||
QNetworkReplyHttpImplPrivate();
|
||||
~QNetworkReplyHttpImplPrivate();
|
||||
|
||||
void _q_startOperation();
|
||||
|
||||
void _q_cacheLoadReadyRead();
|
||||
|
||||
void _q_bufferOutgoingData();
|
||||
void _q_bufferOutgoingDataFinished();
|
||||
|
||||
void _q_cacheSaveDeviceAboutToClose();
|
||||
|
||||
void _q_transferTimedOut();
|
||||
void setupTransferTimeout();
|
||||
|
||||
void _q_finished();
|
||||
|
||||
void finished();
|
||||
void error(QNetworkReply::NetworkError code, const QString &errorString);
|
||||
void _q_error(QNetworkReply::NetworkError code, const QString &errorString);
|
||||
void _q_metaDataChanged();
|
||||
|
||||
void checkForRedirect(const int statusCode);
|
||||
|
||||
// incoming from user
|
||||
QNetworkAccessManager *manager;
|
||||
QNetworkAccessManagerPrivate *managerPrivate;
|
||||
QHttpNetworkRequest httpRequest; // There is also a copy in the HTTP thread
|
||||
bool synchronous;
|
||||
|
||||
State state;
|
||||
|
||||
// from http thread
|
||||
int statusCode;
|
||||
QString reasonPhrase;
|
||||
|
||||
// upload
|
||||
QNonContiguousByteDevice* createUploadByteDevice();
|
||||
std::shared_ptr<QNonContiguousByteDevice> uploadByteDevice;
|
||||
qint64 uploadByteDevicePosition;
|
||||
bool uploadDeviceChoking; // if we couldn't readPointer() any data at the moment
|
||||
QIODevice *outgoingData;
|
||||
std::shared_ptr<QRingBuffer> outgoingDataBuffer;
|
||||
void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal); // dup?
|
||||
void onRedirected(const QUrl &redirectUrl, int httpStatus, int maxRedirectsRemainig);
|
||||
void followRedirect();
|
||||
qint64 bytesUploaded;
|
||||
|
||||
|
||||
// cache
|
||||
void createCache();
|
||||
void completeCacheSave();
|
||||
void setCachingEnabled(bool enable);
|
||||
bool isCachingEnabled() const;
|
||||
bool isCachingAllowed() const;
|
||||
void initCacheSaveDevice();
|
||||
QIODevice *cacheLoadDevice;
|
||||
bool loadingFromCache;
|
||||
|
||||
QIODevice *cacheSaveDevice;
|
||||
bool cacheEnabled; // is this for saving?
|
||||
|
||||
|
||||
QUrl urlForLastAuthentication;
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
QNetworkProxy lastProxyAuthentication;
|
||||
#endif
|
||||
|
||||
|
||||
bool canResume() const;
|
||||
void setResumeOffset(quint64 offset);
|
||||
quint64 resumeOffset;
|
||||
|
||||
qint64 bytesDownloaded;
|
||||
qint64 bytesBuffered;
|
||||
// We use this to keep track of whether or not we need to emit readyRead
|
||||
// when we deal with signal compression (delaying emission) + decompressing
|
||||
// data (potentially receiving bytes that don't end up in the final output):
|
||||
qint64 lastReadyReadEmittedSize = 0;
|
||||
|
||||
QTimer *transferTimeout;
|
||||
|
||||
// Only used when the "zero copy" style is used.
|
||||
// Please note that the whole "zero copy" download buffer API is private right now. Do not use it.
|
||||
qint64 downloadBufferReadPosition;
|
||||
qint64 downloadBufferCurrentSize;
|
||||
QSharedPointer<char> downloadBufferPointer;
|
||||
char* downloadZerocopyBuffer;
|
||||
|
||||
// Will be increased by HTTP thread:
|
||||
std::shared_ptr<QAtomicInt> pendingDownloadDataEmissions;
|
||||
std::shared_ptr<QAtomicInt> pendingDownloadProgressEmissions;
|
||||
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
QScopedPointer<QSslConfiguration> sslConfiguration;
|
||||
bool pendingIgnoreAllSslErrors;
|
||||
QList<QSslError> pendingIgnoreSslErrorsList;
|
||||
#endif
|
||||
|
||||
QNetworkRequest redirectRequest;
|
||||
|
||||
QDecompressHelper decompressHelper;
|
||||
|
||||
bool loadFromCacheIfAllowed(QHttpNetworkRequest &httpRequest);
|
||||
void invalidateCache();
|
||||
bool sendCacheContents(const QNetworkCacheMetaData &metaData);
|
||||
QNetworkCacheMetaData fetchCacheMetaData(const QNetworkCacheMetaData &metaData) const;
|
||||
|
||||
|
||||
void postRequest(const QNetworkRequest& newHttpRequest);
|
||||
QNetworkAccessManager::Operation getRedirectOperation(QNetworkAccessManager::Operation currentOp, int httpStatus);
|
||||
QNetworkRequest createRedirectRequest(const QNetworkRequest &originalRequests, const QUrl &url, int maxRedirectsRemainig);
|
||||
bool isHttpRedirectResponse() const;
|
||||
|
||||
public:
|
||||
// From HTTP thread:
|
||||
void replyDownloadData(QByteArray);
|
||||
void replyFinished();
|
||||
void replyDownloadMetaData(const QList<QPair<QByteArray,QByteArray> > &, int, const QString &,
|
||||
bool, QSharedPointer<char>, qint64, qint64, bool, bool);
|
||||
void replyDownloadProgressSlot(qint64,qint64);
|
||||
void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth);
|
||||
void httpError(QNetworkReply::NetworkError error, const QString &errorString);
|
||||
#ifndef QT_NO_SSL
|
||||
void replyEncrypted();
|
||||
void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
|
||||
void replySslConfigurationChanged(const QSslConfiguration &newSslConfiguration);
|
||||
void replyPreSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator *);
|
||||
#endif
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth);
|
||||
#endif
|
||||
|
||||
// From QNonContiguousByteDeviceThreadForwardImpl in HTTP thread:
|
||||
void resetUploadDataSlot(bool *r);
|
||||
void wantUploadDataSlot(qint64);
|
||||
void sentUploadDataSlot(qint64, qint64);
|
||||
|
||||
// From user's QNonContiguousByteDevice
|
||||
void uploadByteDeviceReadyReadSlot();
|
||||
|
||||
Q_DECLARE_PUBLIC(QNetworkReplyHttpImpl)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,160 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKREPLYIMPL_P_H
|
||||
#define QNETWORKREPLYIMPL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qnetworkreply.h"
|
||||
#include "qnetworkreply_p.h"
|
||||
#include "qnetworkaccessmanager.h"
|
||||
#include "qnetworkproxy.h"
|
||||
#include "QtCore/qmap.h"
|
||||
#include "QtCore/qqueue.h"
|
||||
#include "QtCore/qbuffer.h"
|
||||
#include "private/qringbuffer_p.h"
|
||||
#include "private/qbytedata_p.h"
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAbstractNetworkCache;
|
||||
class QNetworkAccessBackend;
|
||||
|
||||
class QNetworkReplyImplPrivate;
|
||||
class QNetworkReplyImpl: public QNetworkReply
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QNetworkReplyImpl(QObject *parent = nullptr);
|
||||
~QNetworkReplyImpl();
|
||||
virtual void abort() override;
|
||||
|
||||
// reimplemented from QNetworkReply / QIODevice
|
||||
virtual void close() override;
|
||||
virtual qint64 bytesAvailable() const override;
|
||||
virtual void setReadBufferSize(qint64 size) override;
|
||||
|
||||
virtual qint64 readData(char *data, qint64 maxlen) override;
|
||||
virtual bool event(QEvent *) override;
|
||||
|
||||
Q_DECLARE_PRIVATE(QNetworkReplyImpl)
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_startOperation())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_copyReadyRead())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_copyReadChannelFinished())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished())
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
protected:
|
||||
void sslConfigurationImplementation(QSslConfiguration &configuration) const override;
|
||||
void setSslConfigurationImplementation(const QSslConfiguration &configuration) override;
|
||||
virtual void ignoreSslErrors() override;
|
||||
virtual void ignoreSslErrorsImplementation(const QList<QSslError> &errors) override;
|
||||
#endif
|
||||
};
|
||||
|
||||
class QNetworkReplyImplPrivate: public QNetworkReplyPrivate
|
||||
{
|
||||
public:
|
||||
enum InternalNotifications {
|
||||
NotifyDownstreamReadyWrite,
|
||||
};
|
||||
|
||||
QNetworkReplyImplPrivate();
|
||||
|
||||
void _q_startOperation();
|
||||
void _q_copyReadyRead();
|
||||
void _q_copyReadChannelFinished();
|
||||
void _q_bufferOutgoingData();
|
||||
void _q_bufferOutgoingDataFinished();
|
||||
|
||||
void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request,
|
||||
QIODevice *outgoingData);
|
||||
|
||||
void pauseNotificationHandling();
|
||||
void resumeNotificationHandling();
|
||||
void backendNotify(InternalNotifications notification);
|
||||
void handleNotifications();
|
||||
void createCache();
|
||||
void completeCacheSave();
|
||||
|
||||
// callbacks from the backend (through the manager):
|
||||
void setCachingEnabled(bool enable);
|
||||
bool isCachingEnabled() const;
|
||||
void consume(qint64 count);
|
||||
void emitUploadProgress(qint64 bytesSent, qint64 bytesTotal);
|
||||
qint64 nextDownstreamBlockSize() const;
|
||||
|
||||
void initCacheSaveDevice();
|
||||
void appendDownstreamDataSignalEmissions();
|
||||
void appendDownstreamData(QByteDataBuffer &data);
|
||||
void appendDownstreamData(QIODevice *data);
|
||||
|
||||
void setDownloadBuffer(QSharedPointer<char> sp, qint64 size);
|
||||
char* getDownloadBuffer(qint64 size);
|
||||
void appendDownstreamDataDownloadBuffer(qint64, qint64);
|
||||
|
||||
void finished();
|
||||
void error(QNetworkReply::NetworkError code, const QString &errorString);
|
||||
void metaDataChanged();
|
||||
void redirectionRequested(const QUrl &target);
|
||||
void encrypted();
|
||||
void sslErrors(const QList<QSslError> &errors);
|
||||
|
||||
void readFromBackend();
|
||||
|
||||
QNetworkAccessBackend *backend;
|
||||
QIODevice *outgoingData;
|
||||
std::shared_ptr<QRingBuffer> outgoingDataBuffer;
|
||||
QIODevice *copyDevice;
|
||||
QAbstractNetworkCache *networkCache() const;
|
||||
|
||||
bool cacheEnabled;
|
||||
QIODevice *cacheSaveDevice;
|
||||
|
||||
std::vector<InternalNotifications> pendingNotifications;
|
||||
bool notificationHandlingPaused;
|
||||
|
||||
QUrl urlForLastAuthentication;
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
QNetworkProxy lastProxyAuthentication;
|
||||
QList<QNetworkProxy> proxyList;
|
||||
#endif
|
||||
|
||||
qint64 bytesDownloaded;
|
||||
qint64 bytesUploaded;
|
||||
|
||||
QString httpReasonPhrase;
|
||||
int httpStatusCode;
|
||||
|
||||
State state;
|
||||
|
||||
// Only used when the "zero copy" style is used.
|
||||
// Please note that the whole "zero copy" download buffer API is private right now. Do not use it.
|
||||
qint64 downloadBufferReadPosition;
|
||||
qint64 downloadBufferCurrentSize;
|
||||
qint64 downloadBufferMaximumSize;
|
||||
QSharedPointer<char> downloadBufferPointer;
|
||||
char* downloadBuffer;
|
||||
|
||||
Q_DECLARE_PUBLIC(QNetworkReplyImpl)
|
||||
};
|
||||
Q_DECLARE_TYPEINFO(QNetworkReplyImplPrivate::InternalNotifications, Q_PRIMITIVE_TYPE);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QNETWORKREQUEST_P_H
|
||||
#define QNETWORKREQUEST_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qnetworkrequest.h"
|
||||
#include "QtCore/qbytearray.h"
|
||||
#include "QtCore/qlist.h"
|
||||
#include "QtCore/qhash.h"
|
||||
#include "QtCore/qshareddata.h"
|
||||
#include "QtCore/qsharedpointer.h"
|
||||
#include "QtCore/qpointer.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// this is the common part between QNetworkRequestPrivate, QNetworkReplyPrivate and QHttpPartPrivate
|
||||
class QNetworkHeadersPrivate
|
||||
{
|
||||
public:
|
||||
typedef QPair<QByteArray, QByteArray> RawHeaderPair;
|
||||
typedef QList<RawHeaderPair> RawHeadersList;
|
||||
typedef QHash<QNetworkRequest::KnownHeaders, QVariant> CookedHeadersMap;
|
||||
typedef QHash<QNetworkRequest::Attribute, QVariant> AttributesMap;
|
||||
|
||||
RawHeadersList rawHeaders;
|
||||
CookedHeadersMap cookedHeaders;
|
||||
AttributesMap attributes;
|
||||
QPointer<QObject> originatingObject;
|
||||
|
||||
RawHeadersList::ConstIterator findRawHeader(const QByteArray &key) const;
|
||||
RawHeadersList allRawHeaders() const;
|
||||
QList<QByteArray> rawHeadersKeys() const;
|
||||
void setRawHeader(const QByteArray &key, const QByteArray &value);
|
||||
void setAllRawHeaders(const RawHeadersList &list);
|
||||
void setCookedHeader(QNetworkRequest::KnownHeaders header, const QVariant &value);
|
||||
|
||||
static QDateTime fromHttpDate(const QByteArray &value);
|
||||
static QByteArray toHttpDate(const QDateTime &dt);
|
||||
|
||||
private:
|
||||
void setRawHeaderInternal(const QByteArray &key, const QByteArray &value);
|
||||
void parseAndSetHeader(const QByteArray &key, const QByteArray &value);
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(QNetworkHeadersPrivate::RawHeaderPair, Q_RELOCATABLE_TYPE);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2019 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QOCSP_P_H
|
||||
#define QOCSP_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
// Note, this file is a workaround: on 64-bit Windows one of OpenSSL
|
||||
// includes combined with openssl/ocsp.h results in macros from
|
||||
// wincrypt.h exposed. OpenSSL's own very "unique" and "inventive"
|
||||
// names like OCSP_RESPONSE or X509_NAME were asking to clash with
|
||||
// other entities (presumably macros) with the same names. Normally,
|
||||
// ossl_typ.h un-defines them, but due to a bug in OpenSSL, fails
|
||||
// to do this on Win 64. Thus we have to do it here. We only undef
|
||||
// 3 names, ossl_typ.h has more, but apparently we don't need them
|
||||
// (no name clash so far).
|
||||
|
||||
QT_REQUIRE_CONFIG(ocsp);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#undef X509_NAME
|
||||
#undef OCSP_REQUEST
|
||||
#undef OCSP_RESPONSE
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
#include <openssl/ocsp.h>
|
||||
|
||||
#endif // QOCSP_P_H
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (C) 2011 Richard J. Moore <rich@kde.org>
|
||||
// Copyright (C) 2019 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QOCSPRESPONSE_P_H
|
||||
#define QOCSPRESPONSE_P_H
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <qsslcertificate.h>
|
||||
#include <qocspresponse.h>
|
||||
|
||||
#include <qshareddata.h>
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QOcspResponsePrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
|
||||
QOcspCertificateStatus certificateStatus = QOcspCertificateStatus::Unknown;
|
||||
QOcspRevocationReason revocationReason = QOcspRevocationReason::None;
|
||||
|
||||
QSslCertificate signerCert;
|
||||
QSslCertificate subjectCert;
|
||||
};
|
||||
|
||||
inline bool operator==(const QOcspResponsePrivate &lhs, const QOcspResponsePrivate &rhs)
|
||||
{
|
||||
return lhs.certificateStatus == rhs.certificateStatus
|
||||
&& lhs.revocationReason == rhs.revocationReason
|
||||
&& lhs.signerCert == rhs.signerCert
|
||||
&& lhs.subjectCert == rhs.subjectCert;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QOCSPRESPONSE_P_H
|
||||
@@ -0,0 +1,260 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QSOCKS5SOCKETENGINE_P_H
|
||||
#define QSOCKS5SOCKETENGINE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qabstractsocketengine_p.h"
|
||||
#include "qnetworkproxy.h"
|
||||
|
||||
QT_REQUIRE_CONFIG(socks5);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSocks5SocketEnginePrivate;
|
||||
|
||||
class Q_AUTOTEST_EXPORT QSocks5SocketEngine : public QAbstractSocketEngine
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QSocks5SocketEngine(QObject *parent = nullptr);
|
||||
~QSocks5SocketEngine();
|
||||
|
||||
bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) override;
|
||||
bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) override;
|
||||
|
||||
void setProxy(const QNetworkProxy &networkProxy);
|
||||
|
||||
qintptr socketDescriptor() const override;
|
||||
|
||||
bool isValid() const override;
|
||||
|
||||
bool connectInternal();
|
||||
bool connectToHost(const QHostAddress &address, quint16 port) override;
|
||||
bool connectToHostByName(const QString &name, quint16 port) override;
|
||||
bool bind(const QHostAddress &address, quint16 port) override;
|
||||
bool listen(int backlog) override;
|
||||
qintptr accept() override;
|
||||
void close() override;
|
||||
|
||||
qint64 bytesAvailable() const override;
|
||||
|
||||
qint64 read(char *data, qint64 maxlen) override;
|
||||
qint64 write(const char *data, qint64 len) override;
|
||||
|
||||
#ifndef QT_NO_UDPSOCKET
|
||||
#ifndef QT_NO_NETWORKINTERFACE
|
||||
bool joinMulticastGroup(const QHostAddress &groupAddress,
|
||||
const QNetworkInterface &interface) override;
|
||||
bool leaveMulticastGroup(const QHostAddress &groupAddress,
|
||||
const QNetworkInterface &interface) override;
|
||||
QNetworkInterface multicastInterface() const override;
|
||||
bool setMulticastInterface(const QNetworkInterface &iface) override;
|
||||
#endif // QT_NO_NETWORKINTERFACE
|
||||
|
||||
bool hasPendingDatagrams() const override;
|
||||
qint64 pendingDatagramSize() const override;
|
||||
#endif // QT_NO_UDPSOCKET
|
||||
|
||||
qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = nullptr,
|
||||
PacketHeaderOptions = WantNone) override;
|
||||
qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) override;
|
||||
qint64 bytesToWrite() const override;
|
||||
|
||||
int option(SocketOption option) const override;
|
||||
bool setOption(SocketOption option, int value) override;
|
||||
|
||||
bool waitForRead(int msecs = 30000, bool *timedOut = nullptr) override;
|
||||
bool waitForWrite(int msecs = 30000, bool *timedOut = nullptr) override;
|
||||
bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
|
||||
bool checkRead, bool checkWrite,
|
||||
int msecs = 30000, bool *timedOut = nullptr) override;
|
||||
|
||||
bool isReadNotificationEnabled() const override;
|
||||
void setReadNotificationEnabled(bool enable) override;
|
||||
bool isWriteNotificationEnabled() const override;
|
||||
void setWriteNotificationEnabled(bool enable) override;
|
||||
bool isExceptionNotificationEnabled() const override;
|
||||
void setExceptionNotificationEnabled(bool enable) override;
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QSocks5SocketEngine)
|
||||
Q_DISABLE_COPY_MOVE(QSocks5SocketEngine)
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_controlSocketConnected())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_controlSocketReadNotification())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_controlSocketErrorOccurred(QAbstractSocket::SocketError))
|
||||
#ifndef QT_NO_UDPSOCKET
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_udpSocketReadNotification())
|
||||
#endif
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_controlSocketBytesWritten())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_emitPendingReadNotification())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_emitPendingWriteNotification())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_emitPendingConnectionNotification())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_controlSocketDisconnected())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_controlSocketStateChanged(QAbstractSocket::SocketState))
|
||||
|
||||
};
|
||||
|
||||
|
||||
class QTcpSocket;
|
||||
|
||||
class QSocks5Authenticator
|
||||
{
|
||||
public:
|
||||
QSocks5Authenticator();
|
||||
virtual ~QSocks5Authenticator();
|
||||
virtual char methodId();
|
||||
virtual bool beginAuthenticate(QTcpSocket *socket, bool *completed);
|
||||
virtual bool continueAuthenticate(QTcpSocket *socket, bool *completed);
|
||||
|
||||
bool seal(const QByteArray &buf, QByteArray *sealedBuf);
|
||||
bool unSeal(const QByteArray &sealedBuf, QByteArray *buf);
|
||||
bool unSeal(QTcpSocket *sealedSocket, QByteArray *buf);
|
||||
|
||||
virtual QString errorString() { return QString(); }
|
||||
};
|
||||
|
||||
class QSocks5PasswordAuthenticator : public QSocks5Authenticator
|
||||
{
|
||||
public:
|
||||
QSocks5PasswordAuthenticator(const QString &userName, const QString &password);
|
||||
char methodId() override;
|
||||
bool beginAuthenticate(QTcpSocket *socket, bool *completed) override;
|
||||
bool continueAuthenticate(QTcpSocket *socket, bool *completed) override;
|
||||
|
||||
QString errorString() override;
|
||||
|
||||
private:
|
||||
QString userName;
|
||||
QString password;
|
||||
};
|
||||
|
||||
struct QSocks5Data;
|
||||
struct QSocks5ConnectData;
|
||||
struct QSocks5UdpAssociateData;
|
||||
struct QSocks5BindData;
|
||||
|
||||
class QSocks5SocketEnginePrivate : public QAbstractSocketEnginePrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QSocks5SocketEngine)
|
||||
public:
|
||||
QSocks5SocketEnginePrivate();
|
||||
~QSocks5SocketEnginePrivate();
|
||||
|
||||
enum Socks5State
|
||||
{
|
||||
Uninitialized = 0,
|
||||
ConnectError,
|
||||
AuthenticationMethodsSent,
|
||||
Authenticating,
|
||||
AuthenticatingError,
|
||||
RequestMethodSent,
|
||||
RequestError,
|
||||
Connected,
|
||||
UdpAssociateSuccess,
|
||||
BindSuccess,
|
||||
ControlSocketError,
|
||||
SocksError,
|
||||
HostNameLookupError
|
||||
};
|
||||
Socks5State socks5State;
|
||||
|
||||
enum Socks5Mode
|
||||
{
|
||||
NoMode,
|
||||
ConnectMode,
|
||||
BindMode,
|
||||
UdpAssociateMode
|
||||
};
|
||||
Socks5Mode mode;
|
||||
|
||||
enum Socks5Error
|
||||
{
|
||||
SocksFailure = 0x01,
|
||||
ConnectionNotAllowed = 0x02,
|
||||
NetworkUnreachable = 0x03,
|
||||
HostUnreachable = 0x04,
|
||||
ConnectionRefused = 0x05,
|
||||
TTLExpired = 0x06,
|
||||
CommandNotSupported = 0x07,
|
||||
AddressTypeNotSupported = 0x08,
|
||||
LastKnownError = AddressTypeNotSupported,
|
||||
UnknownError
|
||||
};
|
||||
|
||||
void initialize(Socks5Mode socks5Mode);
|
||||
|
||||
void setErrorState(Socks5State state, const QString &extraMessage = QString());
|
||||
void setErrorState(Socks5State state, Socks5Error socks5error);
|
||||
|
||||
void reauthenticate();
|
||||
void parseAuthenticationMethodReply();
|
||||
void parseAuthenticatingReply();
|
||||
void sendRequestMethod();
|
||||
void parseRequestMethodReply();
|
||||
void parseNewConnection();
|
||||
|
||||
bool waitForConnected(int msecs, bool *timedOut);
|
||||
|
||||
void _q_controlSocketConnected();
|
||||
void _q_controlSocketReadNotification();
|
||||
void _q_controlSocketErrorOccurred(QAbstractSocket::SocketError);
|
||||
#ifndef QT_NO_UDPSOCKET
|
||||
void _q_udpSocketReadNotification();
|
||||
#endif
|
||||
void _q_controlSocketBytesWritten();
|
||||
void _q_controlSocketDisconnected();
|
||||
void _q_controlSocketStateChanged(QAbstractSocket::SocketState);
|
||||
|
||||
QNetworkProxy proxyInfo;
|
||||
|
||||
bool readNotificationEnabled, writeNotificationEnabled, exceptNotificationEnabled;
|
||||
|
||||
qintptr socketDescriptor;
|
||||
|
||||
QSocks5Data *data;
|
||||
QSocks5ConnectData *connectData;
|
||||
#ifndef QT_NO_UDPSOCKET
|
||||
QSocks5UdpAssociateData *udpData;
|
||||
#endif
|
||||
QSocks5BindData *bindData;
|
||||
QString peerName;
|
||||
QByteArray receivedHeaderFragment;
|
||||
|
||||
mutable bool readNotificationActivated;
|
||||
mutable bool writeNotificationActivated;
|
||||
|
||||
bool readNotificationPending;
|
||||
void _q_emitPendingReadNotification();
|
||||
void emitReadNotification();
|
||||
bool writeNotificationPending;
|
||||
void _q_emitPendingWriteNotification();
|
||||
void emitWriteNotification();
|
||||
bool connectionNotificationPending;
|
||||
void _q_emitPendingConnectionNotification();
|
||||
void emitConnectionNotification();
|
||||
};
|
||||
|
||||
class Q_AUTOTEST_EXPORT QSocks5SocketEngineHandler : public QSocketEngineHandler
|
||||
{
|
||||
public:
|
||||
virtual QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType,
|
||||
const QNetworkProxy &, QObject *parent) override;
|
||||
virtual QAbstractSocketEngine *createSocketEngine(qintptr socketDescriptor, QObject *parent) override;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSOCKS5SOCKETENGINE_H
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
|
||||
#ifndef QSSL_P_H
|
||||
#define QSSL_P_H
|
||||
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of qsslcertificate.cpp. This header file may change from version to version
|
||||
// without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QtCore/QLoggingCategory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcSsl)
|
||||
|
||||
namespace QTlsPrivate {
|
||||
|
||||
enum class Cipher {
|
||||
DesCbc,
|
||||
DesEde3Cbc,
|
||||
Rc2Cbc,
|
||||
Aes128Cbc,
|
||||
Aes192Cbc,
|
||||
Aes256Cbc
|
||||
};
|
||||
|
||||
} // namespace QTlsPrivate
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSSL_P_H
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
|
||||
#ifndef QSSLCERTIFICATE_P_H
|
||||
#define QSSLCERTIFICATE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qsslcertificateextension.h"
|
||||
#include "qsslcertificate.h"
|
||||
#include "qtlsbackend_p.h"
|
||||
|
||||
#include <qlist.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSslCertificatePrivate
|
||||
{
|
||||
public:
|
||||
QSslCertificatePrivate();
|
||||
~QSslCertificatePrivate();
|
||||
|
||||
QList<QSslCertificateExtension> extensions() const;
|
||||
Q_NETWORK_PRIVATE_EXPORT static bool isBlacklisted(const QSslCertificate &certificate);
|
||||
Q_NETWORK_PRIVATE_EXPORT static QByteArray subjectInfoToString(QSslCertificate::SubjectInfo info);
|
||||
|
||||
QAtomicInt ref;
|
||||
std::unique_ptr<QTlsPrivate::X509Certificate> backend;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSSLCERTIFICATE_P_H
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2011 Richard J. Moore <rich@kde.org>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QSSLCERTIFICATEEXTENSION_P_H
|
||||
#define QSSLCERTIFICATEEXTENSION_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qsslcertificateextension.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSslCertificateExtensionPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
inline QSslCertificateExtensionPrivate()
|
||||
: critical(false),
|
||||
supported(false)
|
||||
{
|
||||
}
|
||||
|
||||
QString oid;
|
||||
QString name;
|
||||
QVariant value;
|
||||
bool critical;
|
||||
bool supported;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSSLCERTIFICATEEXTENSION_P_H
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QSSLCIPHER_P_H
|
||||
#define QSSLCIPHER_P_H
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qsslcipher.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the QLibrary class. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
class QSslCipherPrivate
|
||||
{
|
||||
public:
|
||||
QSslCipherPrivate()
|
||||
: isNull(true), supportedBits(0), bits(0),
|
||||
exportable(false), protocol(QSsl::UnknownProtocol)
|
||||
{
|
||||
}
|
||||
|
||||
bool isNull;
|
||||
QString name;
|
||||
int supportedBits;
|
||||
int bits;
|
||||
QString keyExchangeMethod;
|
||||
QString authenticationMethod;
|
||||
QString encryptionMethod;
|
||||
bool exportable;
|
||||
QString protocolString;
|
||||
QSsl::SslProtocol protocol;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSSLCIPHER_P_H
|
||||
@@ -0,0 +1,141 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// Copyright (C) 2014 BlackBerry Limited. All rights reserved.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** In addition, as a special exception, the copyright holders listed above give
|
||||
** permission to link the code of its release of Qt with the OpenSSL project's
|
||||
** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the
|
||||
** same license as the original version), and distribute the linked executables.
|
||||
**
|
||||
** You must comply with the GNU General Public License version 2 in all
|
||||
** respects for all of the code used other than the "OpenSSL" code. If you
|
||||
** modify this file, you may extend this exception to your version of the file,
|
||||
** but you are not obligated to do so. If you do not wish to do so, delete
|
||||
** this exception statement from your version of this file.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSSLCONFIGURATION_P_H
|
||||
#define QSSLCONFIGURATION_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the QSslSocket API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "qsslconfiguration.h"
|
||||
#include "qlist.h"
|
||||
#include "qsslcertificate.h"
|
||||
#include "qsslcipher.h"
|
||||
#include "qsslkey.h"
|
||||
#include "qsslellipticcurve.h"
|
||||
#include "qssldiffiehellmanparameters.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSslConfigurationPrivate: public QSharedData
|
||||
{
|
||||
public:
|
||||
QSslConfigurationPrivate()
|
||||
: sessionProtocol(QSsl::UnknownProtocol),
|
||||
protocol(QSsl::SecureProtocols),
|
||||
peerVerifyMode(QSslSocket::AutoVerifyPeer),
|
||||
peerVerifyDepth(0),
|
||||
allowRootCertOnDemandLoading(true),
|
||||
peerSessionShared(false),
|
||||
sslOptions(QSslConfigurationPrivate::defaultSslOptions),
|
||||
dhParams(QSslDiffieHellmanParameters::defaultParameters()),
|
||||
sslSessionTicketLifeTimeHint(-1),
|
||||
ephemeralServerKey(),
|
||||
preSharedKeyIdentityHint(),
|
||||
nextProtocolNegotiationStatus(QSslConfiguration::NextProtocolNegotiationNone)
|
||||
{ }
|
||||
|
||||
QSslCertificate peerCertificate;
|
||||
QList<QSslCertificate> peerCertificateChain;
|
||||
|
||||
QList<QSslCertificate> localCertificateChain;
|
||||
|
||||
QSslKey privateKey;
|
||||
QSslCipher sessionCipher;
|
||||
QSsl::SslProtocol sessionProtocol;
|
||||
QList<QSslCipher> ciphers;
|
||||
QList<QSslCertificate> caCertificates;
|
||||
|
||||
QSsl::SslProtocol protocol;
|
||||
QSslSocket::PeerVerifyMode peerVerifyMode;
|
||||
int peerVerifyDepth;
|
||||
bool allowRootCertOnDemandLoading;
|
||||
bool peerSessionShared;
|
||||
|
||||
Q_AUTOTEST_EXPORT static bool peerSessionWasShared(const QSslConfiguration &configuration);
|
||||
|
||||
QSsl::SslOptions sslOptions;
|
||||
|
||||
static const QSsl::SslOptions defaultSslOptions;
|
||||
|
||||
QList<QSslEllipticCurve> ellipticCurves;
|
||||
|
||||
QSslDiffieHellmanParameters dhParams;
|
||||
|
||||
QMap<QByteArray, QVariant> backendConfig;
|
||||
|
||||
QByteArray sslSession;
|
||||
int sslSessionTicketLifeTimeHint;
|
||||
|
||||
QSslKey ephemeralServerKey;
|
||||
|
||||
QByteArray preSharedKeyIdentityHint;
|
||||
|
||||
QList<QByteArray> nextAllowedProtocols;
|
||||
QByteArray nextNegotiatedProtocol;
|
||||
QSslConfiguration::NextProtocolNegotiationStatus nextProtocolNegotiationStatus;
|
||||
|
||||
#if QT_CONFIG(dtls)
|
||||
bool dtlsCookieEnabled = true;
|
||||
#else
|
||||
const bool dtlsCookieEnabled = false;
|
||||
#endif // dtls
|
||||
|
||||
#if QT_CONFIG(ocsp)
|
||||
bool ocspStaplingEnabled = false;
|
||||
#else
|
||||
const bool ocspStaplingEnabled = false;
|
||||
#endif
|
||||
|
||||
#if QT_CONFIG(openssl)
|
||||
bool reportFromCallback = false;
|
||||
bool missingCertIsFatal = false;
|
||||
#else
|
||||
const bool reportFromCallback = false;
|
||||
const bool missingCertIsFatal = false;
|
||||
#endif // openssl
|
||||
|
||||
// in qsslsocket.cpp:
|
||||
static QSslConfiguration defaultConfiguration();
|
||||
static void setDefaultConfiguration(const QSslConfiguration &configuration);
|
||||
static void deepCopyDefaultConfiguration(QSslConfigurationPrivate *config);
|
||||
|
||||
static QSslConfiguration defaultDtlsConfiguration();
|
||||
static void setDefaultDtlsConfiguration(const QSslConfiguration &configuration);
|
||||
};
|
||||
|
||||
// implemented here for inlining purposes
|
||||
inline QSslConfiguration::QSslConfiguration(QSslConfigurationPrivate *dd)
|
||||
: d(dd)
|
||||
{
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2015 Mikkel Krautz <mikkel@krautz.dk>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
|
||||
#ifndef QSSLDIFFIEHELLMANPARAMETERS_P_H
|
||||
#define QSSLDIFFIEHELLMANPARAMETERS_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of qssldiffiehellmanparameters.cpp. This header file may change from version to version
|
||||
// without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qssldiffiehellmanparameters.h"
|
||||
|
||||
#include <QSharedData>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSslDiffieHellmanParametersPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
void initFromDer(const QByteArray &der);
|
||||
void initFromPem(const QByteArray &pem);
|
||||
|
||||
QSslDiffieHellmanParameters::Error error = QSslDiffieHellmanParameters::NoError;
|
||||
QByteArray derData;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSSLDIFFIEHELLMANPARAMETERS_P_H
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
|
||||
#ifndef QSSLKEY_OPENSSL_P_H
|
||||
#define QSSLKEY_OPENSSL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of qsslcertificate.cpp. This header file may change from version to version
|
||||
// without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qsslkey.h"
|
||||
#include "qssl_p.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QTlsPrivate {
|
||||
class TlsKey;
|
||||
}
|
||||
|
||||
class QSslKeyPrivate
|
||||
{
|
||||
public:
|
||||
QSslKeyPrivate();
|
||||
~QSslKeyPrivate();
|
||||
|
||||
using Cipher = QTlsPrivate::Cipher;
|
||||
|
||||
Q_NETWORK_EXPORT static QByteArray decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv);
|
||||
Q_NETWORK_EXPORT static QByteArray encrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv);
|
||||
|
||||
std::unique_ptr<QTlsPrivate::TlsKey> backend;
|
||||
QAtomicInt ref;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(QSslKeyPrivate)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSSLKEY_OPENSSL_P_H
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2014 Governikus GmbH & Co. KG.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QSSLPRESHAREDKEYAUTHENTICATOR_P_H
|
||||
#define QSSLPRESHAREDKEYAUTHENTICATOR_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QSharedData>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSslPreSharedKeyAuthenticatorPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
QSslPreSharedKeyAuthenticatorPrivate();
|
||||
|
||||
QByteArray identityHint;
|
||||
|
||||
QByteArray identity;
|
||||
int maximumIdentityLength;
|
||||
|
||||
QByteArray preSharedKey;
|
||||
int maximumPreSharedKeyLength;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSSLPRESHAREDKEYAUTHENTICATOR_P_H
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Kurt Pattyn <pattyn.kurt@gmail.com>.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QSSLSERVER_P_H
|
||||
#define QSSLSERVER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/qtimer.h>
|
||||
|
||||
#include <QtNetwork/QSslConfiguration>
|
||||
#include <QtNetwork/private/qtcpserver_p.h>
|
||||
#include <utility>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_NETWORK_EXPORT QSslServerPrivate : public QTcpServerPrivate
|
||||
{
|
||||
static constexpr int DefaultHandshakeTimeout = 5'000; // 5 seconds
|
||||
public:
|
||||
Q_DECLARE_PUBLIC(QSslServer)
|
||||
|
||||
QSslServerPrivate();
|
||||
void checkClientHelloAndContinue();
|
||||
void initializeHandshakeProcess(QSslSocket *socket);
|
||||
void removeSocketData(quintptr socket);
|
||||
void handleHandshakeTimedOut(QSslSocket *socket);
|
||||
int totalPendingConnections() const override;
|
||||
|
||||
struct SocketData {
|
||||
QMetaObject::Connection readyReadConnection;
|
||||
QMetaObject::Connection destroyedConnection;
|
||||
std::shared_ptr<QTimer> timeoutTimer; // shared_ptr because QHash demands copying
|
||||
|
||||
SocketData(QMetaObject::Connection readyRead, QMetaObject::Connection destroyed,
|
||||
std::shared_ptr<QTimer> &&timer)
|
||||
: readyReadConnection(readyRead),
|
||||
destroyedConnection(destroyed),
|
||||
timeoutTimer(std::move(timer))
|
||||
{
|
||||
}
|
||||
|
||||
void disconnectSignals()
|
||||
{
|
||||
QObject::disconnect(std::exchange(readyReadConnection, {}));
|
||||
QObject::disconnect(std::exchange(destroyedConnection, {}));
|
||||
}
|
||||
};
|
||||
QHash<quintptr, SocketData> socketData;
|
||||
|
||||
QSslConfiguration sslConfiguration;
|
||||
int handshakeTimeout = DefaultHandshakeTimeout;
|
||||
};
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSSLSERVER_P_H
|
||||
@@ -0,0 +1,169 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
|
||||
#ifndef QSSLSOCKET_P_H
|
||||
#define QSSLSOCKET_P_H
|
||||
|
||||
#include "qsslsocket.h"
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <private/qtcpsocket_p.h>
|
||||
|
||||
#include "qocspresponse.h"
|
||||
#include "qsslconfiguration_p.h"
|
||||
#include "qsslkey.h"
|
||||
#include "qtlsbackend_p.h"
|
||||
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSslContext;
|
||||
class QTlsBackend;
|
||||
|
||||
class Q_NETWORK_EXPORT QSslSocketPrivate : public QTcpSocketPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QSslSocket)
|
||||
public:
|
||||
QSslSocketPrivate();
|
||||
virtual ~QSslSocketPrivate();
|
||||
|
||||
void init();
|
||||
bool verifyProtocolSupported(const char *where);
|
||||
bool initialized;
|
||||
|
||||
QSslSocket::SslMode mode;
|
||||
bool autoStartHandshake;
|
||||
bool connectionEncrypted;
|
||||
bool ignoreAllSslErrors;
|
||||
QList<QSslError> ignoreErrorsList;
|
||||
bool* readyReadEmittedPointer;
|
||||
|
||||
QSslConfigurationPrivate configuration;
|
||||
|
||||
// if set, this hostname is used for certificate validation instead of the hostname
|
||||
// that was used for connecting to.
|
||||
QString verificationPeerName;
|
||||
|
||||
bool allowRootCertOnDemandLoading;
|
||||
|
||||
static bool s_loadRootCertsOnDemand;
|
||||
|
||||
static bool supportsSsl();
|
||||
static void ensureInitialized();
|
||||
|
||||
static QList<QSslCipher> defaultCiphers();
|
||||
static QList<QSslCipher> defaultDtlsCiphers();
|
||||
static QList<QSslCipher> supportedCiphers();
|
||||
static void setDefaultCiphers(const QList<QSslCipher> &ciphers);
|
||||
static void setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers);
|
||||
static void setDefaultSupportedCiphers(const QList<QSslCipher> &ciphers);
|
||||
|
||||
static QList<QSslEllipticCurve> supportedEllipticCurves();
|
||||
static void setDefaultSupportedEllipticCurves(const QList<QSslEllipticCurve> &curves);
|
||||
static void resetDefaultEllipticCurves();
|
||||
|
||||
static QList<QSslCertificate> defaultCaCertificates();
|
||||
static QList<QSslCertificate> systemCaCertificates();
|
||||
static void setDefaultCaCertificates(const QList<QSslCertificate> &certs);
|
||||
static void addDefaultCaCertificate(const QSslCertificate &cert);
|
||||
static void addDefaultCaCertificates(const QList<QSslCertificate> &certs);
|
||||
static bool isMatchingHostname(const QSslCertificate &cert, const QString &peerName);
|
||||
static bool isMatchingHostname(const QString &cn, const QString &hostname);
|
||||
|
||||
// The socket itself, including private slots.
|
||||
QTcpSocket *plainSocket = nullptr;
|
||||
void createPlainSocket(QIODevice::OpenMode openMode);
|
||||
static void pauseSocketNotifiers(QSslSocket*);
|
||||
static void resumeSocketNotifiers(QSslSocket*);
|
||||
// ### The 2 methods below should be made member methods once the QSslContext class is made public
|
||||
static void checkSettingSslContext(QSslSocket*, std::shared_ptr<QSslContext>);
|
||||
static std::shared_ptr<QSslContext> sslContext(QSslSocket *socket);
|
||||
bool isPaused() const;
|
||||
void setPaused(bool p);
|
||||
bool bind(const QHostAddress &address, quint16, QAbstractSocket::BindMode) override;
|
||||
void _q_connectedSlot();
|
||||
void _q_hostFoundSlot();
|
||||
void _q_disconnectedSlot();
|
||||
void _q_stateChangedSlot(QAbstractSocket::SocketState);
|
||||
void _q_errorSlot(QAbstractSocket::SocketError);
|
||||
void _q_readyReadSlot();
|
||||
void _q_channelReadyReadSlot(int);
|
||||
void _q_bytesWrittenSlot(qint64);
|
||||
void _q_channelBytesWrittenSlot(int, qint64);
|
||||
void _q_readChannelFinishedSlot();
|
||||
void _q_flushWriteBuffer();
|
||||
void _q_flushReadBuffer();
|
||||
void _q_resumeImplementation();
|
||||
|
||||
static QList<QByteArray> unixRootCertDirectories(); // used also by QSslContext
|
||||
|
||||
qint64 peek(char *data, qint64 maxSize) override;
|
||||
QByteArray peek(qint64 maxSize) override;
|
||||
bool flush() override;
|
||||
|
||||
void startClientEncryption();
|
||||
void startServerEncryption();
|
||||
void transmit();
|
||||
void disconnectFromHost();
|
||||
void disconnected();
|
||||
QSslCipher sessionCipher() const;
|
||||
QSsl::SslProtocol sessionProtocol() const;
|
||||
void continueHandshake();
|
||||
|
||||
static bool rootCertOnDemandLoadingSupported();
|
||||
static void setRootCertOnDemandLoadingSupported(bool supported);
|
||||
|
||||
static QTlsBackend *tlsBackendInUse();
|
||||
|
||||
// Needed by TlsCryptograph:
|
||||
QSslSocket::SslMode tlsMode() const;
|
||||
bool isRootsOnDemandAllowed() const;
|
||||
QString verificationName() const;
|
||||
QString tlsHostName() const;
|
||||
QTcpSocket *plainTcpSocket() const;
|
||||
bool verifyErrorsHaveBeenIgnored();
|
||||
bool isAutoStartingHandshake() const;
|
||||
bool isPendingClose() const;
|
||||
void setPendingClose(bool pc);
|
||||
qint64 maxReadBufferSize() const;
|
||||
void setMaxReadBufferSize(qint64 maxSize);
|
||||
void setEncrypted(bool enc);
|
||||
QRingBufferRef &tlsWriteBuffer();
|
||||
QRingBufferRef &tlsBuffer();
|
||||
bool &tlsEmittedBytesWritten();
|
||||
bool *readyReadPointer();
|
||||
|
||||
protected:
|
||||
|
||||
bool hasUndecryptedData() const;
|
||||
bool paused;
|
||||
bool flushTriggered;
|
||||
|
||||
static inline QMutex backendMutex;
|
||||
static inline QString activeBackendName;
|
||||
static inline QTlsBackend *tlsBackend = nullptr;
|
||||
|
||||
std::unique_ptr<QTlsPrivate::TlsCryptograph> backend;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Alex Trotsenko <alex1973tr@gmail.com>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QTCPSERVER_P_H
|
||||
#define QTCPSERVER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "QtNetwork/qtcpserver.h"
|
||||
#include "private/qobject_p.h"
|
||||
#include "private/qabstractsocketengine_p.h"
|
||||
#include "QtNetwork/qabstractsocket.h"
|
||||
#include "qnetworkproxy.h"
|
||||
#include "QtCore/qlist.h"
|
||||
#include "qhostaddress.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_NETWORK_EXPORT QTcpServerPrivate : public QObjectPrivate,
|
||||
public QAbstractSocketEngineReceiver
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QTcpServer)
|
||||
public:
|
||||
QTcpServerPrivate();
|
||||
~QTcpServerPrivate();
|
||||
|
||||
QList<QTcpSocket *> pendingConnections;
|
||||
|
||||
quint16 port;
|
||||
QHostAddress address;
|
||||
|
||||
QAbstractSocket::SocketType socketType;
|
||||
QAbstractSocket::SocketState state;
|
||||
QAbstractSocketEngine *socketEngine;
|
||||
|
||||
QAbstractSocket::SocketError serverSocketError;
|
||||
QString serverSocketErrorString;
|
||||
|
||||
int listenBacklog = 50;
|
||||
int maxConnections;
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
QNetworkProxy proxy;
|
||||
QNetworkProxy resolveProxy(const QHostAddress &address, quint16 port);
|
||||
#endif
|
||||
|
||||
virtual void configureCreatedSocket();
|
||||
virtual int totalPendingConnections() const;
|
||||
|
||||
// from QAbstractSocketEngineReceiver
|
||||
void readNotification() override;
|
||||
void closeNotification() override { readNotification(); }
|
||||
void writeNotification() override {}
|
||||
void exceptionNotification() override {}
|
||||
void connectionNotification() override {}
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *) override {}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QTCPSERVER_P_H
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QTCPSOCKET_P_H
|
||||
#define QTCPSOCKET_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/qtcpsocket.h>
|
||||
#include <private/qabstractsocket_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTcpSocketPrivate : public QAbstractSocketPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QTcpSocket)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QTLDURL_P_H
|
||||
#define QTLDURL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of qDecodeDataUrl. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include "QtCore/qstring.h"
|
||||
|
||||
QT_REQUIRE_CONFIG(topleveldomain);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_NETWORK_EXPORT bool qIsEffectiveTLD(QStringView domain);
|
||||
inline bool qIsEffectiveTLD(const QString &domain)
|
||||
{
|
||||
return qIsEffectiveTLD(qToStringViewIgnoringNull(domain));
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QTLDURL_P_H
|
||||
@@ -0,0 +1,400 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QTLSBACKEND_P_H
|
||||
#define QTLSBACKEND_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qsslconfiguration.h"
|
||||
#include "qsslerror.h"
|
||||
#include "qssl_p.h"
|
||||
|
||||
#if QT_CONFIG(dtls)
|
||||
#include "qdtls.h"
|
||||
#endif
|
||||
|
||||
#include <QtNetwork/qsslcertificate.h>
|
||||
#include <QtNetwork/qsslcipher.h>
|
||||
#include <QtNetwork/qsslkey.h>
|
||||
#include <QtNetwork/qssl.h>
|
||||
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtCore/qsharedpointer.h>
|
||||
#include <QtCore/qnamespace.h>
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qmap.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSslPreSharedKeyAuthenticator;
|
||||
class QSslSocketPrivate;
|
||||
class QHostAddress;
|
||||
class QSslContext;
|
||||
|
||||
class QSslSocket;
|
||||
class QByteArray;
|
||||
class QSslCipher;
|
||||
class QUdpSocket;
|
||||
class QIODevice;
|
||||
class QSslError;
|
||||
class QSslKey;
|
||||
|
||||
namespace QTlsPrivate {
|
||||
|
||||
class Q_NETWORK_PRIVATE_EXPORT TlsKey {
|
||||
public:
|
||||
virtual ~TlsKey();
|
||||
|
||||
using KeyType = QSsl::KeyType;
|
||||
using KeyAlgorithm = QSsl::KeyAlgorithm;
|
||||
|
||||
virtual void decodeDer(KeyType type, KeyAlgorithm algorithm, const QByteArray &der,
|
||||
const QByteArray &passPhrase, bool deepClear) = 0;
|
||||
virtual void decodePem(KeyType type, KeyAlgorithm algorithm, const QByteArray &pem,
|
||||
const QByteArray &passPhrase, bool deepClear) = 0;
|
||||
|
||||
virtual QByteArray toPem(const QByteArray &passPhrase) const = 0;
|
||||
virtual QByteArray derFromPem(const QByteArray &pem, QMap<QByteArray, QByteArray> *headers) const = 0;
|
||||
virtual QByteArray pemFromDer(const QByteArray &der, const QMap<QByteArray, QByteArray> &headers) const = 0;
|
||||
|
||||
virtual void fromHandle(Qt::HANDLE handle, KeyType type) = 0;
|
||||
virtual Qt::HANDLE handle() const = 0;
|
||||
|
||||
virtual bool isNull() const = 0;
|
||||
virtual KeyType type() const = 0;
|
||||
virtual KeyAlgorithm algorithm() const = 0;
|
||||
virtual int length() const = 0;
|
||||
|
||||
virtual void clear(bool deepClear) = 0;
|
||||
|
||||
virtual bool isPkcs8() const = 0;
|
||||
|
||||
virtual QByteArray decrypt(Cipher cipher, const QByteArray &data,
|
||||
const QByteArray &passPhrase, const QByteArray &iv) const = 0;
|
||||
virtual QByteArray encrypt(Cipher cipher, const QByteArray &data,
|
||||
const QByteArray &key, const QByteArray &iv) const = 0;
|
||||
|
||||
QByteArray pemHeader() const;
|
||||
QByteArray pemFooter() const;
|
||||
};
|
||||
|
||||
class Q_NETWORK_PRIVATE_EXPORT X509Certificate
|
||||
{
|
||||
public:
|
||||
virtual ~X509Certificate();
|
||||
|
||||
virtual bool isEqual(const X509Certificate &other) const = 0;
|
||||
virtual bool isNull() const = 0;
|
||||
virtual bool isSelfSigned() const = 0;
|
||||
virtual QByteArray version() const = 0;
|
||||
virtual QByteArray serialNumber() const = 0;
|
||||
virtual QStringList issuerInfo(QSslCertificate::SubjectInfo subject) const = 0;
|
||||
virtual QStringList issuerInfo(const QByteArray &attribute) const = 0;
|
||||
virtual QStringList subjectInfo(QSslCertificate::SubjectInfo subject) const = 0;
|
||||
virtual QStringList subjectInfo(const QByteArray &attribute) const = 0;
|
||||
|
||||
virtual QList<QByteArray> subjectInfoAttributes() const = 0;
|
||||
virtual QList<QByteArray> issuerInfoAttributes() const = 0;
|
||||
virtual QMultiMap<QSsl::AlternativeNameEntryType, QString> subjectAlternativeNames() const = 0;
|
||||
virtual QDateTime effectiveDate() const = 0;
|
||||
virtual QDateTime expiryDate() const = 0;
|
||||
|
||||
virtual TlsKey *publicKey() const;
|
||||
|
||||
// Extensions. Plugins do not expose internal representation
|
||||
// and cannot rely on QSslCertificate's internals. Thus,
|
||||
// we provide this information 'in pieces':
|
||||
virtual qsizetype numberOfExtensions() const = 0;
|
||||
virtual QString oidForExtension(qsizetype i) const = 0;
|
||||
virtual QString nameForExtension(qsizetype i) const = 0;
|
||||
virtual QVariant valueForExtension(qsizetype i) const = 0;
|
||||
virtual bool isExtensionCritical(qsizetype i) const = 0;
|
||||
virtual bool isExtensionSupported(qsizetype i) const = 0;
|
||||
|
||||
virtual QByteArray toPem() const = 0;
|
||||
virtual QByteArray toDer() const = 0;
|
||||
virtual QString toText() const = 0;
|
||||
|
||||
virtual Qt::HANDLE handle() const = 0;
|
||||
|
||||
virtual size_t hash(size_t seed) const noexcept = 0;
|
||||
};
|
||||
|
||||
// TLSTODO: consider making those into virtuals in QTlsBackend. After all, we ask the backend
|
||||
// to return those pointers if the functionality is supported, but it's a bit odd to have
|
||||
// this level of indirection. They are not parts of the classes above because ...
|
||||
// you'd then have to ask backend to create a certificate to ... call those
|
||||
// functions on a certificate.
|
||||
using X509ChainVerifyPtr = QList<QSslError> (*)(const QList<QSslCertificate> &chain,
|
||||
const QString &hostName);
|
||||
using X509PemReaderPtr = QList<QSslCertificate> (*)(const QByteArray &pem, int count);
|
||||
using X509DerReaderPtr = X509PemReaderPtr;
|
||||
using X509Pkcs12ReaderPtr = bool (*)(QIODevice *device, QSslKey *key, QSslCertificate *cert,
|
||||
QList<QSslCertificate> *caCertificates,
|
||||
const QByteArray &passPhrase);
|
||||
|
||||
#if QT_CONFIG(ssl)
|
||||
// TLS over TCP. Handshake, encryption/decryption.
|
||||
class Q_NETWORK_PRIVATE_EXPORT TlsCryptograph : public QObject
|
||||
{
|
||||
public:
|
||||
virtual ~TlsCryptograph();
|
||||
|
||||
virtual void init(QSslSocket *q, QSslSocketPrivate *d) = 0;
|
||||
virtual void checkSettingSslContext(std::shared_ptr<QSslContext> tlsContext);
|
||||
virtual std::shared_ptr<QSslContext> sslContext() const;
|
||||
|
||||
virtual QList<QSslError> tlsErrors() const = 0;
|
||||
|
||||
virtual void startClientEncryption() = 0;
|
||||
virtual void startServerEncryption() = 0;
|
||||
virtual void continueHandshake() = 0;
|
||||
virtual void enableHandshakeContinuation();
|
||||
virtual void disconnectFromHost() = 0;
|
||||
virtual void disconnected() = 0;
|
||||
virtual void cancelCAFetch();
|
||||
virtual QSslCipher sessionCipher() const = 0;
|
||||
virtual QSsl::SslProtocol sessionProtocol() const = 0;
|
||||
|
||||
virtual void transmit() = 0;
|
||||
virtual bool hasUndecryptedData() const;
|
||||
virtual QList<QOcspResponse> ocsps() const;
|
||||
|
||||
static bool isMatchingHostname(const QSslCertificate &cert, const QString &peerName);
|
||||
|
||||
void setErrorAndEmit(QSslSocketPrivate *d, QAbstractSocket::SocketError errorCode,
|
||||
const QString &errorDescription) const;
|
||||
};
|
||||
#else
|
||||
class TlsCryptograph;
|
||||
#endif // QT_CONFIG(ssl)
|
||||
|
||||
#if QT_CONFIG(dtls)
|
||||
|
||||
class Q_NETWORK_PRIVATE_EXPORT DtlsBase
|
||||
{
|
||||
public:
|
||||
virtual ~DtlsBase();
|
||||
|
||||
virtual void setDtlsError(QDtlsError code, const QString &description) = 0;
|
||||
|
||||
virtual QDtlsError error() const = 0;
|
||||
virtual QString errorString() const = 0;
|
||||
|
||||
virtual void clearDtlsError() = 0;
|
||||
|
||||
virtual void setConfiguration(const QSslConfiguration &configuration) = 0;
|
||||
virtual QSslConfiguration configuration() const = 0;
|
||||
|
||||
using GenParams = QDtlsClientVerifier::GeneratorParameters;
|
||||
virtual bool setCookieGeneratorParameters(const GenParams ¶ms) = 0;
|
||||
virtual GenParams cookieGeneratorParameters() const = 0;
|
||||
};
|
||||
|
||||
// DTLS cookie: generation and verification.
|
||||
class Q_NETWORK_EXPORT DtlsCookieVerifier : virtual public DtlsBase
|
||||
{
|
||||
public:
|
||||
virtual bool verifyClient(QUdpSocket *socket, const QByteArray &dgram,
|
||||
const QHostAddress &address, quint16 port) = 0;
|
||||
virtual QByteArray verifiedHello() const = 0;
|
||||
};
|
||||
|
||||
// TLS over UDP. Handshake, encryption/decryption.
|
||||
class Q_NETWORK_PRIVATE_EXPORT DtlsCryptograph : virtual public DtlsBase
|
||||
{
|
||||
public:
|
||||
|
||||
virtual QSslSocket::SslMode cryptographMode() const = 0;
|
||||
virtual void setPeer(const QHostAddress &addr, quint16 port, const QString &name) = 0;
|
||||
virtual QHostAddress peerAddress() const = 0;
|
||||
virtual quint16 peerPort() const = 0;
|
||||
virtual void setPeerVerificationName(const QString &name) = 0;
|
||||
virtual QString peerVerificationName() const = 0;
|
||||
|
||||
virtual void setDtlsMtuHint(quint16 mtu) = 0;
|
||||
virtual quint16 dtlsMtuHint() const = 0;
|
||||
|
||||
virtual QDtls::HandshakeState state() const = 0;
|
||||
virtual bool isConnectionEncrypted() const = 0;
|
||||
|
||||
virtual bool startHandshake(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
virtual bool handleTimeout(QUdpSocket *socket) = 0;
|
||||
virtual bool continueHandshake(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
virtual bool resumeHandshake(QUdpSocket *socket) = 0;
|
||||
virtual void abortHandshake(QUdpSocket *socket) = 0;
|
||||
virtual void sendShutdownAlert(QUdpSocket *socket) = 0;
|
||||
|
||||
virtual QList<QSslError> peerVerificationErrors() const = 0;
|
||||
virtual void ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore) = 0;
|
||||
|
||||
virtual QSslCipher dtlsSessionCipher() const = 0;
|
||||
virtual QSsl::SslProtocol dtlsSessionProtocol() const = 0;
|
||||
|
||||
virtual qint64 writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
virtual QByteArray decryptDatagram(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class DtlsCookieVerifier;
|
||||
class DtlsCryptograph;
|
||||
|
||||
#endif // QT_CONFIG(dtls)
|
||||
|
||||
} // namespace QTlsPrivate
|
||||
|
||||
// Factory, creating back-end specific implementations of
|
||||
// different entities QSslSocket is using.
|
||||
class Q_NETWORK_EXPORT QTlsBackend : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QTlsBackend();
|
||||
~QTlsBackend() override;
|
||||
|
||||
virtual bool isValid() const;
|
||||
virtual long tlsLibraryVersionNumber() const;
|
||||
virtual QString tlsLibraryVersionString() const;
|
||||
virtual long tlsLibraryBuildVersionNumber() const;
|
||||
virtual QString tlsLibraryBuildVersionString() const;
|
||||
virtual void ensureInitialized() const;
|
||||
|
||||
virtual QString backendName() const = 0;
|
||||
virtual QList<QSsl::SslProtocol> supportedProtocols() const = 0;
|
||||
virtual QList<QSsl::SupportedFeature> supportedFeatures() const = 0;
|
||||
virtual QList<QSsl::ImplementedClass> implementedClasses() const = 0;
|
||||
|
||||
// X509 and keys:
|
||||
virtual QTlsPrivate::TlsKey *createKey() const;
|
||||
virtual QTlsPrivate::X509Certificate *createCertificate() const;
|
||||
|
||||
virtual QList<QSslCertificate> systemCaCertificates() const;
|
||||
|
||||
// TLS and DTLS:
|
||||
virtual QTlsPrivate::TlsCryptograph *createTlsCryptograph() const;
|
||||
virtual QTlsPrivate::DtlsCryptograph *createDtlsCryptograph(class QDtls *qObject, int mode) const;
|
||||
virtual QTlsPrivate::DtlsCookieVerifier *createDtlsCookieVerifier() const;
|
||||
|
||||
// TLSTODO - get rid of these function pointers, make them virtuals in
|
||||
// the backend itself. X509 machinery:
|
||||
virtual QTlsPrivate::X509ChainVerifyPtr X509Verifier() const;
|
||||
virtual QTlsPrivate::X509PemReaderPtr X509PemReader() const;
|
||||
virtual QTlsPrivate::X509DerReaderPtr X509DerReader() const;
|
||||
virtual QTlsPrivate::X509Pkcs12ReaderPtr X509Pkcs12Reader() const;
|
||||
|
||||
// Elliptic curves:
|
||||
virtual QList<int> ellipticCurvesIds() const;
|
||||
virtual int curveIdFromShortName(const QString &name) const;
|
||||
virtual int curveIdFromLongName(const QString &name) const;
|
||||
virtual QString shortNameForId(int cid) const;
|
||||
virtual QString longNameForId(int cid) const;
|
||||
virtual bool isTlsNamedCurve(int cid) const;
|
||||
|
||||
// Note: int and not QSslDiffieHellmanParameter::Error - because this class and
|
||||
// its enum are QT_CONFIG(ssl)-conditioned. But not QTlsBackend and
|
||||
// its virtual functions. DH decoding:
|
||||
virtual int dhParametersFromDer(const QByteArray &derData, QByteArray *data) const;
|
||||
virtual int dhParametersFromPem(const QByteArray &pemData, QByteArray *data) const;
|
||||
|
||||
static QList<QString> availableBackendNames();
|
||||
static QString defaultBackendName();
|
||||
static QTlsBackend *findBackend(const QString &backendName);
|
||||
static QTlsBackend *activeOrAnyBackend();
|
||||
|
||||
static QList<QSsl::SslProtocol> supportedProtocols(const QString &backendName);
|
||||
static QList<QSsl::SupportedFeature> supportedFeatures(const QString &backendName);
|
||||
static QList<QSsl::ImplementedClass> implementedClasses(const QString &backendName);
|
||||
|
||||
// Built-in, this is what Qt provides out of the box (depending on OS):
|
||||
static constexpr const int nameIndexSchannel = 0;
|
||||
static constexpr const int nameIndexSecureTransport = 1;
|
||||
static constexpr const int nameIndexOpenSSL = 2;
|
||||
static constexpr const int nameIndexCertOnly = 3;
|
||||
|
||||
static const QString builtinBackendNames[];
|
||||
|
||||
template<class DynamicType, class TLSObject>
|
||||
static DynamicType *backend(const TLSObject &o)
|
||||
{
|
||||
return static_cast<DynamicType *>(o.d->backend.get());
|
||||
}
|
||||
|
||||
static void resetBackend(QSslKey &key, QTlsPrivate::TlsKey *keyBackend);
|
||||
|
||||
static void setupClientPskAuth(QSslPreSharedKeyAuthenticator *auth, const char *hint,
|
||||
int hintLength, unsigned maxIdentityLen, unsigned maxPskLen);
|
||||
static void setupServerPskAuth(QSslPreSharedKeyAuthenticator *auth, const char *identity,
|
||||
const QByteArray &identityHint, unsigned maxPskLen);
|
||||
#if QT_CONFIG(ssl)
|
||||
static QSslCipher createCiphersuite(const QString &description, int bits, int supportedBits);
|
||||
static QSslCipher createCiphersuite(const QString &suiteName, QSsl::SslProtocol protocol,
|
||||
const QString &protocolString);
|
||||
static QSslCipher createCipher(const QString &name, QSsl::SslProtocol protocol,
|
||||
const QString &protocolString);
|
||||
|
||||
// Those statics are implemented using QSslSocketPrivate (which is not exported,
|
||||
// unlike QTlsBackend).
|
||||
static QList<QSslCipher> defaultCiphers();
|
||||
static QList<QSslCipher> defaultDtlsCiphers();
|
||||
|
||||
static void setDefaultCiphers(const QList<QSslCipher> &ciphers);
|
||||
static void setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers);
|
||||
static void setDefaultSupportedCiphers(const QList<QSslCipher> &ciphers);
|
||||
|
||||
static void resetDefaultEllipticCurves();
|
||||
|
||||
static void setDefaultCaCertificates(const QList<QSslCertificate> &certs);
|
||||
|
||||
// Many thanks to people who designed QSslConfiguration with hidden
|
||||
// data-members, that sneakily set by some 'friend' classes, having
|
||||
// some twisted logic.
|
||||
static bool rootLoadingOnDemandAllowed(const QSslConfiguration &configuration);
|
||||
static void storePeerCertificate(QSslConfiguration &configuration, const QSslCertificate &peerCert);
|
||||
static void storePeerCertificateChain(QSslConfiguration &configuration,
|
||||
const QList<QSslCertificate> &peerCertificateChain);
|
||||
static void clearPeerCertificates(QSslConfiguration &configuration);
|
||||
// And those are even worse, this is where we don't have the original configuration,
|
||||
// and can have only a copy. So instead we go to d->privateConfiguration.someMember:
|
||||
static void clearPeerCertificates(QSslSocketPrivate *d);
|
||||
static void setPeerSessionShared(QSslSocketPrivate *d, bool shared);
|
||||
static void setSessionAsn1(QSslSocketPrivate *d, const QByteArray &asn1);
|
||||
static void setSessionLifetimeHint(QSslSocketPrivate *d, int hint);
|
||||
using AlpnNegotiationStatus = QSslConfiguration::NextProtocolNegotiationStatus;
|
||||
static void setAlpnStatus(QSslSocketPrivate *d, AlpnNegotiationStatus st);
|
||||
static void setNegotiatedProtocol(QSslSocketPrivate *d, const QByteArray &protocol);
|
||||
static void storePeerCertificate(QSslSocketPrivate *d, const QSslCertificate &peerCert);
|
||||
static void storePeerCertificateChain(QSslSocketPrivate *d, const QList<QSslCertificate> &peerChain);
|
||||
static void addTustedRoot(QSslSocketPrivate *d, const QSslCertificate &rootCert);// TODO: "addTrusted..."
|
||||
// The next one - is a "very important" feature! Kidding ...
|
||||
static void setEphemeralKey(QSslSocketPrivate *d, const QSslKey &key);
|
||||
|
||||
virtual void forceAutotestSecurityLevel();
|
||||
#endif // QT_CONFIG(ssl)
|
||||
|
||||
Q_DISABLE_COPY_MOVE(QTlsBackend)
|
||||
};
|
||||
|
||||
#define QTlsBackend_iid "org.qt-project.Qt.QTlsBackend"
|
||||
Q_DECLARE_INTERFACE(QTlsBackend, QTlsBackend_iid);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QTLSBACKEND_P_H
|
||||
@@ -0,0 +1,14 @@
|
||||
#define QT_FEATURE_ifr_index -1
|
||||
|
||||
#define QT_FEATURE_libproxy -1
|
||||
|
||||
#define QT_FEATURE_linux_netlink -1
|
||||
|
||||
#define QT_FEATURE_system_proxies 1
|
||||
|
||||
#define QT_FEATURE_networklistmanager 1
|
||||
|
||||
#define QT_FEATURE_publicsuffix_qt 1
|
||||
|
||||
#define QT_FEATURE_publicsuffix_system -1
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QTNETWORKEXPORTS_P_H
|
||||
#define QTNETWORKEXPORTS_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/qtnetworkexports.h>
|
||||
|
||||
#define Q_NETWORK_PRIVATE_EXPORT Q_NETWORK_EXPORT
|
||||
|
||||
#endif // QTNETWORKEXPORTS_P_H
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QTNETWORKGLOBAL_P_H
|
||||
#define QTNETWORKGLOBAL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/qtnetworkglobal.h>
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetwork-config_p.h>
|
||||
#include <QtNetwork/private/qtnetworkexports_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
enum {
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_QNX)
|
||||
PlatformSupportsAbstractNamespace = true
|
||||
#else
|
||||
PlatformSupportsAbstractNamespace = false
|
||||
#endif
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
#endif // QTNETWORKGLOBAL_P_H
|
||||
@@ -0,0 +1 @@
|
||||
#include "qabstractnetworkcache.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QAbstractSocket
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QAbstractSocket
Normal file
@@ -0,0 +1 @@
|
||||
#include "qabstractsocket.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QAuthenticator
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QAuthenticator
Normal file
@@ -0,0 +1 @@
|
||||
#include "qauthenticator.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "qdnslookup.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "qdnslookup.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QDnsLookup
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QDnsLookup
Normal file
@@ -0,0 +1 @@
|
||||
#include "qdnslookup.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "qdnslookup.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "qdnslookup.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QDnsTextRecord
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QDnsTextRecord
Normal file
@@ -0,0 +1 @@
|
||||
#include "qdnslookup.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QDtls
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QDtls
Normal file
@@ -0,0 +1 @@
|
||||
#include "qdtls.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "qdtls.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QHostAddress
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QHostAddress
Normal file
@@ -0,0 +1 @@
|
||||
#include "qhostaddress.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QHostInfo
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QHostInfo
Normal file
@@ -0,0 +1 @@
|
||||
#include "qhostinfo.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QHstsPolicy
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QHstsPolicy
Normal file
@@ -0,0 +1 @@
|
||||
#include "qhstspolicy.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "qhttp1configuration.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "qhttp2configuration.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QHttpMultiPart
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QHttpMultiPart
Normal file
@@ -0,0 +1 @@
|
||||
#include "qhttpmultipart.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QHttpPart
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QHttpPart
Normal file
@@ -0,0 +1 @@
|
||||
#include "qhttpmultipart.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QIPv6Address
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QIPv6Address
Normal file
@@ -0,0 +1 @@
|
||||
#include "qhostaddress.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QLocalServer
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QLocalServer
Normal file
@@ -0,0 +1 @@
|
||||
#include "qlocalserver.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QLocalSocket
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QLocalSocket
Normal file
@@ -0,0 +1 @@
|
||||
#include "qlocalsocket.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "qnetworkaccessmanager.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "qnetworkinterface.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "qabstractnetworkcache.h"
|
||||
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QNetworkCookie
Normal file
1
paho-mqtt3as-proxy/Qt/include/QtNetwork/QNetworkCookie
Normal file
@@ -0,0 +1 @@
|
||||
#include "qnetworkcookie.h"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user