Pleas help, Synapse / Indy HttpSend problem lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- patyit · 2026-01-01 12:06 Hi all ! Please help implementig HTTP Rest API belowe: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i curl -X ‘POST’ \ ‘https://api.demoeotpremnica.mfin.gov.rs/public/documents/requests’\-H ‘accept: */*’ \-H ‘Api-key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx’\-H ’Content-Type:multipart/form-data’\-F ’RequestId=20250310-001’\-F ’File=@despatch-advice0603.xml;type=text/xml’With Synapse THTTPSend : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function EUpload(ubl: string): boolean;const  CRLF = #13#10;var  Htt : THTTPSend;  fst : TFileStream;  url, res, bou, s : string;begin  Result := False;  fst := TFileStream.Create(ubl, fmOpenRead);  Htt := THTTPSend.Create;  try    Htt.Protocol := '1.1';    Htt.UserAgent:= 'Mozilla/5.0';     bou := IntToHex(Random(MaxInt), 8)+'_Synapse_boundary';    Htt.MimeType := 'multipart/form-data; boundary='+bou;     s := '--'+bou+CRLF+         'Content-Disposition: form-data; name="RequestId"'+CRLF+         'Content-Type: text/plain'+CRLF+CRLF;    WriteStrToStream(Htt.Document, s);    WriteStrToStream(Htt.Document, '20250310-001');     s := CRLF+'--'+bou+CRLF+        'Content-Disposition: form-data; name="File"; '+        'filename="despatch-advice0603.xml"'+CRLF+      'Content-Type: text/xml'+CRLF+CRLF;    WriteStrToStream(Htt.Document, s);    Htt.Document.CopyFrom(fst, 0);  WriteStrToStream(Htt.Document, CRLF+'--'+bou+'--'+CRLF);     Htt.MimeType := 'multipart/form-data; boundary='+bou;    Htt.Headers.Add('Content-Type: multipart/form-data');    Htt.Headers.Add('accept: */*');    Htt.Headers.Add('Api-key: xxxxxxxx- xxxx-xxxx-xxxx-xxxxxxxxxxxxx');  //      url := 'https://api.demoeotpremnica.mfin.gov.rs/public/documents/requests';  if Htt.HTTPMethod('POST', url) then begin      res := ReadStrFromStream(Htt.Document, Htt.Document.Size);      if Htt.ResultCode = 200 then        Result := True      else        MessageDlg('Error: ('+IntToStr(Htt.ResultCode)+') '+#13+res+#13#13+                                          Htt.ResultString, mtError, [mbOk], 0);    end else      MessageDlg('Error, check internet connection ...', mtError, [mbOk], 0);  finally    Htt.Free;    fst.Free;  end;end; ’      Abawe cod reporter errod : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Error: (400) {"type":"https://tools.ietf.org/html/rfc9110#secti on-15.5.1","title":"One or more validation errors occurred.","status": 400,"errors":[{"code":"Validation","propertyName":"File","detail":"The File field is required."},{"code":"Validation","propertyName":"Request Id","detail":"The RequestId field is required."}],"traceId":"00- 1e937cad8ee7c611d8505e962f92094e-317152e86f46437f-01"} Bad RequestWith Indy TIdHTTP : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TFDataMod.EOtprUpload(ubl, rid: string): boolean;var  idHttp : TIdHTTP;  idHSSL : TIdSSLIOHandlerSocketOpenSSL;  pod : TIdMultipartFormDataStream;  url, res, cir : string;begin  Result := False;   IdOpenSSLSetLibPath(IPat); // path to ssl libs  idHttp := TIdHTTP.Create;  try    idHSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);    try      idHSSL.SSLOptions.Mode := sslmClient;      idHSSL.SSLOptions.SSLVersions := [sslvTLSv1_1,sslvTLSv1_2];      idHttp.IOHandler := idHSSL;      idHttp.HandleRedirects := True;      idHttp.ReadTimeout     := 30000;      idHttp.Request.Accept  := '*/*';      idHttp.Request.ContentType := 'multipart/form-data';      idHttp.Request.CustomHeaders.AddValue('Api-key', 'xxxxxxxx-xxxx-xxxx- xxxx-xxxxxxxxxxxxx');      idHttp.HTTPOptions := idHttp.HTTPOptions+[hoNoProtocolErrorException];      pod := TIdMultipartFormDataStream.Create;      try        pod.AddFormField('RequestId', rid); // reqiestid 20250310-001        pod.AddFile('File', ubl, 'text/xml'); // ubl file despatch- advice0603.xml        url := 'https://api.demoeotpremnica.mfin.gov.rs/public/documents/requests';      try          res := idHttp.Post(url, pod);          if idHttp.ResponseCode = 200 then            Result := True          else            MessageDlg('Error: '+IntToStr(idHttp.ResponseCode)+' '+                        idHttp.ResponseText, mtError, [mbOk], 0);      except          on E: Exception do begin            MessageDlg('Error, check internet connection ...'+#13#13+                      E.Message, mtError, [mbOk], 0);          end;        end;    finally        pod.Free;      end;    finally      idHSSL.Free;    end;  finally    idHttp.Free;  end;end;Abawe cod reporter errod : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Error: 405 HTTP/1.1 405 Not AllowedI would be grateful if anyone has any ideas what the problem could be ! ---------------------------------------------------------------------- Thaddy · 2026-01-01 13:09 Wrong ssl dll's as usual. Too old. ---------------------------------------------------------------------- paweld · 2026-01-01 13:26 for synapse: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  httpsend, ssl_openssl3, ssl_openssl3_lib, synautil, blcksock, synachar; procedure TForm1.Button1Click(Sender: TObject);var  sl: TStringList;begin  sl := TStringList.Create;  if PostXmlFile('https:// api.demoeotpremnica.mfin.gov.rs/public/documents/requests', 'xxxxxxxx- xxxx-xxxx-xxxx-xxxxxxxxxxxxx', '20250310-001', 'd:\test.xml', sl) then    ShowMessage('Response:' + CRLF + sl.Text)  else    ShowMessage('Error:' + CRLF + sl.Text);  sl.Free;end; function TForm1.PostXmlFile(url, apikey, requestid, xmlfilename: String; var outdata: TStringList): Boolean;var  hc: THTTPSend;  b, s: String;  sl: TStringList;begin  outdata.Clear;  Result := False;  if not FileExists(xmlfilename) then    raise Exception.Create('File not exists!');  sl := TStringList.Create;  sl.LoadFromFile(xmlfilename);  b := IntToHex(Random(MaxInt), 8);  hc := THTTPSend.Create;  try    s := '--' + b + CRLF;    s := s + 'Content-Disposition: form-data; name="RequestId"' + CRLF + CRLF + requestid + CRLF;    s := s + '--' + b + CRLF;    s := s + 'Content-Disposition: form-data; name="File"; filename="' + xmlfilename +'"' + CRLF;    s := s + 'Content-Type: text/xml' + CRLF + CRLF;    s := s + sl.Text;    s := s + CRLF + '--' + b + '--' + CRLF;    hc.Document.Clear;    hc.Document.Write(s[1], Length(s));    hc.Document.Position := 0;    hc.MimeType := 'multipart/form-data; boundary=' + b;    hc.Headers.Insert(0, 'Accept: */*');    hc.Headers.Add('Api-key: ' + apikey);    hc.KeepAlive := False;    Result := hc.HTTPMethod('POST', URL);    if Result and ((hc.ResultCode div 100) <> 2) then      Result := False;    if Result then      outdata.LoadFromStream(hc.Document)    else    begin      outdata.LoadFromStream(hc.Document);      outdata.Text := Format('[%d] - %s > %s', [hc.ResultCode, hc.ResultString, outdata.Text]);    end;  finally    hc.Free;    sl.Free;  end;end; ---------------------------------------------------------------------- Thaddy · 2026-01-01 14:25 Yes, but that still assumes correct and current openssl libraries. ---------------------------------------------------------------------- patyit · 2026-01-01 17:18 Hi, Paweld and Thaddy ! Thanks for the quick replies and help ! Paweld's suggestion with the Synapse variant worked perfectly ! Synapse code is paired with ssl3 libraries under Lazarus ... I still have a problem with the Indy variant which is under Delphi 7 (Indy 10.6 I think), here it is still paired with the old ssl1.1 libraries, it is likely that Thaddy is right and it needs to be updated to ssl3 ... I have a problem with this, that in the eInvoice system the Delphi 7 and Indy pair works perfectly, I don't quite understand how it wont works with the eDespatchAdvice system? If I update to ssl3 then what will happen to eInvoice, do you think that what worked with ssl1 will work with ssl3 ? ---------------------------------------------------------------------- paweld · 2026-01-01 18:34 I don't know if it's an OpenSSL issue, but in the case of Indy and TIdMultipartFormDataStream, redundant headers (transfer encoding, content type) are added to the request content, and the API may not recognize them. Check by manually generating the request content: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  IdHTTP, IdSSLOpenSSL; const  CRLF = #13#10; procedure TForm1.Button1Click(Sender: TObject);var  sl: TStringList;begin  sl := TStringList.Create;  if PostXmlFile('https://api.demoeotpremnica.mfin. gov.rs/public/documents/requests', 'xxxxxxxx-xxxx-xxxx-xxxx- xxxxxxxxxxxxx', '20250310-001', 'd:\test.xml', sl) then    ShowMessage('Response:' + CRLF + sl.Text)  else    ShowMessage('Error:' + CRLF + sl.Text);  sl.Free;end; function TForm1.PostXmlFile(url, apikey, requestid, xmlfilename: String; var outdata: TStringList): Boolean;var  hc: TIdHTTP;  hcssl : TIdSSLIOHandlerSocketOpenSSL;  b, s: String;  sl: TStringList;  msin, msout: TMemoryStream;begin  outdata.Clear;  Result := False;  if not FileExists(xmlfilename) then    raise Exception.Create('File not exists!');  sl := TStringList.Create;  sl.LoadFromFile(xmlfilename);  b := IntToHex(Random(MaxInt), 8);  //IdOpenSSLSetLibPath(IPat); // path to ssl libs  msin := TMemoryStream.Create;  msout := TMemoryStream.Create;  hc := TIdHTTP.Create;  hcssl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);  try    hcssl.SSLOptions.Mode := sslmClient;    hcssl.SSLOptions.SSLVersions := [sslvTLSv1_1,sslvTLSv1_2];     hc.IOHandler := hcssl;    //request body    s := '--' + b + CRLF;    s := s + 'Content-Disposition: form- data; name="RequestId"' + CRLF + CRLF + requestid + CRLF;    s := s + '--' + b + CRLF;    s := s + 'Content-Disposition: form-data; name="File"; filename="' + xmlfilename +'"' + CRLF;    s := s + 'Content-Type: text/xml' + CRLF + CRLF;    s := s + sl.Text;    s := s + CRLF + '--' + b + '--' + CRLF;    msin.Write(s[1], Length(s));    msin.Position := 0;    //    hc.HandleRedirects := True;    hc.ReadTimeout     := 30000;    hc.Request.Accept  := '*/*';    hc.Request.ContentType := 'multipart/form-data; boundary=' + b;    hc.Request.CustomHeaders.AddValue('Api-key', 'xxxxxxxx-xxxx-xxxx-xxxx- xxxxxxxxxxxxx');    hc.HTTPOptions := hc.HTTPOptions + [hoNoProtocolErrorException];    hc.Post(url, msin, msout);    msout.Position := 0;    Result := (hc.ResponseCode div 100) = 2;    outdata.LoadFromStream(msout);    if not Result then      outdata.Text := Format('[%d] - %s > %s', [hc.ResponseCode, hc.ResponseText, outdata.Text]);  finally    hcssl.Free;    hc.Free;    sl.Free;    msin.Free;    msout.Free;  end;end; You can also use Indy with the latest version of SSL: https://forum.la zarus.freepascal.org/index.php/topic,69748.msg542222.html#msg542222 ---------------------------------------------------------------------- patyit · 2026-01-01 19:59 Hi Paweld ! Unfortunately this conversion did not help, the operation still ends with "Error 405 Not Allowed". Now it's almost certain, should I try SSL3 ?! Anyway, thanks for the help, I learned something again ! ---------------------------------------------------------------------- rvk · 2026-01-01 20:39 Quote from: patyit on January 01, 2026, 01:06:21 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     Htt.MimeType := 'multipart/form-data; boundary='+bou;    Htt.Headers.Add('Content-Type: multipart/form-data');    Htt.Headers.Add('accept: */*');    Htt.Headers.Add('Api-key: xxxxxxxx- xxxx-xxxx-xxxx-xxxxxxxxxxxxx');  //        I don't do "indy". But for Synapse you have Htt.MimeType (which adds Content-Type) AND a manually added header for Content-Type (both with multipart). In this case, you manually added Content-Type doesn't include the boundary, so the server doesn't see any of the fields given to it (hence the many errors about missing fields). Remove the manually added ( Add('Content-Type') ) and see if it works better. ---------------------------------------------------------------------- Remy Lebeau · 2026-01-01 22:43 Quote from: paweld on January 01, 2026, 07:34:31 pmin the case of Indy and TIdMultipartFormDataStream, redundant headers (transfer encoding, content type) are added to the request content, and the API may not recognize them. You can disable that behavior by setting the TIdFormDataField.ContentType and TIdFormDataField.ContentTransfer properties to blank strings. Quote from: patyit on January 01, 2026, 08:59:10 pmUnfortunately this conversion did not help, the operation still ends with "Error 405 Not Allowed". I would suggest attaching a TIdLogFile component to the TIdHTTP.Intercept property, and look at the server's actual response. I'm guessing that you are being redirected to another URL, and that URL doesn't accept POST'ed data. That could explain why you are getting a 405 error. ---------------------------------------------------------------------- paweld · 2026-01-02 05:43 Quote from: Remy Lebeau on January 01, 2026, 11:43:03 pmYou can disable that behavior by setting the TIdFormDataField.ContentType and TIdFormDataField.ContentTransfer properties to blank strings. Hi Remy, The ContentType property cannot be empty: https://github.com/IndySocke ts/Indy/blob/master/Lib/Protocols/IdMultipartFormData.pas#L844-L852 ---------------------------------------------------------------------- patyit · 2026-01-03 17:51 Hello everyone ! Linux (XUbuntu 24.04 x64) with Lazarus, Synapse package, OpenSSL3 everything works ! In the past few days I have been doing tests to see if it is worth converting a relatively large Delphi7 ERP application that is on WinXP with Delphi 7 32bit to Lazarus, all of this is installed in VitualBox ... I suspect that the source of the problems is WinXP/VirtualBox, which works with OpenSSL1 (except for the new eDespatchAdvice system), but nothing works with OpenSSL3 ! I installed OpenSSL3 32bit (first v.3.5.4, then v.3.6) on WinXP, I have the appropriate DLLs, (libssl-3.dll, libcrypto-3.dll) I copied these into the program's execution directory (just like I did before in the case of OpenSSL1 ssleay32.dll, libeay32.dll bitness is 32), but nothing ! And it looks like there's no way to install Indy OpenSSL3 support on Delphi 7 (by MWASoftware)... but that's no problem if Synapse works ! Based on the above description, any comforting ideas ? ---------------------------------------------------------------------- Remy Lebeau · 2026-01-05 18:21 Quote from: patyit on January 03, 2026, 06:51:18 pmAnd it looks like there's no way to install Indy OpenSSL3 support on Delphi 7 (by MWASoftware)... Indy itself still supports Delphi 7, but I can't attest to any of the 3rd party OpenSSL3 addons, like MWASoftware's IndySecOpenSSL, or JPeterMugaas's TaurusTLS. Any issues you have with them will have to be taken up with their respective authors. ---------------------------------------------------------------------- rvk · 2026-01-06 10:26 Quote from: patyit on January 03, 2026, 06:51:18 pm... but that's no problem if Synapse works !Does Synapse work for you now on XP and OpenSSL3? If not... you do know that you need to use ssl_openssl3 in your uses clause and it's best to take the latest source from https://github.com/geby/synapse. If it still doesn't work... write a clear post about what is not working and what you did to try to get it to work. ---------------------------------------------------------------------- patyit · 2026-01-21 09:25 Greetings to all ! Thank you everyone for your help, the problem was caused by my own mistake and not by the OpenSSL libraries, Synapse or the Indy package ! What happened was that I misspelled the URL address, one letter was entered incorrectly, which I recorded in the program configuration, so it was not obvious ... Thank you again for the helpfulness from everyone who commented on the topic, and sorry for my own stupidity !