Solved

C++ Winsock HTTP POST (submit html form)

Posted on 2015-01-05
15
794 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
  • 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
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

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 35

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 35

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 35

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 35

Expert Comment

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

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Exception thrown at 0x00007FFD5BC81F28 7 49
c++ reading data from file into two dimensional array 3 117
Problem to App 4 97
Finding Divisors 5 16
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
There is an easy way, in .NET, to centralize the treatment of all unexpected errors. First of all, instead of launching the application directly in a Form, you need first to write a Sub called Main, in a module. Then, set the Startup Object to th…
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

860 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