【问题标题】:C# - Send HttpWebRequest to remote upload image?C# - 发送 HttpWebRequest 到远程上传图片?
【发布时间】:2011-07-18 06:32:11
【问题描述】:

几天来,我一直在尝试编写一个将图像远程上传到图像主机 (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();
    }

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

  • 浏览器的 'Connection' 标头 ='keep-alive' 但我的不存在(我不知道为什么,尽管 request.Keep-alive 设置为 'true')

  • 某些浏览器的 cookie 没有出现在我的网站中。

响应应该是 JSON,类似于:

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

但是服务器通过一堆特殊字符响应我的请求...我无法找出以上 2 个差异中的哪一个导致我的代码不起作用。如果您能帮助我使此代码正常工作,我将不胜感激。我是新手,所以如果我的代码或我的表达很傻,请不要怪我。

任何人都可以帮助使此代码正常工作吗?

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

【问题讨论】:

  • 您忽略了对登录请求的响应。它可能包含您需要使用的 cookie 和会话信息。

标签: c# httpwebrequest connection keep-alive


【解决方案1】:

不确定您的代码,但ClipUpload 是一个开源项目,似乎已经可以满足您的需求:

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

【讨论】:

  • 谢谢,但这似乎不是我需要的。我要做的是远程上传,而不是从本地计算机上传图像。无论如何,我会检查他们的代码,谢谢
  • 哦,我误会了。祝你好运!
【解决方案2】:

很可能,第二个请求包含会话 ID cookie。如果没有这些 cookie,服务器将无法识别您,因此无法上传。

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


更新

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

IMGURSESSION=iliutpm33rhl2rugn5vcr8jq60

显然该值会随着每次记录而改变。

【讨论】:

  • 这里是登录请求的一些响应头(由浏览器发出) Cache-Control: max-age=7200, must-revalidate Set-Cookie: authautologin=0c55363d70643ced345006a4d9fe93f6548aebf5%7ERlw7ghczzELpdoO5beHxOGbYf09aSRE4;过期=格林威治标准时间 2011 年 4 月 1 日星期五 15:50:40;路径=/设置Cookie:IMGURSESSION=iliutpm33rhl2rugn5vcr8jq60;路径=/;域=.imgur.com ...
  • 这是对我的代码发出的请求的响应: Set-Cookie: IMGURSESSION=7lema8q57loftnlvj2baifmks5;路径=/; domain=.imgur.com Cache-Control: max-age=7200, must-revalidate Set-Cookie: authautologin=7cf9476bba0ea6729064dd3b8ab02571f738a562%7EjSBYQzpL3IBbFwPWECoDdpKGKWcsIzxP;过期=格林威治标准时间 2011 年 4 月 1 日星期五 15:53:50;路径=/设置Cookie:IMGURSESSION=0kfm0kts43dnlbgd6ojr8h3985;路径=/; domain=.imgur.com Set-Cookie: SERVERID=www2; path=/ 如果您需要更多信息,请告诉我...
  • 实际上,我总是将从第一个响应收到的 cookie 与第二个请求一起发送,正如您在代码中看到的那样:request.CookieContainer = cc;我现在想到的是sid_hash。它是否与 IMGURSESSION 或其他什么关系?
【解决方案3】:

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

【讨论】:

  • 好像是这样...但是在您看来,我怎样才能找到那个 sid_hash?我再次嗅探了请求,保存了所有 cookie 值,但我找不到那个 sid_hash 与以前的服务器 ID 或会话 ID 的关系...... 有什么操作可以计算那个 sid_hash?
  • 使用调试器查看响应头。我会试一试,如果我找到任何东西,我会告诉你
【解决方案4】:

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

谢谢大家。

【讨论】:

    猜你喜欢
    • 2014-12-26
    • 1970-01-01
    • 2012-12-19
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 2010-12-13
    相关资源
    最近更新 更多