How to set TIdHTTPResponseInfo RawHeaders from a nother backend server?

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

 

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)
	{
	ARequestInfo->RawHeaders->ConvertToStdValues(str.get());

	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 :
	{
	try
		{
		_di_IHTTPResponse Response = BackendRequest->Execute(ARequestInfo->Command,
								"http://localhost:" + *Port + ARequestInfo->URI,
								ARequestInfo->PostStream,
								AResponseInfo->ContentStream,
								Headers);

		AResponseInfo->CustomHeaders->Clear();
		
		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)
		{
		*Port++;
		if (Port <= &PortsArr[Count])
			goto ProxyRequest;
		else
            throw Exception("All backend servers are down");
		}
	}
}
//---------------------------------------------------------------------------

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. 

Any help will be appreciated

Thanks in advance

Parents
  • "Invalid encoding name" is not an Indy error message.  What do the raw response headers from the proxy actually look like, and what do the raw headers that are sent by TIdHTTPServer to the client look like?  And why are you using THTTPClient instead of Indy's own TIdHTTP?

Reply Children