удаление типа контента из TIdMultiPartFormDataStream

Это как-то связано с этой публикацией. Я пытаюсь опубликовать некоторые данные формы, используя TIdHTTP и TIdMultiPartFormDataStream, но при мониторинге связи с помощью Wireshark к каждому полю формы прикрепляется content-Type: text/plain, и по какой-то причине сервер которому я посылаю эти вещи, не нравится. Есть ли способ убедиться, что отправляются только имя и значение? Content-Transfer также добавлялся, и я смог удалить его, используя:

aFieldItem := PostStream.AddFormField(fName, fValue);
aFieldItem.ContentTransfer := '';

но я не могу найти способ избавиться от типа контента. На данный момент отправляемые данные выглядят так (в Wireshark)

Boundary: \r\n----------051715151353026\r\n
Encapsulated multipart part:  (text/plain)
    Content-Disposition: form-data; name="description"\r\n
    Content-Type: text/plain\r\n
    Line-based text data: text/plain
        \r\n
        Testing new AW Mobile

и я хочу, чтобы это выглядело так:

Boundary: \r\n------WebKitFormBoundary32hCBG8zkGMBpxqL\r\n
Encapsulated multipart part:
    Content-Disposition: form-data; name="description"\r\n
    Data (21 bytes)
        Data: 0d0a5465737420616e6420747261636520636f6d6d
        Length: 21

Спасибо, Сэм.


person Sam    schedule 17.05.2015    source источник


Ответы (1)


Раздел HTML5 4.10.22.7 изменяет способ RFC 2388 применяется к отправке веб-форм:

Части сгенерированного ресурса multipart/form-data, соответствующие полям, не являющимся файлами, не должны иметь указанного заголовка Content-Type. Их имена и значения должны быть закодированы с использованием выбранной выше кодировки символов (в частности, имена полей не преобразуются в 7-битную безопасную кодировку, как это предлагается в RFC 2388).

Это отличается от RFC 2388:

Как и во всех составных типах MIME, каждая часть имеет необязательный «Content-Type», который по умолчанию имеет значение text/plain.

Ваш сервер явно ожидает поведения HTML5.

Заголовок Content-Type в каждой части MIME, добавляемой к TIdMultipartFormDataStream , жестко закодирован и не может быть удален без изменения исходного кода TIdMultipartFormDataStream можно опустить, задав для свойства TIdFormDataField.ContentType пробел (не пустую строку, например ContentTransfer свойство позволяет):

aFieldItem := PostStream.AddFormField(fName, fValue);
aFieldItem.ContentTransfer := '';
aFieldItem.ContentType := ' '; // <-- here

Если вы установите для свойства ContentType пустую строку, заголовок Content-Type будет установлен на application/octet-stream, но вместо этого назначение символа пробела имеет побочный эффект пропуска заголовка, когда установщик свойств анализирует новое значение.

При этом я уже внес некоторые изменения в TIdMultipartFormDataStream, чтобы учесть это изменение в отправке веб-формы в HTML5, но я еще не завершил и не выпустил его.

person Remy Lebeau    schedule 18.05.2015
comment
Спасибо. Любое предложение относительно того, как я могу справиться с этим в то же время? - person Sam; 18.05.2015
comment
Как я уже сказал, вам придется изменить исходный код TIdMultipartFormDataStream, а затем перекомпилировать Indy. В качестве альтернативы скопируйте его исходный код в новый модуль/класс в вашем проекте, который вы затем сможете изменить по мере необходимости. Или просто запишите свои собственные данные MIME в стандартный поток TStream, например TMemoryStream. У меня нет ETA, когда новый TIdMultipartFormDataStream будет готов к выпуску. - person Remy Lebeau; 18.05.2015
comment
Третий вариант (данные MIME в стандартный поток TStream, такой как TMemoryStream) звучит лучше всего. У вас есть пример этого? Мне нужно выложить кучу пар имя-значение и файл и конец. Спасибо - person Sam; 18.05.2015
comment
На самом деле я нашел пример Здесь, который заставил его работать - person Sam; 19.05.2015
comment
Вот обсуждение, в котором говорится об изменениях, необходимых для того, чтобы TIdMultipartFormDataStream работал с серверами HTML5: Удаление строк из TIdMultiPartFormDataStream - person Remy Lebeau; 19.05.2015
comment
Спасибо, это спасло мой день, я сходил с ума, потому что не мог отправить поля простой формы вместе с почтой файла. - person MichaSchumann; 16.08.2016