Jump to content

Keesver

Members
  • Content Count

    81
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by Keesver


  1. There is no error, the call from the remote server back into the client simply does not reach it's destination. The remote server does receive a HTTPBeforeCommand event, this line is being called on the server: 

    Writeln('Command redirected to DESTINATION: ' + dest_ip + ' - ' +  dest_port.ToString);

    The connection between client and server seems to be working. When I use telnet to connect to the server, I do get a response from the server when I execute the 'HELP' command. Similar the call to SendCmd('DEST') in our client returns '200 OK'. Also 'netstat' shows an active connection between client and server.

     

    Maybe my question is: what do I need more that an active (TCP) connection between client and server? 

    Does the HTTP Proxy server requires additional channels to be opened to make this work? Or should the single channel suffice?


  2. Hello,

    We want to add remote support to our application and for this we want to use two idHttpProxyServer's chained together. The first server resides on our public server, the second instance resides on the customers network. This is the code we are using:

     

    public server:

    constructor TRemoteServer.Create(IP: string; Port: Integer);
    begin
      IdHTTPProxyServer1 := TIdHTTPProxyServer.Create(nil);
      IdHTTPProxyServer1.ReuseSocket := rsTrue;
      IdHTTPProxyServer1.DefaultPort := Port;
    
      IdHTTPProxyServer1.OnHTTPBeforeCommand := HTTPBeforeCommandHandler;
    
      var handler := IdHTTPProxyServer1.CommandHandlers.Add;
      handler.Command := 'DEST';
      handler.HelpSuperScript := 'Sets caller as a DESTINATION for remote support (usage DEST PIN URL)';
      handler.OnCommand := DEST_Handler;
    
      if (IP <> '') and (Port <> 0) then
      begin
        Writeln('Starting server, binding to: ' + IP + '-' + Port.ToString);
        var bind := IdHTTPProxyServer1.Bindings.Add;
        bind.IP := IP;
        bind.Port := Port;
        bind.ReuseSocket := rsTrue;
      end else
        Writeln('Starting server, default binding');
    
      IdHTTPProxyServer1.Active := True;
    
      Writeln('Server running, listening on: ' + IdHTTPProxyServer1.Bindings[0].IP + ' - ' + IdHTTPProxyServer1.Bindings[0].Port.ToString);
    end;
    
    procedure TRemoteServer.DEST_Handler(ASender: TIdCommand);
    begin
      Writeln(ASender.RawLine);
      dest_ip := ASender.Context.Binding.PeerIP;
      dest_port := ASender.Context.Binding.PeerPort;
      dest_pin := ASender.Params[0];
      dest_url := ASender.Params[1];
      Writeln('Address: ' + dest_ip + ' - ' + dest_port.ToString);
    end;
    
    procedure TRemoteServer.HTTPBeforeCommandHandler(AContext: TIdHTTPProxyServerContext);
    begin
      if dest_ip <> '' then
      begin
        Writeln('Command redirected to DESTINATION: ' + dest_ip + ' - ' +  dest_port.ToString);
    
        var tempIO := TIdIOHandlerStack.Create(AContext.OutboundClient);
        tempIO.ReuseSocket := rsTrue;
        // tempIO.BoundIP := '10.0.2.4'; //IdHTTPProxyServer1.Bindings[0].IP;
        tempIO.BoundPort := 443; // IdHTTPProxyServer1.Bindings[0].Port;
    
        var tempProxy := TIdConnectThroughHttpProxy.Create(AContext.OutboundClient);
        tempProxy.Enabled := True;
        tempProxy.Host := dest_ip;
        tempProxy.Port := dest_port;
        tempIO.TransparentProxy := tempProxy;
    
        AContext.OutboundClient.IOHandler := tempIO;
      end;
    end;

    Client code:

    procedure TForm1.ConnectToRemote(Connection: string);
    begin
      HTTPProxyServer.Active := False;
      IdTCPClient1.Disconnect;
    
      IdTCPClient1.Host := <SERVER IP/URL>; //Connection.Split([':'])[0];
      IdTCPClient1.Port := <SERVER PORT>; // Connection.Split([':'])[1].ToInteger;
      IdTCPClient1.Connect;
    
      // Tell server we are there
      IdTCPClient1.SendCmd('DEST 4444 https://abc.com');
    
      HTTPProxyServer.Bindings.Clear;
      var bind := HTTPProxyServer.Bindings.Add;
      bind.IP := IdTCPClient1.Socket.Binding.IP;
      bind.Port := IdTCPClient1.Socket.Binding.Port;
      bind.ReuseSocket := rsTrue;
    
      HTTPProxyServer.Active := True;
    end;

    This setup works when we run both server and client on the same computer. However, when we put the server on a remote computer, it does not work. 

     

    Should this work, or do we need other means to make this happen?

     

    Thanks and regards,

    Kees


  3. ok, will do.

     

    I was trying to use FDBatchMove + FDBatchMoveSQLWriter to import a table from MSSql into Interbase. The internal table generator uses 'Int64' for such fields, am I using the wrong generator?

     

    image.thumb.png.e27cb23f5c48bd87adb1df49981bf1a6.png

     

    Greetings,

    Kees


  4. Which data type should be used for Int64 values?

     

    I tried Int64 and bigint, both return an error:

    create table Test(ID Int64)

    create table Test(ID bigint)

     

    Error message:

    Project IBTest.exe raised exception class EIBNativeException with message '[FireDAC][Phys][IB]Dynamic SQL Error
    SQL error code = -607
    Invalid command
    Specified domain or source column does not exist'.

     

    Thanks


  5. Hello,

     

    We are looking at safely handling queued calls. The problem is that under some circumstances the object used inside the queued method is freed before the method gets executed. This raises an exception. Can we use this construct to fix it:

     

    type
      ITest = interface
        ['{10DD63EA-490E-45D5-9250-72AEB1FF6D19}']
        function GetName: string;
        procedure SetName(const Value: string);
      end;
    
      TTest = class(TInterfacedObject, ITest)
      protected
        FName: string;
    
        function GetName: string;
        procedure SetName(const Value: string);
      end;
    
      TObjectWithTest = class
      private
        FTest: ITest;
    
      public
        constructor Create(const AInterface: ITest);
        procedure   QueueCallSafe([weak]AInterface: ITest);
        function GetTest: ITest;
      end;
    
    implementation
    
    procedure TObjectWithTest.QueueCallSafe([weak]AInterface: ITest);
    begin
      TThread.ForceQueue(nil, procedure begin
        if AInterface = nil then
          ShowMessage('nil') else
          ShowMessage('not nil');
      end);
    end;
    
    procedure TForm1.Button3Click(Sender: TObject);
    begin
      var obj := TObjectWithTest.Create(TTest.Create);
      obj.QueueCallSafe(obj.GetTest);
      
      // Free object --> [weak] reference will be cleared (no exception!!)
      obj.Free;
    end;

     


  6. We are using EV (extended validation) code signing certificates to add trust, this should prevent Windows from asking additional confirmation when installing our software. In addition, when the certificate is renewed, trust statistics are kept because the new certificate is recognized as being the same as the 'old' one. Requesting such a certificate requires extra steps during the certification process.
    (I can send you an installation url if you want to see how this works out)


  7. Thanks everyone for your comments. Enough information to look into.

    The Delphi language guide looks like a good starting point, this is something the person can do by themselves.

     

    @David: your comments include a good list of topics that need to be touched in the learnings. 

     

    Greetings,

    Kees Vermeulen

     

     


  8. We are preparing to release our software using Thinfinity as an alternative to the desktop version. We did some tests and this showed it worked pretty good. We do want to change our application to make it look more 'web' alike. This means hiding the menu for example. Can't tell yet how performant it will be. You do need a server capable of handling the number of concurrent users of your application though.

    We were told RDS licenses are not required because Thinfinity does not use the RDS services (which I can confirm after running multiple sessions on the same server without such license). I can't say if Microsoft agrees on this....


  9. 15 hours ago, Bob Devine said:

    @Keesver We have a private WeMe group and some more recent updates. Email me on gmail.com (name at the end of this post). The deal is that I confirm with Alexander that you're a registered user then you can get access. 

     

    Cheers, Bob (rlsdevine@)

     

    Thanks for your reply. Problem is that we are not a 'registered user' of paxCompiler.

    We are investigating possibilities of adding scripting to our application and paxCompiler seems to have all the right specifications. Maybe someone is willing to sell their license to us?

    I have contacted Apex but got no reply (yet).

×