commit bc113ba911b1a73f7a33284923334f3390e316c7
parent 9cf6f814e802841666ed6d891f676b891205f18d
Author: Sophie <info@soophie.de>
Date: Tue, 11 Mar 2025 15:42:50 +0000
feat: Shortened type names
Diffstat:
M | src/libhttp.h | | | 239 | +++++++++++++++++++++++++++++++++++++------------------------------------------ |
1 file changed, 113 insertions(+), 126 deletions(-)
diff --git a/src/libhttp.h b/src/libhttp.h
@@ -17,7 +17,7 @@ typedef enum {
HTTP_ERR_INVALID_PRIVATE_KEY = 8,
HTTP_ERR_READ_TIMEOUT = 9,
HTTP_ERR_REQUEST_TOO_LONG = 10,
-} http_error_t;
+} http_err_t;
typedef enum {
HTTP_STATUS_CONTINUE = 100,
@@ -124,7 +124,7 @@ typedef struct {
char *body;
long body_len;
void *ext_data;
-} http_request_t;
+} http_req_t;
typedef struct {
char *version;
@@ -133,7 +133,7 @@ typedef struct {
int headers_len;
char *body;
long body_len;
-} http_response_t;
+} http_resp_t;
struct Http {
http_bind_t *binds;
@@ -141,19 +141,18 @@ struct Http {
pthread_t thread;
bool quit;
SSL_CTX *ssl_ctx;
- http_response_t (*on_request_fn)(http_request_t *);
+ http_resp_t (*on_req_fn)(http_req_t *);
};
http_t *http_init(void);
void http_cleanup(http_t *http);
-void http_on_request(http_t *http, http_response_t fn(http_request_t *));
-char *http_header_get(http_request_t *request, char *key);
-void http_header_set(http_response_t *response, char *key, char *value);
-http_response_t http_response_create(http_status_t status);
-void http_response_body(http_response_t *response, char *body, long len);
-void http_response_file(http_response_t *response, char *filename);
-http_error_t http_bind(http_t *http, char *hostname, int port, http_host_t *hosts, int hosts_len);
-http_error_t http_listen(http_t *http);
+void http_on_req(http_t *http, http_resp_t fn(http_req_t *));
+char *http_header_get(http_req_t *req, char *key);
+void http_header_set(http_resp_t *resp, char *key, char *value);
+http_resp_t http_resp_create(http_status_t status);
+void http_resp_body_set(http_resp_t *resp, char *body, long len);
+http_err_t http_bind(http_t *http, char *hostname, int port, http_host_t *hosts, int hosts_len);
+http_err_t http_listen(http_t *http);
void http_close(http_t *http);
#ifdef LIB_HTTP_IMPL
@@ -171,7 +170,11 @@ void http_close(http_t *http);
#include <openssl/ssl.h>
#include <sys/socket.h>
+#define HTTP_VERSION "HTTP/1.1"
#define HTTP_MAX_REQUEST_HEAD_SIZE 1000000
+#define HTTP_SERVER_BACKLOG 5
+#define HTTP_SERVER_SLEEP_TIME 100000000
+#define HTTP_SERVER_POLL_TIME 100
http_t *http_init(void) {
http_t *http = (http_t *) malloc(sizeof(http_t));
@@ -180,7 +183,7 @@ http_t *http_init(void) {
.binds_len = 0,
.quit = false,
.ssl_ctx = NULL,
- .on_request_fn = NULL,
+ .on_req_fn = NULL,
};
return http;
}
@@ -189,20 +192,8 @@ void http_cleanup(http_t *http) {
free(http);
}
-void http_on_request(http_t *http, http_response_t fn(http_request_t *)) {
- http->on_request_fn = fn;
-}
-
-char *http_read_file(char *filename) {
- FILE *fp = fopen(filename, "r");
- fseek(fp, 0, SEEK_END);
- long len = ftell(fp);
- fseek(fp, 0, SEEK_SET);
- char *content = (char *) malloc(sizeof(char) * (len + 1));
- fread(content, len, sizeof(char), fp);
- content[len] = '\0';
- fclose(fp);
- return content;
+void http_on_req(http_t *http, http_resp_t fn(http_req_t *)) {
+ http->on_req_fn = fn;
}
const char *http_status_str(http_status_t status) {
@@ -348,10 +339,10 @@ ssize_t http_write(http_conn_t *conn, char *buffer, size_t len) {
return write(conn->sockfd, buffer, len);
}
-char *http_header_get(http_request_t *request, char *key) {
- if (request->headers_len > 0) {
- for (int i = 0; i < request->headers_len; i++) {
- http_header_t *header = &request->headers[i];
+char *http_header_get(http_req_t *req, char *key) {
+ if (req->headers_len > 0) {
+ for (int i = 0; i < req->headers_len; i++) {
+ http_header_t *header = &req->headers[i];
if (strcmp(header->key, key) == 0) {
return header->value;
}
@@ -360,10 +351,10 @@ char *http_header_get(http_request_t *request, char *key) {
return NULL;
}
-void http_header_set(http_response_t *response, char *key, char *value) {
- response->headers = (http_header_t *) realloc(response->headers, sizeof(http_header_t) * (response->headers_len + 1));
- http_header_t *new_header = &response->headers[response->headers_len];
- response->headers_len++;
+void http_header_set(http_resp_t *resp, char *key, char *value) {
+ resp->headers = (http_header_t *) realloc(resp->headers, sizeof(http_header_t) * (resp->headers_len + 1));
+ http_header_t *new_header = &resp->headers[resp->headers_len];
+ resp->headers_len++;
int key_len = strlen(key);
new_header->key = (char *) malloc(sizeof(char) * (key_len + 1));
memcpy(new_header->key, key, key_len);
@@ -374,48 +365,41 @@ void http_header_set(http_response_t *response, char *key, char *value) {
new_header->value[value_len] = '\0';
}
-http_response_t http_response_create(http_status_t status) {
- const char *version = "HTTP/1.1";
- int version_len = strlen(version);
- http_response_t response = { NULL, status, NULL, 0, NULL, 0 };
- response.version = (char *) malloc(sizeof(char) * (version_len + 1));
- memcpy(response.version, version, version_len);
- response.version[version_len] = '\0';
- return response;
+http_resp_t http_resp_create(http_status_t status) {
+ return (http_resp_t) {
+ .version = strdup(HTTP_VERSION),
+ .status = status,
+ .headers = NULL,
+ .headers_len = 0,
+ .body = NULL,
+ .body_len = 0,
+ };
}
-void http_response_body(http_response_t *response, char *body, long len) {
- if (response != NULL && body != NULL) {
- response->body = (char *) malloc(sizeof(char) * len);
- memcpy(response->body, body, len);
- response->body_len = len;
+void http_resp_body_set(http_resp_t *resp, char *body, long len) {
+ if (resp != NULL && body != NULL) {
+ resp->body = (char *) malloc(sizeof(char) * len);
+ memcpy(resp->body, body, len);
+ resp->body_len = len;
char content_length[50];
snprintf(content_length, 50, "%ld", len);
- http_header_set(response, (char *) "Content-Length", content_length);
+ http_header_set(resp, (char *) "Content-Length", content_length);
}
}
-void http_response_file(http_response_t *response, char *filename) {
- char *content = http_read_file(filename);
- if (content != NULL) {
- http_response_body(response, content, strlen(content));
- free(content);
+void http_req_free(http_req_t *req) {
+ if (req->method != NULL) {
+ free(req->method);
}
-}
-
-void http_request_free(http_request_t *request) {
- if (request->method != NULL) {
- free(request->method);
+ if (req->url != NULL) {
+ free(req->url);
}
- if (request->url != NULL) {
- free(request->url);
+ if (req->version != NULL) {
+ free(req->version);
}
- if (request->version != NULL) {
- free(request->version);
- }
- if (request->headers_len > 0) {
- for (int i = 0; i < request->headers_len; i++) {
- http_header_t *header = &request->headers[i];
+ if (req->headers_len > 0) {
+ for (int i = 0; i < req->headers_len; i++) {
+ http_header_t *header = &req->headers[i];
if (header->key != NULL) {
free(header->key);
}
@@ -424,21 +408,21 @@ void http_request_free(http_request_t *request) {
}
}
}
- if (request->body != NULL) {
- free(request->body);
+ if (req->body != NULL) {
+ free(req->body);
}
- if (request->ext_data != NULL) {
- free(request->ext_data);
+ if (req->ext_data != NULL) {
+ free(req->ext_data);
}
}
-void http_response_free(http_response_t *response) {
- if (response->version != NULL) {
- free(response->version);
+void http_resp_free(http_resp_t *resp) {
+ if (resp->version != NULL) {
+ free(resp->version);
}
- if (response->headers_len > 0) {
- for (int i = 0; i < response->headers_len; i++) {
- http_header_t *header = &response->headers[i];
+ if (resp->headers_len > 0) {
+ for (int i = 0; i < resp->headers_len; i++) {
+ http_header_t *header = &resp->headers[i];
if (header->key != NULL) {
free(header->key);
}
@@ -446,18 +430,21 @@ void http_response_free(http_response_t *response) {
free(header->value);
}
}
+ if (resp->headers != NULL) {
+ free(resp->headers);
+ }
}
- if (response->body != NULL) {
- free(response->body);
+ if (resp->body != NULL) {
+ free(resp->body);
}
}
-http_error_t http_read_request(http_conn_t *conn, http_request_t *request) {
+http_err_t http_read_req(http_conn_t *conn, http_req_t *req) {
int len = 0;
int ln = 0;
int start = 0;
char buffer[HTTP_MAX_REQUEST_HEAD_SIZE];
- *request = (http_request_t) {
+ *req = (http_req_t) {
.conn = conn,
.method = NULL,
.url = NULL,
@@ -505,23 +492,23 @@ http_error_t http_read_request(http_conn_t *conn, http_request_t *request) {
// read method
if (arg == 0) {
int method_length = i - start;
- request->method = (char *) malloc(sizeof(char) * (method_length + 1));
- memcpy(request->method, line + start, method_length);
- request->method[method_length] = '\0';
+ req->method = (char *) malloc(sizeof(char) * (method_length + 1));
+ memcpy(req->method, line + start, method_length);
+ req->method[method_length] = '\0';
}
// read url
if (arg == 1) {
int url_length = i - start;
- request->url = (char *) malloc(sizeof(char) * (url_length + 1));
- memcpy(request->url, line + start, url_length);
- request->url[url_length] = '\0';
+ req->url = (char *) malloc(sizeof(char) * (url_length + 1));
+ memcpy(req->url, line + start, url_length);
+ req->url[url_length] = '\0';
}
// read version
if (arg == 2) {
int version_length = i - start;
- request->version = (char *) malloc(sizeof(char) * (version_length + 1));
- memcpy(request->version, line + start, version_length);
- request->version[version_length] = '\0';
+ req->version = (char *) malloc(sizeof(char) * (version_length + 1));
+ memcpy(req->version, line + start, version_length);
+ req->version[version_length] = '\0';
}
start = i + 1;
arg++;
@@ -531,9 +518,9 @@ http_error_t http_read_request(http_conn_t *conn, http_request_t *request) {
// read headers
else {
int sep = 0;
- request->headers = (http_header_t *) realloc(request->headers, sizeof(http_header_t) * (request->headers_len + 1));
- http_header_t *header = &request->headers[request->headers_len];
- request->headers_len++;
+ req->headers = (http_header_t *) realloc(req->headers, sizeof(http_header_t) * (req->headers_len + 1));
+ http_header_t *header = &req->headers[req->headers_len];
+ req->headers_len++;
for (int i = 0; i < line_len; i++) {
if (line[i] == ':') {
int key_len = i;
@@ -558,13 +545,13 @@ http_error_t http_read_request(http_conn_t *conn, http_request_t *request) {
if (len >= 4) {
char *slice = buffer + (len - 4);
if (strncmp(slice, "\r\n\r\n", 4) == 0) {
- char *content_length = http_header_get(request, (char *) "Content-Length");
+ char *content_length = http_header_get(req, (char *) "Content-Length");
if (content_length != NULL) {
- request->body_len = strtol(content_length, NULL, 10);
- if (request->body_len > 0) {
- request->body = (char *) malloc(sizeof(char) * (request->body_len + 1));
- http_read(conn, request->body, request->body_len);
- request->body[request->body_len] = '\0';
+ req->body_len = strtol(content_length, NULL, 10);
+ if (req->body_len > 0) {
+ req->body = (char *) malloc(sizeof(char) * (req->body_len + 1));
+ http_read(conn, req->body, req->body_len);
+ req->body[req->body_len] = '\0';
}
}
break;
@@ -574,19 +561,19 @@ http_error_t http_read_request(http_conn_t *conn, http_request_t *request) {
return HTTP_ERR_OK;
}
-void http_write_response(http_conn_t *conn, http_response_t response) {
- http_write(conn, response.version, strlen(response.version));
+void http_resp_write(http_conn_t *conn, http_resp_t resp) {
+ http_write(conn, resp.version, strlen(resp.version));
http_write(conn, (char *) " ", 1);
char status[4];
- snprintf(status, 4, "%d", response.status);
+ snprintf(status, 4, "%d", resp.status);
http_write(conn, status, strlen(status));
http_write(conn, (char *) " ", 1);
- const char *status_message = http_status_str(response.status);
+ const char *status_message = http_status_str(resp.status);
http_write(conn, (char *) status_message, strlen(status_message));
http_write(conn, (char *) "\r\n", 2);
- if (response.headers_len > 0) {
- for (int i = 0; i < response.headers_len; i++) {
- http_header_t *header = &response.headers[i];
+ if (resp.headers_len > 0) {
+ for (int i = 0; i < resp.headers_len; i++) {
+ http_header_t *header = &resp.headers[i];
http_write(conn, header->key, strlen(header->key));
http_write(conn, (char *) ": ", 2);
http_write(conn, header->value, strlen(header->value));
@@ -594,12 +581,12 @@ void http_write_response(http_conn_t *conn, http_response_t response) {
}
}
http_write(conn, (char *) "\r\n", 2);
- if (response.body != NULL) {
- http_write(conn, response.body, response.body_len);
+ if (resp.body != NULL) {
+ http_write(conn, resp.body, resp.body_len);
}
}
-void *http_handle_client(void *ptr) {
+void *http_client_handle(void *ptr) {
if (!ptr) {
pthread_exit(0);
}
@@ -622,8 +609,8 @@ void *http_handle_client(void *ptr) {
pthread_exit(0);
}
}
- http_request_t request;
- http_error_t err = http_read_request(conn, &request);
+ http_req_t req;
+ http_err_t err = http_read_req(conn, &req);
if (err != HTTP_ERR_OK) {
if (conn->ssl != NULL) {
SSL_shutdown(conn->ssl);
@@ -633,14 +620,14 @@ void *http_handle_client(void *ptr) {
free(conn);
pthread_exit(0);
}
- if (request.method != NULL && request.url != NULL) {
- if (conn->http->on_request_fn != NULL) {
- http_response_t response = conn->http->on_request_fn(&request);
- http_write_response(conn, response);
- http_response_free(&response);
+ if (req.method != NULL && req.url != NULL) {
+ if (conn->http->on_req_fn != NULL) {
+ http_resp_t resp = conn->http->on_req_fn(&req);
+ http_resp_write(conn, resp);
+ http_resp_free(&resp);
}
}
- http_request_free(&request);
+ http_req_free(&req);
if (conn->ssl != NULL) {
SSL_shutdown(conn->ssl);
SSL_free(conn->ssl);
@@ -650,7 +637,7 @@ void *http_handle_client(void *ptr) {
pthread_exit(0);
}
-void *http_handle_server(void *ptr) {
+void *http_server_handle(void *ptr) {
http_t *http = (http_t *) ptr;
struct pollfd fds[http->binds_len];
for (int i = 0; i < http->binds_len; i++) {
@@ -660,9 +647,9 @@ void *http_handle_server(void *ptr) {
while (!http->quit) {
struct timespec sleep_req, sleep_rem;
sleep_req.tv_sec = 0;
- sleep_req.tv_nsec = 100000000;
+ sleep_req.tv_nsec = HTTP_SERVER_SLEEP_TIME;
nanosleep(&sleep_req, &sleep_rem);
- if (poll(fds, http->binds_len, 100)) {
+ if (poll(fds, http->binds_len, HTTP_SERVER_POLL_TIME)) {
for (int i = 0; i < http->binds_len; i++) {
if (fds[i].revents & POLLIN) {
http_conn_t *conn = (http_conn_t *) malloc(sizeof(http_conn_t));
@@ -679,7 +666,7 @@ void *http_handle_server(void *ptr) {
pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
- pthread_create(&thread, &thread_attr, http_handle_client, (void *) conn);
+ pthread_create(&thread, &thread_attr, http_client_handle, (void *) conn);
pthread_attr_destroy(&thread_attr);
}
}
@@ -690,7 +677,7 @@ void *http_handle_server(void *ptr) {
}
int http_tls_sni_callback(SSL *ssl, int *al, void *arg) {
- (void)(al);
+ (void) al;
http_conn_t *conn = (http_conn_t *) arg;
const char *hostname = SSL_get_servername(ssl, 0);
if (hostname != NULL) {
@@ -708,7 +695,7 @@ int http_tls_sni_callback(SSL *ssl, int *al, void *arg) {
return SSL_TLSEXT_ERR_NOACK;
}
-http_error_t http_bind(http_t *http, char *hostname, int port, http_host_t *hosts, int hosts_len) {
+http_err_t http_bind(http_t *http, char *hostname, int port, http_host_t *hosts, int hosts_len) {
http->binds = (http_bind_t *) realloc(http->binds, sizeof(http_bind_t) * (http->binds_len + 1));
http_bind_t *http_bind = &http->binds[http->binds_len];
http_bind->sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
@@ -731,7 +718,7 @@ http_error_t http_bind(http_t *http, char *hostname, int port, http_host_t *host
if (bind(http_bind->sockfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) < 0) {
return HTTP_ERR_ADDR_IN_USE;
}
- if (listen(http_bind->sockfd, 5) < 0) {
+ if (listen(http_bind->sockfd, HTTP_SERVER_BACKLOG) < 0) {
return HTTP_ERR_NO_LISTEN;
}
for (int i = 0; i < hosts_len; i++) {
@@ -757,7 +744,7 @@ http_error_t http_bind(http_t *http, char *hostname, int port, http_host_t *host
return HTTP_ERR_OK;
}
-http_error_t http_listen(http_t *http) {
+http_err_t http_listen(http_t *http) {
signal(SIGPIPE, SIG_IGN);
const SSL_METHOD *method = TLS_server_method();
http->ssl_ctx = SSL_CTX_new(method);
@@ -765,7 +752,7 @@ http_error_t http_listen(http_t *http) {
return HTTP_ERR_NO_SSL_CONTEXT;
}
SSL_CTX_set_tlsext_servername_callback(http->ssl_ctx, http_tls_sni_callback);
- pthread_create(&http->thread, 0, http_handle_server, (void *) http);
+ pthread_create(&http->thread, 0, http_server_handle, (void *) http);
return HTTP_ERR_OK;
}