changes to send headers and body separately which fixes images not sending

This commit is contained in:
Nayan
2025-05-08 18:32:40 -04:00
parent b12cfd2c17
commit 4e8e22ec61
7 changed files with 80 additions and 51 deletions

View File

@@ -28,14 +28,16 @@ void* client_handler(void* args) {
buffer[bytes_read] = '\0';
// Allocate space for response
char* response = NULL;
size_t response_length = BUFFER_SIZE;
http_response* response = create_http_response();
// Handle request
handle_request(buffer, bytes_read, &response, &response_length);
handle_request(buffer, bytes_read, response);
// Send response
send(client, response, response_length, 0);
char* headers = response_headers_to_string(response);
send(client, headers, strlen(headers), 0);
send(client, response->body, response->content_length, 0);
send(client, "\r\n", 2, 0);
free(response);
return NULL;

View File

@@ -138,7 +138,7 @@ char* response_to_string(http_response* res) {
total_length += strlen("Content-Length: ");
total_length += strlen(content_lenth_str);
total_length += len_crlf;
total_length += strlen(res->body);
total_length += res->content_length;
total_length += len_crlf;
total_length += 1; // For null terminator
@@ -161,6 +161,48 @@ char* response_to_string(http_response* res) {
return response;
}
char* response_headers_to_string(http_response* res) {
// Define lengths
int total_length = 0;
int len_newline = strlen("\r\n");
int len_crlf = strlen("\r\n\r\n");
char* content_lenth_str = (char*)malloc(10);
sprintf(content_lenth_str, "%zu", res->content_length);
// Calculate total length
total_length += strlen(res->status_line);
total_length += len_newline;
for (int i = 0; i < res->num_headers; i++) {
total_length += strlen(res->headers[i].key);
total_length += strlen(": ");
total_length += strlen(res->headers[i].value);
total_length += len_newline;
}
total_length += strlen(res->content_type);
total_length += len_newline;
total_length += strlen("Content-Length: ");
total_length += strlen(content_lenth_str);
total_length += len_crlf;
total_length += 1; // For null terminator
char* response = (char*)malloc(total_length);
strcpy(response, res->status_line);
strcat(response, "\r\n");
for (int i = 0; i < res->num_headers; i++) {
strcat(response, res->headers[i].key);
strcat(response, ": ");
strcat(response, res->headers[i].value);
strcat(response, "\r\n");
}
strcat(response, res->content_type);
strcat(response, "\r\n");
strcat(response, "Content-Length: ");
strcat(response, content_lenth_str);
strcat(response, "\r\n\r\n");
return response;
}
char* get_header_value_request(http_request* req, char* key) {
// printf("Getting header value for key: %s\n", key);
for (int i = 0; i < req->num_headers; i++) {

View File

@@ -139,6 +139,19 @@ void print_http_response(http_response* res);
*/
char* response_to_string(http_response* res);
/**
* Returns the string representation of an http_response struct WITHOUT the
* body. This function is meant to be used when sending a response over a
* socket. It allocates memory for the string and returns a pointer to it, so
* the caller is responsible for freeing the memory when it is no longer
* needed.
*
* @param res The response to convert to a string
*
* @return A pointer to the string representation of the response
*/
char* response_headers_to_string(http_response* res);
/**
* Finds the value associated with a given key in an http_request's headers.
*

BIN
public/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -3,41 +3,19 @@
void parse_http_request(char* request, int length, struct http_request* req);
void debug_print_request(char* request);
void handle_request(char* request, int length, char** response,
size_t* response_length) {
void handle_request(char* request, int length, http_response* response) {
// Terminate request with EOF so strtok stops at end of string
request[length] = EOF;
// printf("Request ---------\n");
// printf("%s\n---------\n", request);
// debug_print_request(request);
// printf("parsing request ---------\n");
// Parse request into struct
http_request* req = create_http_request();
parse_http_request(request, length, req);
// print_http_request(req);
// printf("---------\n");
// request_info_print(req);
// free_http_request(req);
// Switch statement to handle different request types
switch (req->method) {
case GET:
// Build response
http_response* res = create_http_response();
response_handle_get(req, res);
// Convert response to string
char* response_string = response_to_string(res);
// Copy string to response
char* responsestr = (char*)malloc(strlen(response_string) + 1);
strcpy(responsestr, response_string);
*response = responsestr;
// Set response length
*response_length = strlen(response_string);
// Free response
free_http_response(res);
response_handle_get(req, response);
break;
case POST:

View File

@@ -8,7 +8,6 @@
#include "http_stuff.h"
#include "response_builder.h"
void handle_request(char* request, int length, char** response,
size_t* response_length);
void handle_request(char* request, int length, http_response* response);
#endif

View File

@@ -8,42 +8,28 @@ void response_handle_get(http_request* req, http_response* res) {
strcat(file_path, req->url);
printf("%s\n", file_path);
serve_404(res);
return;
// Determine the file type
char* ptr = file_path + strlen(file_path) - 1;
size_t etc_len = 0;
while (*ptr != '.') {
etc_len++;
ptr--;
}
char* etc = (char*)malloc(etc_len + 1);
strncpy(etc, ptr, etc_len);
etc[etc_len] = '\0';
printf("%s\n", etc);
if (strcmp(etc, ".html") == 0) {
if (strcmp(ptr, ".html") == 0) {
response_build_static_file(file_path, HTML, OK, res);
} else if (strcmp(etc, ".jpg") == 0) {
} else if (strcmp(ptr, ".jpg") == 0) {
serve_404(res);
return;
} else if (strcmp(etc, ".png") == 0) {
} else if (strcmp(ptr, ".png") == 0) {
response_build_static_file(file_path, PNG, OK, res);
} else if (strcmp(ptr, ".css") == 0) {
serve_404(res);
return;
} else if (strcmp(etc, ".css") == 0) {
serve_404(res);
return;
} else if (strcmp(etc, ".js") == 0) {
} else if (strcmp(ptr, ".js") == 0) {
serve_404(res);
return;
} else {
serve_404(res);
return;
}
// Serve 404 if file not found or file type not supported (html, jpg, png
// only)
// Serve the file
}
void response_build_static_file(char* file_path, content_type content_type,
@@ -145,6 +131,15 @@ void response_build_static_file(char* file_path, content_type content_type,
}
// Set content type string
res->content_type = content_type_str;
// Add header for close connection
header_kv* close_connection = (header_kv*)malloc(sizeof(header_kv));
close_connection->key = (char*)malloc(strlen("Connection") + 1);
close_connection->value = (char*)malloc(strlen("close") + 1);
strcpy(close_connection->key, "Connection");
strcpy(close_connection->value, "close");
res->headers = close_connection;
res->num_headers = 1;
}
void serve_404(http_response* res) {