Compare commits
No commits in common. "efd4b39311726a85e7809689a399999580916854" and "77945f34b9b8d5b39379f607c73418e013198922" have entirely different histories.
efd4b39311
...
77945f34b9
6 changed files with 2 additions and 370 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +0,0 @@
|
||||||
[submodule "third_party/SimpleArchiver"]
|
|
||||||
path = third_party/SimpleArchiver
|
|
||||||
url = https://git.seodisparate.com/stephenseo/SimpleArchiver.git
|
|
13
Makefile
13
Makefile
|
@ -1,7 +1,4 @@
|
||||||
COMMON_FLAGS = -Wall -Wextra -Wpedantic \
|
COMMON_FLAGS = -Wall -Wextra -Wpedantic
|
||||||
-Ithird_party/SimpleArchiver/src \
|
|
||||||
-Ithird_party/SimpleArchiver/src/data_structures \
|
|
||||||
-Ithird_party/SimpleArchiver/src/algorithms
|
|
||||||
DEBUG_FLAGS = -Og -g
|
DEBUG_FLAGS = -Og -g
|
||||||
RELEASE_FLAGS = -O3 -DNDEBUG
|
RELEASE_FLAGS = -O3 -DNDEBUG
|
||||||
|
|
||||||
|
@ -17,13 +14,7 @@ SOURCES = \
|
||||||
src/big_endian.c \
|
src/big_endian.c \
|
||||||
src/tcp_socket.c \
|
src/tcp_socket.c \
|
||||||
src/signal_handling.c \
|
src/signal_handling.c \
|
||||||
src/globals.c \
|
src/globals.c
|
||||||
src/http.c \
|
|
||||||
third_party/SimpleArchiver/src/helpers.c \
|
|
||||||
third_party/SimpleArchiver/src/data_structures/linked_list.c \
|
|
||||||
third_party/SimpleArchiver/src/data_structures/hash_map.c \
|
|
||||||
third_party/SimpleArchiver/src/data_structures/priority_heap.c \
|
|
||||||
third_party/SimpleArchiver/src/algorithms/linear_congruential_gen.c
|
|
||||||
|
|
||||||
OBJECT_DIR = objs
|
OBJECT_DIR = objs
|
||||||
OBJECTS = $(addprefix ${OBJECT_DIR}/,$(patsubst %.c,%.c.o,${SOURCES}))
|
OBJECTS = $(addprefix ${OBJECT_DIR}/,$(patsubst %.c,%.c.o,${SOURCES}))
|
||||||
|
|
|
@ -19,6 +19,5 @@
|
||||||
|
|
||||||
#define C_SIMPLE_HTTP_SLEEP_NANOS 1000000
|
#define C_SIMPLE_HTTP_SLEEP_NANOS 1000000
|
||||||
#define C_SIMPLE_HTTP_RECV_BUF_SIZE 1024
|
#define C_SIMPLE_HTTP_RECV_BUF_SIZE 1024
|
||||||
#define C_SIMPLE_HTTP_CONFIG_BUF_SIZE 256
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
303
src/http.c
303
src/http.c
|
@ -1,303 +0,0 @@
|
||||||
// ISC License
|
|
||||||
//
|
|
||||||
// Copyright (c) 2024 Stephen Seo
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
#include "http.h"
|
|
||||||
|
|
||||||
// Standard library includes.
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
// Local includes
|
|
||||||
#include <helpers.h>
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
typedef struct HashMapWrapper {
|
|
||||||
SDArchiverHashMap *hash_map;
|
|
||||||
} HashMapWrapper;
|
|
||||||
|
|
||||||
void c_simple_http_hash_map_wrapper_cleanup_hashmap_fn(void *data) {
|
|
||||||
HashMapWrapper *wrapper = data;
|
|
||||||
simple_archiver_hash_map_free(&wrapper->hash_map);
|
|
||||||
free(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
void c_simple_http_hash_map_wrapper_cleanup(HashMapWrapper *wrapper) {
|
|
||||||
simple_archiver_hash_map_free(&wrapper->hash_map);
|
|
||||||
free(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
void c_simple_http_hash_map_cleanup_helper(SDArchiverHashMap *hash_map) {
|
|
||||||
simple_archiver_hash_map_free(&hash_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
HTTPTemplates c_simple_http_set_up_templates(const char *config_filename) {
|
|
||||||
HTTPTemplates templates;
|
|
||||||
templates.paths = simple_archiver_hash_map_init();
|
|
||||||
|
|
||||||
FILE *f = fopen(config_filename, "r");
|
|
||||||
unsigned char key_buf[C_SIMPLE_HTTP_CONFIG_BUF_SIZE];
|
|
||||||
unsigned char value_buf[C_SIMPLE_HTTP_CONFIG_BUF_SIZE];
|
|
||||||
unsigned int key_idx = 0;
|
|
||||||
unsigned int value_idx = 0;
|
|
||||||
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
|
|
||||||
char *current_path = NULL;
|
|
||||||
unsigned int current_path_size = 0;
|
|
||||||
|
|
||||||
// xxx0 - reading key
|
|
||||||
// xxx1 - reading value
|
|
||||||
// xx0x - does not have "HTML" key
|
|
||||||
// xx1x - does have "HTML" key
|
|
||||||
unsigned int state = 0;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
while (feof(f) == 0) {
|
|
||||||
c = fgetc(f);
|
|
||||||
if (c == EOF) {
|
|
||||||
break;
|
|
||||||
} else if (c == ' ' || c == '\t') {
|
|
||||||
// Ignore whitespace.
|
|
||||||
continue;
|
|
||||||
} else if ((state & 1) == 0 && (c == '\r' || c == '\n')) {
|
|
||||||
// Ignore newlines when parsing for key.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((state & 1) == 0) {
|
|
||||||
if (c != '=') {
|
|
||||||
key_buf[key_idx++] = c;
|
|
||||||
if (key_idx >= C_SIMPLE_HTTP_CONFIG_BUF_SIZE) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: config file \"key\" is larger than %u bytes!\n",
|
|
||||||
C_SIMPLE_HTTP_CONFIG_BUF_SIZE - 1);
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (key_idx < C_SIMPLE_HTTP_CONFIG_BUF_SIZE) {
|
|
||||||
key_buf[key_idx++] = 0;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: config file \"key\" is larger than %u bytes!\n",
|
|
||||||
C_SIMPLE_HTTP_CONFIG_BUF_SIZE - 1);
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
state |= 1;
|
|
||||||
}
|
|
||||||
} else if ((state & 1) == 1) {
|
|
||||||
if (c != '\n' && c != '\r') {
|
|
||||||
value_buf[value_idx++] = c;
|
|
||||||
if (value_idx >= C_SIMPLE_HTTP_CONFIG_BUF_SIZE) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: config file \"value\" is larger than %u bytes!\n",
|
|
||||||
C_SIMPLE_HTTP_CONFIG_BUF_SIZE - 1);
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (value_idx < C_SIMPLE_HTTP_CONFIG_BUF_SIZE) {
|
|
||||||
value_buf[value_idx++] = 0;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: config file \"value\" is larger than %u bytes!\n",
|
|
||||||
C_SIMPLE_HTTP_CONFIG_BUF_SIZE - 1);
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
state &= 0xFFFFFFFE;
|
|
||||||
|
|
||||||
// Check if key is "PATH".
|
|
||||||
if (strcmp((char*)key_buf, "PATH") == 0) {
|
|
||||||
if (current_path) {
|
|
||||||
if ((state & 0x2) == 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: config file did not have \"HTML\" key for PATH!"
|
|
||||||
"\n");
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
state &= 0xFFFFFFFD;
|
|
||||||
free(current_path);
|
|
||||||
}
|
|
||||||
current_path = malloc(value_idx);
|
|
||||||
memcpy(current_path, value_buf, value_idx);
|
|
||||||
current_path_size = value_idx;
|
|
||||||
// At this point, key is "PATH".
|
|
||||||
SDArchiverHashMap *hash_map = simple_archiver_hash_map_init();
|
|
||||||
unsigned char *key = malloc(5);
|
|
||||||
key[0] = 'P';
|
|
||||||
key[1] = 'A';
|
|
||||||
key[2] = 'T';
|
|
||||||
key[3] = 'H';
|
|
||||||
key[4] = 0;
|
|
||||||
unsigned char *value = malloc(value_idx);
|
|
||||||
memcpy(value, value_buf, value_idx);
|
|
||||||
if (simple_archiver_hash_map_insert(&hash_map,
|
|
||||||
value,
|
|
||||||
key,
|
|
||||||
5,
|
|
||||||
NULL,
|
|
||||||
NULL) != 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: Failed to create hash map for new PATH block!\n");
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
free(key);
|
|
||||||
free(value);
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMapWrapper *wrapper = malloc(sizeof(HashMapWrapper));
|
|
||||||
wrapper->hash_map = hash_map;
|
|
||||||
|
|
||||||
if (simple_archiver_hash_map_insert(
|
|
||||||
&templates.paths,
|
|
||||||
wrapper,
|
|
||||||
value,
|
|
||||||
value_idx,
|
|
||||||
simple_archiver_helper_datastructure_cleanup_nop,
|
|
||||||
c_simple_http_hash_map_wrapper_cleanup_hashmap_fn) != 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: Failed to insert new hash map for new PATH block!\n");
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
c_simple_http_hash_map_wrapper_cleanup(wrapper);
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
} else if (!current_path) {
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"ERROR: config file has invalid key: No preceding \"PATH\" "
|
|
||||||
"key!\n");
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
return templates;
|
|
||||||
} else {
|
|
||||||
// Non-"PATH" key.
|
|
||||||
if (strcmp((char*)key_buf, "HTML") == 0
|
|
||||||
|| strcmp((char*)key_buf, "HTML_FILE") == 0) {
|
|
||||||
state |= 0x2;
|
|
||||||
}
|
|
||||||
HashMapWrapper *hash_map_wrapper = simple_archiver_hash_map_get(
|
|
||||||
templates.paths,
|
|
||||||
current_path,
|
|
||||||
current_path_size);
|
|
||||||
if (!hash_map_wrapper) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: Internal error failed to get existing hash map with path "
|
|
||||||
"\"%s\"!", current_path);
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char *key = malloc(key_idx);
|
|
||||||
memcpy(key, key_buf, key_idx);
|
|
||||||
unsigned char *value;
|
|
||||||
if (strcmp((char*)key_buf, "HTML_FILE") == 0) {
|
|
||||||
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
|
|
||||||
FILE *html_file = fopen((char*)value_buf, "r");
|
|
||||||
if (!html_file) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: Internal error failed to open HTML_FILE \"%s\"!",
|
|
||||||
value_buf);
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(html_file, 0, SEEK_END);
|
|
||||||
long file_size = ftell(html_file);
|
|
||||||
if (file_size <= 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: Internal error HTML_FILE \"%s\" is invalid size!",
|
|
||||||
value_buf);
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
fseek(html_file, 0, SEEK_SET);
|
|
||||||
unsigned long file_size_u = file_size;
|
|
||||||
|
|
||||||
unsigned char *read_buf = malloc(file_size_u);
|
|
||||||
size_t read_amount = 0;
|
|
||||||
read_amount = fread(read_buf, 1, file_size_u, html_file);
|
|
||||||
if (read_amount != file_size_u) {
|
|
||||||
fprintf(stderr, "ERROR: Failed to read HTML_FILE \"%s\"!\n",
|
|
||||||
value_buf);
|
|
||||||
free(read_buf);
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
value = read_buf;
|
|
||||||
} else {
|
|
||||||
value = malloc(value_idx);
|
|
||||||
memcpy(value, value_buf, value_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (simple_archiver_hash_map_insert(&hash_map_wrapper->hash_map,
|
|
||||||
value,
|
|
||||||
key,
|
|
||||||
key_idx,
|
|
||||||
NULL,
|
|
||||||
NULL) != 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: Internal error failed to insert into hash map with path "
|
|
||||||
"\"%s\"!", current_path);
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
free(key);
|
|
||||||
free(value);
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key_idx = 0;
|
|
||||||
value_idx = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
if (!current_path) {
|
|
||||||
fprintf(stderr, "ERROR: Never got \"PATH\" key in config!\n");
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
} else if ((state & 0x2) == 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR: Current \"PATH\" did not get \"HTML\" key in config!\n");
|
|
||||||
c_simple_http_clean_up_templates(&templates);
|
|
||||||
templates.paths = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
|
|
||||||
void c_simple_http_clean_up_templates(HTTPTemplates *templates) {
|
|
||||||
simple_archiver_hash_map_free(&templates->paths);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *c_simple_http_request_response(const char *request, unsigned int size,
|
|
||||||
const HTTPTemplates *templates) {
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// vim: ts=2 sts=2 sw=2
|
|
51
src/http.h
51
src/http.h
|
@ -1,51 +0,0 @@
|
||||||
// ISC License
|
|
||||||
//
|
|
||||||
// Copyright (c) 2024 Stephen Seo
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
#ifndef SEODISPARATE_COM_C_SIMPLE_HTTP_HTTP_H_
|
|
||||||
#define SEODISPARATE_COM_C_SIMPLE_HTTP_HTTP_H_
|
|
||||||
|
|
||||||
#include <hash_map.h>
|
|
||||||
|
|
||||||
typedef struct HTTPTemplates {
|
|
||||||
/// Each entry in this data structure is a hash map where its value for the
|
|
||||||
/// key "PATH" is the path it represents. The "key" value should match the
|
|
||||||
/// mentioned value for "PATH".
|
|
||||||
SDArchiverHashMap *paths;
|
|
||||||
} HTTPTemplates;
|
|
||||||
|
|
||||||
/// Each line in the config should be a key-value pair separated by an equals
|
|
||||||
/// sign. All whitespace is ignored unless if the value is quoted. If there
|
|
||||||
/// exists a line with the key "PATH", then the value must be a path like
|
|
||||||
/// "/cache" and all the following key-value pairs are associated with that PATH
|
|
||||||
/// until the next "PATH" key or EOF. Each "PATH" "block" should have a "HTML"
|
|
||||||
/// key-value pair where the value is a HTML template. Inside such HTML
|
|
||||||
/// templates should be strings like "{{{{example_key}}}}" which will be
|
|
||||||
/// replaced by the string value of the key name deliminated by the four curly
|
|
||||||
/// braces. "HTML_FILE" specifies a filename to read instead of using a literal
|
|
||||||
/// string in the config file. It will store the contents of the specified file
|
|
||||||
/// with the "HTML" key internally.
|
|
||||||
HTTPTemplates c_simple_http_set_up_templates(const char *config_filename);
|
|
||||||
|
|
||||||
void c_simple_http_clean_up_templates(HTTPTemplates *templates);
|
|
||||||
|
|
||||||
/// Returned buffer must be "free"d after use.
|
|
||||||
/// If the request is not valid, or 404, then the buffer will be NULL.
|
|
||||||
char *c_simple_http_request_response(const char *request, unsigned int size,
|
|
||||||
const HTTPTemplates *templates);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// vim: ts=2 sts=2 sw=2
|
|
1
third_party/SimpleArchiver
vendored
1
third_party/SimpleArchiver
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit 2e46790ecee627738469ef7370f4c082e96b03fc
|
|
Loading…
Reference in a new issue