【发布时间】:2017-02-20 17:15:09
【问题描述】:
我正在尝试使用 TIdMultipartFormDataStream 执行 multipart upload to Box.com。虽然文件名最多为 '\u0424\u042B\u0412\u0410\u041F.txt' 它可以正常工作,但是当它更长时('\u0424\u042B\u0412\u0410\u041F\u0420.txt')它会导致'HTTP /1.1 400 错误请求'。
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”分割。
【问题讨论】:
-
TIdMultipartFormDataStream本身没有限制,但在 Box 的末尾有:“Box 仅支持 255 个字符或更少字符的文件名。不支持的名称是包含不可打印的 ascii、/ 或 \、带有尾随空格的名称和特殊名称“.”和“..”。“ -
为什么你要对 Unicode 字符进行 JSON 编码呢?你不应该这样做:
MD.AddFormField('metadata', '{"name": "ФЫВАПР.txt", "parent": {"id": "0"}}', 'utf-8', 'application/json'); -
谢谢@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"}} -
很抱歉我一开始跳过了日志。在我看来,根据日志,Indy 将数据拆分为“=CRLF”。
标签: delphi indy delphi-2009 box indy10