#1 2014-05-29 09:12:55

martin.suer
Member
Registered: 2013-12-15
Posts: 76

How to get IP-Addr. of caller of an Interface based service method

Hi,

in an interface based service method I can access the ServiceContext with the Request and the Factory. I can get access to all sort of information, however I haven't found out how to get the IP-Address of the caller of the method.

Is that possible?

Martin

Offline

#2 2014-05-29 10:59:39

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: How to get IP-Addr. of caller of an Interface based service method

You have the RemoteIP property in TAuthSession.

Or just call

IP := FindIniNameValue(pointer(ServiceContext.Request.Call.InHead),'REMOTEIP: ')

Offline

#3 2014-05-29 12:07:37

martin.suer
Member
Registered: 2013-12-15
Posts: 76

Re: How to get IP-Addr. of caller of an Interface based service method

well, in my case that returns an empty RawUTF8
(XE5, Win8.1)

and InHead contains:
'Cache-Control: no-cache'#$D#$A'Connection: Keep-Alive'#$D#$A'Pragma: no-cache'#$D#$A'Content-Length: 3'#$D#$A'Content-Type: application/json; charset=UTF-8'#$D#$A'Accept: */*'#$D#$A'Accept-Encoding: synlz'#$D#$A'Host: localhost:888'#$D#$A'User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; Synopse mORMot 1.18 TWinHTTP)'#$D#$A'ConnectionID: FD00000060000009'#$D#$A

Offline

#4 2014-05-29 13:33:04

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: How to get IP-Addr. of caller of an Interface based service method

Are you using the latest 1.18 version of the source code tree?

Which server class do you use?
Normally, THttpServer.Process() will put the 'RemoteIP: ' header via THttpServerSocket.HeaderGetText.
And THttpAPIServer.Execute should call RetrieveHeaders() which should set the 'RemoteIP: ' header...

Offline

#5 2014-05-29 14:52:06

martin.suer
Member
Registered: 2013-12-15
Posts: 76

Re: How to get IP-Addr. of caller of an Interface based service method

I am using the latest nightly build and register the server with the following code:

    fServer := TSQLRestServerDB.Create(FModel, ChangeFileExt(paramstr(0), '.db3'),True);
    fServer.CreateMissingTables;
    fServer.ServiceRegister(TAuftragsbearbeitung,[TypeInfo(IFuseAuftragsbearbeitung)],sicSingle);
    fHTTPServer := TSQLHttpServer.Create(PORT_NAME,[fServer],'+',useHttpApiRegisteringURI);

The client is created as follows:

  fClient := TSQLHttpClient.Create('localhost', PORT_NAME, FModel);
  fClient.SetUser('User', 'synopse');
  fClient.ServiceRegister([TypeInfo(IFuseAuftragsbearbeitung)], sicSingle);

Offline

#6 2014-05-30 19:27:08

martin.suer
Member
Registered: 2013-12-15
Posts: 76

Re: How to get IP-Addr. of caller of an Interface based service method

solved....

just found out that if I use the IP-Address instead of 'localhost' while creating the client, everything works like expected and I can see the REMOTEIP

smile

Offline

#7 2014-05-30 19:39:26

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: How to get IP-Addr. of caller of an Interface based service method

So it sounds like a socket feature... not a mORMot bug...
wink

In fact, if you connected at localhost, there is no "remote" IP, but only a "local" IP...

Offline

#8 2015-06-22 00:47:17

houdw2006
Member
Registered: 2015-05-23
Posts: 48

Re: How to get IP-Addr. of caller of an Interface based service method

Is this a bug? RemoteIP is NOT the server's IP.

I am using the Synopse Framework 1.18.1500 under XE7. I called the service by Firefox.

RemoteIP in THttpServerRequest and TServiceRunningContext is not the expected.

when the next line of code is  called from the context of implementation of the service function:

          RemoteIP := FindIniNameValue(pointer(ServiceContext.Request.Call.InHead),'REMOTEIP: ');

I get the Callee's IP instead of the Caller's IP! ( to call a service deployed in a remote server from another client machine, the RemoteIP is the server's IP, not the client IP).

================================ Details ==============================
In function TCustomHttpServer.Request(Ctxt: THttpServerRequest): cardinal;

Ctxt.Method:  GET
Ctxt.URL: /root/AddService/Add?A=30&B=45
Ctxt.InHeaders: Param:

InHeader:
   Host: 103.30.231.6:9800
   User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
   Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
   Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
   Accept-Encoding: gzip, deflate
   Connection: keep-alive
   RemoteIP: 103.30.231.6



In the Service function Add, I Called:
        RemoteIP := := FindIniNameValue(pointer(ServiceContext.Request.Call.InHead),'REMOTEIP: ');

And I get 103.30.231.6  (Synopse Framework Version: 1.18.1500, Delphi XE7)

The REMOTEIP is the Callee's IP, not the Caller's IP.

Offline

#9 2015-06-22 05:46:42

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: How to get IP-Addr. of caller of an Interface based service method

Which HTTP server class did you test?

Sockets or HTTP.sys?

Offline

#10 2015-06-22 10:45:23

houdw2006
Member
Registered: 2015-05-23
Posts: 48

Re: How to get IP-Addr. of caller of an Interface based service method

Thanks for you reply, ab.

I registered the Service function in the client side by means of the TSQLRestServerDB, and the client which connect to another remote AppServer through TSQLHttpClient, and runs in still another remote server. 

When the AppServer and Client both are running, I call the service function by entering the GET command in the Address box of Firefox which running in my laptop.


  //code fragments of the client side:

  TCustomHttpServer = class(TSQLHttpServer)
  protected
    /// override the server response - must be thread-safe
    function Request(Ctxt: THttpServerRequest): cardinal; override;
  end;

  ....................

    Model: TSQLModel;
    AppServer: TSQLHttpClient;
    RestServer: TSQLRestServerRemoteDB;
    HttpServer: TCustomHttpServer;


    .......................
    Model := CreateDataModel(AppServerHttpRoot);     // AppServerHttpRoot, AppServerIP, AppServerPort and HttpServicePort are Properties.

    AppServer := TSQLHttpClient.Create(AppServerIP, AppServerPort, aModel);

    RestServer := TSQLRestServerRemoteDB.Create(AppServer);
    RestServer.ServiceRegister(TAddService, [TypeInfo(IAddService)], sicShared);

    HttpServer := TCustomHttpServer.Create(HttpServicePort, [RestServer], '+', useHttpApiRegisteringURI);
    HttpServer.AccessControlAllowOrigin := '*'; // allow cross-site AJAX queries

Offline

#11 2015-06-22 14:16:52

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: How to get IP-Addr. of caller of an Interface based service method

Did you register the URI for http.sys?

Offline

#12 2015-06-22 21:30:39

houdw2006
Member
Registered: 2015-05-23
Posts: 48

Re: How to get IP-Addr. of caller of an Interface based service method

Thank you so much, ab!

That's the answer! The real problem is that I did NOT register the URI. This puzzled me more than one week and I couldn't find the reason by myself!

After I run the server (which runs the service) with administrator user rights once, after that the RemoteIP is correct now.

Last edited by houdw2006 (2015-06-25 09:10:21)

Offline

#13 2015-06-23 08:39:23

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: How to get IP-Addr. of caller of an Interface based service method

There was a problem with the socket-based server.
Should be fixed by http://synopse.info/fossil/info/534c00dae4

Note that running the server ONCE with admin rights is enough, since you used useHttpApiRegisteringURI option.
See http://synopse.info/files/html/Synopse% … #TITLE_250

Offline

Board footer

Powered by FluxBB