我可以将 TIdMappedPortTCP 代理特定客户端到不同的目的地吗?

问题描述 投票:0回答:1

使用适用于 Delphi 的 Indy Internet Direct 和 Linux 上的 Lazarus,我开发了一个充当代理的应用程序,目的是根据客户端的 IP 地址将客户端重定向到不同的内容。

为此,我使用了

TIdMappedPortTCP
对象。

我尝试过的一些事情是:

  1. 设置
    OnConnect
    通知事件,并更改
    AContext.Binding.Port
  2. 上面那个,但是用
    OnBeforeConnect
    通知事件代替。
  3. 再次更改
    Binding.Port
    但在
    OnContextCreate
    上。
  4. 改变
    TIdMappedPortTCP.MappedPort

尝试

作为示例,我尝试了 2 号,它会覆盖

OnBeforeConnect
。我认为这次尝试失败了,因为现阶段
AContext.Connection.Connected
已经是
true
,但我找不到比这更早修改它的方法。

procedure TMapperApplication.OnBeforeConnect(AContext: TIdContext);
var
  IP, Host: string;
var
  I: integer;
begin
  // List
  Inc(ConnectionCount);
  AddConnection(AContext);

  // Write
  WriteDate;

  IP := AContext.Binding.PeerIP;
  Host := GStack.HostByAddress(IP);

  TConsole.TextColor := TConsoleColor.LightMagenta;
  TConsole.Write := 'Incoming connection from ';
  TConsole.TextColor := TConsoleColor.LightBlue;
  TConsole.Write := Format('"%S" (%S) on port %D', [Host, IP, AContext.Binding.Port]);

  WriteNewLn;

  // Common date
  WriteDate;

  // Redirect port
  for I := 0 to High(Servers) do
    if IP = Servers[I].Source then
      begin
        AContext.Binding.IP:=Servers[I].Host;
        AContext.Binding.Port:=Servers[I].Port;

        TConsole.TextColor := TConsoleColor.Yellow;
        TConsole.Write := 'Mapped connection to ';
        TConsole.ResetStyle;
        TConsole.WriteLn:=Format('%S:%D', [Servers[I].Host, Servers[I].Port]);
        ResetNewLn;
        Exit;
      end;

  // Default mapping
  if EnableDefault then
    begin
      AContext.Binding.IP:=Servers[I].Host;
      AContext.Binding.Port:=Servers[I].Port;
      Mapper.Active:=true;

      TConsole.WriteLn:='Mapped connection to default host.';
      Exit;
    end;

  // Mapping failed
  TConsole.TextColor:=TConsoleColor.Red;
  TConsole.WriteLn:='Connection was dropped. No mapping found.';
  AContext.Connection.Disconnect;
  TConsole.ResetStyle;
end; 

为什么要用IP来区分客户端?

解决这个问题后,我计划替换IP地址检测,并使用一种方法来检测

server1.site.com
server2.site.com
,但我不确定这在Delphi中是否可以通过可用的库实现。我尝试了
GStack.HostByAddress(AContext.Binding.PeerIP)
,但返回一个空字符串。下次有问题。

研究

我也会搜索

www.indyproject.org
,但似乎网络服务器目前已关闭。下载不起作用。还有this,但它没有提供任何对这个问题有用的信息。

我还发现了this旧论坛,但不幸的是,该解决方案似乎已经过时,因为

TIdMappedPortThread
是一个未定义的声明,并且未在
TIdMappedPortTCP
中使用。还有this,但它也已经过时了。

所以目前我已经用尽了所有的想法。也许创建自定义

TIdMappedPortTCP
会有帮助?但我现在不确定。

delphi proxy indy lazarus
1个回答
0
投票

您找到的旧解决方案适用于 Indy 9,但它仍然适用于 Indy 10。只需在 Indy 10 中将

TIdMappedPortThread
替换为
TIdMappedPortContext

您无法更改

AContext.Binding.Port
,即客户端连接到代理的侦听端口。要更改代理转发到的下一个位置,您必须将
AContext
转换为
TIdMappedPortContext
,然后将其
OutboundClient
转换为
TIdTCPClient
,然后根据需要设置其
Host
和 Port`。

© www.soinside.com 2019 - 2024. All rights reserved.