QTcpServer POST multipart/form-data проблемы

95
28 апреля 2021, 23:30

Не могу найти как обрабатывать сигналы POST в QTcpServer. На сервер посылаются данные в следующем виде

curl -F "image=@/PATH/*txt" localhost:PORT
curl -F "image=@/PATH/*txt" -F "image=@/PATH/*png localhost:PORT

На сервер приходят данные и слот QTcpSocket::readyRead вызывается дважды для каждого вызова curl. В первом приходит шапка примерно в таком виде:

POST / HTTP/1.1
Host: localhost:PORT
User-Agent: curl/7.65.3
Accept: /
Content-Length: 35297
Content-Type: multipart/form-data; boundary=------------------------cedafef30775ef86
Expect: 100-continue

Дальше приходят данные вторым вызовом QTcpSocket::readyRead Выглядят так:

--------------------------cedafef30775ef86
Content-Disposition: form-data; name="image"; filename="20uVlYSnKOU.jpg"
Content-Type: image/jpeg
\xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\  <-- Тут очень много текста

Как правильно принимать такие данные? Писать в отдельный файл? или в QByteArray::append()? Как дальше правильно достать вложенные файлы в QByteArray? В гугле в основном все проблемы с отправкой POST, а не с приемом.

Буду очень признателен за ответы!

Answer 1

Метод QTcpSocket::readyRead может срабатывать и большее количество раз, все зависит от размера и количества файлов, которые Вы отправляете.

Алгоритм действий примерно такой:

  • Считываем все заголовки, пока не встретится пустая строка - признак того, что заголовки закончились.
  • Ищем заголовок Content-Length из которого узнаем размер передаваемых данных.
  • Считаем все новые данные, в QByteArray, пока там не наберется число из Content-Length.
  • Далее уже каким-то парсером извлекаем имя файла, тип данных. Еще иногда есть поле ContentEncoding которые сообщает в каком формате был передан файл.

Тут стоит заметить, что данный подход будет нормально работать, если передаете маленькие файлы. Если нужно прогонять файлы > 50 мбайт. То лучше сразу файл кусками сохранять на диск.

Я долго искал подходящий парсер, в итоге пришлось написать самому.

READ ALSO
Соединение Kinect с Arduino

Соединение Kinect с Arduino

Нужно данные от сенсора kinect передать в программу на Arduino, как это проще всего сделать? Очень желательно, чтобы использовался только язык C/C++

100
Ошибка при копировании файла QFile в Windows

Ошибка при копировании файла QFile в Windows

Создаю файл, пишу в него текст, потом хочу скопироватьНо функция copy возвращает false

77
Создание графического приложения C++

Создание графического приложения C++

Пишу программы для универа, всегда обходился консолью, а тут понадобилось сделать программу в которой выводится декартова система координат...

182
Как применять алгоритмы STL в Qt?

Как применять алгоритмы STL в Qt?

Как применять алгоритмы STL в Qt, на примере QStringList и set_difference, например? Если это возможно, конечно

163