I'm trying to upload a file to Dropbox using Indy 10 and XE8. While file name like 'file.txt' it works OK, but with 'файл.txt' or so, I have '????.txt' on DropBox. I read about parameters with utf-8 but it is don't work with headers :-(.
How can I upload a file and save utf-8 file name?
procedure TSaveFilterForm.TestButtonClick(Sender: TObject);
const
URL = 'https://content.dropboxapi.com/2/files/upload';
var
IdHTTP: TIdHTTP;
Source: TFileStream;
Res: String;
begin
IdHTTP := TIdHTTP.Create(nil);
try
IdHTTP.HandleRedirects := True;
IdHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
IdHTTP.Request.BasicAuthentication := False;
IdHTTP.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + AccessToken;
IdHTTP.Request.ContentType := 'application/octet-stream';
Source := TFileStream.Create('c:\test.txt', fmOpenRead);
IdHTTP.Request.CustomHeaders.Values['Dropbox-API-Arg'] :=
Format('{ "path": "%s", "mode": "overwrite"}',
['/файл.txt']); // Dropbox => ????.txt
try
Res := IdHTTP.Post(URL, Source);
finally
Source.Free;
end;
finally
IdHTTP.Free;
end;
end;
For these calls with the parameters in the header, you need to escape these characters. That is, when you use the “Dropbox-API-Arg” header, you need to make it “HTTP header safe”. This means using JSON-style “\uXXXX” escape codes for the character 0x7F and all non-ASCII characters.
Some, but not all, languages/libraries do this for you. For example, for JavaScript, to do this yourself you could do something like this:
var charsToEncode = /[\u007f-\uffff]/g;
function http_header_safe_json(v) {
return JSON.stringify(v).replace(charsToEncode,
function(c) {
return '\\u' + ('000' + c.charCodeAt(0).toString(16)).slice(-4);
}
);
}
and then something like:
'Dropbox-API-Arg': http_header_safe_json({ path: dropboxFilePath })
It sounds like your platform doesn't do that for you, so you'll want to implement this in your code.