Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP Post as IE6 using C#

I need to do a HTTP POST using C#. It needs to do a postback the same way as an IE6 page.

From the documentation the postback should look like

POST /.../Upload.asp?b_customerId=[O/M1234] HTTP/1.1
Content-length: 12345
Content-type: multipart/form-data; boundary=vxvxv
Host: www.foo.com
--vxvxv
Content-disposition: form-data; name=”File1”; filename=”noColonsSpacesOrAmpersandsInHere”
Content-type: text/xml
<?xml version=”1.0” encoding=”UTF-8”?>
...
<bat:Batch ...
.......
</bat:Batch>
--vxvxv--

I think im having trouble with the boundary characters. I tried setting the boundary in the post data and fiddler shows something similar but I get a page back with the error "Invalid procedure call or argument". the Content-disposition is in the body rather than the header to keep it within the boundaries. Im not sure that is right. Am I setting the boundary the correct way? Can anyone give some guidance on how to do an IE6 style HTTP POST using C# ? Thanks

My Code

data = "--vxvxv" + Environment.NewLine + 
    "Content-disposition: form-data; name=\"File1\";" + Environment.NewLine + 
    "filename=\"provideTest.xml\"" + Environment.NewLine + 
    "Content-type: text/xml" + Environment.NewLine + 
    @"<?xml version=""1.0"" encoding=""UTF-8""?>" + Environment.NewLine + 
    data + Environment.NewLine + 
    "--vxvxv--";

var encoding = ASCIIEncoding.UTF8;
HttpWebRequest request;
var postData = encoding.GetBytes(data);

request = (HttpWebRequest)WebRequest.Create(url);
request.ContentLength = postData.Length;
request.Method = "POST";
request.ContentType = "multipart/form-data; boundary=vxvxv";
request.Host = "www.foo.com";
request.ContentLength = postData.Length;

X509Certificate2Collection certCollect = new X509Certificate2Collection();
X509Certificate2 cert = new X509Certificate2(@"C:\a\cert.pfx", "password");

certCollect.Add(cert);
request.ClientCertificates = certCollect;

using (Stream writeStream = request.GetRequestStream()) {
    writeStream.Write(postData, 0, postData.Length); }

WebResponse webResponse = request.GetResponse();
string output = new StreamReader(webResponse.GetResponseStream()).ReadToEnd();

LogEntry.Write("Recieved : " + output);
return output;

Fiddler Output (raw)

POST https://../Upload.asp?b_customerId=%5BO/M1234%5D HTTP/1.1
Content-Type: multipart/form-data; boundary=vxvxv
Host: www.foo.com
Content-Length: 5500
Expect: 100-continue
Connection: Keep-Alive

--vxvxv
Content-disposition: form-data; name="File1";
filename="provideTest.xml"
Content-type: text/xml
<?xml version="1.0" encoding="UTF-8"?>
...SNIP...
</bat:Batch>
--vxvxv--
like image 600
Tom Squires Avatar asked Jan 04 '12 11:01

Tom Squires


1 Answers

I think that you have two potential problems:

1) The URL that you are sending formats the b_CustomerId parameter differently than the IE6 implementation. If the site you are targeting does not expect an HTML-encoded value, this could very easily be the source of the error message.

Your request:

Upload.asp?b_customerId=%5BO/M1234%5D

The IE6 request:

Upload.asp?b_customerId=[O/M1234]

In order to fix this issue, you can create a new Url from an overload of the Uri class constructor that has been marked as obsolete, but still works correctly. This overload allows you to specify that the string has already been escaped in the second parameter.

In order to use this constructor, change this line:

request = (HttpWebRequest)WebRequest.Create(url);

to this:

request = (HttpWebRequest)WebRequest.Create(new Uri(url, true));

2) The Content-disposition tag is not formatted the same way in your request as it is in the IE6 request.

Your request:

Content-disposition: form-data; name="File1";
filename="provideTest.xml"

IE6 request:

Content-disposition: form-data; name=”File1”; filename=”noColonsSpacesOrAmpersandsInHere”

This can be resolved by changing these two lines:

"Content-disposition: form-data; name=\"File1\";" + Environment.NewLine + 
"filename=\"provideTest.xml\"" + Environment.NewLine + 

to:

"Content-disposition: form-data; name=\"File1\"; " + 
"filename=\"provideTest.xml\"" + Environment.NewLine + 
like image 70
competent_tech Avatar answered Sep 18 '22 12:09

competent_tech