Recent

Author Topic: [SOLVED] Question about IdMappedPortTCP, change port at runtime  (Read 479 times)

cappe

  • Full Member
  • ***
  • Posts: 116
[SOLVED] Question about IdMappedPortTCP, change port at runtime
« on: October 19, 2020, 11:28:32 am »
Is it possible to change the destination port during the OnExecute event?
I would like to make sure that all requests are received on one port, and then on the basis of a parameter, send them to different port. Is it possible to do this?
« Last Edit: October 23, 2020, 10:46:48 am by cappe »

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 836
    • Lebeau Software
Re: Question about IdMappedPortTCP, change port at runtime
« Reply #1 on: October 20, 2020, 12:06:10 am »
Is it possible to change the destination port during the OnExecute event?

Not in the OnExecute event, no.  A TCP connection to the destination server has already been established before that event is fired (OnExecute is fired whenever TIdMappedPortTCP receives data from the source client to forward to the destination server.  The OnOutboundData event is fired for data in the opposite direction).

But, you can change the destination info in the OnConnect event.  That event is fired after a source client has connected to TIdMappedPortTCP and before an outbound TCP connection is made to the destination server.  You can type-cast the event's AContext parameter to TIdMappedPortContext, then type-cast its OutboundClient property to TIdTCPClient, and then you will have access to all of that client's properties, like Host, Port, IOHandler, etc.

I would like to make sure that all requests are received on one port, and then on the basis of a parameter, send them to different port. Is it possible to do this?

Maybe, maybe not.  It depends on where that parameter is coming from exactly.  Can you provide more details?
« Last Edit: October 20, 2020, 08:35:07 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

cappe

  • Full Member
  • ***
  • Posts: 116
Re: Question about IdMappedPortTCP, change port at runtime
« Reply #2 on: October 20, 2020, 09:49:21 am »
In summary I would like to put an IdMappedPortTcp component on port 3218, then depending on a parameter in the url this is redirected to a specific port. For example

x.x.x.x: 3218 / pi = 1 // be redirected to 8080
x.x.x.x: 3218 / pi = 2 // is redirected to 8081

It can be done?

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 836
    • Lebeau Software
Re: Question about IdMappedPortTCP, change port at runtime
« Reply #3 on: October 20, 2020, 08:45:56 pm »
In summary I would like to put an IdMappedPortTcp component on port 3218, then depending on a parameter in the url this is redirected to a specific port. For example

x.x.x.x: 3218 / pi = 1 // be redirected to 8080
x.x.x.x: 3218 / pi = 2 // is redirected to 8081

It can be done?

Perhaps, with some work.  Assuming each request actually contains a full URL you can extract.

In the OnConnect event, manually read the URL from the Context.Connection.IOHandler, then setup the TIdMappedPortContext.OutboundClient as I described earlier.  Any data that you read that needs to be sent to the destination, put it in the TIdMappedPortContext.NetData property, and then you can manually send it to the destination via the TIdMappedPortContext.OutboundClient in the OnOutboundConnect event.

Alternatively, instead of reading the data and having to manually re-send it afterwards, have your OnConnect event handler call the Context.Connection.IOHandler.CheckForDataOnSource() method in a loop until the URL appears in the Context.Connection.IOHandler.InputBuffer, then peek it from the buffer without extracting it, then update the TIdMappedPortContext.OutboundClient as needed.  By leaving the data unread in the InputBuffer, it will get sent automatically once the connection is made successfully, after the OnOutboundConnect event.

Things get a bit trickier if you need to handle multiple requests per client connection (such as with HTTP persistent connections).  Preferably, each request should use a new TCP connection in order to work with multiple destinations.  Otherwise, you would likely have to move your processing to the OnExecute event, and swap out the TIdMappedPortContext.OutboundClient.IOHandler as needed per request (but then you still need an initial destination for TIdMappedPortTCP to connect to in between the OnConnect and OnOutboundConnect events).

Depending on what you are actually trying to accomplish, TIdMappedPortTCP may not be a good choice for you.  For HTTP, you might consider TIdHTTPProxyServer or TIdHTTPServer+TIdHTTP instead, either of which will let you handle HTTP requests on a per-request basis.  Otherwise, you may just have to resort to using a plain vanilla TIdTCPServer instead and implement your own forwarding logic as needed in its OnExecute event using your own per-request TIdTCPClient.

Can you provide more details about what exactly you are trying to accomplish?
« Last Edit: October 20, 2020, 09:03:25 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

cappe

  • Full Member
  • ***
  • Posts: 116
Re: Question about IdMappedPortTCP, change port at runtime
« Reply #4 on: October 22, 2020, 03:42:42 pm »
Alternatively, instead of reading the data and having to manually re-send it afterwards, have your OnConnect event handler call the Context.Connection.IOHandler.CheckForDataOnSource() method in a loop until the URL appears in the Context.Connection.IOHandler.InputBuffer, then peek it from the buffer without extracting it, then update the TIdMappedPortContext.OutboundClient as needed. 
I did this and it works. It shouldn't slow down from the first option.

I would like to implement an authentication web page (with username and password) and then from here redirect to TIdMappedPortTCP.
Now it would be interesting to implement the authentication page inside as well. The initial idea was to do the authentication page externally (and this is easy), but it's more interesting to do everything inside. How do you advise me to do?

How could I do to display a web page with the word "Access Denied" (in cases where there is no authentication)?

Thank you.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 836
    • Lebeau Software
Re: Question about IdMappedPortTCP, change port at runtime
« Reply #5 on: October 22, 2020, 06:53:54 pm »
I would like to implement an authentication web page (with username and password) and then from here redirect to TIdMappedPortTCP.

If that is the case, then the client is an HTTP client, so I would probably suggest using TIdHTTPServer or TIdHTTPProxyServer instead of TIdMappedPortTCP, which has no concept of HTTP.  But it really depends on what you are trying to accomplish with using forwarded connections in the first place.

Now it would be interesting to implement the authentication page inside as well. The initial idea was to do the authentication page externally (and this is easy), but it's more interesting to do everything inside. How do you advise me to do?

How could I do to display a web page with the word "Access Denied" (in cases where there is no authentication)?

That gets into you having to manually parse the HTTP protocol entirely, which can be difficult when using TIdMappedPortTCP since it has no concept of message boundaries and just gives you access to arbitrary blocks of raw data.  That is why I would suggest using TIdHTTP(Proxy)Server instead, let them handle the HTTP parsing for you, and then you can focus on processing whole HTTP messages at a time, and sending HTTP responses back to the client as needed.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

cappe

  • Full Member
  • ***
  • Posts: 116
Re: Question about IdMappedPortTCP, change port at runtime
« Reply #6 on: October 23, 2020, 10:35:42 am »
thanks Remy

 

TinyPortal © 2005-2018