0

I am using Delphi 2009, Indy ver 10.5498 together with libeay32.dll and ssleay32.dll from the zip file openssl-1.0.2r-i386-win32 at https://indy.fulgan.com/SSL/. Range checking is turned on in project options and not turned off anywhere.

Using the code below, which I generated with Remy's help from this post, I can upload data to an API on a server via https when running in the IDE with debugging turned on or from a compiled exe generated with debugging tuned on.

However, if I build a release version then whether I run it through the IDE or as an exe I get a range check error on the line result := HttpClient.Post(THE_URL, FormData);

The params list simply contains the to, from, subject, body etc and there is no attachment in the filenames list ie filenames.Count = 0. U_GeneralRoutines.TheFileStoreFolder is simply a folder inside ProgramData where the SSL DLL's are stored.

As the debugger didn't catch this I put in the two showmessage lines before and after the call. When built as debug, both messages get shown and the post succeeds. When built as release the first one gets displayed and then I get the range check error.

I don't suppose there is a bug in the POST code, so what can be going wrong?

function UploadToAPI(params, filenames: TStrings): string;
var
  HttpClient: TIdHttp;
  IdSSLIOHandler: TIdSSLIOHandlerSocketOpenSSL;
  FormData : TIdMultiPartFormDataStream;
  i : integer;
  PathToSSLlibraries : string;
begin
  FormData := TIdMultiPartFormDataStream.Create;
  HttpClient:= TIdHttp.Create;
  IdSSLIOHandler:= TIdSSLIOHandlerSocketOpenSSL.Create;

  PathToSSLlibraries := IncludeTrailingPathDelimiter(U_GeneralRoutines.TheFileStoreFolder);
  IdOpenSSLSetLibPath(PathToSSLlibraries);  //set path to libeay32.dll and  ssleay32.dll in the common ProgramData folder

  HttpClient.IOHandler := IdSSLIOHandler;
  HttpClient.Request.CustomHeaders.FoldLines := true ; 

  try
    for i := 0 to params.Count - 1 do
      FormData.AddFormField(params.Names[i], params.ValueFromIndex[i]);

    for i := 0 to filenames.Count - 1 do
      FormData.AddFile('attachment', filenames[i]);   //works with ver 10.5498 but not with 10.2.5

    //add authorisation header
    HttpClient.Request.CustomHeaders.Add('Authorization:Basic ' + ATHORISATION_STR);  //byte64 encoding of the api key   

     HttpClient.ProtocolVersion := pv1_1;  //get the full server response which allows for just one try-except
     HttpClient.HTTPOptions := HttpClient.HTTPOptions + [hoKeepOrigProtocol, hoNoProtocolErrorException, hoWantProtocolErrorContent];

     try
     showmessage('about to post');
     result := HttpClient.Post(THE_URL, FormData);   //post to the api
     showmessage('posted');

     except
      on E: Exception do
      begin
      result := E.ClassName + ': ' + E.message;
      raise;
      end;
     end; //try
  finally
    FormData.Free;
    IdSSLIOHandler.free;
    HttpClient.free;
  end;

I appreciate that this type of scenario is often caused by unintialised variables in the release version that would get automatically initialised when in the IDE / debug. But all the variables in my procedure do seem to be getting initialised before the call to POST.

user2834566
  • 775
  • 9
  • 22
  • There is no diagnostic info to troubleshoot what is happening. You are going to have to step into Indy's source code to find the error. You can enable debug info while still making a release build so you can step through the code. – Remy Lebeau May 26 '19 at 17:09
  • I'll have another go tomorrow but it takes a long time stepping through code I don't understand, especially as it seems to call some procedures many times. It's a shame I can't make the debugger stop at the offending line of Indy's code. It might be easier just change the flags used by 'release' one by one to the same as those used in 'debug' until it no longer gives the error and then leave that option turned off when I distribute it! – user2834566 May 26 '19 at 21:26
  • "*It's a shame I can't make the debugger stop at the offending line of Indy's code*" - you can if you compile it with debug info enabled, and stack frames too. Then when the error occurs, you can jump right to the offending code, and look at the stack trace leading up to the error – Remy Lebeau May 27 '19 at 02:23
  • Thanks Remy. I did some work including putting {$R-} and {$R+} around the POST but still got the error on that line. Odd though as a test bed program didn't show the error. Indy logs of both test bed and the real application showed I was passing sensible data in both cases. Then suddenly the error in the application stopped. The only code change was to remove the two lines setting the protocol as I saw from your code that you reset this to 1.0 anyway. My question said I didn't really think the POST had a range check error in it. I can only assume the compiler had got itself in a twist! – user2834566 May 27 '19 at 18:05

0 Answers0