38bool QHttpHeaderParser::parseHeaders(QByteArrayView header)
42 Q_ASSERT(fields.isEmpty());
43 const auto hSpaceStart = [](QByteArrayView h) {
44 return h.startsWith(
' ') || h.startsWith(
'\t');
47 if (hSpaceStart(header) || (!header.empty() && !header.endsWith(
'\n')))
50 while (
int tail = header.endsWith(
"\n\r\n") ? 2 : header.endsWith(
"\n\n") ? 1 : 0)
53 if (header.size() - (header.endsWith(
"\r\n") ? 2 : 1) > maxTotalSize)
57 while (!header.empty()) {
58 const qsizetype colon = header.indexOf(
':');
60 return result.isEmpty() && (header ==
"\n" || header ==
"\r\n");
61 if (result.size() >= maxFieldCount)
63 QByteArrayView name = header.first(colon);
64 if (!fieldNameCheck(name))
66 header = header.sliced(colon + 1);
68 qsizetype valueSpace = maxFieldSize - name.size() - 1;
70 const qsizetype endLine = header.indexOf(
'\n');
71 Q_ASSERT(endLine != -1);
72 auto line = header.first(endLine);
73 valueSpace -= line.size() - (line.endsWith(
'\r') ? 1 : 0);
76 line = line.trimmed();
81 value = line.toByteArray();
83 header = header.sliced(endLine + 1);
84 }
while (hSpaceStart(header));
85 Q_ASSERT(name.size() + 1 + value.size() <= maxFieldSize);
86 result.append(name, value);
93bool QHttpHeaderParser::parseStatus(QByteArrayView status)
101 static const int minLength = 11;
102 static const int dotPos = 6;
103 static const int spacePos = 8;
104 static const char httpMagic[] =
"HTTP/";
106 if (status.size() < minLength
107 || !status.startsWith(httpMagic)
108 || status.at(dotPos) !=
'.'
109 || status.at(spacePos) !=
' ') {
115 majorVersion = status.at(dotPos - 1) -
'0';
116 minorVersion = status.at(dotPos + 1) -
'0';
119 qsizetype j = status.indexOf(
' ', i + 1);
120 const QByteArrayView code = j > i ? status.sliced(i + 1, j - i - 1)
121 : status.sliced(i + 1);
124 statusCode = code.toInt(&ok);
126 reasonPhrase = j > i ? QString::fromLatin1(status.sliced(j + 1))
129 return ok && uint(majorVersion) <= 9 && uint(minorVersion) <= 9;