Delphi SSL MITM Proxy на основе INDY - проблема с загрузкой контента - PullRequest
0 голосов
/ 05 октября 2019

Я пишу MITM SSL-прокси с использованием indy. Я использую компонент IdHTTPserver с самозаверяющим сертификатом для прокси-сервера, а в случае CommandOther я делаю запрос TcpCleint на сайт и возвращаю данные в HTTPServer. Но проблема в том, что некоторые скрипты, особенно JS и некоторые картинки с веб-страниц, вообще не загружаются или загружаются после тайм-аута, поэтому я получаю HTML-код в браузере, но пока не работаю с js (в основном). Вот мой код для CommandOther:

procedure TForm3.IdHTTPServer1CommandOther(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var

client: TIdTCPClient;
Headers, headers1: TIdHeaderList;
s, ResponseCode, ResponseText: string;
req,req2:string;
Size: Int64;
Strm,strm2: TIdTCPStream;
ssl: TIdSSLIOHandlerSocketOpenSSL;
clientcount:integer;

  begin
  Memo3.lines.Add('start');


client := TIdtCPClient.Create(nil);

ssl := TIdSSLIOHandlerSocketOpenSSL.Create(client);
client.IOHandler := ssl;

s := ARequestInfo.URI;
client.Host := Fetch(s, ':', True);
client.Port := StrToIntDef(s, 443);


client.ConnectTimeout := 2000;

s := '';
Memo3.lines.Add('connecting');


client.UseNagle:=true;

client.Connect;

 //here i handle CONNECT command
 AResponseInfo.ResponseNo := 200;
  AResponseInfo.ResponseText := 'Connection established';
     aresponseinfo.WriteHeader;


  // activate SSL between this proxy and the client
  TIdSSLIOHandlerSocketOpenSSL(AContext.Connection.Socket).PassThrough
  := false;
Memo3.lines.Add('connected');

 while AContext.Connection.Connected and Client.Connected do
  begin
  try



          memo4.Lines.Add('---start header-------');
  headers1 := TIdHeaderList.Create(QuoteHTTP);

    headers1.FoldLength := MaxInt;




    repeat
      s := AContext.Connection.IOHandler.ReadLn;
                 Memo4.lines.Add(s);
      headers1.Add(s);
      if s = '' then

        Break;

    until False;

  client.WriteHeader(headers1);
   memo4.Lines.Add('-----header written-----');


   memo5.Lines.Add('----------');
  if Headers1.IndexOfName('Content-Length') <> -1 then
      begin
      strm2:=TIdTCPStream.Create(client);
      memo5.Lines.Add('post');
        Size := StrToInt64(Headers1.Values['Content-Length']);


        if Size > 0 then
          AContext.Connection.IOHandler.ReadStream(Strm2, Size, False);
      end;




       memo4.Lines.Add('---response headers-------');
  Headers := TIdHeaderList.Create(QuoteHTTP);
  try
    Headers.FoldLength := MaxInt;

    repeat
      s := client.IOHandler.ReadLn;
             Memo4.lines.Add(s);
      acontext.Connection.IOHandler.WriteLn(s);
      Headers.Add(s);
      if s = '' then

        Break;

    until False;
        memo4.Lines.Add('---respone headers read-------');

    Strm := TIdTCPStream.Create(AContext.Connection);
    try


      if Pos('chunked', Headers.Values['Transfer-Encoding']) <> 0 then
      begin
      memo4.Lines.Add('chunked');


        repeat
          s := client.IOHandler.ReadLn;
          AContext.Connection.IOHandler.WriteLn(s);
          Size := StrToInt64('$' + Fetch(s, ';'));
          if Size = 0 then
            Break;
          client.IOHandler.ReadStream(Strm, Size, False);
          s := client.IOHandler.ReadLn;
          AContext.Connection.IOHandler.WriteLn(s);
        until False;

        repeat
          s := client.IOHandler.ReadLn;
          AContext.Connection.IOHandler.WriteLn(s);
        until s = '';
      end
      else if Headers.IndexOfName('Content-Length') <> -1 then
      begin
        Size := StrToInt64(Headers.Values['Content-Length']);


        end;
        if Size > 0 then
          client.IOHandler.ReadStream(Strm, Size, False);
      end
      else
      begin
      memo5.Lines.Add('big read(');
        AResponseInfo.CloseConnection := true;

        try
          client.IOHandler.ReadStream(Strm, -1, True);
        except
          on E: EIdSocketError do
          begin

            raise;
          end;
        end;
      end;
    finally

      Strm.Free;

    end;
  finally
    Headers.Free;
     strm2.Free;
       headers1.Free;
  end;

finally
client.Disconnect;

end;

client.Free;


      end;

      end;
...