开发者

Sending image with HttpListener only working for some images

I'm trying create a small http proxy service. This is not working so well. It is able to serve HTML okayish, however it chokes up on images. That is, some images.

Sending in a url through my proxy yields 19.4 kb in the response (according to firebug) Visiting that url 开发者_如何学Cdirectly also yields 19.4 kb in the response, again according to firebug. The difference is, it doesn't show up when I put it through my proxy, but it does when I browse directly.

A completely different url works just fine. Does anyone have any idea?

private void DoProxy()
{
    var http = listener.GetContext();
    string url = http.Request.QueryString["url"];
    WebRequest request = HttpWebRequest.Create(url);
    WebResponse response = request.GetResponse();
    http.Response.ContentType = response.ContentType;

    byte[] content;
    using (Stream responseStream = response.GetResponseStream())
        content = ReadAll(responseStream);
    http.Response.ContentLength64 = content.Length;
    http.Response.OutputStream.Write(content, 0, content.Length);
    http.Response.Close();
}

private byte[] ReadAll(Stream stream)
{
    IList<byte> array = new List<byte>();
    int b;
    while ((b = stream.ReadByte()) != -1)
        array.Add(Convert.ToByte(b));
    return array.ToArray();
}


I would try and flush/close the OutputStream before you close the response.

Also as a second suggestion have a look at the HTTP traffic from the original site and then through your proxy site using an HTTP debugger like Fiddler - there must be a difference when using your proxy.

Also to make the ReadAll method more effective, in general I would avoid to load the full content into memory, because this will blow up on huge files - just stream them directly from the input stream to the output stream. If you still want to use byte arrays consider the following (untested but should work):

private byte[] ReadAll(Stream stream)
{
    byte[] buffer = new byte[8192];
    int bytesRead = 1;
    List<byte> arrayList = new List<byte>();

    while (bytesRead > 0)
    {
        bytesRead = stream.Read(buffer, 0, buffer.Length);
        arrayList.AddRange(new ArraySegment<byte>(buffer, 0, bytesRead).Array);
    }
    return arrayList.ToArray();
}


You can try to replace

http.Response.Close();

with

http.Response.Flush();
http.Response.End();


A problem could be that you don't specify the MIME type of the response. Browsersthese days are very forgiving, but maybe there is a circumstance where the browser doesn't know how to handle whatever you are sticking through its throat.

I have written the most smallish file-based http server, presented here, which as far as I can remember can serve images without much problem.


Just separate the text response and image response, and write the outputs separately. I did like below and it worked for me.

static void Main(string[] args)
    {
        HttpListener server = new HttpListener();
        server.Prefixes.Add("http://localhost:9020/");
        server.Start();
        Console.WriteLine("Listening...");
        while (true)
        {
            try
            { 
            HttpListenerContext context = server.GetContext();
            HttpListenerResponse response = context.Response;
            String localpath = context.Request.Url.LocalPath;
            string page = Directory.GetCurrentDirectory() + localpath;
            string msg = "";
            bool imgtest = false;
            if (localpath == "/")
              page = "index.html";
            Console.WriteLine(localpath);
            if (!page.Contains("jpg") && !page.Contains("png"))//Separates image request
            { 
               TextReader tr = new StreamReader(page);
               msg = tr.ReadToEnd();
               tr.Dispose();
            }
            else
            {
               byte[] output = File.ReadAllBytes(page);
               response.ContentLength64 = output.Length;
               Stream st1 = response.OutputStream;
               st1.Write(output, 0, output.Length);
               imgtest = true;
            }
            if (imgtest==false)
            { 
               byte[] buffer = Encoding.UTF8.GetBytes(msg);
               response.ContentLength64 = buffer.Length;
               Stream st = response.OutputStream;
               st.Write(buffer, 0, buffer.Length);
               context.Response.Close();
            }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error:  "+ex);
                Console.ReadKey();
            }
        }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜