Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
 |
|
04-02-2007, 12:37 PM
|
#1
|
Member
Registered: Dec 2006
Distribution: Ubuntu 20.04
Posts: 87
Rep:
|
How can I post data with POST method in C programming.
I extreamly want to how can we program in C code to perform post data (such as login to some website which we send the username and pass data to web server, or any type of this kind which involve POST method).
I have try to program with GET method, it's work fine. Also i search through the net all day today, but i found info that can't immediately go into the real situaion here.
Below is C Code with GET Method, you can try with
# ./httpgetconnect <IPaddress> <relative_url> => ./httpgetconnect 210.1.13.198 /
this result will print the content in html to STDOUT
Please save from this link: [HTML]http://210.1.13.198/haxpor/httpgetconnect[/HTML]
the source is below.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <usr/mynetwork.h>
int
main(int argc, char** argv) {
int sockfd, n;
char buff[MAXLINE],recvline[MAXLINE];
struct sockaddr_in servaddr;
if(argc != 3){
printf("usage: httpgetconnect <ipaddress> <relative_url>");
exit(0);
}
if( (sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1 ){
printf("socket: error");
exit(0);
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(80); //connect to http server
if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr) < 0){
printf("port: assigned invalid");
exit(0);
}
if( connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) == -1){
printf("connect: error");
exit(0);
}
//Sending Http header
bzero(&buff,sizeof(buff));
sprintf(buff,"GET %s HTTP1.1\nAccept: */*\nUser-Agent: Mozilla/4.0\nContent-Type: text/html\nPragma: no-cache\nConnection: keep-alive\n\n",argv[2]);
if(write(sockfd,buff,sizeof(buff)) == -1)
err_exit("write");
while ((n =read(sockfd,recvline,sizeof(recvline))) > 0){
recvline[n] = 0;
if(fputs(recvline,stdout) == EOF)
err_abort("read error");
}
return (EXIT_SUCCESS);
}
Any suggesstion that the code would be modify to "Perform POST Method" would be appreciate.
I guess it might be something about header.
Thanks.
NOTE
mynetwork.h is nothing special, it just include socket and relate header files and it contained err_exit() function only.
|
|
|
04-02-2007, 01:02 PM
|
#2
|
Senior Member
Registered: Dec 2003
Location: Trondheim, Norway
Distribution: Debian and Ubuntu
Posts: 1,466
|
Hi
I don't know, is this for learning or a practical issue? Anyway, why not use libcurl, wget, or some other tool? If it's for learning, why not look at the source?
What I really like about opensource is the huge amount of examples - I have source code for everything 
|
|
|
04-02-2007, 01:18 PM
|
#3
|
Member
Registered: Dec 2006
Distribution: Ubuntu 20.04
Posts: 87
Original Poster
Rep:
|
I also download curl to my computer not long ago, but I go into it search through the source but I cant found the API function that perform for Post Method in curl. Maybe I miss something but I try it so long to keep finding it.
Maybe you can show me that section of sourcecode then (if you have time)
Thank very much. It's great to be helped.
|
|
|
04-02-2007, 07:05 PM
|
#4
|
Member
Registered: May 2005
Location: uk - Reading
Distribution: slackware 14.2 kernel 4.19.43
Posts: 462
Rep:
|
Your best bet is to read the HTTP rfc to see how to properly form a POST request.
Once you understand the protocol properly you can then translate this to C code.
I have done a bit of http/https programing and that is how I approach it.
http://www.w3.org/Protocols/rfc2616/rfc2616.html
|
|
|
04-03-2007, 08:52 AM
|
#5
|
Senior Member
Registered: Dec 2003
Location: Trondheim, Norway
Distribution: Debian and Ubuntu
Posts: 1,466
|
|
|
|
04-03-2007, 08:56 AM
|
#6
|
Member
Registered: Dec 2006
Distribution: Ubuntu 20.04
Posts: 87
Original Poster
Rep:
|
slzckboy, do you have some sample sourcecode (POST Method) if then, could you show me right away.
I really want it.
This can save my time alot and also the others who want to know too.
Thanks in advance.
|
|
|
04-04-2007, 10:10 AM
|
#7
|
Member
Registered: Dec 2006
Distribution: Ubuntu 20.04
Posts: 87
Original Poster
Rep:
|
After a long time for trying and experimenting the code with c. I decide to see the header in http which sending between my computer and server (that trap with Proxomitron 4.5 in Windows), I take that info and adapt it then try it with perl (usually very close with C), and it work with POST Method.
The sourcecode for Perl which connect to Any web server with POST Method is below.
Code:
#!/usr/bin/perl -w
use IO::Socket;
$socket = IO::Socket::INET->new(
Proto => 'tcp',
PeerAddr => '<IPofWebserver>',
PeerPort => 80,
Timeout => 10
);
$header = "POST <Link> HTTP/1.1\n";
$header .= "Accept: */*\n";
$header .= "Referer: <FullUrlLink>\n";
$header .= "Accept-Language: */*\n";
$header .= "Content-Type: application/x-www-form-urlencoded\n";
$header .= "Accept-Encoding: gzip, deflate\n";
$header .= "User-Agent: Mozilla/4.0\n";
$header .= "Content-Length: <SizeofData>\n";
$header .= "Pragma: no-cache\n";
$header .= "Connection: keep-alive\n\n";
$header .= "param1=value1¶m2=value2"; #Calculate size here plus 1 byte for null-terminate string
unless($socket){
print "Could not connect...\n";
exit(0);
}
$socket->autoflush(1);
print $socket($header);
while(<$socket>){
s/\r\n//;
s/\n//;
last if($_ eq "");
}
while(<$socket>){
print $_;
}
close $socket;
print "Success";
Note
You must fill in the infomation by yourself with that bold string(url of web server, data to send, etc)
Also be careful with the line that I commented, not include '&' in calculation so you have your data plus 1 byte to fill in Content-Length: header.
_Example_
<LINK> => /member.php?act=login
<FullUrlLink> => http://www.something.org
After this perl code is work fine, then I jump it concept to C immediately but I found it wont work.
Any suggestion?
|
|
|
04-04-2007, 10:30 AM
|
#8
|
Member
Registered: May 2005
Location: uk - Reading
Distribution: slackware 14.2 kernel 4.19.43
Posts: 462
Rep:
|
what is the server replying with?
are theyjust closing the connection straight away,or are the sending
a http response code
if so what code.
All my http code is for the GET method,but I will have
a go at figuring it out with you.
Is this to interact with cgi programs on servers;i.e for login info
?
|
|
|
04-04-2007, 11:04 AM
|
#9
|
Member
Registered: Dec 2006
Distribution: Ubuntu 20.04
Posts: 87
Original Poster
Rep:
|
Yes, this interact with CGI script hosted on the web server.
The server return with 400 Bad Request code, still now I figuring it out what my header in C code is wrong. I do change it to be the same as Perl code above and modify it a little but the result is same it return 400 code every time.
IT MUST BE WRONG WITH HEADER, i guess that, other part is fine.
I am sure you have some account with some web server, if possible you can test this thing with the C Code above that i post
but change the line -> "GET %s .... to 'POST header' in Perl code above and run it with web server ip.
Thanks again.
|
|
|
04-04-2007, 11:17 AM
|
#10
|
Member
Registered: May 2005
Location: uk - Reading
Distribution: slackware 14.2 kernel 4.19.43
Posts: 462
Rep:
|
one thing i notice about your header is that it is non
standard in that you are suppose to have
\r\n between each header element as per the rfc
This is the header I use.
Note:you should terminate your header with \r\n\r\n
Code:
GET %s HTTP/1.1\r\nHost: %s\r\nConnection:"\
"keep-alive\r\nAccept: text/html\r\nAccept: image/gif\r\nAccept: image/x-xbitmap\r\n"\
"Accept: image/jpeg\r\nAccept: image/png\r\n\r\n"
|
|
|
04-04-2007, 11:27 AM
|
#11
|
Member
Registered: Dec 2006
Distribution: Ubuntu 20.04
Posts: 87
Original Poster
Rep:
|
thanks for that point.
I fix as per slzckboy suggest but it still wont work with POST Method.
Keep it coming, i calmly waiting.
Thanks again.
|
|
|
04-04-2007, 11:47 AM
|
#12
|
Member
Registered: Dec 2006
Distribution: Ubuntu 20.04
Posts: 87
Original Poster
Rep:
|
OK i will make it more comfortable for you all who trying to help.
You can download the sourcecode in .tar package (include main source and header file) for httpgetconnect, for this you can modify it to test with POST Method.
http://210.1.13.198/haxpor/httpgetconnect.tar
Hope this will provide more convenient.
|
|
|
04-06-2007, 04:15 AM
|
#13
|
Member
Registered: May 2005
Location: uk - Reading
Distribution: slackware 14.2 kernel 4.19.43
Posts: 462
Rep:
|
I't would be more helpful if you Just post the C code section relevant to
the POST request.
You havn't posted that yet.
Only you GET code.
thnx
|
|
|
04-06-2007, 11:48 PM
|
#14
|
Member
Registered: Dec 2006
Distribution: Ubuntu 20.04
Posts: 87
Original Poster
Rep:
|
In fact the POST code is the same as GET code but instead you must change the HEADER section of the line 'sprint("GET...' to POST Specific header.
But as you wish, Below is the code for POST Method.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <usr/mynetwork.h>
/*
*
*/
int
main(int argc, char** argv) {
int sockfd, n;
char buff[MAXLINE],recvline[MAXLINE];
struct sockaddr_in servaddr;
if(argc != 3){
printf("usage: httppostconnect <ipaddress> <relative_url>");
exit(0);
}
if( (sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1 ){
printf("socket: error");
exit(0);
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(80); //connect to http server
if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr) < 0){
printf("port: assigned invalid");
exit(0);
}
if( connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) == -1){
printf("connect: error");
exit(0);
}
//Sending Http header
bzero(&buff,sizeof(buff));
char postdata[] = "param1=value1¶m2=value"; /* Change param and value here */
sprintf(buff,"POST %s HTTP1.1\r\nAccept: */*\r\nReferer: <REFERER HERE>\r\nAccept-Language: en-us\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip,deflate\r\nUser-Agent: Mozilla/4.0\r\nContent-Length: %d\r\nPragma: no-cache\r\nConnection: keep-alive\r\n\r\n%s",argv[2],strlen(postdata),postdata);
if(write(sockfd,buff,strlen(buff)+1) == -1)
err_exit("write");
while ((n =read(sockfd,recvline,sizeof(recvline))) > 0){
recvline[n] = 0;
if(fputs(recvline,stdout) == EOF)
err_abort("read error");
}
return (EXIT_SUCCESS);
}
The header line is depand on what data to be send to server such as 'username' = 'something' to send to server, etc.
This is the link for httppostconnect (include header fies and sourcecode)
http://210.1.13.198/haxpor/httppostconnect.tar
|
|
|
04-07-2007, 04:18 AM
|
#15
|
Member
Registered: Dec 2006
Distribution: Ubuntu 20.04
Posts: 87
Original Poster
Rep:
|
Ok everyone, i want to tell you all that the problem is the HEADER as I suggest, and it is true.
It is my mistake not to calmly and slowly see at the header. The header is wrong.
As you can see from GET Method code from above the line 'sprintf(..'
you will see "GET %s HTTP1.1.." this is wrong, the correct is "GET %s HTTP/1.1". Although that mistake work with GET Method but it wont work with POST Method.
So after all, you can try this by correct that line of header to the correct one as i tell you, then run it. (NOTE: you must fill in the info of the server and data you want to send by yourself)
Tell me if it work!
PS.
-Thanks to you all that work along and together figure it out the problem. Guttorm, slzckboy.
|
|
|
All times are GMT -5. The time now is 08:05 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|