HTTP POST与HttpWebRequest的 [英] HTTP POST with HttpWebRequest

查看:184
本文介绍了HTTP POST与HttpWebRequest的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想,如果我是用表格上HTML网站(的ContentType =的multipart / form-data的),以张贴一些数据。我们的目标是Amazon的S3。 我使用的HttpWebRequest / HttpWebResponse和一切似乎有种没什么问题,但我还是不能打一个问题,我不断收到错误:

I'm trying to POST some data as if I was using FORM on HTML site (ContentType = multipart/form-data). The target is amazon's s3. I'm using HttpWebRequest / HttpWebResponse and all seems kind of fine to me, but I still can't fight one problem, I keep getting the error:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>InvalidArgument</Code>
  <Message>POST requires exactly one file upload per request.</Message>
  <ArgumentValue>0</ArgumentValue>
  <ArgumentName>file</ArgumentName>
</Error>

这似乎是自描述的,但我真的发了文件字段。我已经成功通过测试网站发送,没有任何问题的文件,整个后的数据似乎是完全一样的。 当我间谍通过Wireshark的所有头和后数据的请求,以及 - 它的存在,预期

it seems to be self-describing, but I really do send the "file" field. I've managed to send a file with no problems through test web-site, the whole post-data seems to be exactly the same. When I "spy" the request via wireshark all the headers and the post data as well - it's there as expected.

有没有人有任何想法,为什么亚马逊能不能看到文件字段?

Does anyone have any idea, why amazon can not see "file" field?

使用code(它切位,使其更具可读性):

code used (it's cut a bit to make it more readable):

private void addStringToStream(string buff, Stream s)
{
    var bytes = Encoding.UTF8.GetBytes(buff);
    s.Write(bytes, 0, bytes.Length);

    counter += bytes.Length;
}

private void doPost()
{
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);

    request.Method = "POST";
    request.ProtocolVersion = new Version(1, 1);

    request.KeepAlive = true;
    request.AllowAutoRedirect = true;

    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.Accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
    request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.10) Gecko/20071115 Firefox/2.0.0.10";

    string boundary = "---------------------------317205771417341028";
    request.ContentType = "multipart/form-data; boundary=" + boundary;

    request.SendChunked = false;
    request.Credentials = CredentialCache.DefaultCredentials;
    request.CookieContainer = new CookieContainer();

    request.ContentLength = calculateLength();

    using (Stream s = request.GetRequestStream())
    {
        boundary += "\n";

        string inLineContentH = "Content-Disposition: form-data; name=\"{0}\"";
        string contentH = "Content-Disposition: form-data; name=\"{0}\"" + "\n" + "\n";

        string keyH = "key";

        string aclH = "acl";
        string aclV = "public-read";

        string accessKeyH = "AWSAccessKeyId";
        string accessKeyV = publicKey;

        string policyH = "policy";
        string policyV = this.generatePolicy();

        string signatureH = "signature";
        string signatureV = generateSignature(policyV);

        string fileH = "file";
        string fileContentNameH = "filename=\"{0}\"";
        string contentType2H = "Content-Type: application/octet-stream";

        buff = boundary;
        addStringToStream(buff, s);

        buff = string.Format(contentH, keyH);
        addStringToStream(buff, s);

        buff = keyV + "\n";
        addStringToStream(buff, s);

        /* here are all of the others necessary fields added to stream just as the one above
        no other operations are used, just adding bytes to stream 
        and finally we get to the file: */

        buff = boundary;
        addStringToStream(buff, s);

        buff = string.Format(inLineContentH, fileH) + "; " + string.Format(fileContentNameH, Path.GetFileName(this.FilePath)) + "\n";
        addStringToStream(buff, s);

        buff = contentType2H + "\n" + "\n";
        addStringToStream(buff, s);

        var inStream = File.OpenRead(FilePath);
        int val;
        while ((val = inStream.ReadByte()) != -1)
        {
            s.WriteByte((byte)val);
            counter++;
        }

        buff = "\n";
        addStringToStream(buff, s);

        buff = boundary;
        addStringToStream(buff, s);

        buff = string.Format(contentH, "submit");
        addStringToStream(buff, s);

        buff = "Upload to Amazon S3" + "\n";
        addStringToStream(buff, s);

        buff = boundary.Replace("\r", "").Replace("\n", "") + "--";
        addStringToStream(buff, s);
    }

    request.GetResponse();
}

这是去流后的数据:

---------------------------317205771417341028
Content-Disposition: form-data; name="key"

webtest/image.png
---------------------------317205771417341028
Content-Disposition: form-data; name="acl"

public-read
---------------------------317205771417341028
Content-Disposition: form-data; name="AWSAccessKeyId"

AKIAJOQLTUC5H2NJ65NA
---------------------------317205771417341028
Content-Disposition: form-data; name="policy"

Oi8vd3d3Lmdvb2dsZS[...]c3QiXSwNCiAgXQ0KfQ0K
---------------------------317205771417341028
Content-Disposition: form-data; name="Signature"

06GBK5DJ71aB[...]M8Ct8JOE=
---------------------------317205771417341028
Content-Disposition: form-data; name="file"; filename="eclipse.png"
Content-Type: application/octet-stream

‰PNG

IHDRn
[...the rest of the image...]
IEND®B‚
---------------------------317205771417341028
Content-Disposition: form-data; name="submit"

Upload to Amazon S3
---------------------------317205771417341028--

和... Wireshark的名单:

and... the wireshark's list:

OUT TCP 58383 > http [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=2 SACK_PERM=1
IN  TCP http > 58383 [SYN, ACK] Seq=0 Ack=1 Win=8190 Len=0 MSS=1460 WS=6 SACK_PERM=1
OUT TCP 58383 > http [ACK] Seq=1 Ack=1 Win=65700 Len=0
OUT TCP [TCP segment of a reassembled PDU]
IN  HTTP    HTTP/1.1 100 Continue 
OUT TCP [TCP segment of a reassembled PDU]
OUT TCP [TCP segment of a reassembled PDU]
OUT TCP [TCP segment of a reassembled PDU]
OUT TCP [TCP segment of a reassembled PDU]
IN  TCP http > 58383 [ACK] Seq=26 Ack=2031 Win=1331456 Len=0
OUT TCP [TCP segment of a reassembled PDU]
OUT TCP [TCP segment of a reassembled PDU]
IN  TCP http > 58383 [ACK] Seq=26 Ack=3969 Win=1337344 Len=0
OUT TCP [TCP segment of a reassembled PDU]
OUT TCP [TCP segment of a reassembled PDU]
IN  TCP http > 58383 [ACK] Seq=26 Ack=6889 Win=1343232 Len=0
OUT TCP [TCP segment of a reassembled PDU]
OUT TCP [TCP segment of a reassembled PDU]
IN  TCP http > 58383 [ACK] Seq=26 Ack=8441 Win=1346048 Len=0
OUT HTTP    POST / HTTP/1.1
//the one above contains the last bytes added to the stream
IN  TCP http > 58383 [ACK] Seq=26 Ack=10225 Win=1348864 Len=0
IN  TCP http > 58383 [ACK] Seq=26 Ack=10857 Win=1351936 Len=0
IN  TCP http > 58383 [ACK] Seq=26 Ack=12162 Win=1354752 Len=0
IN  TCP http > 58383 [ACK] Seq=26 Ack=13622 Win=1357824 Len=0
IN  TCP http > 58383 [ACK] Seq=26 Ack=13913 Win=1360640 Len=0
IN  TCP [TCP segment of a reassembled PDU]
IN  HTTP/XML    HTTP/1.1 400 Bad Request 
//the one above includes the error info quoted in the beginning
IN  TCP http > 58383 [FIN, ACK] Seq=649 Ack=13913 Win=1360640 Len=0
OUT TCP 58383 > http [ACK] Seq=13913 Ack=650 Win=65052 Len=0
OUT TCP 58383 > http [FIN, ACK] Seq=13913 Ack=650 Win=65052 Len=0
IN  TCP http > 58383 [ACK] Seq=650 Ack=13914 Win=1360640 Len=0

通过web应用程序基于上传生成上述报告和1之间唯一的区别是基于该网络的应用程序有少[TCP一个重组的PDU的段]位置,并具有一定的[TCP DUP ACK 156#1]的HTTP> 58364 [ACK]平方米= 1 ACK = 7017运= 11668莱恩= 0的条目(如果可能会有所帮助,我可以发送完整的痕迹)。

the only difference between above report and one generated by web-app based upload is that web-app based has less [TCP segment of a reassembled PDU] positions, and has some [TCP Dup ACK 156#1] http > 58364 [ACK] Sq=1 Ack=7017 Win=11668 Len=0 entries (if might be helpful I can send full traces).

推荐答案

解决了! 边界是错误的 - 它是需要增加2破折号多为后期的数据比报头的值了。 有什么需要做的obove code是:

solved! the boundary was wrong - it is needed to add 2 dashes more for post data than the value in the header has. what was needed to do in obove code was:

string boundary = "---------------------------317205771417341028";
request.ContentType = "multipart/form-data; boundary=" + boundary;

[...]

[...]

using (Stream s = request.GetRequestStream())
{
    boundary = "--" + boundary "\n";

[...] 那么容易......,却又如此恼人的...

[...] so easy... and yet so annoying...

这篇关于HTTP POST与HttpWebRequest的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆