mirror of
https://github.com/opus-tango/http-server-in-c.git
synced 2026-03-20 12:05: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';
|
buffer[bytes_read] = '\0';
|
||||||
|
|
||||||
// Allocate space for response
|
// Allocate space for response
|
||||||
char* response = NULL;
|
http_response* response = create_http_response();
|
||||||
size_t response_length = BUFFER_SIZE;
|
|
||||||
|
|
||||||
// Handle request
|
// Handle request
|
||||||
handle_request(buffer, bytes_read, &response, &response_length);
|
handle_request(buffer, bytes_read, response);
|
||||||
|
|
||||||
// Send 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);
|
free(response);
|
||||||
return NULL;
|
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-Length: ");
|
||||||
total_length += strlen(content_lenth_str);
|
total_length += strlen(content_lenth_str);
|
||||||
total_length += len_crlf;
|
total_length += len_crlf;
|
||||||
total_length += strlen(res->body);
|
total_length += res->content_length;
|
||||||
total_length += len_crlf;
|
total_length += len_crlf;
|
||||||
total_length += 1; // For null terminator
|
total_length += 1; // For null terminator
|
||||||
|
|
||||||
@@ -161,6 +161,48 @@ char* response_to_string(http_response* res) {
|
|||||||
return response;
|
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) {
|
char* get_header_value_request(http_request* req, char* key) {
|
||||||
// printf("Getting header value for key: %s\n", key);
|
// printf("Getting header value for key: %s\n", key);
|
||||||
for (int i = 0; i < req->num_headers; i++) {
|
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);
|
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.
|
* 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 parse_http_request(char* request, int length, struct http_request* req);
|
||||||
void debug_print_request(char* request);
|
void debug_print_request(char* request);
|
||||||
|
|
||||||
void handle_request(char* request, int length, char** response,
|
void handle_request(char* request, int length, http_response* response) {
|
||||||
size_t* response_length) {
|
|
||||||
// Terminate request with EOF so strtok stops at end of string
|
// Terminate request with EOF so strtok stops at end of string
|
||||||
request[length] = EOF;
|
request[length] = EOF;
|
||||||
|
|
||||||
// printf("Request ---------\n");
|
|
||||||
// printf("%s\n---------\n", request);
|
|
||||||
|
|
||||||
// debug_print_request(request);
|
|
||||||
|
|
||||||
// printf("parsing request ---------\n");
|
|
||||||
// Parse request into struct
|
// Parse request into struct
|
||||||
http_request* req = create_http_request();
|
http_request* req = create_http_request();
|
||||||
parse_http_request(request, length, req);
|
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 statement to handle different request types
|
||||||
switch (req->method) {
|
switch (req->method) {
|
||||||
case GET:
|
case GET:
|
||||||
// Build response
|
// Build response
|
||||||
http_response* res = create_http_response();
|
response_handle_get(req, 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);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POST:
|
case POST:
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "http_stuff.h"
|
#include "http_stuff.h"
|
||||||
#include "response_builder.h"
|
#include "response_builder.h"
|
||||||
|
|
||||||
void handle_request(char* request, int length, char** response,
|
void handle_request(char* request, int length, http_response* response);
|
||||||
size_t* response_length);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -8,42 +8,28 @@ void response_handle_get(http_request* req, http_response* res) {
|
|||||||
strcat(file_path, req->url);
|
strcat(file_path, req->url);
|
||||||
printf("%s\n", file_path);
|
printf("%s\n", file_path);
|
||||||
|
|
||||||
serve_404(res);
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Determine the file type
|
// Determine the file type
|
||||||
char* ptr = file_path + strlen(file_path) - 1;
|
char* ptr = file_path + strlen(file_path) - 1;
|
||||||
size_t etc_len = 0;
|
|
||||||
while (*ptr != '.') {
|
while (*ptr != '.') {
|
||||||
etc_len++;
|
|
||||||
ptr--;
|
ptr--;
|
||||||
}
|
}
|
||||||
char* etc = (char*)malloc(etc_len + 1);
|
if (strcmp(ptr, ".html") == 0) {
|
||||||
strncpy(etc, ptr, etc_len);
|
|
||||||
etc[etc_len] = '\0';
|
|
||||||
printf("%s\n", etc);
|
|
||||||
if (strcmp(etc, ".html") == 0) {
|
|
||||||
response_build_static_file(file_path, HTML, OK, res);
|
response_build_static_file(file_path, HTML, OK, res);
|
||||||
} else if (strcmp(etc, ".jpg") == 0) {
|
} else if (strcmp(ptr, ".jpg") == 0) {
|
||||||
serve_404(res);
|
serve_404(res);
|
||||||
return;
|
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);
|
serve_404(res);
|
||||||
return;
|
return;
|
||||||
} else if (strcmp(etc, ".css") == 0) {
|
} else if (strcmp(ptr, ".js") == 0) {
|
||||||
serve_404(res);
|
|
||||||
return;
|
|
||||||
} else if (strcmp(etc, ".js") == 0) {
|
|
||||||
serve_404(res);
|
serve_404(res);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
serve_404(res);
|
serve_404(res);
|
||||||
return;
|
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,
|
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
|
// Set content type string
|
||||||
res->content_type = content_type_str;
|
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) {
|
void serve_404(http_response* res) {
|
||||||
|
|||||||
Reference in New Issue
Block a user