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

发布于 2024-10-24 18:56:45 字数 3897 浏览 2 评论 0原文

几天来,我一直在尝试编写一个程序,将图像远程上传到图像主机(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' header ='keep-alive ' 但我的不存在(我不知道为什么,尽管 request.Keep-alive 设置为 'true')

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

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

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

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

有人可以帮助使这段代码工作吗?

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

For several days I've tried to write a program that remote upload image to an image host (imgur.com). I used Wireshark to sniff http requests sent by browser, then create HttpWebRequest with similar headers and parameters. But the server always send back to me something weird. Please look at the code (this code is simplified):

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();
    }

Now I sniff my uploading request (2nd request) and compare it to the browser's request, there're only 2 differences:

  • Browser's 'Connection' header ='keep-alive' but mine doesn't exist (I don' know why although request.Keep-alive is set to 'true')

  • Some browser's cookies doesn't appear in mine.

The response should be a JSON, something like this:

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

But the server responses to my request by a pile of special characters... I can't find out which in above 2 differences makes my code doesn't work. I will extremely appreciate if you can help me making this code work. I'm a newbie so please don't blame me if my code or my expression's silly.

Can anybody help to make this code work?

P/S: i'm using .net framework 4

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

口干舌燥 2024-10-31 18:56:45

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

My guess is that the sid_hash url parameter in your attempt to upload the image is a session id that needs to change when you log in.

迷雾森÷林ヴ 2024-10-31 18:56:45

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

谢谢大家,伙计们。

OK, now I've found out the solution, fortunately. Forget all things in my function configRequest() (except 3 first lines), they just make things go wrong. The solution is, after sending the login request, send another request to the homepage (no parameter needed, but remember to include the cookies received from the 1st request). The sid_hash can be found in the returned HTML. Use that sid_hash to make the remote uploading request.

Thank you all, guys.

我不是你的备胎 2024-10-31 18:56:45

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

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

Not sure about your code, but ClipUpload is an open source project that seems to already do about what you want:

Quickly upload anything thats on your clipboard to the internet. It supports FTP, Imgur.com, Pastebin.com and SendSpace.com. Usage? Step 1: Copy. Step 2: Click system tray icon. Step 3: Paste public link. The easiest way to share your clipboard!

风轻花落早 2024-10-31 18:56:45

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

您可以自己设置保持活动状态,但我的建议是将响应标头的片段发布到第一个请求,以便我们可以提供帮助。


更新

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

IMGURSESSION=iliutpm33rhl2rugn5vcr8jq60

显然该值会随着每次日志记录而变化。

Most likely, the second request contains the session ID cookies. Without those cookies, server will not be able to recognise you hence upload will not work.

You can set the keep-alive yourself but my suggestion is to post snippet of the response headers to the first request so we could help.


UPDATE

According to your updates, you need to include this cookie:

IMGURSESSION=iliutpm33rhl2rugn5vcr8jq60

Obviously the value will change with each logging.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文