Reputation: 4127
I'm trying to use TDownloadURL.DownloadRawBytes from the Rest.Client unit to download a PDF file from an Amazon S3 bucket.
My problem seems to be an empty ContentType returned with the file. I don't control the server side and don't have any way to get them to correctly set the ContentType.
TRESTRequest.Execute looks at the returned context type, if it is empty then it forces the MimeKind to TMimeTypes.TKind.Text. That in turn forces the returned Bytes to be converted to a string.
There is a way to pass in a different string encoding, but not a way to force a MimeType or to skip the string conversion.
Without that when I Execute the request I get the following error:
Project raised exception class EEncodingError with message 'No mapping for the Unicode character exists in the target multi-byte code page'.
Upvotes: 2
Views: 117
Reputation: 4127
Here is my modified version of DownloadRawBytes. I needed the response saved to a file so it write is out directly instead of returning a stream.
Based on Remy's comment I set the FallbackCharsetEncoding, both CP437 and ISO-8859-1 worked for me.
procedure TMapRightIntegration.SaveAttachment(AUrl, AFileName: String);
var
FileStream: TFileStream;
Request: TRESTRequest;
Client: TRESTClient;
Response: TCustomRESTResponse;
begin
Client := TRESTClient.Create(AUrl);
try
Request := TRESTRequest.Create(Client);
Request.SynchronizedEvents := False;
// We don't need the string, this encoding will ensure the
// conversion from binary will not fail on any byte.
Client.FallbackCharsetEncoding := 'CP437';
Request.Execute;
Response := Request.Response;
if Response.StatusCode >= 300 then
raise ERequestError.Create(Response.StatusCode, Response.StatusText, Response.Content);
if Response.RawBytes = nil then
raise Exception.Create('RawBytes is nil');
FileStream := TFileStream.Create(AFileName, fmCreate);
try
FileStream.WriteBuffer(Response.RawBytes[0], Length(Response.RawBytes));
finally
FileStream.Free;
end;
finally
Client.Free;
end;
end;
Upvotes: 1