Skip to content

Instantly share code, notes, and snippets.

@pixyj
Last active February 10, 2023 09:48
Show Gist options
  • Save pixyj/5202810 to your computer and use it in GitHub Desktop.
Save pixyj/5202810 to your computer and use it in GitHub Desktop.
Simple HTTP client in C
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
/************************************************************************************************
* Try it out:
* $ git clone https://gist.github.com/5202810.git http_client
* $ cd http_client
* $ python -m SimpleHTTPServer
* $ make
* $ ./http_client
*
************************************************************************************************/
/************************************************************************************************
* Blocking call to send HTTP Request and Get Response.
*
* 'request' must contain necessary http request data including http version, method and data
* 'response' is allocated dynamically by the function. Must be freed by caller
*
* Output: 0 - FAILURE in creating sockets/sending data
* 1 - SUCCESS
*
************************************************************************************************/
#define RECV_SIZE 1024
int sendHttpDataAndGetResponse(const char* ipAddress, int port, char* request, char** response)
{
int socketDesc;
struct sockaddr_in server;
char* recvData = calloc(RECV_SIZE, 1);
socketDesc = socket(AF_INET , SOCK_STREAM , 0);
if (socketDesc == -1)
{
printf("%s Could not create socket\n", __FUNCTION__);
return 0;
}
server.sin_addr.s_addr = inet_addr(ipAddress);
server.sin_family = AF_INET;
server.sin_port = htons(port);
if(connect(socketDesc , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
return 0;
}
if(send(socketDesc , request , strlen(request) , 0) < 0)
{
printf("%s Send failed\n", __FUNCTION__);
return 0;
}
int iteration = 1;
char* intermediateData = recvData;
while(recv(socketDesc, intermediateData, RECV_SIZE, 0) > 0)
{
//printf("intermediateData %s\n", intermediateData);
iteration += 1;
recvData = realloc(recvData, iteration*RECV_SIZE);
memset(recvData+(iteration-1)*RECV_SIZE, 0, RECV_SIZE);
//intermediateData = recvData + (iteration-1)*RECV_SIZE-1;
intermediateData = recvData + strlen(recvData);
}
close(socketDesc);
*response = recvData;
return 1;
}
int main()
{
char* response = NULL;
sendHttpDataAndGetResponse("0.0.0.0", 8000, "GET /Makefile HTTP/1.1\r\n\r\n", &response);
printf("Response received\n %s\n", response);
free(response);
sendHttpDataAndGetResponse("0.0.0.0", 8000, "GET / HTTP/1.1\r\n\r\n", &response);
printf("Second response\n %s\n", response);
free(response);
return 0;
}
all:
gcc -Wall http_client.c -o http_client
clean:
rm *.o;rm http_client
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment