I have this simple C code that try to connect to www host by using 80 port. I'm getting normally http headers response, but instead of HTML contents, I'm getting unknow characters(am I printing garbage?)
(facebook.com is only example, it happens with any server)
check out my code:
#define BUF_SIZE 4096
struct sockaddr_in sockaddr;
struct hostent *host;
char buffer[BUF_SIZE] = { 0 };
int sock;
static const char const headers[] =
"GET / HTTP/1.1\r\n"
"Host:www.facebook.com\r\n"
"User-Agent:Mozilla/5.0 (X11; Linux i686; rv:7.0.1) Gecko/20100101 Firefox/7.0.1\r\n"
"Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
"Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"Accept-Encoding:gzip,deflate\r\n"
"Connection:close\r\n"
"\r\n\r\n";
if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
perror("Cannot create TCP socket");
exit(1);
}
if((host = gethostbyname("www.facebook.com")) == NULL) {
perror("Cannot get host");
exit(1);
}
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
memcpy(&sockaddr.sin_addr,
host -> h_addr_list[0],
(size_t) host -> h_length);
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(80);
if(connect(sock, (struct sockaddr *)&sockaddr, sizeof(struct sockaddr)) == -1) {
perror("cannot connect");
exit(1);
}
if(send(sock, headers, strlen(headers), 0) == -1) {
perror("Cannot send packet");
exit(1);
}
ssize_t readed;
while((readed = recv(sock, buffer, BUF_SIZE, 0)) > 0) {
write(fileno(stdout), buffer, readed);
memset(buffer, 0, readed);
}
close(sock);
Example of response:
HTTP/1.1 200 OK
Cache-Control: private, no-cache, no-store, must-revalidate
Expires: Sat, 01 Jan 2000 00:00:00 GMT
P3P: CP="Facebook does not have a P3P policy. Learn why here: http://fb.me/p3p"
Pragma: no-cache
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Set-Cookie: datr=7HVjUC3-OlTdOMH3HivA_8Ge; expires=Fri, 26-Sep-2014 21:38:52 GMT; path=/; domain=.facebook.com; httponly
Set-Cookie: reg_ext_ref=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=.facebook.com
Set-Cookie: reg_fb_gate=http%3A%2F%2Fwww.facebook.com%2F; path=/; domain=.facebook.com
Set-Cookie: reg_fb_ref=http%3A%2F%2Fwww.facebook.com%2F; path=/; domain=.facebook.com
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
X-FB-Debug: 36+IohXvxWRp+3LHt+aLebawuS3W/MaBkmgR9TJGMrk=
Date: Wed, 26 Sep 2012 21:38:52 GMT
Transfer-Encoding: chunked
Connection: close
2f03
�}Yo�X��{�
�S-U)���P!����V��2�
F�A�AFr -9
�
��0�p�{�1cx��1`▒������0m� �
�\��XH)3U�v��yy���{��g�O��:�l_�lKoh�����L��7��'K�{jW����,uM�ue+��L�uU[:�=U�T�ս��{�LM���Oݮc����ou=ö$�▒;XR��G;K]�e;KcՑ4ɰ$u��Z{�P�c���[�6,;^u�w���������K��m��v����A���v!�pm�m�W���'�A�ծٹk��q���������Z�g�Ǘ�#�+���\��tU�������*s�V�ڶ7��W��[�����������xO��uM��jZ���ptR����Z5qv�QO��Ʀww���5K7�����Mg�c^쩻C+h��M<;V՛ڕ��e���P�1��գw���?���~w~�����ܖ�ky�U����X�����UTk\�Xw�'�b�V\����<Єҳ���ؖbڪ��z*�'%���⍬[od��]�H��W��?F��q� ��M�<�n�Owl)�>�fK�R~E�
��
[...]
How to fix this?
remove the line:
"Accept-Encoding:gzip,deflate\r\n"
as it tells the remote host that yoz accept compressed data, which you dont!
This is simple. You formed a request that informs the server that you are supporting gzip transfer encoding. remove the "Accept-Encoding:gzip,deflate\r\n" from your request and you will see plain text in response
Related
Here is my code where I tried to make an HTTP request
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char* argv[]) {
//create the socket
int network_socket;
network_socket = socket(AF_INET, SOCK_STREAM, 0);
//specify an address for the socket
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(80);
inet_pton(AF_INET, "208.97.177.124", &server_address.sin_addr);
//connect
int connection_status = connect(network_socket, (struct sockaddr *) &server_address, sizeof(server_address));
if (connection_status == -1) {
printf("There was an error making a connection to the remote socket\n\n");
}
//send information
char message[1024];
strcpy(message , "GET /index.html HTTP/1.1\r\nHost: perdu.com\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)\r\nAccept-Language: en-us\r\nAccept-Encoding: gzip, deflate\r\nConnection: Keep-Alive\r\n\r\n");
send(network_socket, message, sizeof(message), 0);
//receive information
char server_response[2048];
memset(server_response, '0',sizeof(server_response));
int size = recv(network_socket, &server_response, sizeof(server_response), 0);
//print the size
printf("size is %d\n\n", size);
//print the data
printf("The server sent the response : %s\n", server_response);
//close the socket
close(network_socket);
return 0;
}
The server sent the response :
HTTP/1.1 200 OK
Date: Wed, 25 Mar 2020 14:29:19 GMT
Server: Apache
Upgrade: h2
Connection: Upgrade, Keep-Alive
Last-Modified: Thu, 02 Jun 2016 06:01:08 GMT
ETag: "cc-5344555136fe9-gzip"
Accept-Ranges: bytes
Cache-Control: max-age=600
Expires: Wed, 25 Mar 2020 14:39:19 GMT
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Length: 163
Keep-Alive: timeout=2, max=100
Content-Type: text/html
?
And it ends with a question mark "?" instead of the HTML content. Why ?
I am trying to perform the C equivalent of the python's:
requests.get('http://test.com')
I am first using getaddrinfo() to resolve the hostname (it has 4 ips) to ip then server.sin_addr.s_addr = inet_addr(ip); and it connects successfully (doesn't give an error). But when I try to display the page by sending "GET / HTTP/1.1\r\n\r\n request, it basically returns 404 error (page not found) content. Here is the function:
void foo ()
{
struct addrinfo hints;
struct addrinfo *result = NULL;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
char host[256], port [256];
strcpy(host, "www.test.com");
strcpy(port, "80");
getaddrinfo(host, port, &hints, &result);
struct sockaddr_in *sockaddr_ipv4 = (struct sockaddr_in *)result->ai_addr;
char ip [256];
strcpy(ip, inet_ntoa(sockaddr_ipv4->sin_addr));
struct sockaddr_in server;
SOCKET s = socket(AF_INET , SOCK_STREAM , 0 );
char *message , server_reply[2000];
int recv_size;
server.sin_addr.s_addr = inet_addr(ip);
server.sin_family = AF_INET;
server.sin_port = htons( 80 );
if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
return 1;
}
message = "GET / HTTP/1.1\r\n\r\n";
if( send(s , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
if((recv_size = recv(s , server_reply , 2000 , 0)) == SOCKET_ERROR)
{
puts("recv failed");
}
server_reply[recv_size] = '\0';
puts(server_reply);*/
system("PAUSE");
}
Result
HTTP/1.1 404 Not Found Date: Fri, 15 Sep 2017 03:19:41 GMT
Content-Type: text/html; charset=UTF-8 Server: ghs Content-Length:
1561 X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN
Error 404 (Not Found)!!1
{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{backgrou
nd:#fff;color:#222;padding:15px}body{margin:7% auto
0;max-width:390px;min-height :180px;padding:30px 0 15px} >
body{background:url(//www.google.com/images/error s/robot.png) 100%
5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflo
w:hidden}ins{color:#777;text-decoration:none}a img{border:0}#media
screen and (m
ax-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0
}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo
_color_150x54dp.png) no-repeat;margin-left:-5px}#media only screen and (min-reso
lution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/
2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100%
100%;-moz-border-image:ur
l(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png)
0}}#media only screen and
(-webkit-min-device-pixel-ratio:2){#logo{background:ur
l(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png)
no-repeat;-webkit-background-size:100%
100%}}#logo{display:inline-block;height:5 4px;width:150px}
404. Thata?Ts an error. The requested URL
/ was not found on this server. Thata? Ts all we
know.
What am I doing wrong? How must I approach this?
Within HTTP/1.1 you need to specify a Host header. Within HTTP/1.0 you do not. Therefore, you must either change this to be:
GET / HTTP/1.0\r\n\r\n
or
GET / HTTP/1.1\r\n
Host: the.hostname.com\r\n\r\n
This change was made since virtual hostnames had become so prevalent.
I am sending two different https header to different address on same host. I am getting the same response from both test() and test1() functions... It seems like something can be used only once.... thanks in advance :)
#include <iostream>
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define FAIL -1
using namespace std;
SSL_CTX* InitCTX(void);
void test(SSL_CTX* ctx, int server);
void test1(SSL_CTX* ctx, int server);
int OpenConnection(char *hostname, int port);
int main()
{
SSL_CTX *ctx;
char *host = "academics.vit.ac.in";
char *port = "443";
SSL_library_init();
ctx = InitCTX();
int server = OpenConnection(host, atoi(port));
test(ctx, server);
test1(ctx, server);// Both functions prints exactly same data
return 0;
}
void test(SSL_CTX* ctx, int server)
{
char buf[9999];
int bytes;
SSL *ssl;
ssl = SSL_new(ctx);
SSL_set_fd(ssl, server);
if(SSL_connect(ssl) == FAIL)
{
ERR_print_errors_fp(stderr);
}
else
{
printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
char*msg = "GET /student/captcha.asp HTTP/1.1\nHost: academics.vit.ac.in\nCookie: ASPSESSIONIDCUTRADAT=OMDEAOKCPOLOKCLJMPAALAJN\n\n";
SSL_write(ssl, msg, strlen(msg));
bytes = SSL_read(ssl, buf, sizeof(buf));
buf[bytes] = 0;
printf("%s",buf);
SSL_free(ssl);
}
}
void test1(SSL_CTX* ctx, int server)
{
char buf[9999];
int bytes;
SSL *ssl;
ssl = SSL_new(ctx);
SSL_set_fd(ssl, server);
if(SSL_connect(ssl) == FAIL)
{
ERR_print_errors_fp(stderr);
}
else
{
printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
char*msg = "GET / HTTP/1.1\nHost: academics.vit.ac.in\nCookie: ASPSESSIONIDCUTRADAT=OMDEAOKCPOLOKCLJMPAALAJN\n\n";
SSL_write(ssl, msg, strlen(msg));
bytes = SSL_read(ssl, buf, sizeof(buf));
buf[bytes] = 0;
printf("%s",buf);
SSL_free(ssl);
}
}
SSL_CTX* InitCTX(void)
{
const SSL_METHOD *method;
SSL_CTX *ctx;
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
method = SSLv3_client_method();
ctx = SSL_CTX_new(method);
if ( ctx == NULL )
{
ERR_print_errors_fp(stderr);
abort();
}
return ctx;
}
int OpenConnection(char *hostname, int port)
{
int sd;
struct hostent *host;
struct sockaddr_in addr;
if ( (host = gethostbyname(hostname)) == NULL )
{
perror(hostname);
abort();
}
sd = socket(PF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = *(long*)(host->h_addr);
if ( connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
{
close(sd);
perror(hostname);
abort();
}
return sd;
}
The response i am getting is
Connected with RC4-SHA encryption
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: image/bmp
Expires: Tue, 25 Jun 2013 08:27:30 GMT
Server: Microsoft-IIS/7.0
Content-Disposition: inline; filename=captcha.bmp
Set-Cookie: ASPSESSIONIDCUSTBBBT=BHEANFEAHBBCBIJDIBNOPDAI; secure; path=/
X-Powered-By: ASP.NET
Date: Tue, 25 Jun 2013 08:28:30 GMT
Connection: close
Connected with (NONE) encryption
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: image/bmp
Expires: Tue, 25 Jun 2013 08:27:30 GMT
Server: Microsoft-IIS/7.0
Content-Disposition: inline; filename=captcha.bmp
Set-Cookie: ASPSESSIONIDCUSTBBBT=BHEANFEAHBBCBIJDIBNOPDAI; secure; path=/
X-Powered-By: ASP.NET
Date: Tue, 25 Jun 2013 08:28:30 GMT
Connection: close
Hi I have a simple browser that sends a request to yahoo.com which the server responds telling me 200 Ok and that it will send me a gzip file using encoded-transfer:chunked. Thats fine and all but when I run my program and continuously call recv(), I eventually run into a Bus Error. I'm not sure what that means at this point. Also I'm unclear how to read the header of the packet to tell me how many bytes it will send since the compressed file is in machine code. In this question I have included right bellow my code as well as the output that I see in terminal.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#define MAXDATASIZE 500;
int main(int argc, char *argv[]){
struct addrinfo serverSide,*serverInfo;
int mySock, status;
char buf[501],ipstr[INET6_ADDRSTRLEN];
memset(&serverSide, 0, sizeof serverSide);
serverSide.ai_family = AF_UNSPEC;
serverSide.ai_socktype = SOCK_STREAM;
if(getaddrinfo("www.yahoo.com","80",&serverSide,&serverInfo)==0){
}
mySock = socket(serverInfo->ai_family, serverInfo->ai_socktype, serverInfo->ai_protocol);
connect(mySock, serverInfo->ai_addr, serverInfo->ai_addrlen);
char msg[500] = "GET http://www.yahoo.com HTTP/1.1\r\n";
strcat(msg,"Host: www.yahoo.com:80\r\n");
strcat(msg,"User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1\r\n");
strcat(msg,"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n");
strcat(msg,"Accept-Language: en-us,en;q=0.5\r\n");
strcat(msg,"Accept-Encoding: gzip, deflate\r\n");
strcat(msg,"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n");
strcat(msg,"Connection: keep-alive\r\n\r\n");
// I want to keep the code simple so I just call recv enough times to see what has been
// written to my buffer. If I could read the packet length in the header then I would
// code in a while loop to adjust for that.
if((status = send(mySock,msg,strlen(msg),0))== -1){
printf("request not sent %d\n",status);
perror("\n");
}else{
if((status = recv(mySock, buf, 1500, 0))== -1){
printf("recieved byte error");
}else{
printf("%s",buf);
}
if((status = recv(mySock, buf, 1500, 0))== -1){
printf("recieved byte error");
}else{
printf("%s",buf);
}
if((status = recv(mySock, buf, 1500, 0))== -1){
printf("recieved byte error");
}else{
printf("%s",buf);
}
if((status = recv(mySock, buf, 1500, 0))== -1){
printf("recieved byte error");
}else{
printf("%s",buf);
}
}
close(mySock);
freeaddrinfo(serverInfo);
return 0;
}
Bellow is the output of my code. The server responds with the following...
HTTP/1.1 200 OK Date: Sat, 21 Jan 2012 08:53:09 GMT Set-Cookie:
B=4peq6lh7hkv7l&b=3&s=u4; expires=Tue, 21-Jan-2014 20:00:00 GMT;
path=/; domain=.yahoo.com P3P:
policyref="http://info.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM
DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi
IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC GOV"
Cache-Control: private X-Frame-Options: SAMEORIGIN Set-Cookie:
IU=deleted; expires=Fri, 21-Jan-2011 08:53:09 GMT; path=/;
domain=.yahoo.com Set-Cookie: PH=deleted; expires=Fri, 21-Jan-2011
08:53:09 GMT; path=/; domain=.yahoo.com Set-Cookie:
fpc=d=2BrdHmSMUw00.1uwnK1w8hHJcKnQt3UjRGxvUnBVIn0e6eAyRyd96eAPIN33Jne3IWoEE8r8eAk9xF0ExLsN5JJJmANZRlEBg8hpcDJ1GD7Gd50uZeP1H0_Wbf_mc.LJ45tDfhhwjR1BSedjT7AeGszK321i_gS34xKNuHlH2niKnP1lFG8y3aztEQsOkQHUu1w3zxk-&v=2;
expires=Sun, 20-Jan-2013 08:53:10 GMT; path=/; domain=www.yahoo.com
Set-Cookie: CH=deleted; expires=Fri, 21-Jan-2011 08:53:09 GMT; path=/;
domain=www.yahoo.com Set-Cookie:
CH=AgBPGnwQAA9AEAAA3RAAKY0QAAMPEAAYcxAAKN0QAD5XEAASNBAAJeoQACI8;
expires=Mon, 20-Feb-2012 08:53:09 GMT; path=/; domain=.yahoo.com
Set-Cookie:
fpt=d=nZFZlZHXecyEB3UWO0p6uOQtHkIdLjY734kqWOMHwg8Yq1e0sUpJBiMgYN63uaJ0.zEBsZIbeO93bfF0mXfQ8CtJYxAuet8CIS5PYmNMWfBDUU6ew8pXSI6cY3aX7Nk743wzRxbuCoBZGqvOM0eGhQMFOQ7BrCYBAZsAIYAOqwHKu7sNvbkPN7r0T7ncKpu5bX8LWPGngHHS97cCbNgpbgzOh13nP1m6.9cw7oPeudXdRjfzxsDUYqq2LvQJdECPWmccPhDEYfAoIl.Cfc8T8w_5.zrvoWG5kJr_T0megV4GtcTB324ZS2zkf0pi1GiMGYVHxGNh01c04XJnjk5q0ek_Xg�ogaa5oZoyhkMYQLI66nMCt1yAiz1jXmq2MTBxHqtbxBkoJaVsJt0YQMdpkkxwpRpXZHUgur.K9kY4j3vgyG1j44CQPlNsh7mBMxNe5nLdCMjFMy0ufmocRYowg38kMiK9hpFqkFnwYZSZPMGM4wAK5wVvFrwn1phkY3OXr76z5OC5tjNeq3Q--&v=1;
path=/; domain=www.yahoo.com Set-Cookie: fpps=deleted; expires=Fri,
21-Jan-2011 08:53:09 GMT; path=/; domain=www.yahoo.com Set-Cookie:
fpc_s=d=33OMFTGMUw2Z.oeMhzS8DGMizJ2NFSc4VT5QjW6pM.25xOqOYy5nr_kK5C83.tjkxzIiFvBITPc7P5YBehviyRS3piAAliJxvHQHDlbZYOlAdvgPXzJ4zGghf.xEL6Rb6rVdP90xlOc_njpBqlqOcwyMeq0ZqBy2VXuNrIxiD9QjUUsJyfVJ4miF1frSXQOI5Z8MVIErFoBjW3jTQANFu_CayJrjp6RRDc.YG5DCn04SFk3hKALdzVPSyIoawxmicCoWFfN7dvyge8jRoeQXHey.IALpAtcCPlY4eX.teLb.GO0yQxUN5HzgR9I-&v=2;
path=/; domain=www.yahoo.com Vary: Accept-Encoding Content-Type:
text/html;charset=utf-8 Content-Encoding: gzip Age: 2
Transfer-Encoding: chunked Connection: keep-alive Server: YTS/1.20.0
000088e ���I�HG8Ae��t�>#%xc�c#���a��e9��*d��S��#�~}�ZF��~x�
6�S8�#ӉO�i:i%��?���a��9rxJ�n���<Q����_�-�A����!D{�{ޱN���f*/h��ΰ ���Ea�h��E��2UY�
2�7�����dL>U���^W˳g��H�Q�>���~����iiΟ��#:���R�L�b��K���=�#
Ғ�5���|'�J��eo��{� Bus error
char buf[501];
...
recv(mySock, buf, 1500, 0)
^^^^
If recv ever actually reads more than 501 bytes, you'll overflow your buffer, which results in undefined behavior. Make sure you never read more than 501 bytes, or increase your buffer's size.
Also the printfs are not safe. There is nothing that guarantees the input will be proper, 0-terminated C strings. (You could use write and pass the length recv returned.)
At a glance, it looks like you are overrunning buf; you declare it as having a length of 501 but then try and read 1500 bytes into it.
If I telnet into telnet www.xlhi.com 80, and apply the following GET request:
GET http://www.xlhi.com/ HTTP/1.1
Host: www.xlhi.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
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
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Proxy-Connection: keep-alive
Cookie: CG=IE:04:Cork
Cache-Control: max-age=0
I get the following response:
HTTP/1.1 200 OK
Date: Tue, 06 Dec 2011 10:35:08 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.9
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 48
Content-Type: text/html
��(�ͱ���I�O����H�����ч��
�4�#�
Everything is fine and as expected. I'm interested in the gzipped binary data returned ("Hello").
Now, I have this C function which applies a GET request to a server (in this case www.xlhi.com)
char* applyGetReq(char* url,char* data,int len){
int sockfd, numbytes;
struct addrinfo hints, *servinfo, *p;
int rv;
char s[INET6_ADDRSTRLEN];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
printf("Server name: %s\n\n",url);
if ((rv = getaddrinfo(url,"80", &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
exit(1);
}
// loop through all the results and connect to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) {
perror("client: socket");
continue;
}
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("client: connect");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "client: failed to connect\n");
exit(1);
}
inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),s, sizeof s);
//printf("client: connecting to %s\n", s);
sendall(sockfd,data,&len);
freeaddrinfo(servinfo); // all done with this structure
char* buf=malloc(MAXDATASIZE*sizeof(char));
if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
perror("recv");
exit(1);
}
//printf("numbytes:%d\n",numbytes);
buf[numbytes] = '\0';
close(sockfd);
return buf;
}
Now, when I call this function and print out the result:
...
int len = strlen(data); //data is a char[] and contains the exact same GET request as mentioned above
char* buf=NULL;
buf=applyGetReq(stripped_url,data,len);
printf("%s\n",buf);
I get the following response from the server:
HTTP/1.1 200 OK
Date: Tue, 06 Dec 2011 10:03:13 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.9
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 48
Content-Type: text/html
�
As you can see, the page contents (binary data) is cut short for some unexplained reason. I should be getting:
��(�ͱ���I�O����H�����ч��
�4�#�
I've been looking at this for two hours now and can't seem to get to the bottom of it so I thought I'd ask the community.
That's how printf works. It stops when it encounters a NUL (0) byte. Try to use another function
fwrite(buf, 1, numbytes, stdout);