Thread: HTTP GET request

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    17

    HTTP GET request

    From my knowledge of HTTP sending a get request via HTTP with c (I'm only worried about get) should just be sending a packet containing something like GET <filename> HTTP/1.0 ... I've been trying to do it with something like this:

    Code:
    	request = malloc( ((tok - &(*argv[1])) - sizeof(argv[1])) + sizeof(char) * 17 + 1 + 4 );
    	sprintf(request, "%s %s %s", "GET", &(*argv[1]) + (tok - &(*argv[1])), "HTTP/1.0");
    	printf("%s\n", request);
    	serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    	if (serverSocket == -1)
    		error("socket()");
    	if (connect(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) != 0)
    		error("connect()");
    	if (send(serverSocket, &request, sizeof(request), 0) < 0)
    		error("send()");
    do I have to hton this data? I'm not getting a response from the server.

    TIA

  2. #2
    Or working on it anyways mramazing's Avatar
    Join Date
    Dec 2005
    Location
    Lehi, UT
    Posts
    121
    you might have to end it with \r\n\r\n that is how the server knows the request is done. If I remember correctly the request should look something like this in c...

    Code:
         char request[] = "GET /index.html HTTP/1.1\r\n",
                                    "host: somewebsite.com\r\n",
                                    "\r\n";
    -- Will you show me how to c++?

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
    request = malloc( ((tok - &(*argv[1])) - sizeof(argv[1])) + sizeof(char) * 17 + 1 + 4 );
    what length are you trying to allocate here?
    Code:
    	sprintf(request, "%s %s %s", "GET", &(*argv[1]) + (tok - &(*argv[1])), "HTTP/1.0");
    why not
    Code:
    	sprintf(request, "GET %s HTTP/1.0", tok);
    Code:
    	if (send(serverSocket, &request, sizeof(request), 0) < 0)
    		error("send()");
    sizeof (request) is 4 bytes
    so you just sent the pointer to request - instead of the request itself...

    use Wireshark to check what is being sent to network
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Registered User
    Join Date
    Mar 2010
    Posts
    17
    MrAmazing and Vart - Thanks for the responses.

    I caught the sprintf while debugging:

    Code:
    sprintf(request, "GET %s HTTP/1.0\r\nHOST:%s \r\n", &(*argv[1]) + (tok - &(*argv[1])), host);
    That terrible malloc is because I need the length of the requested file, minus the domain (example.com).

    size problems fixed:

    Code:
    i = send(serverSocket, &request, strlen(request) * sizeof(char), 0);
    if (strlen(request) != i)
    {
    	printf("%d , %d\nMismatch!\n", i, strlen(request));
    }
    printf("request sent!\n%d\n", i);
    printf("waiting for response...\n");
    printf("%d", recv(serverSocket, &buffer, sizeof(buffer), 0));
    now I'm hanging on the receive (why it's in the printf).

    I can see a packet going out with a payload of 44bytes (in the case of the data I was using my request was 44 bytes). The rest are just SYN ACK (no response from server). the payload the of packet is:

    Code:
    00000   00 40 10 20 00 01 00 25  56 11 bf 49 08 00 45 00    .@. ...%V..I..E.
    00010   00 60 b1 9f 40 00 40 06  70 dd c0 a8 01 02 4a 36    .`..@[email protected]
    00020   0c 3b d6 cd 00 50 15 a0  25 7f d4 28 0b ce 80 18    .;...P..%..(....
    00030   ff ff 0b fb 00 00 01 01  08 0a 29 f0 3c 27 94 35    ..........).<'.5
    00040   d7 79 47 45 54 20 2f 69  6e 64 65 78 2e 70 68 70    .yGET /index.php
    00050   20 48 54 54 50 2f 31 2e  30 0d 0a 48 4f 53 54 3a     HTTP/1.0..HOST:
    00060   61 63 65 6e 73 75 6d 2e  63 6f 6d 20 0d 0a          acensum.com ..
    compete (albeit rather messy right now) code:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <stdbool.h>
    #include <unistd.h>
    
    #define BUFFSIZE 512
    
    void error(char *msg);
    
    int serverSocket;
    int i = 0;
    size_t bWritten, bTotal;
    struct sockaddr_in serverAddr;
    struct hostent *hostptr;
    char *ip = "74.54.12.59";
    char *tok, *host, *request, *buffer[BUFFSIZE];
    
    
    int main (int argc, const char * argv[]) {
    	printf("%s rev.0\n", argv[0]);
    	if (argc < 2)
    	{
    		printf("Usage: %s [address]\n", argv[0]);
    		exit(-1);
    	}
    	memset(&serverAddr, 0, sizeof(serverAddr));
    	serverAddr.sin_family = AF_INET;
    	serverAddr.sin_port = htons(80);
    	serverAddr.sin_addr.s_addr = inet_addr(ip);
    	tok = strpbrk(argv[1], "/");
    	host = malloc(sizeof(char) * (tok - &(*argv[1]) + 1));
    	strncpy(host, argv[1], tok - &(*argv[1]) );
    	//disabled because xcode has a problem with gethostbyname()
    	//char *test = "acenusm.com";
    	//hostptr = gethostbyname(test);
    	//printf("Resolved: %s\n", host);
    	//printf("%s \n", hostptr->h_addr_list[0]);
    	//these are really nasty but they work.
    	printf("Requesting: %s\n", argv[1] + (tok - argv[1]));
    	request = malloc( (tok - argv[1]) - strlen(argv[1]) + sizeof(char) * 26 + strlen(host) + 1 );
    	sprintf(request, "GET %s HTTP/1.0\r\nHOST:%s \r\n", argv[1] + (tok - argv[1]), host);
    	//free and Null pointer
    	if(host)
    	{
    		free(host);
    		host = NULL;
    	}
    	serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    	if (serverSocket < 0)
    		error("socket()");
    	if (connect(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
    		error("connect()");
    	for (bTotal = 0; bTotal < strlen(request); bTotal += bWritten)
    	{
    		bWritten = write(serverSocket, &request[bTotal], strlen(request) - bTotal);
    		if (bWritten == 0)
    			break;
    	}
    	//i = send(serverSocket, &request, (strlen(request) + 1), 0);
    	//if (strlen(request) + 1 != i)
    	//	error("send()");
    	printf("waiting for response...\n");
    	//assuming recv return 0 when socket is closed)
    	FILE *fp;
    	fp = fopen("default.txt", "a");
    	for(int j; j < BUFFSIZE; j++)
    	{
    		i = recv(serverSocket, &buffer+j, 4, 0);
    		printf("%s\n", buffer);
    	}
    	free(request);
    	request = NULL;
    	
    }
    
    void error(char *msg)
    {
    	printf("Error: %s\n", msg);
    	perror("");
    	exit(0);
    }
    Last edited by aosmith; 03-21-2010 at 03:10 AM. Reason: cleaned up code

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    You need TWO \r\n pairs at the end of the request:
    Code:
    sprintf(request, "GET %s HTTP/1.0\r\nHOST:%s \r\n\r\n", argv[1] + (tok - argv[1]), host);
    It's hanging because the server is waiting for the second one.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function call from another .c module
    By Ali.B in forum C Programming
    Replies: 14
    Last Post: 08-03-2009, 11:45 AM
  2. my HTTP request handler code correct?
    By George2 in forum C# Programming
    Replies: 0
    Last Post: 04-25-2008, 04:01 AM
  3. HTTP GET and POST REQUEST
    By strickey in forum Networking/Device Communication
    Replies: 3
    Last Post: 04-20-2007, 04:23 PM

Tags for this Thread