Solved

C++ Winsock HTTP POST (submit html form)

Posted on 2015-01-05
15
872 Views
Last Modified: 2015-01-05
Hello!

I'm trying to to submit a form in a html page: http://www.jus-bol.com/index.php
If you want to test: username admin, password 123

It's a very simple login system (i did using html + php):
index.php = login
login_success.php = if login redirect to here.

I'm trying to send a HTTP POST with winsock to my index.php that have a HTML form.
I'm have problem to do the header to send and how can i know if the loggin is OK?

My header:

const char * header;
	header = { 
		"POST /index.php HTTP/1.1\r\n"
		"Host: www.jus-bol.com\r\n"
		"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3\r\n"
		"Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n"
		"Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
		"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
		"Keep-Alive: 300\r\n"
		"Connection: keep-alive\r\n"
		"Referer: http://www.jus-bol.com/index.php\r\n"
		"Content-Type: application/x-www-form-urlencoded\r\n"
		"Content-Length: 30\r\n"
		"\r\n"
		"user=admin&pass=123=submit\r\n"
		"\r\n"
	};
	cout << "send: \n " << header << endl;
	cout << "----------------------------------------\n" << endl;;

	MySock::Instance().SendInfo(header);

Open in new window


To check if i did login, i need to send again, but to where? I did  a cookie, so if you try to access to login_success.php wihout login you can't.

index.php:

<html>
<body>
<h1>Welcome to index page</h1>
<br/>

<form action="login.php" method="POST">

<p>Username:</p><input type="text" name="user"/>
<p>Password:</p><input type="password" name="pass"/>
<br/>
<input type="submit" value="Login"/>
<br/>
<a href="new_user.php">Create New Account</a>

</form>

</body>
</html>

Open in new window


"SendInfo":

bool MySock::SendInfo(const char * buf){

	if (!InitWinSock()) return false; //ok

	if (!ConfigureSock()) return false; //ok

	if (!Connect()){ //ok
		Disconnect();
		return false;
	}
	//send
	int result = send(mySocket, buf, (int)strlen(buf), 0);
	if (result == SOCKET_ERROR){
		printf_s("send failed: %d\n", WSAGetLastError());
		Disconnect();
		return false;
	}

	printf_s("Bytes Sent: %ld\n", result);
	result = shutdown(mySocket, SD_SEND);
	if (result == SOCKET_ERROR){
		printf_s("shutdown failed: %d\n", WSAGetLastError());
		Disconnect();
		return false;
	}

	//recv
	int recvbuflen = 512;
	char recvbuf[512];


	result = recv(mySocket, recvbuf, recvbuflen, 0);
	if (result > 0){
		printf("Bytes received: %d\n", result);
		cout << recvbuf;
	}
	else if (result == 0)
		printf("Connection closed\n");
	else
		printf("recv failed: %d\n", WSAGetLastError());

	Disconnect();
	return true;
}

Open in new window


Summary:
1- What i'm doing wrong in my HTTP POST header?
2- And how i could check if i did login?

*my winsock functions is working perfectly, so this is not the problem.
*I'm getting as response: HTTP/1.1 200 OK
*I'm reading so much info about it in google, that i'm confused now.

Ty!
0
Comment
Question by:Júlio
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
  • 3
  • +1
15 Comments
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 40532167
The 'Set-Cookie' would be returned with the HTTP Response.  That should tell you whether you were able to login or not.  You may need a much larger recv buffer because the entire page contents should be returned.
0
 

Author Comment

by:Júlio
ID: 40532229
But i need to send again to get it?
*i'm noob to winsocks, just studying it.

index.php -> Submit form -> login.php process it -> redirect to login_success.php.

I could send a submit and try to check the login_success too?
0
 
LVL 86

Expert Comment

by:jkr
ID: 40532231
The only thing I can spot in your request header is that the POST line should be terminated with two CR/LFs, i.e.

"POST /index.php HTTP/1.1\r\n\r\n"

Open in new window


And, if your login did not succed, accessing any other resource in that context should result in a 401 (Unauthorized) or 403 (Forbidden).
0
Transaction Monitoring Vs. Real User Monitoring

Synthetic Transaction Monitoring Vs. Real User Monitoring: When To Use Each Approach? In this article, we will discuss two major monitoring approaches: Synthetic Transaction and Real User Monitoring.

 

Author Comment

by:Júlio
ID: 40532243
If i change to your POST line @jkr, i get "bad request"

And this line was wrong too;

"user=admin&pass=123=submit\r\n"

Open in new window


->

"user=admin&pass=123&action=submit\r\n"

Open in new window


Since i'm using cookies, to check if i have access to login_success.php a simple GET would work?
0
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 40532278
a simple GET would work?
No, you need to use the method expected by the page.  POST is usually used for logins.  The cookie will be set in the HTTP Response headers.

I copied your page.  Since the 'submit' button does not have a 'name' attribute, it will not be part of the post data.  This is what I get in the headers for your login form.  'postdump.php' is a test program that displays the POST data on the screen.
http://10.202.46.40/ee2/postdump.php

POST /ee2/postdump.php HTTP/1.1
Host: 10.202.46.40
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:34.0) Gecko/20100101 Firefox/34.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.202.46.40/ee2/logincheck.html
Cookie: test=999; ASPSESSIONIDSQRTBSCR=IMLBDNHBKDBLFPFHKDHAEBCD
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 31
user=the+user&pass=the+password

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Mon, 05 Jan 2015 20:56:54 GMT
X-Powered-By: ASP.NET, PHP/5.3.28
Connection: close
Content-Type: text/html

Open in new window

0
 

Author Comment

by:Júlio
ID: 40532403
Do you have a better document so i can study? i'm using a HTTP doc but is bad to understand correctly.

So, if i send a submit and i recv a code 200, this mean that i did login?
And i don't want to set a cookie, i want the login.php do it for me.

I think i will try more tomorrow, my head now.

drooling-homer-simpson.jpg
0
 
LVL 36

Accepted Solution

by:
mccarl earned 250 total points
ID: 40532422
1- What i'm doing wrong in my HTTP POST header?
The problem is (at least one of them anyway) that you are posting the form to your "index.php" page instead of your "login.php" page. index.php is only used to render the user interface in a browser, and since your not doing this, ie. you are programtically logging in from code, you don't need to be concerned with the index.php page at all.

2- And how i could check if i did login?
Once you fix the above, you should be able to check for a successful login by looking for a redirect HTTP response (such as 302, etc) and in the redirect response it should have a "Location" header that points to your "login_success.php" page.
0
 
LVL 83

Assisted Solution

by:Dave Baldwin
Dave Baldwin earned 250 total points
ID: 40532425
So, if i send a submit and i recv a code 200, this mean that i did login?
No, that means the page request was successful.  The request was accepted (as valid) and the page data is being returned to you.
And i don't want to set a cookie, i want the login.php do it for me.
It is always the server that sets the cookie and it is returned to you as part of the HTTP Response.  You have to find it in the header of the response data and save it so you can return it with the next request.  See here: http://en.wikipedia.org/wiki/HTTP_cookie#Implementation
0
 

Author Comment

by:Júlio
ID: 40532475
Ok, i changed my header to this following your pro tips:
c++
		string logininfo = "myusername=" + string(username) + "&mypassword=" + string(password);
	int loginInfoSize = logininfo.length();
	string header;
	header = "POST /login.php HTTP/1.1\r\n";
	header += "Host: www.jus-bol.com:80\r\n";
	header += "Content-Type: application/x-www-form-urlencoded\r\n";
	header += "Content-Length: " + to_string(loginInfoSize) + "\r\n";
	header += "\r\n";
	header += logininfo + "\r\n";

Open in new window


It's showing the code 302 (moved temp..) but the location is index.php and should be login_success.php.
I checked with debug if username and password have a value and it is ok.

My vars in login.php:

$myusername = $_POST['user'];
$mypassword = $_POST['pass'];

(...)

if($count==1){
	$seconds = 120 + time(); //2 minutes of cookie
	setcookie(loggedin, date("F jS - g:i a"), $seconds);
	header("location:login_success.php");
}else{
	header("location:index.php");
}

Open in new window

0
 
LVL 36

Expert Comment

by:mccarl
ID: 40532612
It's showing the code 302 (moved temp..)
Good !

but the location is index.php and should be login_success.php.
Yes, that just means that the login failed. Which is understandable since it looks like you have gone and made other changes that will break what you had...

string logininfo = "myusername=" + string(username) + "&mypassword=" + string(password);
You are now sending the username and password under the field names "myusername" and "mypassword" but your login.php page is looking for them to be under the field names "user" and "pass" ??? You had this correct in your original question!

My guess is if you change these back to what you had, it will all just work! ie.

string logininfo = "user=" + string(username) + "&pass=" + string(password);

Open in new window

0
 

Author Comment

by:Júlio
ID: 40532616
love you all!

I will give points to everybody that i can.

Final header:

       string logininfo = "user=" + string(username) + "&pass=" + string(password);
	int loginInfoSize = logininfo.length();
	string header;
	header = "POST /login.php HTTP/1.1\r\n";
	header += "Host: www.jus-bol.com:80\r\n";
	header += "Content-Type: application/x-www-form-urlencoded\r\n";
	header += "Content-Length: " + to_string(loginInfoSize) + "\r\n";
	header += "Accept-Charset: utf-8\r\n";
	header += "\r\n";
	header += logininfo + "\r\n";

Open in new window


I changed like this, because i was reading the wiki page and i noted that i don't need to send all that info.

Let me just ask one more think: what happen if the user have a big ms from my server? Like, my server is in USA, and the user is from CHINA, what can happen?
0
 

Author Closing Comment

by:Júlio
ID: 40532619
They are the best!
0
 
LVL 36

Expert Comment

by:mccarl
ID: 40532622
Let me just ask one more think: what happen if the user have a big ms from my server? Like, my server is in USA, and the user is from CHINA, what can happen?
Well, from what you have shown us so far, we can't really say. But my guess would be no major issues because I can't see anything in what you have posted that would be dependant on timing.
0
 

Author Comment

by:Júlio
ID: 40532624
Ty! i wish i could give 500 points! But Dave help me a lot too.

Have a nice day! I see you in the next =p
0
 
LVL 36

Expert Comment

by:mccarl
ID: 40532625
You're welcome! :)
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

How to remove superseded packages in windows w60 or w61 installation media (.wim) or online system to prevent unnecessary space. w60 means Windows Vista or Windows Server 2008. w61 means Windows 7 or Windows Server 2008 R2. There are various …
This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question