6#include "multipartformdataparser_p.h"
15 qCWarning(CUTELYST_MULTIPART) <<
"Parsing sequential body is not supported" << body;
19 int start = contentType.
indexOf(u
"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 QChar ch = contentType.
at(i);
33 if ((quotes == 0 && i > start) || ++quotes == 2) {
36 }
else if (ch == u
';') {
44 qCWarning(CUTELYST_MULTIPART) <<
"Boundary match was empty" << contentType;
49 if (bufferSize < 1024) {
52 char *buffer =
new char[bufferSize];
54 ret = MultiPartFormDataParserPrivate::execute(buffer, bufferSize, body, boundary);
61Uploads MultiPartFormDataParserPrivate::execute(
char *buffer,
69 qint64 startOffset = 0;
71 qint64 contentLength = body->
size();
73 int boundarySize = boundary.
size();
74 ParserState state = FindBoundary;
77 while (pos < contentLength) {
78 qint64 len = body->
read(buffer + bufferSkip, bufferSize - bufferSkip);
80 qCWarning(CUTELYST_MULTIPART) <<
"Error while reading POST body" << body->
errorString();
91 i += findBoundary(buffer + i, len - i, matcher, boundarySize, state);
95 if (buffer[i] !=
'\r') {
99 state = EndBoundaryLF;
102 if (buffer[i] !=
'\n') {
106 state = StartHeaders;
109 if (headerLine.
isEmpty() && buffer[i] ==
'\r') {
113 char *pch =
static_cast<char *
>(memchr(buffer + i,
'\r', len - i));
115 headerLine.
append(buffer + i, len - i);
118 headerLine.
append(buffer + i, pch - buffer - i);
120 state = FinishHeader;
125 if (buffer[i] ==
'\n') {
126 int dotdot = headerLine.
indexOf(
':');
129 headerLine = QByteArray();
130 state = StartHeaders;
137 if (buffer[i] ==
'\n') {
147 startOffset = pos - len + i;
151 i += findBoundary(buffer + i, len - i, matcher, boundarySize, state);
153 if (state == EndBoundaryCR) {
156 const qint64 endOffset = pos - len + i - boundarySize - 1;
158 new Upload(
new UploadPrivate(body, headers, startOffset, endOffset));
165 bufferSkip = boundarySize - 1;
166 memmove(buffer, buffer + len - bufferSkip, bufferSkip);
178int MultiPartFormDataParserPrivate::findBoundary(
char *buffer,
180 const QByteArrayMatcher &matcher,
182 MultiPartFormDataParserPrivate::ParserState &state)
184 int i = matcher.
indexIn(buffer, len);
189 state = EndBoundaryCR;
190 return i + boundarySize - 1;
195#include "moc_multipartformdataparser_p.cpp"
Cutelyst Upload handles file upload request
The Cutelyst namespace holds all public Cutelyst API.
QVector< Upload * > Uploads
QByteArray & append(char ch)
int indexOf(char ch, int from) const const
bool isEmpty() const const
QByteArray left(int len) const const
QByteArray mid(int pos, int len) const const
QByteArray & prepend(char ch)
QByteArray trimmed() const const
int indexIn(const QByteArray &ba, int from) const const
char toLatin1() const const
QString errorString() const const
virtual bool isSequential() const const
qint64 read(char *data, qint64 maxSize)
virtual qint64 size() const const
QString fromLatin1(const char *str, int size)
QString fromUtf8(const char *str, int size)
QChar at(qsizetype n) const const
qsizetype indexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs) const const
void append(const T &value)