mirror of
https://github.com/opus-tango/http-server-in-c.git
synced 2026-03-20 03:55:25 +00:00
add body extraction and clean up and fix http stuff, in particular add auto_fill content metadata from headers
This commit is contained in:
36
http_stuff.c
36
http_stuff.c
@@ -26,20 +26,17 @@ http_response* create_http_response() {
|
|||||||
void free_http_request(http_request* req) {
|
void free_http_request(http_request* req) {
|
||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
printf("Attempting to free NULL request\n");
|
printf("Attempting to free NULL request\n");
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
if (req->method != NULL) {
|
if (req->method != NULL) {
|
||||||
printf("Freeing request method\n");
|
|
||||||
free(req->method);
|
free(req->method);
|
||||||
req->method = NULL;
|
req->method = NULL;
|
||||||
}
|
}
|
||||||
if (req->url != NULL) {
|
if (req->url != NULL) {
|
||||||
printf("Freeing request url\n");
|
|
||||||
free(req->url);
|
free(req->url);
|
||||||
req->url = NULL;
|
req->url = NULL;
|
||||||
}
|
}
|
||||||
if (req->headers != NULL) {
|
if (req->headers != NULL) {
|
||||||
printf("Freeing request headers\n");
|
|
||||||
for (int i = 0; i < req->num_headers; i++) {
|
for (int i = 0; i < req->num_headers; i++) {
|
||||||
free(req->headers[i].key);
|
free(req->headers[i].key);
|
||||||
req->headers[i].key = NULL;
|
req->headers[i].key = NULL;
|
||||||
@@ -50,16 +47,13 @@ void free_http_request(http_request* req) {
|
|||||||
req->headers = NULL;
|
req->headers = NULL;
|
||||||
}
|
}
|
||||||
if (req->content_type != NULL) {
|
if (req->content_type != NULL) {
|
||||||
printf("Freeing request content type\n");
|
|
||||||
free(req->content_type);
|
free(req->content_type);
|
||||||
req->content_type = NULL;
|
req->content_type = NULL;
|
||||||
}
|
}
|
||||||
if (req->body != NULL) {
|
if (req->body != NULL) {
|
||||||
printf("Freeing request body\n");
|
|
||||||
free(req->body);
|
free(req->body);
|
||||||
req->body = NULL;
|
req->body = NULL;
|
||||||
}
|
}
|
||||||
printf("Freeing request\n");
|
|
||||||
free(req);
|
free(req);
|
||||||
req = NULL;
|
req = NULL;
|
||||||
}
|
}
|
||||||
@@ -67,7 +61,7 @@ void free_http_request(http_request* req) {
|
|||||||
void free_http_response(http_response* res) {
|
void free_http_response(http_response* res) {
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
printf("Attempting to free NULL response\n");
|
printf("Attempting to free NULL response\n");
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
if (res->status_line != NULL) {
|
if (res->status_line != NULL) {
|
||||||
free(res->status_line);
|
free(res->status_line);
|
||||||
@@ -185,14 +179,26 @@ void request_add_header(http_request* req, char* key, char* value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void request_info_print(http_request* req) {
|
void request_info_print(http_request* req) {
|
||||||
printf("Method: %d\n", (int)req->method);
|
printf("Method: %p\n", (int*)req->method);
|
||||||
printf("URL: %d\n", (int)req->url);
|
printf("URL: %p\n", (int*)req->url);
|
||||||
printf("Headers:\n");
|
printf("Headers:\n");
|
||||||
for (int i = 0; i < req->num_headers; i++) {
|
for (int i = 0; i < req->num_headers; i++) {
|
||||||
printf("%d: %d\n", (int)req->headers[i].key,
|
printf("%p: %p\n", (int*)req->headers[i].key,
|
||||||
(int)req->headers[i].value);
|
(int*)req->headers[i].value);
|
||||||
|
}
|
||||||
|
printf("Content-Type: %p\n", (int*)req->content_type);
|
||||||
|
printf("Content-Length: %d\n", (int)req->content_length);
|
||||||
|
printf("Body:\n%p\n", (int*)req->body);
|
||||||
|
}
|
||||||
|
|
||||||
|
void autofill_content_meta(http_request* req) {
|
||||||
|
char* cptr = get_header_value_request(req, "Content-Type");
|
||||||
|
if (cptr != NULL) {
|
||||||
|
req->content_type = malloc(strlen(cptr) + 1);
|
||||||
|
strcpy(req->content_type, cptr);
|
||||||
|
}
|
||||||
|
cptr = get_header_value_request(req, "Content-Length");
|
||||||
|
if (cptr != NULL) {
|
||||||
|
req->content_length = atoi(cptr);
|
||||||
}
|
}
|
||||||
printf("Content-Type: %d\n", (int)req->content_type);
|
|
||||||
printf("Content-Length: %zu\n", req->content_length);
|
|
||||||
printf("Body:\n%d\n", (int)req->body);
|
|
||||||
}
|
}
|
||||||
24
http_stuff.h
24
http_stuff.h
@@ -173,6 +173,30 @@ void request_add_header_n(http_request* req, char* key, size_t key_length,
|
|||||||
*/
|
*/
|
||||||
void request_add_header(http_request* req, char* key, char* value);
|
void request_add_header(http_request* req, char* key, char* value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints out information about an HTTP request, in a way that is not
|
||||||
|
* particularly human-readable. This function is used for debugging
|
||||||
|
* purposes.
|
||||||
|
*
|
||||||
|
* @param req The request to print information about
|
||||||
|
*/
|
||||||
void request_info_print(http_request* req);
|
void request_info_print(http_request* req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically fills in the Content-Type and Content-Length fields of the
|
||||||
|
* given http_request if they are not already set. This function is meant to be
|
||||||
|
* used when the content type and length are not known when the request is
|
||||||
|
* created, but are known when the request is processed.
|
||||||
|
*
|
||||||
|
* @param req The request whose Content-Type and Content-Length fields are to
|
||||||
|
* be filled in
|
||||||
|
*
|
||||||
|
* @details
|
||||||
|
* This function will search for the Content-Type and Content-Length headers in
|
||||||
|
* the request. If it finds either of them, it will copy the value of the header
|
||||||
|
* into the appropriate field in the request. If it does not find either of
|
||||||
|
* them, it does nothing.
|
||||||
|
*/
|
||||||
|
void autofill_content_meta(http_request* req);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -19,6 +19,7 @@ void handle_request(char* request, int length, char* response,
|
|||||||
parse_http_request(request, length, req);
|
parse_http_request(request, length, req);
|
||||||
print_http_request(req);
|
print_http_request(req);
|
||||||
printf("---------\n");
|
printf("---------\n");
|
||||||
|
request_info_print(req);
|
||||||
free_http_request(req);
|
free_http_request(req);
|
||||||
|
|
||||||
// Create reponse string
|
// Create reponse string
|
||||||
@@ -93,12 +94,14 @@ void parse_http_request(char* request, int length, struct http_request* req) {
|
|||||||
header_start = header_end + 2;
|
header_start = header_end + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in content type and length. In order to avoid a double free we copy
|
// Autofill content metadata based on headers
|
||||||
// the content type instead of just pointing to the request header
|
autofill_content_meta(req);
|
||||||
req->content_type =
|
|
||||||
malloc(strlen(get_header_value_request(req, "Content-Type")) + 1);
|
// Extract body
|
||||||
strcpy(req->content_type, get_header_value_request(req, "Content-Type"));
|
char* body_start = headers_end + 4;
|
||||||
req->content_length = atoi(get_header_value_request(req, "Content-Length"));
|
req->body = (char*)malloc(length - (body_start - request) + 1);
|
||||||
|
strncpy(req->body, body_start, length - (body_start - request));
|
||||||
|
req->body[length - (body_start - request)] = '\0';
|
||||||
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user