user656822
user656822

Reputation: 1167

reverse proxy in mvc

I have to implement something like proxy in mvc to send user file that is on another server . I found this class :

public class ProxyHandler : IHttpHandler, IRouteHandler
{
    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {

        string str = "http://download.thinkbroadband.com/100MB.zip"; 

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(str);
        request.Method = "GET";
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        StreamReader reader = new StreamReader(response.GetResponseStream());


        HttpResponse res = context.Response;
        res.Write(reader.ReadToEnd());
    }

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return this;
    }
}

The problem is in this solution i first download file and then send downloded file to user with is not what i want. I want to send file to user as soon as I start to download it like in this Online Anonymizer for example http://bind2.com/

Any suggestions how to achieve this?

Upvotes: 8

Views: 3280

Answers (2)

Dhiren Gupta
Dhiren Gupta

Reputation: 1

You can achieve this by streaming the file directly to the user’s response stream. This way, you don’t have to wait for the entire file to be downloaded on your server before starting to send it to the user.

Here's the code snipped:

public void ProcessRequest(HttpContext context)
{
    string str = "http://download.thinkbroadband.com/100MB.zip"; 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(str);
    request.Method = "GET";
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        context.Response.ContentType = response.ContentType;
        using (Stream responseStream = response.GetResponseStream())
        {
            responseStream.CopyTo(context.Response.OutputStream);
        }
    }
}

Let me know if it works.

Upvotes: 0

Justin
Justin

Reputation: 86729

The following line in the above sample:

res.Write(reader.ReadToEnd());

Is equivalent to:

string responseString = reader.ReadToEnd();
res.Write(responseString);

I.e. the entire web response is being downloaded and stored in a string before it is being passed to the client.

Instead you should use something like the following:

Stream responseStream = response.GetResponseStream();

byte[] buffer = new byte[32768];
while (true)
{
    int read = responseStream.Read(buffer, 0, buffer.Length);
    if (read <= 0)
        return;
    context.Response.OutputStream.Write(buffer, 0, read);
}

(Stream copying code taken from Best way to copy between two Stream instances - C#)

This copies the stream in 32 KB chunks - you may want to make this chunk size smaller.

Upvotes: 8

Related Questions