Please help me implement this CURL script with Indy:
You are calling
TIdHTTP.Post() with a filename as a parameter, which will
POST the contents of that file as-is as the entire HTTP request body. That is not what you need in this situation.
So what you have to do is to read the file TAM721TEST-test.xml and either construct the form content yourself (by url encoding the data and creating a key-value list in the form format) or simply by putting the data in a key-value string list and passing it to the .Post method of IdHTTP
That is the wrong advice in this situation. You can clearly see in the curl example that the request needs to be in
multipart/form-data format, but what you suggest will send the request in
application/x-www-form-urlencoded format instead.
TIdHTTP.Post() has an overload which takes a
TIdMultipartFormDataStream to handle
multipart/form-data requests, eg:
function sales_invoice_ubl_upload(url, key, ubl, rid: string): string;
var
idHttp : TIdHTTP;
postData: TIdMultipartFormDataStream;
begin
Result := '';
idHttp := TIdHTTP.Create;
try
idHttp.HandleRedirects := False;
idHttp.ReadTimeout := 30000;
idHttp.Request.Accept := 'text/plain';
idHttp.Request.ContentType := 'multipart/form-data';
idHttp.Request.CustomHeaders.Values['ApiKey'] := key;
postData := TIdMultipartFormDataStream.Create;
try
url := url + '/api/publicApi/sales-invoice/ubl/upload?requestId=' + TIdURI.ParamsEncode(rid) + '&sendToCir=No';
postData.AddFile('ublFile', ubl, 'text/xml');
try
Result := idHttp.Post(url, postData);
except
on E: EIdHTTPProtocolException do begin
if E.ErrorCode = 400 then
MessageDlg('Request Error !'+#13#13+
IntToStr(E.ErrorCode) + ' ' + E.Message,
mtError, [mbOk], 0)
else
MessageDlg('Error: '+IntToStr(E.ErrorCode) + ' ' + E.Message,
mtError, [mbOk], 0);
end;
on E: Exception do begin
MessageDlg('Check the Internet connection ...'+#13#13+
E.Message, mtError, [mbOk], 0);
end;
end;
finally
postData.Free;
end;
finally
idHttp.Free;
Sleep(200);
end;
end;
Also note that I moved the handling of the HTTP response code inside of the
except block. By default,
TIdHTTP raises
EIdHTTPProtocolException if the HTTP response code indicates the request failed. If you want to handle the
TIdHTTP.ResponseCode yourself without raising the exception, you would need to specify the
hoNoProtocolErrorException flag in the
TIdHTTP.HTTPOptions property, eg:
function sales_invoice_ubl_upload(url, key, ubl, rid: string): string;
var
idHttp : TIdHTTP;
postData: TIdMultipartFormDataStream;
res: string;
begin
Result := '';
idHttp := TIdHTTP.Create;
try
idHttp.HandleRedirects := False;
idHttp.ReadTimeout := 30000;
idHttp.Request.Accept := 'text/plain';
idHttp.Request.ContentType := 'multipart/form-data';
idHttp.Request.CustomHeaders.Values['ApiKey'] := key;
idHttp.HTTPOptions := idHttp.HTTPOptions + [hoNoProtocolErrorException];
postData := TIdMultipartFormDataStream.Create;
try
url := url + '/api/publicApi/sales-invoice/ubl/upload?requestId=' + TIdURI.ParamsEncode(rid) + '&sendToCir=No';
postData.AddFile('ublFile', ubl, 'text/xml');
try
res := idHttp.Post(url, postData);
if idHttp.ResponseCode = 200 then
Result := res
else if idHttp.ResponseCode = 400 then
MessageDlg('Request Error !'+#13#13+
IntToStr(idHttp.ResponseCode) + ' ' + idHttp.ResponseText,
mtError, [mbOk], 0)
else
MessageDlg('Error: '+IntToStr(idHttp.ResponseCode) + ' ' + idHttp.ResponseText,
mtError, [mbOk], 0);
except
on E: Exception do begin
MessageDlg('Check the Internet connection ...'+#13#13+
E.Message, mtError, [mbOk], 0);
end;
end;
finally
postData.Free;
end;
finally
idHttp.Free;
Sleep(200);
end;
end;