Add px_path_t and functions and memory allocation convenience macros.

This commit is contained in:
ingrix 2024-05-05 19:43:38 -07:00
parent 32314e45c0
commit 5cf7452da1
9 changed files with 172 additions and 31 deletions

25
main.c
View File

@ -281,6 +281,20 @@ int main(int argc, char* argv[]) {
px_connection_delete(conn);
continue;
}
if (req->url && req->url->path) {
px_path_t* pth = px_path_split(req->url->path);
for (char** p = pth->components; *p; ++p) {
px_log_info(" component: '%s'", *p);
}
px_path_t* pth_norm = px_path_normalize(pth);
px_path_delete(pth);
if (pth_norm) {
for (char** p = pth_norm->components; *p; ++p) {
px_log_info(" norm component: '%s'", *p);
}
px_path_delete(pth_norm);
}
}
if (req->url) {
px_log_info("got url path: %s", req->url->path);
@ -309,17 +323,6 @@ int main(int argc, char* argv[]) {
px_connection_shutdown(conn);
px_connection_delete(conn);
}
//int r = px_gemini_response_send(resp, conn);
//if (r != 0) {
// px_log_error("bad return from response send: %d", r);
//}
//px_gemini_response_delete(resp);
//px_connection_shutdown(conn);
//px_connection_delete(conn);
}
px_gemini_request_delete(req);
if (--times == 0)

View File

@ -5,6 +5,7 @@
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <px_common.h>
#include <px_config.h>
#include <px_log.h>
@ -38,7 +39,7 @@ px_server_config_t* px_server_config_from_file(char const* path) {
return NULL;
}
cfg = (px_server_config_t*)malloc(sizeof(px_server_config_t));
cfg = PX_NEW_UNINITIALIZED(px_server_config_t);
if (!cfg) {
int e = errno;
px_log_error("could not allocate server config: %d, %s", e, strerror(e));

View File

@ -1,3 +1,4 @@
#include <px_common.h>
#include <px_connection.h>
#include <unistd.h>
#include <px_log.h>
@ -78,7 +79,7 @@ px_connection_t* px_connection_accept(px_listener_t* lsn) {
"unsupported sa_family for lsn connection");
if (lsn->bind_addr->sa_family == AF_INET) { // AF_INET
client_ai = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
client_ai = (struct sockaddr*)PX_NEW(struct sockaddr_in);
if (!client_ai) {
int e = errno;
px_log_error("could not allocate sockaddr for client connection: %d, %s", e, strerror(e));
@ -126,7 +127,7 @@ px_connection_t* px_connection_accept(px_listener_t* lsn) {
//px_log_debug("accepted connection");
px_connection_t* conn = (px_connection_t*)malloc(sizeof(px_connection_t));
px_connection_t* conn = PX_NEW_UNINITIALIZED(px_connection_t);
if (!conn) {
int e = errno;
px_log_error("could not allocate connection structure: %d, %s", e, strerror(e));

View File

@ -7,13 +7,14 @@
#include <fcntl.h>
#include <unistd.h>
#include <px_common.h>
#include <px_gemini_msg.h>
#include <px_log.h>
#include <px_msg_buf.h>
#include <openssl/err.h>
px_gemini_request_t* px_gemini_request_new() {
px_gemini_request_t* req = (px_gemini_request_t*)malloc(sizeof(px_gemini_request_t));
px_gemini_request_t* req = PX_NEW_UNINITIALIZED(px_gemini_request_t);
if (!req)
return req;
px_gemini_request_init(req);
@ -107,7 +108,7 @@ int px_gemini_valid_url(px_url_t* url) {
}
px_gemini_response_t* px_gemini_response_new() {
px_gemini_response_t* req = (px_gemini_response_t*)malloc(sizeof(px_gemini_response_t));
px_gemini_response_t* req = PX_NEW_UNINITIALIZED(px_gemini_response_t);
if (!req)
return req;
px_gemini_response_init(req);
@ -310,10 +311,7 @@ px_gemini_response_t* px_gemini_response_from_buffer(char const* content, size_t
if (!resp)
return resp;
struct px_gem_static_buffer_* info
= (struct px_gem_static_buffer_*)malloc(sizeof(struct px_gem_static_buffer_));
memset(info, 0, sizeof(*info));
struct px_gem_static_buffer_* info = PX_NEW(struct px_gem_static_buffer_);
if (!info) {
px_gemini_response_delete(resp);
return NULL;

View File

@ -7,6 +7,7 @@
#include <string.h>
#include <unistd.h>
#include <px_common.h>
#include <px_config.h>
#include <px_log.h>
#include <px_listener.h>
@ -37,7 +38,7 @@ void px_listener_delete(px_listener_t* lsn) {
}
px_listener_t* px_listener_new() {
px_listener_t* lsn = (px_listener_t*)malloc(sizeof(px_listener_t));
px_listener_t* lsn = PX_NEW_UNINITIALIZED(px_listener_t);
px_listener_init(lsn);
return lsn;
}
@ -64,7 +65,7 @@ int px_listener_listen_inet4(px_listener_t* lsn, in_addr_t addr, in_port_t port)
return -1;
}
struct sockaddr_in* ai = (struct sockaddr_in*)calloc(1, sizeof(struct sockaddr_in));
struct sockaddr_in* ai = PX_NEW(struct sockaddr_in);
if (!ai) {
int e = errno;
px_log_error("could not allocate ipv4 bind_addr: %d, %s", e, strerror(e));

View File

@ -2,11 +2,12 @@
#include <stdlib.h>
#include <string.h>
#include <px_common.h>
#include <px_msg_buf.h>
#include <px_log.h>
px_msg_buf_t* px_msg_buf_new(size_t sz) {
px_msg_buf_t* rbuf = (px_msg_buf_t*)malloc(sizeof(px_msg_buf_t));
px_msg_buf_t* rbuf = PX_NEW_UNINITIALIZED(px_msg_buf_t);
if (!rbuf) {
int e = errno;
px_log_error("could not allocate response buffer: %s", strerror(e));

120
px_url.c
View File

@ -1,12 +1,12 @@
#include <px_common.h>
#include <px_url.h>
#include <stdlib.h>
#include <string.h>
#include <px_log.h>
#include <errno.h>
px_url_t* px_url_new() {
px_url_t* url = (px_url_t*)malloc(sizeof(px_url_t));
memset(url, 0, sizeof(*url));
return url;
return PX_NEW(px_url_t);
}
void px_url_destroy(px_url_t* url) {
@ -44,3 +44,117 @@ px_url_t* px_url_parse(char const* buf, unsigned buflen) {
}
return url;
}
px_path_t* px_path_split(char const* pathname) {
if (!pathname)
return NULL;
px_path_t* p = PX_NEW(px_path_t);
const size_t COMPONENT_INCREMENT = 8;
// give us 7 components + NULL to start = 8 entries.
// why? 8 entries * 8 bytes = 64, cache line on many systems
size_t n_components = 7;
size_t curi = 0;
p->components = (char**)calloc(n_components + 1, sizeof(char*));
char const* s = pathname;
while (*s && *s == '/')
++s;
while (*s != '\0') {
char const* curp = s;
while (*curp && *curp != '/')
++curp;
if (curi == n_components) {
size_t new_ct = n_components + COMPONENT_INCREMENT;
char** newbuf = (char**)realloc(p->components, new_ct * sizeof(char**));
if (!newbuf) {
px_log_error("could not allocate path");
px_path_delete(p);
return NULL;
}
memset(p->components + curi, 0, COMPONENT_INCREMENT * sizeof(char**));
p->components = newbuf;
n_components = new_ct;
}
char* newstr = strndup(s, curp - s);
if (newstr) {
px_log_assert(*newstr != '\0', "programming error, newstr should not be empty");
p->components[curi++] = newstr;
} else {
int e = errno;
px_log_error("could not strndup: %s", strerror(e));
free(newstr);
errno = e;
}
s = curp;
while (*s == '/')
++s;
}
return p;
}
// remove . and .. from
px_path_t* px_path_normalize(px_path_t* path) {
if (!path)
return NULL;
px_path_t* newpath = PX_NEW(px_path_t);
if (!path->components)
return newpath;
size_t n_comp = 0;
char** p = path->components;
while (*p) {
++n_comp;
++p;
}
if (n_comp == 0)
return newpath;
newpath->components = (char**)calloc(n_comp + 1, sizeof(char*));
if (!newpath->components) {
px_log_error("could not allocate path");
px_path_delete(newpath);
return NULL;
}
size_t n_kept = 0;
p = newpath->components;
for (char** po = path->components; *po; ++po) {
if (**po == '\0' || strcmp(*po, ".") == 0) // empty string or '.'
continue;
if (strcmp(*po, "..") == 0) {
if (n_kept > 0) {
--n_kept;
--p;
free(*p);
}
*p = NULL;
} else {
*p = strdup(*po);
++n_kept;
++p;
}
}
return newpath;
}
void px_path_destroy(px_path_t* path) {
if (!path)
return;
for (char** p = path->components; p && *p; ++p) {
free(*p);
}
free(path->components);
}
void px_path_delete(px_path_t* path) {
px_path_destroy(path);
free(path);
}

View File

@ -16,11 +16,14 @@ px_url_t* px_url_new();
void px_url_destroy(px_url_t* info);
void px_url_delete(px_url_t* info);
//char* px_url_get_scheme(char const* buf);
//char* px_url_get_host(char const* buf);
//char* px_url_get_path(char const* buf);
//char* px_url_get_query(char const* buf);
//char* px_url_get_fragment(char const* buf);
struct px_path_ {
char** components;
};
typedef struct px_path_ px_path_t;
px_path_t* px_path_split(char const* pathname);
px_path_t* px_path_normalize(px_path_t* path);
void px_path_delete(px_path_t* path);
// return the number of output fields populated, or < 0 for error
px_url_t* px_url_parse(char const* buf, unsigned buflen);

19
px_worker.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef PX_WORKER_H__
#define PX_WORKER_H__
enum px_worker_mode_ {
PX_SYNCHRONOUS = 0,
PX_ASYNCHRONOUS,
PX_THREAD
};
typedef enum px_worker_mode_ px_worker_mode_e;
struct px_worker_ {
struct {
};
};
typedef struct px_worker_ px_worker_t;
px_worker_t* px_worker_new(px_worker_mode_e mode);
#endif // PX_WORKER_H__