Reputation: 81
I am trying to build a HTTP request using sockets in c. So, in order to navigate the socket to the correct site ip. I need to get the site ip. I have managed to get the host ip but that not always work. The following code gets the host ip:
host = gethostbyname(host_name);
if (host != NULL) {
memcpy(&inp, host->h_addr_list[0], host->h_length);
sprintf(ip, "%s", inet_ntoa(inp));
}
But that not always work, for example if I want to send the socket to stackoverflow.com and get his HTML content.I used this code and the output was: "198.252.206.16". And if you enter that ip you can see that it is a wrong ip,so what can I do? Please help.
P.S that this all my code:
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <errno.h>
#include <assert.h>
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "usage: %s domain_name\nE.g. %s www.yahoo.com/lalal.html\n", argv[0], argv[0]);
return(0);
}
struct protoent *pr;
struct in_addr inp;
int x = 1;
int ret;
char buf[4192];
char ip[16];
struct hostent *host;
int sock, bytes_recieved;
struct sockaddr_in server_addr;
char url[strlen(argv[1])];
strcpy(url,argv[1]);
char *index_page = strstr(argv[1], "/");
char *host_name = strtok(url,"/");
char message[4000];
sprintf(message,"GET %s HTTP/1.1\r\nHost: %s\r\n\r\n",index_page,host_name);
printf("%s",message);
host = gethostbyname(host_name);
if (host != NULL) {
memcpy(&inp, host->h_addr_list[0], host->h_length);
sprintf(ip, "%s", inet_ntoa(inp));
}
else {
printf("ERROR - Host ip was not found.\n\n");
exit(1);
}
printf("%s\n",ip);
pr = getprotobyname("tcp");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Socket");
exit(1);
}
printf("%s\n",message);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8);
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
perror("Connect");
exit(1);
}
write(sock, message, strlen(message));
while ((ret = read(sock, buf, 4192)) != 0) {
buf[ret]='\0';
fwrite(buf, ret, sizeof(char), stdout);
x++;
}
if (close(sock) == -1)
printf("Close socket error\n");
return 0;
}
Upvotes: 0
Views: 1179
Reputation: 597941
StackExchange hosts multiple sites on the same server. 198.252.206.16
is the IP address of that server, and that is the correct IP address you need to connect your socket to.
When requesting an HTTP resource from a site that resides on a shared server, you must provide an HTTP Host
header to specify the site's hostname so the server knows which site you are trying to access.
For example, if you go to http://198.252.206.16
, the request would look like this:
(connect to 198.252.206.16)
GET / HTTP 1.1
Host: 198.252.206.16
...
If you go to http://www.stackoverflow.com
, the request looks like this:
(connect to 198.252.206.16)
GET / HTTP 1.1
Host: www.stackoverflow.com
...
If you go to http://www.stackexchange.com
, the request looks like this:
(connect to 198.252.206.16)
GET / HTTP 1.1
Host: www.stackexchange.com
...
Notice that they all connect to the same IP address.
There is no site associated with the 198.252.206.16
host, which is why you get the error message.
The Host
header is required for all HTTP 1.1 requests, and is optional for HTTP 1.0 requests (but an HTTP 1.0 request will fail in this situation if the Host
header is missing). It was designed specifically to support multiple sites on a shared server.
Upvotes: 1