Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to forward an HttpRequestMessage to another server

What's the best way to forward an http web api request to another server?

Here's what I'm trying:

I have a .NET project where when I get certain API requests I want to modify the request, forward it to another server, and return the response sent by that second server.

I'm doing the following:

[Route("forward/{*api}")]
public HttpResponseMessage GetRequest(HttpRequestMessage request)
{
    string redirectUri = "http://productsapi.azurewebsites.net/api/products/2";
    HttpRequestMessage forwardRequest = request.Clone(redirectUri);

    HttpClient client = new HttpClient();
    Task<HttpResponseMessage> response = client.SendAsync(forwardRequest);
    Task.WaitAll(new Task[] { response } );
    HttpResponseMessage result = response.Result;

    return result;
}

Where the Clone method is defined as:

public static HttpRequestMessage Clone(this HttpRequestMessage req, string newUri)
{
    HttpRequestMessage clone = new HttpRequestMessage(req.Method, newUri);

    if (req.Method != HttpMethod.Get)
    {
        clone.Content = req.Content;
    }
    clone.Version = req.Version;

    foreach (KeyValuePair<string, object> prop in req.Properties)
    {
        clone.Properties.Add(prop);
    }

    foreach (KeyValuePair<string, IEnumerable<string>> header in req.Headers)
    {
        clone.Headers.TryAddWithoutValidation(header.Key, header.Value);
    }

    return clone;
}

However, for some reason instead of redirecting the url to the specified redirectUri I get a 404 response where the RequestMessage.RequestUri is set to http://localhost:61833/api/products/2. (http://localhost:61833 is the root of the original request uri).

Thanks

like image 869
Zain Rizvi Avatar asked Jan 30 '14 20:01

Zain Rizvi


1 Answers

You might need to explicitly set the host header on the clone instance. Otherwise you are just copying the original request's host header value across to the clone.

i.e. add the following line to the end of your Clone method:

clone.Headers.Host = new Uri(newUri).Authority;

Also, depending on what you are trying to achieve here, you may also need to handle other issues like cookie domains on the request not matching the new domain you are forwarding to as well as setting the correct domain on any response cookies that are returned.

like image 121
Casey Avatar answered Oct 24 '22 04:10

Casey