start working on proper HTTP parser

This commit is contained in:
Nayan
2025-05-06 17:54:28 -04:00
parent 77ce9bca8b
commit 2739b3ae95
3 changed files with 115 additions and 77 deletions

View File

@@ -10,6 +10,9 @@ I also plan to publish this as a portfolio project for my resume.
## TODO List ## TODO List
- [x] Get basic HTTP interaction working - [x] Get basic HTTP interaction working
- [x] Get url parsing working - [x] Get url parsing working
- [x] Fix existing bugs in socket handling and TCP buffering
- [ ] Finish code to parse HTTP requests
- [ ] Finish code to build HTTP responses
- [ ] Get file serving working - [ ] Get file serving working
- [ ] Create basic templating engine for HTML working - [ ] Create basic templating engine for HTML working
- [ ] Get POST requests working - [ ] Get POST requests working

View File

@@ -1,93 +1,108 @@
#include "request_handler.h" #include "request_handler.h"
void handle_request(char* request, int length, char* response, void handle_request(char* request, int length, char* response,
size_t* response_length) { size_t* response_length) {
request[length] = '\0'; // Null terminate request for printing // Terminate request with EOF so strtok stops at end of string
request[length] = EOF;
printf("Request ---------\n"); printf("Request ---------\n");
printf("%s\n---------\n", request); printf("%s\n---------\n", request);
// Check if request is GET // Parse request into struct
char* ptr = request; // Modifiable pointer to request http_request req;
char buf_temp[10]; // Temporary buffer to store request code char* lines[100];
char* ptr_temp = int num_lines = 0;
(char*)&buf_temp; // Modifiable pointer to temporary buffer char* tok = strtok(request, "\n");
// Copy request code to temporary buffer
while (*ptr != ' ') { while (tok != NULL) {
*ptr_temp = *ptr; printf("%s\n", tok);
ptr++; tok = strtok(NULL, "\n");
ptr_temp++;
}
// Null terminate temporary buffer
*ptr_temp = '\0';
ptr++; // Skip over space
if (strcmp(buf_temp, "GET") == 0) {
printf("Received a GET request!!\n");
} else {
printf("Received a non-GET request!!\n");
return;
} }
// Get filename from request url // printf("tok is %s\n", tok);
char filename[100]; // Buffer to store filename
ptr_temp = (char*)&filename; // Modifiable pointer to filename
*ptr_temp = '.'; // Prepend . to filename
ptr_temp++;
// While loop to copy filename to temporary buffer
while (*ptr != ' ') {
// Convert %20 to space
if (*ptr == '%' && *(ptr + 1) == '2' && *(ptr + 2) == '0') {
ptr += 3;
*ptr_temp = ' ';
ptr_temp++;
} else {
// Copy character
*ptr_temp = *ptr;
ptr++;
ptr_temp++;
}
}
*ptr_temp = '\0'; // Null terminate filename
// Print filename // // Check if request is GET
printf("Filename: %s\n", filename); // char* ptr = request; // Modifiable pointer to request
// char buf_temp[10]; // Temporary buffer to store request code
// char* ptr_temp =
// (char*)&buf_temp; // Modifiable pointer to temporary buffer
// // Copy request code to temporary buffer
// while (*ptr != ' ') {
// *ptr_temp = *ptr;
// ptr++;
// ptr_temp++;
// }
// // Null terminate temporary buffer
// *ptr_temp = '\0';
// ptr++; // Skip over space
// if (strcmp(buf_temp, "GET") == 0) {
// printf("Received a GET request!!\n");
// } else {
// printf("Received a non-GET request!!\n");
// return;
// }
// // Get filename from request url
// char filename[100]; // Buffer to store filename
// ptr_temp = (char*)&filename; // Modifiable pointer to filename
// *ptr_temp = '.'; // Prepend . to filename
// ptr_temp++;
// // While loop to copy filename to temporary buffer
// while (*ptr != ' ') {
// // Convert %20 to space
// if (*ptr == '%' && *(ptr + 1) == '2' && *(ptr + 2) == '0') {
// ptr += 3;
// *ptr_temp = ' ';
// ptr_temp++;
// } else {
// // Copy character
// *ptr_temp = *ptr;
// ptr++;
// ptr_temp++;
// }
// }
// *ptr_temp = '\0'; // Null terminate filename
// // Print filename
// printf("Filename: %s\n", filename);
// Create reponse string // Create reponse string
ptr_temp = response; char* ptr_temp = response;
char* temp = char* temp =
"HTTP/1.1 200 OK\r\nContent-Type: text/html \r\nContent-Length: "; "HTTP/1.1 200 OK\r\nContent-Type: text/html \r\nContent-Length: "
while (*temp != '\0') { "0\r\n\r\n\0";
*ptr_temp = *temp; strcpy(ptr_temp, temp);
ptr_temp++; // while (*temp != '\0') {
temp++; // *ptr_temp = *temp;
} // ptr_temp++;
// Put content length in the html response // temp++;
int content_length = strlen(filename); // }
char content_length_str[10]; // // Put content length in the html response
sprintf(content_length_str, "%d", content_length); // int content_length = strlen(filename);
temp = (char*)&content_length_str; // char content_length_str[10];
while (*temp != '\0') { // sprintf(content_length_str, "%d", content_length);
*ptr_temp = *temp; // temp = (char*)&content_length_str;
ptr_temp++; // while (*temp != '\0') {
temp++; // *ptr_temp = *temp;
} // ptr_temp++;
// Terminate header // temp++;
temp = "\r\n\r\n\0"; // }
while (*temp != '\0') { // // Terminate header
*ptr_temp = *temp; // temp = "\r\n\r\n\0";
ptr_temp++; // while (*temp != '\0') {
temp++; // *ptr_temp = *temp;
} // ptr_temp++;
// Put the filename in the html response // temp++;
temp = filename; // }
while (*temp != '\0') { // // Put the filename in the html response
*ptr_temp = *temp; // temp = filename;
ptr_temp++; // while (*temp != '\0') {
temp++; // *ptr_temp = *temp;
} // ptr_temp++;
// temp++;
// }
*ptr_temp = '\0'; // Null terminate response // *ptr_temp = '\0'; // Null terminate response
printf("Response --------\n"); printf("Response --------\n");
printf("%s\n--------\n", response); printf("%s\n--------\n", response);

View File

@@ -1,10 +1,30 @@
#ifndef HTTP_RESPONSE_BUILDER_H #ifndef REQUEST_HANDLER_H
#define HTTP_RESPONSE_BUILDER_H #define REQUEST_HANDLER_H
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
struct http_request {
char* method;
char* url;
char** headers;
int num_headers;
char* body;
size_t body_length;
};
struct http_response {
char* status_line;
char** headers;
int num_headers;
char* body;
size_t body_length;
};
typedef struct http_request http_request;
typedef struct http_response http_response;
void handle_request(char* request, int length, char* response, void handle_request(char* request, int length, char* response,
size_t* response_length); size_t* response_length);