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);
61 Uploads 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(
':');
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);
178 int MultiPartFormDataParserPrivate::findBoundary(
char *buffer,
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"
void append(const T &value)
QByteArray trimmed() const const
int indexIn(const QByteArray &ba, int from) const const
QString errorString() const const
bool isEmpty() const const
virtual bool isSequential() const const
Cutelyst Upload handles file upload request
int indexOf(char ch, int from) const const
QString fromUtf8(const char *str, int size)
virtual qint64 size() const const
qsizetype indexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs) const const
QByteArray & prepend(char ch)
qint64 read(char *data, qint64 maxSize)
The Cutelyst namespace holds all public Cutelyst API.
QByteArray mid(int pos, int len) const const
QByteArray & append(char ch)
char toLatin1() const const
QByteArray left(int len) const const
QChar at(qsizetype n) const const
QString fromLatin1(const char *str, int size)