6 #include "multipartformdataparser_p.h" 15 qCWarning(CUTELYST_MULTIPART) <<
"Parsing sequential body is not supported" << body;
19 int start = contentType.
indexOf(
"boundary=");
21 qCWarning(CUTELYST_MULTIPART) <<
"No boundary match" << contentType;
27 const int len = contentType.
length();
30 for (
int i = start, quotes = 0; i < len; ++i) {
31 const char ch = contentType.
at(i);
33 if (quotes == 0 && i > start) {
35 }
else if (++quotes == 2) {
38 }
else if (ch ==
';') {
46 qCWarning(CUTELYST_MULTIPART) <<
"Boundary match was empty" << contentType;
51 if (bufferSize < 1024) {
54 char *buffer =
new char[bufferSize];
56 ret = MultiPartFormDataParserPrivate::execute(buffer, bufferSize, body, boundary);
63 Uploads MultiPartFormDataParserPrivate::execute(
char *buffer,
71 qint64 startOffset = 0;
73 qint64 contentLength = body->
size();
75 int boundarySize = boundary.
size();
76 ParserState state = FindBoundary;
79 while (pos < contentLength) {
80 qint64 len = body->
read(buffer + bufferSkip, bufferSize - bufferSkip);
82 qCWarning(CUTELYST_MULTIPART) <<
"Error while reading POST body" << body->
errorString();
93 i += findBoundary(buffer + i, len - i, matcher, boundarySize, state);
97 if (buffer[i] !=
'\r') {
101 state = EndBoundaryLF;
104 if (buffer[i] !=
'\n') {
108 state = StartHeaders;
111 if (headerLine.
isEmpty() && buffer[i] ==
'\r') {
115 const char *pch =
static_cast<char *
>(memchr(buffer + i,
'\r', len - i));
116 if (pch ==
nullptr) {
117 headerLine.
append(buffer + i, len - i);
120 headerLine.
append(buffer + i, pch - buffer - i);
122 state = FinishHeader;
127 if (buffer[i] ==
'\n') {
128 int dotdot = headerLine.
indexOf(
':');
130 headerLine.
left(dotdot),
133 state = StartHeaders;
140 if (buffer[i] ==
'\n') {
150 startOffset = pos - len + i;
154 i += findBoundary(buffer + i, len - i, matcher, boundarySize, state);
156 if (state == EndBoundaryCR) {
159 const qint64 endOffset = pos - len + i - boundarySize - 1;
161 new Upload(
new UploadPrivate(body, headers, startOffset, endOffset));
168 bufferSkip = boundarySize - 1;
169 memmove(buffer, buffer + len - bufferSkip, bufferSkip);
181 int MultiPartFormDataParserPrivate::findBoundary(
char *buffer,
185 MultiPartFormDataParserPrivate::ParserState &state)
187 int i = matcher.
indexIn(buffer, len);
192 state = EndBoundaryCR;
193 return i + boundarySize - 1;
198 #include "moc_multipartformdataparser_p.cpp"
QByteArray trimmed() const const
void reserve(qsizetype size)
QString errorString() const const
bool isEmpty() const const
virtual bool isSequential() const const
QByteArray read(qint64 maxSize)
Cutelyst Upload handles file upload requests.
qsizetype indexOf(QByteArrayView bv, qsizetype from) const const
virtual qint64 size() const const
The Cutelyst namespace holds all public Cutelyst API.
QByteArray sliced(qsizetype pos) const const
QByteArray & append(QByteArrayView data)
qsizetype length() const const
QByteArray left(qsizetype len) const const
qsizetype indexOf(QByteArrayView bv, qsizetype from) const const
void append(QList< T > &&value)
char at(qsizetype n) const const
QByteArray & prepend(QByteArrayView ba)
qsizetype size() const const
qsizetype indexIn(QByteArrayView data, qsizetype from) const const