我正在尝试创建一个小的http代理服务。这不是很好。它可以提供HTML okayish,但它会扼杀图像。也就是说,有些图片。
通过我的代理发送网址在响应中产生19.4 kb(根据firebug) 根据萤火虫的说法,直接访问该网址也会在响应中产生19.4 kb。不同的是,当我通过我的代理时,它没有出现,但是当我直接浏览时它就会出现。
一个完全不同的网址工作正常。有没有人有任何想法?
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();
}
答案 0 :(得分:2)
在关闭响应之前,我会尝试刷新/关闭OutputStream
。
另外,作为第二个建议,请查看来自原始网站的HTTP流量,然后使用像Fiddler这样的HTTP调试器通过您的代理网站 - 使用您的代理时必须有所不同。
另外,为了使ReadAll方法更有效,通常我会避免将完整内容加载到内存中,因为这会炸掉大量文件 - 直接将它们从输入流直接传输到输出流。如果您仍想使用字节数组,请考虑以下内容(未经测试但应该有效):
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();
}
答案 1 :(得分:1)
您可以尝试替换
http.Response.Close();
与
http.Response.Flush();
http.Response.End();
答案 2 :(得分:0)
问题可能是您没有指定响应的MIME类型。浏览这些日子是非常宽容的,但也许有一种情况,浏览器不知道如何处理你的喉咙。
我已经编写了最小的基于文件的http服务器presented here,据我所知,它可以提供图像而没有太多问题。
答案 3 :(得分:0)
只需将文本响应和图像响应分开,然后分别编写输出即可。我喜欢下面的方法,它对我有用。
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();
}
}