2017-02-20 24 views
2

Я пытаюсь сделать multipart upload to Box.com с помощью TIdMultipartFormDataStream. Хотя имя файла соответствует «\ u0424 \ u042B \ u0412 \ u0410 \ u041F.txt ', он работает нормально, но когда он длиннее (' \ u0424 \ u042B \ u0412 \ u0410 \ u041F \ u0420.txt '), он вызывает" HTTP /1.1 400 Bad Request '.Indy 10 + XE8 многопользовательская загрузка с длинным именем файла

Есть ли ограничение для FormField.FFieldValue длина? Если да, есть ли способ обойти его?

procedure TBoxComSaveFilter.UploadTest; 
const 
    URL = 'https://upload.box.com/api/2.0/files/content'; 
var 
    IdHTTP: TIdHTTP; 
    MD: TIdMultipartFormDataStream; 
begin 
    IdHTTP := TIdHTTP.Create(nil); 
    try 
    IdHTTP.HandleRedirects := True; 
    IdHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP); 
    IdHTTP.Request.BasicAuthentication := False; 
    IdHTTP.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + FAccessToken; 
    MD := TIdMultipartFormDataStream.Create; 
    try 
     MD.AddFormField('metadata', '{"name": "' + 
     '\u0424\u042B\u0412\u0410\u041F.txt' +  // => OK 
//  '\u0424\u042B\u0412\u0410\u041F\u0420.txt' + // => 400 Bad Request 
     '", "parent": {"id": "0"}}', '', 'application/json'); 

     MD.AddFile('content', 'source.txt', 'application/octet-stream'); 
     IdHTTP.Post(URL, MD); 
    finally 
     MD.Free; 
    end; 
    finally 
    IdHTTP.Free; 
    end; 
end; 

Частичный лог для короткого файла:

Sent 20.02.2017 21:16:26: ----------022017211625520 
Content-Disposition: form-data; name="metadata" 
Content-Type: application/json 
Content-Transfer-Encoding: quoted-printable 

{"name": "\u0424\u042B\u0412\u0410\u041F.txt", "parent": {"id": "0"}} 
----------022017211625520 

То же часть для длинного файла:

Sent 20.02.2017 21:17:48: ----------022017211748412 
Content-Disposition: form-data; name="metadata" 
Content-Type: application/json 
Content-Transfer-Encoding: quoted-printable 

{"name": "\u0424\u042B\u0412\u0410\u041F\u0420.txt", "parent": {"id": = 
"0"}} 
----------022017211748412 

Как можно видеть разделение данных после 70 байт с помощью "= CRLF" ,

+0

В 'TIdMultipartFormDataStream' нет ограничений, но есть конец Box:« * Box поддерживает только имена файлов не более 255 символов. Имена, которые не будут поддерживаться, - это те, которые содержат непечатаемые ascii,/или \, имена с завершающими пробелами и специальные имена «.» И «..». * « –

+0

Почему вы кодируете JSON символы Unicode, хотя «вам не нужно это делать:« MD.AddFormField («метаданные», «{» name »:« ФЫВАПР.txt »,« parent »: {« id »:« 0 »}} ',' utf- 8 ',' application/json '); ' –

+0

Спасибо @RemyLebeau. Я пробовал« ФЫВАПР.txt »и« utf-8 », а результатом был« HTTP/1.1 400 Bad Request ». Журнал:' {"name" : "= D0 = A4 = D0 = AB = D0 = 92 = D0 = 90 = D0 = 9F = D0 = A0.txt", "parent": {"id": = CRLF' '" 0 "}}' –

ответ

7

Кодировка передачи по умолчанию для текстовых полей - формат quoted-printable MIME. Казалось бы, Box не нравится этот формат.

AddFormField() возвращает TIdFormDataField, который имеет ContentTransfer свойство, которое вы можете установить его в 8bit или binary отправить текст JSON как есть (после того, как он кодировки кодируются в байты, то есть):

MD.AddFormField('metadata', '{"name": "ФЫВАПР.txt", "parent": {"id": "0"}}', 'utf-8', 'application/json').ContentTransfer := '8bit'; 

с другой стороны, положить JSON в TStream, как TStringStream или TMemoryStream, а затем использовать TStream перегрузку AddFormField(), который устанавливает ContentTransfer в binary по умолчанию:

JsonStream := TStringStream.Create('{"name": "ФЫВАПР.txt", "parent": {"id": "0"}}', TEncoding.UTF8); 
try 
    MD.AddFormField('metadata', 'application/json', 'utf-8', JsonStream); 
    // send the post... 
finally 
    JsonStream.Free; 
end; 
+0

Оба эти метода работают нормально. Также я пробовал TMemoryStream, например [multipart upload to OneDrive] (http: //stackoverflow.com/questions/42157101/indy-10-multipart-upload-to-onedrive-error): it также работает. Спасибо @RemyLebeau. –

 Смежные вопросы

  • Нет связанных вопросов^_^