Ole*_*kov 2 delphi indy delphi-2009 indy10 box
我正在尝试使用TIdMultipartFormDataStream 进行多部分上传到 Box.com.虽然文件名最多为'\ u0424\u042B\u0412\u0410\u041F.txt'但它可以正常工作,但是当它更长时('\ u0424\u042B\u0412\u0410\u040F\u0420.txt')它会导致'HTTP' /1.1 400 Bad Request'.
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"拆分.
文本字段的默认传输编码是MIME的quoted-printable格式.似乎Box不喜欢那种格式.
AddFormField()返回a TIdFormDataField,它有一个ContentTransfer你可以设置它的属性,8bit或者binary按原样发送JSON文本(在charset编码为字节后,即):
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;