18 #include "multipartformdataparser_p.h" 28 qCWarning(CUTELYST_MULTIPART) <<
"Parsing sequential body is not supported" << body;
34 qCWarning(CUTELYST_MULTIPART) <<
"No boundary match" << contentType;
40 const int len = contentType.
length();
43 for (
int i = start, quotes = 0; i < len; ++i) {
44 const QChar ch = contentType.
at(i);
46 if ((quotes == 0 && i > start) || ++quotes == 2) {
57 qCWarning(CUTELYST_MULTIPART) <<
"Boundary match was empty" << contentType;
62 if (bufferSize < 1024) {
65 char *buffer =
new char[bufferSize];
67 ret = MultiPartFormDataParserPrivate::execute(buffer, bufferSize, body, boundary);
81 qint64 contentLength = body->
size();
83 int boundarySize = boundary.
size();
84 ParserState state = FindBoundary;
87 while (pos < contentLength) {
88 qint64 len = body->
read(buffer + bufferSkip, bufferSize - bufferSkip);
90 qCWarning(CUTELYST_MULTIPART) <<
"Error while reading POST body" << body->
errorString();
101 i += findBoundary(buffer + i, len - i, matcher, boundarySize, state);
105 if (buffer[i] !=
'\r') {
109 state = EndBoundaryLF;
112 if (buffer[i] !=
'\n') {
116 state = StartHeaders;
119 if (headerLine.
isEmpty() && buffer[i] ==
'\r') {
123 char *pch = static_cast<char *>(memchr(buffer + i,
'\r', len - i));
125 headerLine.
append(buffer + i, len - i);
128 headerLine.
append(buffer + i, pch - buffer - i);
130 state = FinishHeader;
135 if (buffer[i] ==
'\n') {
136 int dotdot = headerLine.
indexOf(
':');
140 state = StartHeaders;
147 if (buffer[i] ==
'\n') {
156 startOffset = pos - len + i;
159 i += findBoundary(buffer + i, len - i, matcher, boundarySize, state);
161 if (state == EndBoundaryCR) {
163 const qint64 endOffset = pos - len + i - boundarySize - 1;
164 auto upload =
new Upload(
new UploadPrivate(body, headers, startOffset, endOffset));
171 bufferSkip = boundarySize - 1;
172 memmove(buffer, buffer + len - bufferSkip, bufferSkip);
184 int MultiPartFormDataParserPrivate::findBoundary(
char *buffer,
int len,
const QByteArrayMatcher &matcher,
int boundarySize, MultiPartFormDataParserPrivate::ParserState &state)
186 int i = matcher.
indexIn(buffer, len);
190 state = EndBoundaryCR;
191 return i + boundarySize - 1;
196 #include "moc_multipartformdataparser_p.cpp"
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
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
virtual qint64 size() 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
const QChar at(int position) const const
QString fromLatin1(const char *str, int size)