some changes idk
This commit is contained in:
@ -24,19 +24,19 @@ uint64_t get_file_size(char *filename){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct str get_file_format(struct str filename){
|
str get_file_format(str filename){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(filename.len-i > 0){
|
while(filename.len-i > 0){
|
||||||
if(filename.ptr[filename.len-i-1] == '.') break;
|
if(filename.ptr[filename.len-i-1] == '.') break;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if(i == 0 || i == filename.len){
|
if(i == 0 || i == filename.len){
|
||||||
return ((struct str){0});
|
return ((str){0});
|
||||||
}
|
}
|
||||||
struct str fmt;
|
str fmt;
|
||||||
fmt.len = i;
|
fmt.len = i;
|
||||||
fmt.ptr = calloc(fmt.len+1, sizeof(char));
|
fmt.ptr = calloc(fmt.len+1, sizeof(char));
|
||||||
if(fmt.ptr == NULL) return ((struct str){0});
|
if(fmt.ptr == NULL) return ((str){0});
|
||||||
memcpy(fmt.ptr, filename.ptr+filename.len-i, fmt.len);
|
memcpy(fmt.ptr, filename.ptr+filename.len-i, fmt.len);
|
||||||
return fmt;
|
return fmt;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
|
|
||||||
struct file {
|
struct file {
|
||||||
struct str name;
|
str name;
|
||||||
bool temp;
|
bool temp;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ uint64_t get_fp_size(FILE *fp);
|
|||||||
|
|
||||||
uint64_t get_file_size(char *filename);
|
uint64_t get_file_size(char *filename);
|
||||||
|
|
||||||
struct str get_file_format(struct str filename);
|
str get_file_format(str filename);
|
||||||
|
|
||||||
uint64_t getNEntries(const char *dir);
|
uint64_t getNEntries(const char *dir);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
|
|
||||||
|
|
||||||
ipc_sender *setup_ipc_sender(struct str addr, int backlog){
|
ipc_sender *setup_ipc_sender(str addr, int backlog){
|
||||||
ipc_sender *is = calloc(1, sizeof(ipc_sender));
|
ipc_sender *is = calloc(1, sizeof(ipc_sender));
|
||||||
is->addr = dup_str(addr);
|
is->addr = dup_str(addr);
|
||||||
is->ssocket = socket(AF_UNIX, SOCK_STREAM, 0);
|
is->ssocket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
@ -40,7 +40,7 @@ void destroy_ipc_sender(ipc_sender **is){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ipc_listener *setup_ipc_listener(struct str saddr){
|
ipc_listener *setup_ipc_listener(str saddr){
|
||||||
ipc_listener *il = calloc(1, sizeof(ipc_listener));
|
ipc_listener *il = calloc(1, sizeof(ipc_listener));
|
||||||
il->saddr = dup_str(saddr);
|
il->saddr = dup_str(saddr);
|
||||||
il->csocket = socket(AF_UNIX, SOCK_STREAM, 0);
|
il->csocket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
@ -78,8 +78,8 @@ void free_ipc_message(ipc_message im){
|
|||||||
free_str(&im.val);
|
free_str(&im.val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct str ipc_message_to_str(ipc_message msg){
|
static inline str ipc_message_to_str(ipc_message msg){
|
||||||
struct str smsg = nstr(msg.key.len + msg.val.len + 2*sizeof(u32));
|
str smsg = dnstr(msg.key.len + msg.val.len + 2*sizeof(u32));
|
||||||
memcpy(smsg.ptr+smsg.len, &msg.key.len, sizeof(msg.key.len));
|
memcpy(smsg.ptr+smsg.len, &msg.key.len, sizeof(msg.key.len));
|
||||||
smsg.len += sizeof(msg.key.len);
|
smsg.len += sizeof(msg.key.len);
|
||||||
copy_str(smsg, msg.key);
|
copy_str(smsg, msg.key);
|
||||||
@ -90,7 +90,7 @@ static inline struct str ipc_message_to_str(ipc_message msg){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int send_ipc_message(int to, ipc_message msg){
|
int send_ipc_message(int to, ipc_message msg){
|
||||||
struct str smsg = ipc_message_to_str(msg);
|
str smsg = ipc_message_to_str(msg);
|
||||||
if(send(to, smsg.ptr, smsg.len, 0) == -1){
|
if(send(to, smsg.ptr, smsg.len, 0) == -1){
|
||||||
log_error("cant send message to socket %d: %s", to, strerror(errno));
|
log_error("cant send message to socket %d: %s", to, strerror(errno));
|
||||||
free_str(&smsg);
|
free_str(&smsg);
|
||||||
@ -109,25 +109,25 @@ int send_ipc_message(int to, ipc_message msg){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline ipc_message str_to_ipc_message(struct str smsg){
|
static inline ipc_message str_to_ipc_message(str smsg){
|
||||||
struct ipc_message msg;
|
struct ipc_message msg;
|
||||||
u32 l;
|
u32 l;
|
||||||
memcpy(&l, smsg.ptr, sizeof(l));
|
memcpy(&l, smsg.ptr, sizeof(l));
|
||||||
smsg.ptr += sizeof(l);
|
smsg.ptr += sizeof(l);
|
||||||
msg.key = nstr(l);
|
msg.key = dnstr(l);
|
||||||
msg.key.len = l;
|
msg.key.len = l;
|
||||||
memcpy(msg.key.ptr, smsg.ptr, l);
|
memcpy(msg.key.ptr, smsg.ptr, l);
|
||||||
smsg.ptr += l;
|
smsg.ptr += l;
|
||||||
memcpy(&l, smsg.ptr, sizeof(l));
|
memcpy(&l, smsg.ptr, sizeof(l));
|
||||||
smsg.ptr += sizeof(l);
|
smsg.ptr += sizeof(l);
|
||||||
msg.val = nstr(l);
|
msg.val = dnstr(l);
|
||||||
msg.val.len = l;
|
msg.val.len = l;
|
||||||
memcpy(msg.val.ptr, smsg.ptr, l);
|
memcpy(msg.val.ptr, smsg.ptr, l);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipc_message receive_ipc_message(ipc_listener *il){
|
ipc_message receive_ipc_message(ipc_listener *il){
|
||||||
struct str smsg = nstr(MAX_IPC_MSG_LEN); // we are gonna have to poll btw
|
str smsg = dnstr(MAX_IPC_MSG_LEN); // we are gonna have to poll btw
|
||||||
ipc_message msg = {0};
|
ipc_message msg = {0};
|
||||||
smsg.len = recv(il->csocket, smsg.ptr, smsg.cap, 0);
|
smsg.len = recv(il->csocket, smsg.ptr, smsg.cap, 0);
|
||||||
if(smsg.len == -1){
|
if(smsg.len == -1){
|
||||||
|
@ -14,25 +14,25 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef struct ipc_sender {
|
typedef struct ipc_sender {
|
||||||
struct str addr;
|
str addr;
|
||||||
int ssocket;
|
int ssocket;
|
||||||
} ipc_sender;
|
} ipc_sender;
|
||||||
|
|
||||||
typedef struct ipc_listener {
|
typedef struct ipc_listener {
|
||||||
struct str saddr;
|
str saddr;
|
||||||
int csocket;
|
int csocket;
|
||||||
} ipc_listener;
|
} ipc_listener;
|
||||||
|
|
||||||
#define MAX_IPC_MSG_LEN 1024
|
#define MAX_IPC_MSG_LEN 1024
|
||||||
typedef struct ipc_message {
|
typedef struct ipc_message {
|
||||||
struct str key;
|
str key;
|
||||||
struct str val;
|
str val;
|
||||||
} ipc_message;
|
} ipc_message;
|
||||||
|
|
||||||
ipc_sender *setup_ipc_sender(struct str addr, int backlog);
|
ipc_sender *setup_ipc_sender(str addr, int backlog);
|
||||||
void destroy_ipc_sender(ipc_sender **is);
|
void destroy_ipc_sender(ipc_sender **is);
|
||||||
|
|
||||||
ipc_listener *setup_ipc_listener(struct str saddr);
|
ipc_listener *setup_ipc_listener(str saddr);
|
||||||
void destroy_ipc_listener(ipc_listener **il);
|
void destroy_ipc_listener(ipc_listener **il);
|
||||||
|
|
||||||
void free_ipc_message(ipc_message im);
|
void free_ipc_message(ipc_message im);
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
#define BACKLOG 15
|
#define BACKLOG 15
|
||||||
|
|
||||||
struct str ipcaddr = sstr(".ipcserver");
|
str ipcaddr = sstr(".ipcserver");
|
||||||
struct str port;
|
str port;
|
||||||
http_server *server;
|
http_server *server;
|
||||||
ipc_sender *sender;
|
ipc_sender *sender;
|
||||||
struct worker {
|
struct worker {
|
||||||
@ -77,6 +77,8 @@ void show_commands(void){
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "crc64/crc64.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[]){
|
int main(int argc, char *argv[]){
|
||||||
|
|
||||||
if(argc < 2){
|
if(argc < 2){
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
|
||||||
|
|
||||||
struct str response_headers[] = {
|
enum header_enum {
|
||||||
|
CONTENT_LENGTH,
|
||||||
|
CONTENT_TYPE,
|
||||||
|
TRANSFER_ENCODING
|
||||||
|
};
|
||||||
|
str response_headers[] = {
|
||||||
sstr("Content-Length"),
|
sstr("Content-Length"),
|
||||||
sstr("Content-Type"),
|
sstr("Content-Type"),
|
||||||
sstr("Transfer-Encoding"),
|
sstr("Transfer-Encoding"),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct str fmt;
|
str fmt;
|
||||||
struct str type;
|
str type;
|
||||||
} mime_types[] = {
|
} mime_types[] = {
|
||||||
{.fmt = sstr("avif"), .type = sstr("image/avif")},
|
{.fmt = sstr("avif"), .type = sstr("image/avif")},
|
||||||
{.fmt = sstr("bmp"), .type = sstr("image/bmp")},
|
{.fmt = sstr("bmp"), .type = sstr("image/bmp")},
|
||||||
@ -66,7 +71,7 @@ static int pleasesslgivemetheerror(int ssl_get_error){
|
|||||||
return ssl_get_error;
|
return ssl_get_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
http_server *setup_http_server(struct str port, int backlog){
|
http_server *setup_http_server(str port, int backlog){
|
||||||
http_server *hs = calloc(1, sizeof(http_server));
|
http_server *hs = calloc(1, sizeof(http_server));
|
||||||
hs->port = dup_str(port);
|
hs->port = dup_str(port);
|
||||||
hs->backlog = backlog;
|
hs->backlog = backlog;
|
||||||
@ -118,7 +123,7 @@ void destroy_http_server(http_server **hs){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
http_worker *setup_http_worker(int ssocket, int secure, struct str certfile, struct str keyfile){
|
http_worker *setup_http_worker(int ssocket, int secure, str certfile, str keyfile){
|
||||||
http_worker *hw = calloc(1, sizeof(http_worker));
|
http_worker *hw = calloc(1, sizeof(http_worker));
|
||||||
hw->ssocket = ssocket;
|
hw->ssocket = ssocket;
|
||||||
hw->csocket = -1;
|
hw->csocket = -1;
|
||||||
@ -133,6 +138,11 @@ http_worker *setup_http_worker(int ssocket, int secure, struct str certfile, str
|
|||||||
if(hw->ssl_ctx == NULL){
|
if(hw->ssl_ctx == NULL){
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
//SSL_CTX_set_verify(hw->ssl_ctx, SSL_VERIFY_PEER, NULL);
|
||||||
|
if(SSL_CTX_load_verify_locations(hw->ssl_ctx, "ssl/mkarchive.net/ca_bundle.crt", NULL) <= 0){
|
||||||
|
log_error("ca_bundle.crt");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if(SSL_CTX_use_certificate_file(hw->ssl_ctx, certfile.ptr, SSL_FILETYPE_PEM) <= 0){
|
if(SSL_CTX_use_certificate_file(hw->ssl_ctx, certfile.ptr, SSL_FILETYPE_PEM) <= 0){
|
||||||
log_error("worker_cert");
|
log_error("worker_cert");
|
||||||
goto error;
|
goto error;
|
||||||
@ -200,13 +210,13 @@ int accept_connection(http_worker *hw, char ip[INET_ADDRSTRLEN]){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int worker_read(http_worker *hw, struct str *buf){
|
static inline int worker_read(http_worker *hw, str *buf){
|
||||||
return hw->secure ?
|
return hw->secure ?
|
||||||
SSL_read(hw->ssl, buf->ptr+buf->len, buf->cap-buf->len) :
|
SSL_read(hw->ssl, buf->ptr+buf->len, buf->cap-buf->len) :
|
||||||
recv(hw->csocket, buf->ptr+buf->len, buf->cap-buf->len, 0);
|
recv(hw->csocket, buf->ptr+buf->len, buf->cap-buf->len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int receive_request(http_worker *hw, struct str *request){
|
int receive_request(http_worker *hw, str *request){
|
||||||
// for some reason SSL_has_pending can return 0 but we can still read data
|
// for some reason SSL_has_pending can return 0 but we can still read data
|
||||||
struct pollfd pfd[1] = { {.fd = hw->csocket, .events = POLLIN } };
|
struct pollfd pfd[1] = { {.fd = hw->csocket, .events = POLLIN } };
|
||||||
while((hw->secure && SSL_has_pending(hw->ssl)) || poll(pfd, 1, 0)){
|
while((hw->secure && SSL_has_pending(hw->ssl)) || poll(pfd, 1, 0)){
|
||||||
@ -229,19 +239,19 @@ int receive_request(http_worker *hw, struct str *request){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct file generate_resource(struct uri resource, struct str url){
|
struct file generate_resource(struct uri resource, str url){
|
||||||
struct file file = {0};
|
struct file file = {0};
|
||||||
/*
|
/*
|
||||||
generate if both of these are true
|
generate if all of these are true
|
||||||
1) no file specified (aka we need index.html)
|
1) no file specified (aka we need index.html)
|
||||||
2) theres an index.html.php
|
2) theres an index.html.php
|
||||||
3) index.html isnt cached (future)
|
3) index.html isnt cached (future)
|
||||||
*/
|
*/
|
||||||
struct str phpfile = nstr(resource.path.len + slen(".php"));
|
str phpfile = dnstr(resource.path.len + slen(".php"));
|
||||||
copy_strs(phpfile, resource.path, sstr(".php"));
|
copy_strs(phpfile, resource.path, sstr(".php"));
|
||||||
if(access(phpfile.ptr, F_OK) == 0){
|
if(access(phpfile.ptr, F_OK) == 0){
|
||||||
// we need a str_copy or something
|
// we need a str_copy or something
|
||||||
struct str command = nstr(
|
str command = dnstr(
|
||||||
slen("REQUEST_URI='") + resource.path.len + slen("' QUERY_STRING='") + resource.query.len +
|
slen("REQUEST_URI='") + resource.path.len + slen("' QUERY_STRING='") + resource.query.len +
|
||||||
slen("' URL='") + url.len +
|
slen("' URL='") + url.len +
|
||||||
slen("' php -c ./ ") + phpfile.len + slen(" > ") + resource.path.len
|
slen("' php -c ./ ") + phpfile.len + slen(" > ") + resource.path.len
|
||||||
@ -265,11 +275,11 @@ struct file generate_resource(struct uri resource, struct str url){
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct str pid = utostr(getpid(), 10);
|
str pid = utostr(getpid(), 10);
|
||||||
file.name.ptr = calloc(uri.path.len + pid.len + 1, sizeof(char));
|
file.name.ptr = calloc(uri.path.len + pid.len + 1, sizeof(char));
|
||||||
copy_strs(file.name, uri.path, pid);
|
copy_strs(file.name, uri.path, pid);
|
||||||
|
|
||||||
struct str command = {0};
|
str command = {0};
|
||||||
command.ptr = calloc(
|
command.ptr = calloc(
|
||||||
slen("REQUEST_URI='") + uri.path.len + slen("' REQUEST_QUERY='") + uri.query.len +
|
slen("REQUEST_URI='") + uri.path.len + slen("' REQUEST_QUERY='") + uri.query.len +
|
||||||
slen("' php -c ./ ") + uri.path.len + slen(" > ") + file.name.len,
|
slen("' php -c ./ ") + uri.path.len + slen(" > ") + file.name.len,
|
||||||
@ -294,7 +304,7 @@ struct file generate_resource(struct uri resource, struct str url){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: REVISE; return 201/204
|
// TODO: REVISE; return 201/204
|
||||||
char *handlePOST(char *request/*struct str uri, struct str body*/){
|
char *handlePOST(char *request/*str uri, str body*/){
|
||||||
/*
|
/*
|
||||||
char *resource = malloc(1), *uri = getURI(request), *params = getPOSTParams(request);
|
char *resource = malloc(1), *uri = getURI(request), *params = getPOSTParams(request);
|
||||||
|
|
||||||
@ -364,7 +374,7 @@ void build_http_message(char *request, int rlen, struct http_message *hm){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check if endianness affects this
|
// TODO: check if endianness affects this
|
||||||
__attribute__ ((optimize(3))) enum http_method get_http_method(struct str method){
|
__attribute__ ((optimize(3))) http_method get_http_method(str method){
|
||||||
uint64_t m;
|
uint64_t m;
|
||||||
memmove(&m, method.ptr, sizeof(uint64_t));
|
memmove(&m, method.ptr, sizeof(uint64_t));
|
||||||
if(((m & 0x0000000000FFFFFF) - 0x0000000000544547) == 0){
|
if(((m & 0x0000000000FFFFFF) - 0x0000000000544547) == 0){
|
||||||
@ -388,8 +398,8 @@ static uint64_t http_len(struct http_message *hm){
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static struct str assemble_with_body(struct http_message *hm, FILE *body, uint64_t len){
|
/*static str assemble_with_body(struct http_message *hm, FILE *body, uint64_t len){
|
||||||
struct str s = {0};
|
str s = {0};
|
||||||
s.ptr = calloc(http_len(hm) + len + 1, sizeof(char));
|
s.ptr = calloc(http_len(hm) + len + 1, sizeof(char));
|
||||||
copy_strs(s, hm->method, sstr(" "), hm->uri, sstr(" "), hm->req_ver, sstr("\r\n"));
|
copy_strs(s, hm->method, sstr(" "), hm->uri, sstr(" "), hm->req_ver, sstr("\r\n"));
|
||||||
|
|
||||||
@ -405,8 +415,8 @@ static uint64_t http_len(struct http_message *hm){
|
|||||||
return s;
|
return s;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
static struct str http_header_to_str(struct http_message *hm){
|
static str http_header_to_str(struct http_message *hm){
|
||||||
struct str s = {0};
|
str s = {0};
|
||||||
s.ptr = calloc(http_len(hm) + 1, sizeof(char));
|
s.ptr = calloc(http_len(hm) + 1, sizeof(char));
|
||||||
copy_strs(s, hm->method, sstr(" "), hm->uri, sstr(" "), hm->req_ver, sstr("\r\n"));
|
copy_strs(s, hm->method, sstr(" "), hm->uri, sstr(" "), hm->req_ver, sstr("\r\n"));
|
||||||
for(int i = 0; i < hm->hlen; i++){
|
for(int i = 0; i < hm->hlen; i++){
|
||||||
@ -438,19 +448,19 @@ static struct str http_header_to_str(struct http_message *hm){
|
|||||||
to the output if the token number 3 in the array exists (has length > 0)
|
to the output if the token number 3 in the array exists (has length > 0)
|
||||||
All other characters get outputted normally
|
All other characters get outputted normally
|
||||||
*/
|
*/
|
||||||
static struct uri uri_rewrite(struct str p, struct str u, struct uri o){
|
static struct uri uri_rewrite(str p, str u, struct uri o){
|
||||||
int i = 0, j = 0, in = 0, ti = 0;
|
int i = 0, j = 0, in = 0, ti = 0;
|
||||||
struct str tokens[9] = {0};
|
str tokens[9] = {0};
|
||||||
for(; j < p.len; i += 1){
|
for(; j < p.len; i += 1){
|
||||||
if(i < u.len && p.ptr[j+in] == '<' && p.ptr[j+in+1] == u.ptr[i]){
|
if(i < u.len && p.ptr[j+in] == '<' && p.ptr[j+in+1] == u.ptr[i]){
|
||||||
if(ti < 9) tokens[ti++] = (struct str){.ptr = u.ptr+i, .len = 1};
|
if(ti < 9) tokens[ti++] = (str){.ptr = u.ptr+i, .len = 1};
|
||||||
j += 3+in, in = 0;
|
j += 3+in, in = 0;
|
||||||
}else if(i < u.len && (p.ptr[j+in] == '^' || p.ptr[j+in] == u.ptr[i])){
|
}else if(i < u.len && (p.ptr[j+in] == '^' || p.ptr[j+in] == u.ptr[i])){
|
||||||
if(p.ptr[j] == '^' && ti < 9) tokens[ti++] = (struct str){.ptr = u.ptr+i, .len = 1};
|
if(p.ptr[j] == '^' && ti < 9) tokens[ti++] = (str){.ptr = u.ptr+i, .len = 1};
|
||||||
j += 1+in, in = 0;
|
j += 1+in, in = 0;
|
||||||
}else if(i < u.len && p.ptr[j] == '*'){
|
}else if(i < u.len && p.ptr[j] == '*'){
|
||||||
if(!in){
|
if(!in){
|
||||||
if(ti < 9) tokens[ti++] = (struct str){.ptr = u.ptr+i, .len = 0};
|
if(ti < 9) tokens[ti++] = (str){.ptr = u.ptr+i, .len = 0};
|
||||||
in = 1;
|
in = 1;
|
||||||
}
|
}
|
||||||
if(ti-in < 9) tokens[ti-in].len++;
|
if(ti-in < 9) tokens[ti-in].len++;
|
||||||
@ -463,7 +473,7 @@ static struct uri uri_rewrite(struct str p, struct str u, struct uri o){
|
|||||||
if(i < u.len) return (struct uri){0};
|
if(i < u.len) return (struct uri){0};
|
||||||
|
|
||||||
struct uri r = {0};
|
struct uri r = {0};
|
||||||
struct str *no = &o.path, *nr = &r.path;
|
str *no = &o.path, *nr = &r.path;
|
||||||
for(int k = 0, rlen = 0; k < 2; k++, no = &o.query, nr = &r.query){
|
for(int k = 0, rlen = 0; k < 2; k++, no = &o.query, nr = &r.query){
|
||||||
for(int i = 0; i < no->len; i++, rlen++){
|
for(int i = 0; i < no->len; i++, rlen++){
|
||||||
if(no->ptr[i] == '$') rlen += tokens[no->ptr[++i]-'1'].len-1;
|
if(no->ptr[i] == '$') rlen += tokens[no->ptr[++i]-'1'].len-1;
|
||||||
@ -491,8 +501,8 @@ static struct uri uri_rewrite(struct str p, struct str u, struct uri o){
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct uri sanitize_uri(struct str uri){
|
struct uri sanitize_uri(str uri){
|
||||||
struct str suri = {.ptr = calloc(uri.len+1, sizeof(char)), .len = 0};
|
str suri = {.ptr = calloc(uri.len+1, sizeof(char)), .len = 0};
|
||||||
if(suri.ptr == NULL) return (struct uri){0};
|
if(suri.ptr == NULL) return (struct uri){0};
|
||||||
int i = 0, o = 0;
|
int i = 0, o = 0;
|
||||||
while(i+o < uri.len){
|
while(i+o < uri.len){
|
||||||
@ -517,13 +527,13 @@ struct uri sanitize_uri(struct str uri){
|
|||||||
}
|
}
|
||||||
free_str(&suri);
|
free_str(&suri);
|
||||||
if(u.path.len == 0){
|
if(u.path.len == 0){
|
||||||
u.path = str("localc/404/index.html");
|
u.path = dstr("localc/404/index.html");
|
||||||
free_str(&u.query);
|
free_str(&u.query);
|
||||||
}
|
}
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int worker_write(http_worker *hw, struct str buf){
|
static inline int worker_write(http_worker *hw, str buf){
|
||||||
return hw->secure ?
|
return hw->secure ?
|
||||||
SSL_write(hw->ssl, buf.ptr, buf.len) :
|
SSL_write(hw->ssl, buf.ptr, buf.len) :
|
||||||
send(hw->csocket, buf.ptr, buf.len, 0);
|
send(hw->csocket, buf.ptr, buf.len, 0);
|
||||||
@ -534,7 +544,7 @@ static inline int worker_write(http_worker *hw, struct str buf){
|
|||||||
// Because this copying is done within the kernel, sendfile() is
|
// Because this copying is done within the kernel, sendfile() is
|
||||||
// more efficient than the combination of read(2) and write(2),
|
// more efficient than the combination of read(2) and write(2),
|
||||||
// which would require transferring data to and from user space."
|
// which would require transferring data to and from user space."
|
||||||
void send_file(http_worker *hw, struct str filename){
|
void send_file(http_worker *hw, str filename){
|
||||||
log_info("requested '%.*s' -> ", filename.len, filename.ptr);
|
log_info("requested '%.*s' -> ", filename.len, filename.ptr);
|
||||||
uint64_t fsize = get_file_size(filename.ptr);
|
uint64_t fsize = get_file_size(filename.ptr);
|
||||||
if(fsize == 0){
|
if(fsize == 0){
|
||||||
@ -545,7 +555,7 @@ void send_file(http_worker *hw, struct str filename){
|
|||||||
log_info("sending '%.*s'", filename.len, filename.ptr);
|
log_info("sending '%.*s'", filename.len, filename.ptr);
|
||||||
|
|
||||||
enum mime_type type = TXT;
|
enum mime_type type = TXT;
|
||||||
struct str fmt = get_file_format(filename);
|
str fmt = get_file_format(filename);
|
||||||
for(int i = 0; i < sizeof(mime_types)/sizeof(mime_types[0]); i++){
|
for(int i = 0; i < sizeof(mime_types)/sizeof(mime_types[0]); i++){
|
||||||
if(strncmp(fmt.ptr, mime_types[i].fmt.ptr, fmt.len) == 0){
|
if(strncmp(fmt.ptr, mime_types[i].fmt.ptr, fmt.len) == 0){
|
||||||
type = i;
|
type = i;
|
||||||
@ -563,7 +573,7 @@ void send_file(http_worker *hw, struct str filename){
|
|||||||
.body = {0},
|
.body = {0},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct str header = http_header_to_str(&hm);
|
str header = http_header_to_str(&hm);
|
||||||
free_str(&hm.headers[1].value);
|
free_str(&hm.headers[1].value);
|
||||||
int sent = worker_write(hw, header);
|
int sent = worker_write(hw, header);
|
||||||
if(sent != header.len){
|
if(sent != header.len){
|
||||||
@ -588,7 +598,7 @@ void send_file(http_worker *hw, struct str filename){
|
|||||||
// sendfile(socket, fd, NULL, fsize);
|
// sendfile(socket, fd, NULL, fsize);
|
||||||
|
|
||||||
// we're ignoring MAX_BODY_SIZE
|
// we're ignoring MAX_BODY_SIZE
|
||||||
struct str fuckcygwinineedsendfile;
|
str fuckcygwinineedsendfile;
|
||||||
fd_to_str(&fuckcygwinineedsendfile, fd, fsize);
|
fd_to_str(&fuckcygwinineedsendfile, fd, fsize);
|
||||||
sent = worker_write(hw, fuckcygwinineedsendfile);
|
sent = worker_write(hw, fuckcygwinineedsendfile);
|
||||||
free_str(&fuckcygwinineedsendfile);
|
free_str(&fuckcygwinineedsendfile);
|
||||||
|
@ -28,10 +28,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
enum http_method {
|
typedef enum http_method {
|
||||||
GET, HEAD, OPTIONS, TRACE,
|
GET, HEAD, OPTIONS, TRACE,
|
||||||
DELETE, PUT, POST, PATCH
|
DELETE, PUT, POST, PATCH
|
||||||
};
|
} http_method;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -45,18 +45,18 @@ enum mime_type {
|
|||||||
|
|
||||||
|
|
||||||
struct uri {
|
struct uri {
|
||||||
struct str path;
|
str path;
|
||||||
struct str query;
|
str query;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uri_mod {
|
struct uri_mod {
|
||||||
struct str pattern;
|
str pattern;
|
||||||
struct uri output;
|
struct uri output;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct header {
|
struct header {
|
||||||
struct str name;
|
str name;
|
||||||
struct str value;
|
str value;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_HEADERS 16
|
#define MAX_HEADERS 16
|
||||||
@ -64,24 +64,24 @@ struct header {
|
|||||||
|
|
||||||
struct http_message {
|
struct http_message {
|
||||||
union {
|
union {
|
||||||
struct str method;
|
str method;
|
||||||
struct str resp_ver;
|
str resp_ver;
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
struct str uri;
|
str uri;
|
||||||
struct str status;
|
str status;
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
struct str req_ver;
|
str req_ver;
|
||||||
struct str reason;
|
str reason;
|
||||||
};
|
};
|
||||||
int hlen;
|
int hlen;
|
||||||
struct header headers[MAX_HEADERS];
|
struct header headers[MAX_HEADERS];
|
||||||
struct str body;
|
str body;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct http_server {
|
typedef struct http_server {
|
||||||
struct str port;
|
str port;
|
||||||
int backlog;
|
int backlog;
|
||||||
int ssocket;
|
int ssocket;
|
||||||
} http_server;
|
} http_server;
|
||||||
@ -105,11 +105,11 @@ typedef struct http_worker {
|
|||||||
(hm).headers[(hm).hlen++] = (h)
|
(hm).headers[(hm).hlen++] = (h)
|
||||||
|
|
||||||
|
|
||||||
http_server *setup_http_server(struct str port, int backlog);
|
http_server *setup_http_server(str port, int backlog);
|
||||||
|
|
||||||
void destroy_http_server(http_server **hs);
|
void destroy_http_server(http_server **hs);
|
||||||
|
|
||||||
http_worker *setup_http_worker(int ssocket, int secure, struct str certfile, struct str keyfile);
|
http_worker *setup_http_worker(int ssocket, int secure, str certfile, str keyfile);
|
||||||
|
|
||||||
void destroy_http_worker(http_worker **hw);
|
void destroy_http_worker(http_worker **hw);
|
||||||
|
|
||||||
@ -117,19 +117,19 @@ void reset_worker_ssl(http_worker *hw);
|
|||||||
|
|
||||||
int accept_connection(http_worker *hw, char ip[INET_ADDRSTRLEN]);
|
int accept_connection(http_worker *hw, char ip[INET_ADDRSTRLEN]);
|
||||||
|
|
||||||
int receive_request(http_worker *hw, struct str *request);
|
int receive_request(http_worker *hw, str *request);
|
||||||
|
|
||||||
struct file generate_resource(struct uri resource, struct str url);
|
struct file generate_resource(struct uri resource, str url);
|
||||||
|
|
||||||
char *handlePOST(char *request);
|
char *handlePOST(char *request);
|
||||||
|
|
||||||
void build_http_message(char *request, int len, struct http_message *hm);
|
void build_http_message(char *request, int len, struct http_message *hm);
|
||||||
|
|
||||||
enum http_method get_http_method(struct str method);
|
enum http_method get_http_method(str method);
|
||||||
|
|
||||||
struct uri sanitize_uri(struct str uri);
|
struct uri sanitize_uri(str uri);
|
||||||
|
|
||||||
void send_file(http_worker *hw, struct str filename);
|
void send_file(http_worker *hw, str filename);
|
||||||
|
|
||||||
int read_uri_rewrites(char *map, uint64_t size);
|
int read_uri_rewrites(char *map, uint64_t size);
|
||||||
|
|
||||||
|
11
src/worker.c
11
src/worker.c
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
ipc_listener *listener;
|
ipc_listener *listener;
|
||||||
http_worker *worker;
|
http_worker *worker;
|
||||||
struct str rewritesfile;
|
str rewritesfile;
|
||||||
|
|
||||||
|
|
||||||
int init(char *argv[]){
|
int init(char *argv[]){
|
||||||
@ -16,11 +16,8 @@ int init(char *argv[]){
|
|||||||
// reinit
|
// reinit
|
||||||
// finish
|
// finish
|
||||||
// toggle ssl
|
// toggle ssl
|
||||||
//log_set_level(LOG_DEBUG, 0);
|
|
||||||
//log_set_level(LOG_INFO, 0);
|
|
||||||
//log_set_level(LOG_WARN, 0);
|
|
||||||
|
|
||||||
struct str saddr = str(argv[1]);
|
str saddr = dstr(argv[1]);
|
||||||
listener = setup_ipc_listener(saddr);
|
listener = setup_ipc_listener(saddr);
|
||||||
free_str(&saddr);
|
free_str(&saddr);
|
||||||
if(listener == NULL){
|
if(listener == NULL){
|
||||||
@ -32,7 +29,7 @@ int init(char *argv[]){
|
|||||||
ipc_message msg = receive_ipc_message(listener);
|
ipc_message msg = receive_ipc_message(listener);
|
||||||
int ssocket = strtou(msg.val);
|
int ssocket = strtou(msg.val);
|
||||||
free_ipc_message(msg); // v configurable certificate locations?
|
free_ipc_message(msg); // v configurable certificate locations?
|
||||||
worker = setup_http_worker(ssocket, 1, sstr("ssl/cert.pem"), sstr("ssl/key.pem"));
|
worker = setup_http_worker(ssocket, 1, sstr("ssl/mkarchive.net/certificate.crt"), sstr("ssl/mkarchive.net/private.key"));
|
||||||
if(worker == NULL){
|
if(worker == NULL){
|
||||||
log_error("setting up http worker");
|
log_error("setting up http worker");
|
||||||
return 1;
|
return 1;
|
||||||
@ -76,7 +73,7 @@ int main(int argc, char **argv){
|
|||||||
log_info("init'd");
|
log_info("init'd");
|
||||||
|
|
||||||
bool end = false;
|
bool end = false;
|
||||||
struct str request = {.cap = 8192, .len = 0, .ptr = alloca(8192)};
|
str request = {.cap = 8192, .len = 0, .ptr = alloca(8192)};
|
||||||
while(!end){
|
while(!end){
|
||||||
char cip[INET_ADDRSTRLEN] = {0};
|
char cip[INET_ADDRSTRLEN] = {0};
|
||||||
return_value = accept_connection(worker, cip);
|
return_value = accept_connection(worker, cip);
|
||||||
|
Reference in New Issue
Block a user