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);
63Uploads 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 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);
181int 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"
Cutelyst Upload handles file upload requests.
The Cutelyst namespace holds all public Cutelyst API.
QByteArray & append(QByteArrayView data)
qsizetype indexOf(QByteArrayView bv, qsizetype from) const const
bool isEmpty() const const
QByteArray left(qsizetype len) const const
QByteArray & prepend(QByteArrayView ba)
void reserve(qsizetype size)
qsizetype size() const const
QByteArray sliced(qsizetype pos) const const
QByteArray trimmed() const const
qsizetype indexIn(QByteArrayView data, qsizetype from) const const
char at(qsizetype n) const const
qsizetype indexOf(QByteArrayView bv, qsizetype from) const const
qsizetype length() const const
QString errorString() const const
virtual bool isSequential() const const
QByteArray read(qint64 maxSize)
virtual qint64 size() const const
void append(QList::parameter_type value)