views:

8778

answers:

3

Hi. I'm trying to login to a website using HTTP POST method. I've inspected and altered the POST data while logging in to the website and I came to the conclusion that only the two "username" and "password" fields are required to be passed as POST data to the login page, I removed all other headers namely user-agent, Referer etc and still I was able to login to the website(using Firefox). However when I try to do this in my solution I keep getting "The remote server returned an error: (417) Expectation Failed."

I should also note that I've tried doing it both with HTTPWebResponse/HttpWebRequest and WebClient, They have both resulted in the same thing; Here's a sample of the code I'm using: (I'm getting the Exception right when I try to get a response from the page)

        WebClient client = new WebClient();
        NameValueCollection postData = new NameValueCollection();
        postData.Add("username", "MyUserName");
        postData.Add("password", "MyPassword");
        byte[] response = client.UploadValues("http://www.example.com/login.php",postData);
        Console.WriteLine(new System.Text.ASCIIEncoding().GetString(response));//This is where I get the Exception.
        Console.ReadKey();

I'm sorry if this issue has been covered before But after a day of Googling I still couldn't find a reasonable answer explaining why it works with my browser and not with my application. If you need extra info feel free to ask here. Thanks for your time and sharing your knowledge in advance. ~Phidelity

EDIT - I fixed my posted code. It was correct in my solution but I typed it wrong here. Sorry for the confusion.

+6  A: 

You're currently posting "username" as a key and "password" as the value. Do you mean

postData.Add("username", "foo");
postData.Add("password", "whatever");

?

Jon Skeet
Dang, beaten to the answer by Jon Skeet himself! I feel priveleged to have this brush with greatness!
Moose
+2  A: 

Does the form you are trying to emulate have two fields, username and password?

If so, this line:

 postData.Add("username", "password");

is not correct.

you would need two lines like:

 postData.Add("username", "Moose");
postData.Add("password", "NotMoosespasswordreally");

Edit:

Okay, since that is not the problem, one way to tackle this is to use something like Fiddler or Wireshark to watch what is being sent to the web server from the browser successfully, then compare that to what is being sent from your code. If you are going to a normal port 80 from .Net, Fiddler will still capture this traffic.

There is probably some other hidden field on the form that the web server is expecting that you are not sending.

Moose
+46  A: 

System.Net.HttpWebRequest adds the header 'HTTP header "Expect: 100-Continue"' to every request unless you explicitly ask it not to by setting this static property to false:

System.Net.ServicePointManager.Expect100Continue = false;

Some servers choke on that header and send back the 417 error you're seeing.

Give that a shot.

xcud
wow, +1 for seriously obscure!
Moose
I had some code that talked to Twitter that suddenly stopped working the day after Christmas. They'd done an upgrade or config change that caused their servers to start choking on that header. It was a pain to find the fix.
xcud
Hats off to you xcud. My solution is working like a charm now. As soon as I get my 15 reputation I'm gonna vote this up. Thanks.~Phidelity
Phidelity
I think I picked up an extra 10 points for getting an answer accepted in a thread that Jon Skeet posted a solution into.
xcud
think i am still looking at this and going, wtf!! Awesome answer, saved me a ton of time debugging
xximjasonxx
Thanks - saved me stacks of time - worked 100%. My solution used to work without this and then stopped working until I added it in... I guess they changed the config on their server..?
Vixen