Frank Ibem
Frank Ibem

Reputation: 834

How to forward HTTP response to client

I have a client (Xamarin) and two Web API servers, A and B. The client makes a request to A which uses the request parameters to make another request to B. How do I return the response that A receives from B to the client such that B's use of C is transparent to the client.

For example, if I make a request from A to B using HttpClient how do I forward the HttpResponseMessage to the client in a controller's action?

Upvotes: 7

Views: 7487

Answers (3)

Ilya Chumakov
Ilya Chumakov

Reputation: 25039

Look at aspnet/AspLabs repository for a good example of a transparent HTTP proxy.

This proxy is a middleware handling client's requests to A and making its own requests to B. With time, its source code was deleted from AspLabs repo and now can be found only in its git history

This is the code actually forwarding a response, i.e. copying a received HttpResponseMessage to the upstream HttpContext.Response:

using (var responseMessage = await _httpClient.SendAsync(
    requestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted))
{
    context.Response.StatusCode = (int)responseMessage.StatusCode;
    foreach (var header in responseMessage.Headers)
    {
        context.Response.Headers[header.Key] = header.Value.ToArray();
    }

    foreach (var header in responseMessage.Content.Headers)
    {
        context.Response.Headers[header.Key] = header.Value.ToArray();
    }

    // SendAsync removes chunking from the response. This removes the header so it doesn't expect a chunked response.
    context.Response.Headers.Remove("transfer-encoding");
    await responseMessage.Content.CopyToAsync(context.Response.Body);
}

Upvotes: 12

ToDevAndBeyond
ToDevAndBeyond

Reputation: 1503

I took IIya's answer and adapted it for asp.net MVC 5

 public async Task GetFile(CancellationToken cancellationToken)
    {
        var context = HttpContext;
        var _httpClient = StaticHttpClient.Instance;
        var requestMessage = new HttpRequestMessage()
        {
            RequestUri = new Uri("https://localhost:44305/api/files/123"),
        };
        using (var responseMessage = await _httpClient.SendAsync(
requestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken))
        {
            Response.StatusCode = (int)responseMessage.StatusCode;
            foreach (var header in responseMessage.Headers)
            {
                Response.Headers[header.Key] = header.Value.First();
            }
            foreach (var header in responseMessage.Content.Headers)
            {
                Response.Headers[header.Key] = header.Value.First();
            }
            Response.Headers.Remove("transfer-encoding");
            //Response.BinaryWrite(await responseMessage.Content.ReadAsByteArrayAsync());
            await responseMessage.Content.CopyToAsync(Response.OutputStream);
            Response.Flush();
            Response.Close();
            context.ApplicationInstance.CompleteRequest();
        }
    }

Upvotes: 1

VolkanCetinkaya
VolkanCetinkaya

Reputation: 699

this is a Server Side:

WebForm1.aspx.cs

protected void Page_Load(object sender, EventArgs e)
    {
        HttpClient client = new HttpClient();
        client.Timeout = TimeSpan.FromSeconds(10);

        client.GetAsync("http://localhost:14388/WebForm2.aspx").ContinueWith(
             getTask =>
             {
                 if (getTask.IsCanceled)
                 {
                     Console.WriteLine("Request was canceled");
                 }
                 else if (getTask.IsFaulted)
                 {
                     Console.WriteLine("Request failed: {0}", getTask.Exception);
                 }
                 else
                 {
                     HttpResponseMessage response = getTask.Result;

                     string _message = response.Content.ReadAsStringAsync()
                                           .Result
                                           .Replace("\\", "")
                                           .Trim(new char[1] { '"' });
                 }
             });
    }

WebForm2.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="Volkan.WebForm2" %>

WebForm2.aspx.cs:

protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write("ahada cevabım");
    }

this is a Client side: https://stackoverflow.com/a/38218387/2797185

Upvotes: 0

Related Questions