Page 1 of 1

How to set TIdHTTPResponseInfo RawHeaders on get request?

PostPosted: Mon Apr 15, 2019 1:05 pm
by Ahmed Sayed
Hi, I finally managed to create some kind of a load balancer and failover using indy TIdHttpServer.

I just have a problem for now is that i can't set the Headers from an THTTPClient object to TIdHTTPResponseInfo RawHeaders

This is my code for the On GET event
Code: Select all
void __fastcall TMain::IdHTTPServer1CommandGet(TIdContext *AContext, TIdHTTPRequestInfo *ARequestInfo,
        TIdHTTPResponseInfo *AResponseInfo)
unique_ptr<THTTPClient> BackendRequest(THTTPClient::Create());
BackendRequest->ConnectionTimeout = 1000;
BackendRequest->ResponseTimeout = 1000;

TNameValueArray Headers;
unique_ptr<TStringList> str(new TStringList);

if (ARequestInfo->RawHeaders->Count > 0)

   Headers.Length = ARequestInfo->RawHeaders->Count;

   TNameValuePair *H = &Headers[0];

   for (int i = 0; i < ARequestInfo->RawHeaders->Count; ++i, *H++)
      H->Name = str->Names[i];
      H->Value = str->ValueFromIndex[i];

AResponseInfo->ContentStream = new TMemoryStream;
BackendRequest->CustomHeaders["X-Forwarded-For"] = AContext->Connection->Socket->Binding->PeerIP;
TStringDynArray PortsArr = SplitString(Ports->Text, ";");

String *Port = &PortsArr[0];
int Count = PortsArr.High;

ProxyRequest :
      _di_IHTTPResponse Response = BackendRequest->Execute(ARequestInfo->Command,
                        "http://localhost:" + *Port + ARequestInfo->URI,

      forDynArray(Head, Response->Headers)
         AResponseInfo->CustomHeaders->Values[(*Head).Name] = (*Head).Value;  //this causes the client to the error

      AResponseInfo->ResponseNo = Response->StatusCode;
      AResponseInfo->ResponseText = Response->StatusText;
   catch (ENetHTTPClientException &NetHttpEx)
      if (Port <= &PortsArr[Count])
         goto ProxyRequest;
            throw Exception("All backend servers are down");

I even tried with delphi interposer class like this:

Code: Select all
unit ProxyResponse;


  System.Classes, System.SysUtils, IdCustomHTTPServer, System.Net.HttpClient, System.Net.URLClient;

  TIdHTTPResponseInfo = class(IdCustomHTTPServer.TIdHTTPResponseInfo)
    FBackEndResponse: IHTTPResponse;

    procedure SetHeaders; override;
    property BackEndResponse: IHTTPResponse read FBackEndResponse write FBackEndResponse;
procedure TIdHTTPResponseInfo.SetHeaders;
  Header: TNetHeader;
  inherited SetHeaders;
  for Header in FBackEndResponse.Headers do
      FRawHeaders.Values[Header.Name] := Header.Value;


I get "Invalid encoding name" error on the client side when I make a request to that server. I know that Indy clears the RawHeaders after the ObGet event is handled. and set its values from the actual properties like ContentType or ContentLength. But i was wondering if there is a workaround this issue to set the headers of the proxy server from the response headers of the backend server like i demonstrated in the code.

If i used the interposer class instead nothing happens and i made sure to add this to the code:
Code: Select all
#include "ProxyResponse.hpp"
#define TIdHTTPResponseInfo Proxyresponse::TIdHTTPResponseInfo
//inside OnGet event
AResponseInfo->BackEndResponse = Response;

Any help will be appreciated

Thanks in advance

Re: How to set TIdHTTPResponseInfo RawHeaders on get request

PostPosted: Wed Apr 17, 2019 1:48 pm
by rlebeau
Asked and answered on the Embarcadero community forums:

How to set TIdHTTPResponseInfo RawHeaders from a nother backend server?