C# - 将HttpWebRequest发送到远程上传图像?

时间:2011-03-18 15:28:03

标签: c# httpwebrequest connection keep-alive

几天来,我试图编写一个程序,将图像远程上传到图像主机(imgur.com)。我使用Wireshark来嗅探浏览器发送的http请求,然后用类似的头文件和参数创建HttpWebRequest。但是服务器总是向我发回一些奇怪的东西。请查看代码(此代码已简化):

static void Main(string[] args)
    {
        ServicePointManager.Expect100Continue = false;
        CookieContainer cc = new CookieContainer();
        List<string> formData = new List<string>();

        //The first request - login
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://imgur.com/signin");
        configRequest(request, cc);
        //add POST params
        add(formData, "username", "abcdefgh"); //this is a working account,
        add(formData, "password", "abcdefgh"); //feel free to use it if you 
        add(formData, "remember", "remember"); //want to test
        add(formData, "submit", "");
        writeToRequestStream(request, formData);
        //send request
        request.GetResponse();

        //The second request - remote upload image
        request = (HttpWebRequest)WebRequest.Create("http://imgur.com/upload?sid_hash=9efff36179fef47dc5e078a4575fd96a");
        configRequest(request, cc);
        //add POST params
        formData = new List<string>();
        add(formData, "url", "http://img34.imageshack.us/img34/8425/89948070152259768406.jpg");
        add(formData, "create_album", "0");
        add(formData, "album_title", "Optional Album Title");
        add(formData, "album_layout", "b");
        add(formData, "edit_url", "0");
        writeToRequestStream(request, formData);
        //send request
        Stream s = request.GetResponse().GetResponseStream();
        StreamReader sr = new StreamReader(s);
        string html = sr.ReadToEnd();
        sr.Close();s.Close();
        Console.WriteLine(html + "\n\n");
    }
    static void add(List<string> formData, string key, string value)
    {
        formData.Add(HttpUtility.UrlEncode(key) + "=" + HttpUtility.UrlEncode(value));
    }
    static void configRequest(HttpWebRequest request, CookieContainer cc)
    {
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
        request.CookieContainer = cc;
        request.Credentials = CredentialCache.DefaultCredentials;
        request.Accept = "*/*";
        request.KeepAlive = true;
        request.Referer = "http://imgur.com/";
        request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15";
        request.Headers.Add("Accept-Language", "en-us,en;q=0.5");
        request.Headers.Add("Accept-Encoding", "gzip,deflate");
        request.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
        request.Headers.Add("Keep-Alive", "115");
        request.Headers.Add("X-Requested-With", "XMLHttpRequest");
        request.Headers.Add("Pragma", "no-cache");
        request.Headers.Add("Cache-Control", "no-cache");
    }
    static void writeToRequestStream(HttpWebRequest request, List<string> formData)
    {
        //build request stream
        string queryString = String.Join("&", formData.ToArray());
        byte[] byteArray = Encoding.UTF8.GetBytes(queryString);
        //write to stream
        request.ContentLength = byteArray.Length;
        Stream rs = request.GetRequestStream();
        rs.Write(byteArray, 0, byteArray.Length);
        rs.Close();
    }

现在我嗅探我的上传请求(第二次请求)并将其与浏览器的请求进行比较,只有两点不同:

  • 浏览器的'连接'标题='保持活着'但我的不存在(我不知道为什么虽然request.Keep-alive设置为'true')

  • 某些浏览器的Cookie不会出现在我的。

响应应该是JSON,如下所示:

{"hashes":"[\"QcvII\"]","hash":"QcvII","album":false,"edit":false}

但服务器通过一堆特殊字符响应我的请求......我无法找出上述哪些差异使我的代码不起作用。如果你能帮我制作这段代码,我将非常感激。我是新手,所以如果我的代码或表达方式愚蠢,请不要怪我。

任何人都可以帮助使这段代码有效吗?

P / S:我正在使用.net framework 4

4 个答案:

答案 0 :(得分:1)

我的猜测是,您尝试上传图片时的sid_hash url参数是您登录时需要更改的会话ID。

答案 1 :(得分:1)

好的,幸运的是,现在我已经找到了解决方案。忘记我的函数configRequest()中的所有东西(除了3个第一行),它们只会让事情出错。解决方案是,在发送登录请求后,向主页发送另一个请求(不需要参数,但记得包括从第一个请求收到的cookie)。可以在返回的HTML中找到sid_hash。使用该sid_hash发出远程上传请求。

谢谢大家,伙计。

答案 2 :(得分:0)

不确定您的代码,但ClipUpload是一个开源项目,似乎已经做了您想要的事情:

  

快速将剪贴板上的任何内容上传到互联网。它支持FTP,Imgur.com,Pastebin.com和SendSpace.com。用法?第1步:复制。第2步:单击系统托盘图标。第3步:粘贴公共链接。分享剪贴板的最简单方法!

答案 3 :(得分:0)

最有可能的是,第二个请求包含会话ID cookie。没有这些cookie,服务器将无法识别您,因此上传将无法正常工作。

您可以自己设置keep-alive,但我的建议是将响应标题的片段发布到第一个请求,以便我们提供帮助。


更新

根据您的更新,您需要包含此Cookie:

IMGURSESSION=iliutpm33rhl2rugn5vcr8jq60

显然,每次记录都会改变该值。