2017-02-20 6 views
2

Ich versuche multipart upload to Box.com mit TIdMultiPartFormDataStream zu tun. Während der Dateiname bis '\ u0424 \ u042B \ u0412 \ u0410 \ u041F.txt' ist, funktioniert es OK, aber wenn es länger ist ('\ u0424 \ u042B \ u0412 \ u0410 \ u041F \ u0420.txt'), verursacht es 'HTTP /1.1 400 Ungültige Anfrage '.Indy 10 + XE8 mehrteiligen Upload mit langen Dateinamen

Gibt es eine Einschränkung für die Länge von FormField.FFieldValue? Wenn ja, gibt es eine Möglichkeit, es zu umgehen?

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; 

ein Teilprotokoll für kurze Dateinamen:

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 

Das gleiche Teil für lange Dateinamen:

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 

Als ich die Datenteilung nach 70 Byte "= CRLF" sehen .

+0

Es gibt keine Begrenzung in 'TIdMultipartFormDataStream' selbst, aber es gibt am Ende der Box:" * Box unterstützt nur Dateinamen mit maximal 255 Zeichen. Namen, die nicht unterstützt werden, sind solche, die nicht druckbare ASCII-,/oder \ -Namen mit folgenden Leerzeichen enthalten, und die speziellen Namen "." Und "..". * " –

+0

Warum sind Sie JSON-Codierung der Unicode-Zeichen? Sie sollten das nicht tun müssen: 'MD.AddFormField ('metadata', '{" name ":" ЫЫВАПР.txt "," übergeordnete ": {" id ":" 0 "}}', 'utf- 8 ',' application/json '); ' –

+0

Danke @RemyLebeau. Ich habe" ЫЫВАПР.txt "und" utf-8 "versucht und das Ergebnis war" HTTP/1.1 400 Bad Request ". Das Protokoll:' {"name" : "= D0 = A4 = D0 = AB = D0 = 92 = D0 = 90 = D0 = 9F = D0 = A0.txt", "Elternteil": {"id": = CRLF' '" 0 "}}' –

Antwort

7

Die Standardübertragungscodierung für Textfelder ist MIME quoted-printable Format. Es scheint, dass Box dieses Format nicht mag.

AddFormField() gibt ein TIdFormDataField, die eine ContentTransfer Eigenschaft hat man es zu 8bit oder binary zu senden, um den JSON Text festlegen kann wie sie ist (nachdem es charset zu Bytes codiert wird, das ist):

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

Alternativ dazu können Sie Ihre JSON in einem TStream, wie TStringStream oder TMemoryStream, und verwenden Sie dann die TStream Überlastung von AddFormField(), die die ContentTransfer zu binary durch Standardsätze:

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

Beide Methoden funktionieren OK Auch TMemoryStream wie [multipart upload to OneDrive] //stackoverflow.com/questions/42157101/indy-10-multipart-upload-to-onedrive-error): it funktioniert auch. Danke @RemyLebeau. –

Verwandte Themen