6#include <QtCore/qdebug.h>
29 const unsigned sum = unsigned(
name.size() +
value.size());
30 if (std::numeric_limits<unsigned>::max() - 32 <
sum)
40 if (
const int minLen = std::min(lhs.
size(), rhs.
size())) {
53FieldLookupTable::SearchEntry::SearchEntry()
61FieldLookupTable::SearchEntry::SearchEntry(
const HeaderField *
f,
64 const FieldLookupTable *
t)
73bool FieldLookupTable::SearchEntry::operator < (
const SearchEntry &rhs)
const
78 int cmp =
compare(field->name, rhs.field->name);
82 cmp =
compare(field->value, rhs.field->value);
95 const quint32 leftChunkIndex =
table->indexOfChunk(chunk);
96 const quint32 rightChunkIndex = rhs.table->indexOfChunk(rhs.chunk);
99 if (leftChunkIndex != rightChunkIndex)
100 return leftChunkIndex > rightChunkIndex;
103 return offset > rhs.offset;
106FieldLookupTable::FieldLookupTable(
quint32 maxSize,
bool use)
107 : maxTableSize(maxSize),
108 tableCapacity(maxSize),
121 if (!entrySize.first)
124 if (entrySize.second > tableCapacity) {
129 while (nDynamic && tableCapacity -
dataSize < entrySize.second)
134 chunks.push_front(ChunkPtr(
new Chunk(
ChunkSize)));
144 auto &newField = front();
145 newField.name =
name;
146 newField.value =
value;
149 const auto result = searchIndex.insert(frontKey());
165 const auto res = searchIndex.erase(backKey());
228 const auto staticPos = findInStaticPart(
field, CompareMode::nameAndValue);
229 if (staticPos !=
table.end()) {
230 if (staticPos->name ==
name && staticPos->value ==
value)
236 qCritical(
"lookup in dynamic table requires search index enabled");
241 const auto pos = searchIndex.lower_bound(
key);
242 if (
pos != searchIndex.end()) {
245 return keyToIndex(*
pos);
256 const auto staticPos = findInStaticPart(
field, CompareMode::nameOnly);
257 if (staticPos !=
table.end()) {
258 if (staticPos->name ==
name)
264 qCritical(
"lookup in dynamic table requires search index enabled");
269 const auto pos = searchIndex.lower_bound(
key);
270 if (
pos != searchIndex.end()) {
273 return keyToIndex(*
pos);
296 Q_ASSERT(chunkIndex < chunks.size());
319 Q_ASSERT(nDynamic && begin !=
end && chunks.size());
320 return (*chunks[0])[begin];
323HeaderField &FieldLookupTable::front()
325 Q_ASSERT(nDynamic && begin !=
end && chunks.size());
326 return (*chunks[0])[begin];
329const HeaderField &FieldLookupTable::back()
const
335 Q_ASSERT(chunkIndex < chunks.size());
337 return (*chunks[chunkIndex])[
offset];
340quint32 FieldLookupTable::indexOfChunk(
const Chunk *chunk)
const
344 for (size_type
i = 0;
i < chunks.size(); ++
i) {
345 if (chunks[
i].
get() == chunk)
349 Q_UNREACHABLE_RETURN(0);
352quint32 FieldLookupTable::keyToIndex(
const SearchEntry &
key)
const
356 const auto chunkIndex = indexOfChunk(
key.chunk);
364FieldLookupTable::SearchEntry FieldLookupTable::frontKey()
const
367 return SearchEntry(&front(), chunks.front().get(), begin,
this);
370FieldLookupTable::SearchEntry FieldLookupTable::backKey()
const
374 const HeaderField &
field = back();
377 const auto chunk = chunks[absIndex /
ChunkSize].get();
389 if (
size > maxTableSize)
392 tableCapacity =
size;
393 while (nDynamic &&
dataSize > tableCapacity)
414 static std::vector<HeaderField>
table = {
419 {
":path",
"/index.html"},
421 {
":scheme",
"https"},
429 {
"accept-charset",
""},
430 {
"accept-encoding",
"gzip, deflate"},
431 {
"accept-language",
""},
432 {
"accept-ranges",
""},
434 {
"access-control-allow-origin",
""},
437 {
"authorization",
""},
438 {
"cache-control",
""},
439 {
"content-disposition",
""},
440 {
"content-encoding",
""},
441 {
"content-language",
""},
442 {
"content-length",
""},
443 {
"content-location",
""},
444 {
"content-range",
""},
445 {
"content-type",
""},
454 {
"if-modified-since",
""},
455 {
"if-none-match",
""},
457 {
"if-unmodified-since",
""},
458 {
"last-modified",
""},
461 {
"max-forwards",
""},
462 {
"proxy-authenticate",
""},
463 {
"proxy-authorization",
""},
470 {
"strict-transport-security",
""},
471 {
"transfer-encoding",
""},
475 {
"www-authenticate",
""}
481std::vector<HeaderField>::const_iterator FieldLookupTable::findInStaticPart(
const HeaderField &field, CompareMode
mode)
484 const auto acceptPos =
table.begin() + 18;
485 if (
field.name ==
"accept") {
486 if (
mode == CompareMode::nameAndValue &&
field.value !=
"")
491 auto predicate = [
mode](
const HeaderField &lhs,
const HeaderField &rhs) {
492 const int cmp =
compare(lhs.name, rhs.name);
495 else if (
mode == CompareMode::nameAndValue)
496 return compare(lhs.value, rhs.value) < 0;
501 if (staticPos != acceptPos)
bool fieldName(quint32 index, QByteArray *dst) const
void setMaxDynamicTableSize(quint32 size)
quint32 numberOfDynamicEntries() const
friend struct SearchEntry
bool fieldValue(quint32 index, QByteArray *dst) const
bool updateDynamicTableSize(quint32 size)
quint32 numberOfEntries() const
static const std::vector< HeaderField > & staticPart()
quint32 indexOf(const QByteArray &name, const QByteArray &value) const
bool indexIsValid(quint32 index) const
quint32 numberOfStaticEntries() const
bool field(quint32 index, QByteArray *name, QByteArray *value) const
quint32 dynamicDataSize() const
bool prependField(const QByteArray &name, const QByteArray &value)
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
HeaderSize entry_size(QByteArrayView name, QByteArrayView value)
QPair< bool, quint32 > HeaderSize
Combined button and popup list for selecting options.
static QDBusError::ErrorType get(const char *name)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLintptr offset
GLenum GLenum GLsizei void * table
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
static int compare(quint64 a, quint64 b)