mirror of
https://github.com/opus-tango/http-server-in-c.git
synced 2026-03-20 03:55:25 +00:00
changes to send headers and body separately which fixes images not sending
This commit is contained in:
@@ -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;
|
||||
|
||||
44
http_stuff.c
44
http_stuff.c
@@ -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++) {
|
||||
|
||||
13
http_stuff.h
13
http_stuff.h
@@ -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
BIN
public/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user