I am trying to use IdHTTP to equivalence the following curl operation:
curl -X POST -F "message=@C:\Users\santon\Desktop\ESM_download\token.txt" "https://esm-db.eu/esmws/eventdata/1/query?eventid=IT-1997-0004&station=CLF&format=ascii" -o RecordFileName.zip
The curl command is used to download a file from the server that is then saved on the hard drive as DownloadedFileName.zip. An authorization is required through a token file on the hard drive called token.txt. The path of the token file is specified as a parameter of curl. The best I could do is the following code:
procedure TMainForm.HTTPGetFile;
var
IdHTTP: TIdHTTP;
Params: TIdMultipartFormDataStream;
LHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
try
Params := TIdMultipartFormDataStream.Create;
Params.AddFormField('message', '@"C:\Users\santon\Desktop\ESM_download\token.txt"');
IdHTTP := TIdHTTP.Create(nil);
LHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(self);
LHandler.SSLOptions.Method := sslvTLSv1;
try
IdHTTP.IOHandler := LHandler;
IdHTTP.Post('https://esm-db.eu/esmws/eventdata/1/query?eventid=IT-1997-0004&station=CLF&format=ascii',Params);
finally
IdHTTP.Free;
LHandler.Free;
Params.Free;
end;
except
on E: Exception do
ShowMessage('Error: '+E.ToString);
end;
end;
But I keep on getting a HTTP/1.1 403 Forbidden error. Any ideas of what I am doing wrong?
Thanks in advance
You are not loading the token file into TIdMultiPartFormDataStream
correctly.
Per the curl documentation:
https://curl.se/docs/manpage.html#-F
-F, --form <name=content>
(HTTP SMTP IMAP) For HTTP protocol family, this lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data using the Content-Type multipart/form-data according to RFC 2388.
...
This enables uploading of binary files etc. To force the 'content' part to be a file, prefix the file name with an @ sign. To just get the content part from a file, prefix the file name with the symbol <. The difference between @ and < is then that @ makes a file get attached in the post as a file upload, while the < makes a text field and just get the contents for that text field from a file.
...
Example: send an image to an HTTP server, where 'profile' is the name of the form-field to which the file portrait.jpg will be the input:
curl -F profile=@portrait.jpg https://example.com/upload.cgi
...
In your code, you are creating a text field whose content is the filename itself. You are not creating a file upload field whose content is the data from the file.
Try this instead:
procedure TMainForm.HTTPGetFile;
var
IdHTTP: TIdHTTP;
Params: TIdMultipartFormDataStream;
LHandler: TIdSSLIOHandlerSocketOpenSSL;
LOutFile: TFileStream;
begin
try
Params := TIdMultipartFormDataStream.Create;
try
Params.AddFile('message', 'C:\Users\santon\Desktop\ESM_download\token.txt');
IdHTTP := TIdHTTP.Create(nil);
try
LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
LHandler.SSLOptions.Method := sslvTLSv1;
IdHTTP.IOHandler := LHandler;
LOutFile := TFileStream.Create('<path>\RecordFileName.zip', fmCreate);
try
IdHTTP.Post('https://esm-db.eu/esmws/eventdata/1/query?eventid=IT-1997-0004&station=CLF&format=ascii', Params, LOutFile);
finally
LOutFile.Free;
end;
finally
IdHTTP.Free;
end;
finally
Params.Free;
end;
except
on E: Exception do
ShowMessage('Error: ' + E.ToString);
end;
end;