Compare commits

..

No commits in common. "main" and "1.2" have entirely different histories.
main ... 1.2

20 changed files with 223 additions and 1657 deletions

View file

@ -172,8 +172,6 @@ jobs:
cmake -S . -B buildRelease -DCMAKE_BUILD_TYPE=Release cmake -S . -B buildRelease -DCMAKE_BUILD_TYPE=Release
make -C buildRelease c_simple_http make -C buildRelease c_simple_http
strip --strip-unneeded buildRelease/c_simple_http
popd >&/dev/null popd >&/dev/null
zstd --ultra -20 c_simple_http_clone/buildRelease/c_simple_http -o "${BUILD_ASSET_NAME}" zstd --ultra -20 c_simple_http_clone/buildRelease/c_simple_http -o "${BUILD_ASSET_NAME}"
@ -235,8 +233,6 @@ jobs:
cmake -S . -B buildRelease -DCMAKE_BUILD_TYPE=Release cmake -S . -B buildRelease -DCMAKE_BUILD_TYPE=Release
make -C buildRelease c_simple_http make -C buildRelease c_simple_http
strip --strip-unneeded buildRelease/c_simple_http
popd >&/dev/null popd >&/dev/null
zstd --ultra -20 c_simple_http_clone/buildRelease/c_simple_http -o "${BUILD_ASSET_NAME}" zstd --ultra -20 c_simple_http_clone/buildRelease/c_simple_http -o "${BUILD_ASSET_NAME}"

View file

@ -2,64 +2,6 @@
## Upcoming Changes ## Upcoming Changes
## Version 1.5
Add flag `--generate-static-enable-overwrite`. This flag enables overwriting of
files from static-dir to generate-dir (if static-dir was specified). Previous
implementation relied on `--generate-enable-ovewrite` for this behavior.
Minor refactorings related to `printf` and `uintX_t`/`size_t` types.
## Version 1.4
Implemented "IF", "ELSEIF", "ELSE", "ENDIF", and "INDEX" for templates.
IF is used like: `{{{!IF Variable==SomeString}}}`.
Not equals can also be used: `{{{!IF Variable!=OtherString}}}`.
ELSEIF is used like: `{{{!ELSEIF Variable==AnotherString}}}`.
Not equals can also be used: `{{{!ELSEIF Variable!=AnotherOtherString}}}`.
ELSE is used like: `{{{!ELSE}}}`.
ENDIF is used like: `{{{!ENDIF}}}`.
INDEX is used like: `{{{!INDEX ArrayVar[2]}}}`.
Implemented "FOREACH" and "ENDFOREACH" for templates.
FOREACH is used like:
PATH=/
HTML='''
{{{!FOREACH ArrayVar}}}
{{{ArrayVar}}}
{{{!ENDFOREACH}}}'''
ArrayVar=FirstValue
ArrayVar=SecondValue
ArrayVar=ThirdValue
For multiple variables to expand in FOREACH:
PATH=/
HTML='''
{{{!FOREACH ArrayVar!ArrayVarSecond!ArrayVarThird}}}
{{{ArrayVar}}}
{{{ArrayVarSecond}}}
{{{ArrayVarThird}}}
{{{!ENDFOREACH}}}'''
ArrayVar=FirstVarOnce
ArrayVar=FirstVarTwice
ArrayVarSecond=SecondVarOnce
ArrayVarSecond=SecondVarTwice
ArrayVarThird=ThirdVarOnce
ArrayVarThird=ThirdVarTwice
Implemented nestable "IF" and "FOREACH" expressions in templates. In other
words, there can be `{{{!IF}}}` inside other IF/FOREACH blocks, and vice versa.
## Version 1.3
Fix internal erronous buffer declaration.
Fix internal missing NULL check.
## Version 1.2 ## Version 1.2
Add the `--generate-dir=<DIR>` option, which will generate all html into the Add the `--generate-dir=<DIR>` option, which will generate all html into the
@ -87,7 +29,3 @@ Features:
- Reload configuration on SIGUSR1 or by listening (enabled by cmd parameter). - Reload configuration on SIGUSR1 or by listening (enabled by cmd parameter).
- Cache served html (enabled by cmd parameter). - Cache served html (enabled by cmd parameter).
- Serve static files from "static-dir" (enabled by cmd parameter). - Serve static files from "static-dir" (enabled by cmd parameter).
<!--
vim: textwidth=80 et sw=2 ts=2 sts=2
-->

View file

@ -17,7 +17,6 @@ A simple HTTP/1.1 server written in C.
--enable-static-dir=<DIR> --enable-static-dir=<DIR>
--generate-dir=<DIR> --generate-dir=<DIR>
--generate-enable-overwrite --generate-enable-overwrite
--generate-static-enable-overwrite
## Changelog ## Changelog

View file

@ -1 +0,0 @@
<b>Each File ONE</b><br>

View file

@ -1 +0,0 @@
<b>Each File TWO</b><br>

View file

@ -1 +0,0 @@
<b>Each File ZERO</b><br>

View file

@ -25,130 +25,13 @@ HTML='''
</style> </style>
</head> </head>
<body> <body>
<h2>Test IF/FOREACH Expr</h2> <h1>Test HTML</h1><br>
<h2>{{{Var}}}</h2>
Outer IF<br> <h3><a href="/inner">To inner.</a></h3>
<pre>
{{{!IF ThisValue==true}}}
ThisValue is <b>true</b>.<br>
{{{!FOREACH ArrayValue}}}
{{{!IF ThisOtherValue==true}}}
{{{ArrayValue}}}<br>
ThisOtherValue is <b>true</b>.<br>
{{{Var}}}<br>
{{{!ELSE}}}
{{{ArrayValue}}}<br>
ThisOtherValue is <b>NOT true</b>.<br>
{{{Var}}}<br>
{{{!ENDIF}}}
{{{!ENDFOREACH}}}
{{{!ELSE}}}
ThisValue is <b>NOT true</b>.<br>
{{{!FOREACH ArrayValueSecond}}}
{{{!IF ThisOtherValue==true}}}
{{{ArrayValueSecond}}}<br>
ThisOtherValue is <b>true</b>.<br>
{{{Var}}}<br>
{{{!ELSE}}}
{{{ArrayValueSecond}}}<br>
ThisOtherValue is <b>NOT true</b>.<br>
{{{Var}}}<br>
{{{!ENDIF}}}
{{{!ENDFOREACH}}}
{{{!ENDIF}}}
</pre><br>
Outer FOREACH<br>
<pre>
{{{!FOREACH ArrayValue}}}
{{{ArrayValue}}}<br>
{{{!IF ThisValue==true}}}
ThisValue is <b>true</b>.<br>
{{{!FOREACH ArrayValueSecond}}}
{{{ArrayValueSecond}}}<br>
{{{!IF ThisOtherValue==true}}}
ThisOtherValue is <b>true</b>.<br>
{{{Var}}}<br>
{{{!ELSE}}}
ThisOtherValue is <b>NOT true</b>.<br>
{{{Var}}}<br>
{{{!ENDIF}}}
{{{!ENDFOREACH}}}
{{{!ELSE}}}
ThisValue is <b>NOT true</b>.<br>
{{{!FOREACH ArrayValueSecond}}}
{{{ArrayValueSecond}}}<br>
{{{!IF ThisOtherValue==true}}}
ThisOtherValue is <b>true</b>.<br>
{{{Var}}}<br>
{{{!ELSE}}}
ThisOtherValue is <b>NOT true</b>.<br>
{{{Var}}}<br>
{{{!ENDIF}}}
{{{!ENDFOREACH}}}
{{{!ENDIF}}}
{{{!ENDFOREACH}}}
</pre><br>
Nested FOREACH:<br>
<pre>
{{{!FOREACH ArrayValue}}}
{{{ArrayValue}}}
{{{!FOREACH ArrayValueSecond}}}
{{{ArrayValueSecond}}}
{{{!FOREACH ArrayValueThird}}}
{{{ArrayValueThird}}}
{{{!FOREACH ArrayValueFourth}}}
{{{ArrayValueFourth}}}
{{{!FOREACH Each_FILE}}}
{{{Each_FILE}}}
{{{!ENDFOREACH}}}
{{{!ENDFOREACH}}}
{{{!ENDFOREACH}}}
{{{!ENDFOREACH}}}
{{{!ENDFOREACH}}}
</pre>
<br><h2><a href="/inner">inner</a></h2>
</body> </body>
</html>
''' '''
Var='''Test var value''' Var='''Test var value'''
ThisValue=true
ThisOtherValue=true
ArrayValue=1_IDX_Zero
ArrayValue=1_IDX_One
ArrayValue=1_IDX_Two
ArrayValueSecond=2_IDX_Zero
ArrayValueSecond=2_IDX_One
ArrayValueSecond=2_IDX_Two
ArrayValueThird=3_IDX_Zero
ArrayValueThird=3_IDX_One
ArrayValueThird=3_IDX_Two
ArrayValueFourth=4_IDX_Zero
ArrayValueFourth=4_IDX_One
ArrayValueFourth=4_IDX_Two
EachTestHead='''First Entry Head'''
EachTestMid='''First Entry Mid'''
EachTestTail='''First Entry Tail'''
EachTestHead='''Second Entry Head'''
EachTestMid='''Second Entry Mid'''
EachTestTail='''Second Entry Tail'''
EachTestHead='''Third Entry Head'''
EachTestMid='''Third Entry Mid'''
EachTestTail='''Third Entry Tail'''
Each_FILE='''example_config/each_file_zero.html'''
Each_FILE='''example_config/each_file_one.html'''
Each_FILE='''example_config/each_file_two.html'''
PATH=/inner PATH=/inner
HTML_FILE='''example_config/inner.html''' HTML_FILE='''example_config/inner.html'''

View file

@ -46,7 +46,6 @@ void print_usage(void) {
puts(" --enable-static-dir=<DIR>"); puts(" --enable-static-dir=<DIR>");
puts(" --generate-dir=<DIR>"); puts(" --generate-dir=<DIR>");
puts(" --generate-enable-overwrite"); puts(" --generate-enable-overwrite");
puts(" --generate-static-enable-overwrite");
} }
Args parse_args(int32_t argc, char **argv) { Args parse_args(int32_t argc, char **argv) {
@ -129,7 +128,7 @@ Args parse_args(int32_t argc, char **argv) {
exit(1); exit(1);
} else { } else {
printf( printf(
"NOTICE set cache-entry-lifetime to %zu\n", "NOTICE set cache-entry-lifetime to %lu\n",
args.cache_lifespan_seconds); args.cache_lifespan_seconds);
} }
} else if (strncmp(argv[0], "--enable-static-dir=", 20) == 0) { } else if (strncmp(argv[0], "--enable-static-dir=", 20) == 0) {
@ -185,13 +184,9 @@ Args parse_args(int32_t argc, char **argv) {
} else { } else {
printf("Directory \"%s\" exists.\n", args.generate_dir); printf("Directory \"%s\" exists.\n", args.generate_dir);
} }
if (d) {
closedir(d); closedir(d);
}
} else if (strcmp(argv[0], "--generate-enable-overwrite") == 0) { } else if (strcmp(argv[0], "--generate-enable-overwrite") == 0) {
args.flags |= 4; args.flags |= 4;
} else if (strcmp(argv[0], "--generate-static-enable-overwrite") == 0) {
args.flags |= 8;
} else { } else {
fprintf(stderr, "ERROR: Invalid args!\n"); fprintf(stderr, "ERROR: Invalid args!\n");
print_usage(); print_usage();

View file

@ -29,7 +29,6 @@ typedef struct Args {
// xxxx xx0x - disable listen on config file for reloading. // xxxx xx0x - disable listen on config file for reloading.
// xxxx xx1x - enable listen on config file for reloading. // xxxx xx1x - enable listen on config file for reloading.
// xxxx x1xx - enable overwrite on generate. // xxxx x1xx - enable overwrite on generate.
// xxxx 1xxx - enable overwrite on generate for static dir.
uint16_t flags; uint16_t flags;
uint16_t port; uint16_t port;
// Does not need to be free'd, this should point to a string in argv. // Does not need to be free'd, this should point to a string in argv.

View file

@ -36,23 +36,6 @@ typedef struct C_SIMPLE_HTTP_INTERNAL_RequiredCheck {
const SDArchiverLinkedList *required; const SDArchiverLinkedList *required;
} C_SIMPLE_HTTP_INTERNAL_RequiredCheck; } C_SIMPLE_HTTP_INTERNAL_RequiredCheck;
void c_simple_http_cleanup_config_value(
C_SIMPLE_HTTP_ConfigValue *config_value) {
if (config_value) {
if (config_value->next) {
c_simple_http_cleanup_config_value(config_value->next);
}
if(config_value->value) {
free(config_value->value);
}
free(config_value);
}
}
void c_simple_http_cleanup_config_value_void_ptr(void *config_value) {
c_simple_http_cleanup_config_value(config_value);
}
int c_simple_http_required_iter_fn(void *data, void *ud) { int c_simple_http_required_iter_fn(void *data, void *ud) {
C_SIMPLE_HTTP_INTERNAL_RequiredIter *req_iter_struct = ud; C_SIMPLE_HTTP_INTERNAL_RequiredIter *req_iter_struct = ud;
uint32_t data_str_length = (uint32_t)strlen(data) + 1; uint32_t data_str_length = (uint32_t)strlen(data) + 1;
@ -204,17 +187,13 @@ int internal_check_add_value(uint32_t *state,
SDArchiverHashMap *hash_map = simple_archiver_hash_map_init(); SDArchiverHashMap *hash_map = simple_archiver_hash_map_init();
unsigned char *key = malloc(separating_key_size); unsigned char *key = malloc(separating_key_size);
strncpy((char*)key, separating_key, separating_key_size); strncpy((char*)key, separating_key, separating_key_size);
C_SIMPLE_HTTP_ConfigValue *config_value = unsigned char *value = malloc(*value_idx);
malloc(sizeof(C_SIMPLE_HTTP_ConfigValue)); memcpy(value, *value_buf, (*value_idx));
config_value->value = malloc(*value_idx); if (simple_archiver_hash_map_insert(hash_map,
config_value->next = NULL; value,
memcpy(config_value->value, *value_buf, (*value_idx));
if (simple_archiver_hash_map_insert(
hash_map,
config_value,
key, key,
separating_key_size, separating_key_size,
c_simple_http_cleanup_config_value_void_ptr, NULL,
NULL) != 0) { NULL) != 0) {
fprintf(stderr, fprintf(stderr,
"ERROR: Failed to create hash map for new separating_key " "ERROR: Failed to create hash map for new separating_key "
@ -222,8 +201,7 @@ int internal_check_add_value(uint32_t *state,
c_simple_http_clean_up_parsed_config(config); c_simple_http_clean_up_parsed_config(config);
config->hash_map = NULL; config->hash_map = NULL;
free(key); free(key);
free(config_value->value); free(value);
free(config_value);
return 1; return 1;
} }
@ -234,7 +212,7 @@ int internal_check_add_value(uint32_t *state,
if (simple_archiver_hash_map_insert( if (simple_archiver_hash_map_insert(
config->hash_map, config->hash_map,
wrapper, wrapper,
config_value->value, value,
(*value_idx), (*value_idx),
c_simple_http_hash_map_wrapper_cleanup_hashmap_fn, c_simple_http_hash_map_wrapper_cleanup_hashmap_fn,
simple_archiver_helper_datastructure_cleanup_nop) != 0) { simple_archiver_helper_datastructure_cleanup_nop) != 0) {
@ -245,7 +223,7 @@ int internal_check_add_value(uint32_t *state,
c_simple_http_hash_map_wrapper_cleanup(wrapper); c_simple_http_hash_map_wrapper_cleanup(wrapper);
return 1; return 1;
} }
simple_archiver_list_add(paths, config_value->value, simple_archiver_list_add(paths, value,
simple_archiver_helper_datastructure_cleanup_nop); simple_archiver_helper_datastructure_cleanup_nop);
} else if (!(*current_separating_key_value)) { } else if (!(*current_separating_key_value)) {
fprintf( fprintf(
@ -276,27 +254,11 @@ int internal_check_add_value(uint32_t *state,
unsigned char *value = malloc(*value_idx); unsigned char *value = malloc(*value_idx);
memcpy(value, *value_buf, (*value_idx)); memcpy(value, *value_buf, (*value_idx));
// Check if key already exists in wrapped hash-map. if (simple_archiver_hash_map_insert(hash_map_wrapper->paths,
C_SIMPLE_HTTP_ConfigValue *config_value = value,
simple_archiver_hash_map_get(hash_map_wrapper->paths, key, *key_idx);
if (config_value) {
while(config_value->next) {
config_value = config_value->next;
}
config_value->next = malloc(sizeof(C_SIMPLE_HTTP_ConfigValue));
config_value->next->value = (char*)value;
config_value->next->next = NULL;
free(key);
} else {
config_value = malloc(sizeof(C_SIMPLE_HTTP_ConfigValue));
config_value->value = (char*)value;
config_value->next = NULL;
if (simple_archiver_hash_map_insert(
hash_map_wrapper->paths,
config_value,
key, key,
*key_idx, *key_idx,
c_simple_http_cleanup_config_value_void_ptr, NULL,
NULL) != 0) { NULL) != 0) {
fprintf(stderr, fprintf(stderr,
"ERROR: Internal error failed to insert into hash map with path " "ERROR: Internal error failed to insert into hash map with path "
@ -308,7 +270,6 @@ int internal_check_add_value(uint32_t *state,
return 1; return 1;
} }
} }
}
(*key_idx) = 0; (*key_idx) = 0;
(*value_idx) = 0; (*value_idx) = 0;
return 0; return 0;

View file

@ -30,9 +30,6 @@ typedef struct C_SIMPLE_HTTP_ParsedConfig {
/// KEY: "/", VALUE: HashMapWrapper struct /// KEY: "/", VALUE: HashMapWrapper struct
/// KEY: "/inner", VALUE: HashMapWrapper struct /// KEY: "/inner", VALUE: HashMapWrapper struct
/// KEY: "/inner/further", VALUE: HashMapWrapper struct /// KEY: "/inner/further", VALUE: HashMapWrapper struct
///
/// Each HashMapWrapper struct's hash-map has the following:
/// KEY: VAR_NAME, VALUE: ConfigValue struct
union { union {
SDArchiverHashMap *paths; SDArchiverHashMap *paths;
SDArchiverHashMap *hash_map; SDArchiverHashMap *hash_map;
@ -41,15 +38,6 @@ typedef struct C_SIMPLE_HTTP_ParsedConfig {
typedef C_SIMPLE_HTTP_ParsedConfig C_SIMPLE_HTTP_HashMapWrapper; typedef C_SIMPLE_HTTP_ParsedConfig C_SIMPLE_HTTP_HashMapWrapper;
typedef struct C_SIMPLE_HTTP_ConfigValue {
char *value;
struct C_SIMPLE_HTTP_ConfigValue *next;
} C_SIMPLE_HTTP_ConfigValue;
void c_simple_http_cleanup_config_value(
C_SIMPLE_HTTP_ConfigValue *config_value);
void c_simple_http_cleanup_config_value_void_ptr(void *config_value);
/// Each line in the config should be a key-value pair separated by an equals /// 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". A part /// sign "=". All whitespace is ignored unless if the value is "quoted". A part
/// of a string can be "quoted" if it is surrounded by three single-quotes or /// of a string can be "quoted" if it is surrounded by three single-quotes or

View file

@ -17,7 +17,6 @@
#include "helpers.h" #include "helpers.h"
// Standard library includes. // Standard library includes.
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@ -32,9 +31,7 @@ int c_simple_http_internal_get_string_part_full_size(void *data, void *ud) {
C_SIMPLE_HTTP_String_Part *part = data; C_SIMPLE_HTTP_String_Part *part = data;
size_t *count = ud; size_t *count = ud;
if (part->size > 0) {
*count += part->size - 1; *count += part->size - 1;
}
return 0; return 0;
} }
@ -89,36 +86,9 @@ void c_simple_http_add_string_part(
C_SIMPLE_HTTP_String_Part *string_part = C_SIMPLE_HTTP_String_Part *string_part =
malloc(sizeof(C_SIMPLE_HTTP_String_Part)); malloc(sizeof(C_SIMPLE_HTTP_String_Part));
if (c_string) {
string_part->size = strlen(c_string) + 1; string_part->size = strlen(c_string) + 1;
string_part->buf = malloc(string_part->size); string_part->buf = malloc(string_part->size);
memcpy(string_part->buf, c_string, string_part->size); memcpy(string_part->buf, c_string, string_part->size);
} else {
string_part->size = 0;
string_part->buf = NULL;
}
string_part->extra = extra;
simple_archiver_list_add(
list, string_part, c_simple_http_cleanup_string_part);
}
void c_simple_http_add_string_part_sized(
SDArchiverLinkedList *list,
const char *buffer,
size_t size,
uintptr_t extra) {
C_SIMPLE_HTTP_String_Part *string_part =
malloc(sizeof(C_SIMPLE_HTTP_String_Part));
if (buffer && size > 0) {
string_part->size = size;
string_part->buf = malloc(string_part->size - 1);
memcpy(string_part->buf, buffer, string_part->size - 1);
} else {
string_part->size = 0;
string_part->buf = NULL;
}
string_part->extra = extra; string_part->extra = extra;
@ -294,66 +264,4 @@ void c_simple_http_cleanup_DIR(DIR **fd) {
} }
} }
char *c_simple_http_FILE_to_c_str(const char *filename, uint64_t *size_out) {
FILE *fd = fopen(filename, "rb");
if (!fd) {
fprintf(stderr, "ERROR Failed to open %s!\n", filename);
return NULL;
} else if (fseek(fd, 0, SEEK_END) != 0) {
fprintf(stderr, "ERROR Failed to seek to end of %s!\n", filename);
fclose(fd);
return NULL;
}
long size = ftell(fd);
if (size < 0) {
fprintf(stderr, "ERROR Failed to get seek pos of end of %s!\n", filename);
fclose(fd);
return NULL;
} else if (size == 0) {
fprintf(stderr, "ERROR Size of file \"%s\" is zero!\n", filename);
fclose(fd);
return NULL;
}
if (size_out) {
*size_out = (uint64_t)size;
}
char *buf = malloc((uint64_t)size + 1);
if (fseek(fd, 0, SEEK_SET) != 0) {
fprintf(stderr, "ERROR Failed to seek to beginning of %s!\n", filename);
free(buf);
fclose(fd);
return NULL;
} else if (fread(buf, 1, (uint64_t)size, fd) != (uint64_t)size) {
fprintf(stderr, "ERROR Failed to read from file %s!\n", filename);
free(buf);
fclose(fd);
return NULL;
}
buf[size] = 0;
fclose(fd);
return buf;
}
size_t c_simple_http_trim_end_whitespace(char *c_str) {
size_t trimmed = 0;
uint64_t idx= strlen(c_str);
for (; idx-- > 0;) {
if (c_str[idx] == ' '
|| c_str[idx] == '\n'
|| c_str[idx] == '\r'
|| c_str[idx] == '\t') {
c_str[idx] = 0;
++trimmed;
} else {
break;
}
}
return trimmed;
}
// vim: et ts=2 sts=2 sw=2 // vim: et ts=2 sts=2 sw=2

View file

@ -56,16 +56,6 @@ void c_simple_http_cleanup_string_part(void *data);
void c_simple_http_add_string_part( void c_simple_http_add_string_part(
SDArchiverLinkedList *list, const char *c_string, uintptr_t extra); SDArchiverLinkedList *list, const char *c_string, uintptr_t extra);
/// Puts a malloced instance of String_Part into the list.
/// The given c_string will be copied into a newly malloced buffer.
/// "size" must include NULL if "buffer" is a c_string.
/// If there is no NULL at the end, "size" must be +1 actual size.
void c_simple_http_add_string_part_sized(
SDArchiverLinkedList *list,
const char *buffer,
size_t size,
uintptr_t extra);
/// Combines all String_Parts in the list and returns it as a single buffer. /// Combines all String_Parts in the list and returns it as a single buffer.
char *c_simple_http_combine_string_parts(const SDArchiverLinkedList *list); char *c_simple_http_combine_string_parts(const SDArchiverLinkedList *list);
@ -90,13 +80,6 @@ int c_simple_http_helper_mkdir_tree(const char *dirpath);
void c_simple_http_cleanup_DIR(DIR **fd); void c_simple_http_cleanup_DIR(DIR **fd);
/// Must be free'd if non-NULL.
char *c_simple_http_FILE_to_c_str(const char *filename, uint64_t *size_out);
/// Trims by placing NULL bytes in place of whitespace at the end of c_str.
/// Returns number of whitespace trimmed.
size_t c_simple_http_trim_end_whitespace(char *c_str);
#endif #endif
// vim: et ts=2 sts=2 sw=2 // vim: et ts=2 sts=2 sw=2

View file

@ -38,12 +38,8 @@
#include "helpers.h" #include "helpers.h"
#include "http_template.h" #include "http_template.h"
int c_simple_http_internal_write_filenames_to_cache_file( int c_simple_http_internal_write_filenames_to_cache_file(void *data, void *ud) {
const void *key, char *filename = data;
__attribute__((unused)) size_t key_size,
__attribute__((unused)) const void *value,
void *ud) {
const char *filename = key;
FILE *cache_fd = ud; FILE *cache_fd = ud;
const size_t filename_size = strlen(filename); const size_t filename_size = strlen(filename);
@ -440,8 +436,8 @@ CACHE_FILE_WRITE_CHECK:
return -5; return -5;
} }
__attribute__((cleanup(simple_archiver_hash_map_free))) __attribute__((cleanup(simple_archiver_list_free)))
SDArchiverHashMap *used_filenames = NULL; SDArchiverLinkedList *used_filenames = NULL;
size_t generated_html_size = 0; size_t generated_html_size = 0;
@ -456,10 +452,10 @@ CACHE_FILE_WRITE_CHECK:
return -4; return -4;
} }
if (simple_archiver_hash_map_iter( if (simple_archiver_list_get(
used_filenames, used_filenames,
c_simple_http_internal_write_filenames_to_cache_file, c_simple_http_internal_write_filenames_to_cache_file,
cache_fd) != 0) { cache_fd)) {
fprintf(stderr, "ERROR Failed to write filenames to cache file!\n"); fprintf(stderr, "ERROR Failed to write filenames to cache file!\n");
return -6; return -6;
} else if (fwrite("--- BEGIN HTML ---\n", 1, 19, cache_fd) != 19) { } else if (fwrite("--- BEGIN HTML ---\n", 1, 19, cache_fd) != 19) {

File diff suppressed because it is too large Load diff

View file

@ -17,16 +17,13 @@
#ifndef SEODISPARATE_COM_C_SIMPLE_HTTP_HTTP_TEMPLATE_H_ #ifndef SEODISPARATE_COM_C_SIMPLE_HTTP_HTTP_TEMPLATE_H_
#define SEODISPARATE_COM_C_SIMPLE_HTTP_HTTP_TEMPLATE_H_ #define SEODISPARATE_COM_C_SIMPLE_HTTP_HTTP_TEMPLATE_H_
#include "http.h"
// Standard library includes. // Standard library includes.
#include <stddef.h> #include <stddef.h>
// Third-party includes. // Third-party includes.
#include <SimpleArchiver/src/data_structures/linked_list.h> #include <SimpleArchiver/src/data_structures/linked_list.h>
#include <SimpleArchiver/src/data_structures/hash_map.h>
// Local includes.
#include "http.h"
// Returns non-NULL on success, which must be free'd after use. Takes a path // Returns non-NULL on success, which must be free'd after use. Takes a path
// string and templates and returns the generated HTML. If "output_buf_size" is // string and templates and returns the generated HTML. If "output_buf_size" is
@ -38,7 +35,7 @@ char *c_simple_http_path_to_generated(
const char *path, const char *path,
const C_SIMPLE_HTTP_HTTPTemplates *templates, const C_SIMPLE_HTTP_HTTPTemplates *templates,
size_t *output_buf_size, size_t *output_buf_size,
SDArchiverHashMap **files_set_out); SDArchiverLinkedList **files_list_out);
#endif #endif

View file

@ -19,7 +19,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <inttypes.h>
// Linux/Unix includes. // Linux/Unix includes.
#include <sys/socket.h> #include <sys/socket.h>
@ -233,7 +232,7 @@ int c_simple_http_manage_connections(void *data, void *ud) {
snprintf( snprintf(
content_length_buf + content_length_buf_size, content_length_buf + content_length_buf_size,
127 - content_length_buf_size, 127 - content_length_buf_size,
"%zu\n%n", "%lu\n%n",
response_size, response_size,
&written); &written);
if (written <= 0) { if (written <= 0) {
@ -305,7 +304,7 @@ int c_simple_http_manage_connections(void *data, void *ud) {
snprintf( snprintf(
content_length_buf, content_length_buf,
content_str_len + 1 + 16 + 1, content_str_len + 1 + 16 + 1,
"Content-Length: %" PRIu64 "\n", "Content-Length: %lu\n",
file_info.buf_size); file_info.buf_size);
CHECK_ERROR_WRITE_NO_FD(write( CHECK_ERROR_WRITE_NO_FD(write(
citem->fd, content_length_buf, content_str_len + 1 + 16)); citem->fd, content_length_buf, content_str_len + 1 + 16));
@ -364,7 +363,7 @@ int main(int argc, char **argv) {
puts("Static dir option specified, copying over static dir entries..."); puts("Static dir option specified, copying over static dir entries...");
if (c_simple_http_static_copy_over_dir(args.static_dir, if (c_simple_http_static_copy_over_dir(args.static_dir,
args.generate_dir, args.generate_dir,
(args.flags & 8) != 0 ? 1 : 0) (args.flags & 4) != 0 ? 1 : 0)
!= 0) { != 0) {
fprintf(stderr, "ERROR during static-dir-entires copying!\n"); fprintf(stderr, "ERROR during static-dir-entires copying!\n");
return 1; return 1;
@ -386,8 +385,7 @@ int main(int argc, char **argv) {
socklen_t size = sizeof(ipv6_addr); socklen_t size = sizeof(ipv6_addr);
int ret = getsockname(tcp_socket, (struct sockaddr*)&ipv6_addr, &size); int ret = getsockname(tcp_socket, (struct sockaddr*)&ipv6_addr, &size);
if (ret == 0) { if (ret == 0) {
printf("Listening on port: %" PRIu16 "\n", printf("Listening on port: %u\n", u16_be_swap(ipv6_addr.sin6_port));
u16_be_swap(ipv6_addr.sin6_port));
} else { } else {
fprintf( fprintf(
stderr, stderr,
@ -464,7 +462,7 @@ int main(int argc, char **argv) {
++config_try_reload_attempts; ++config_try_reload_attempts;
fprintf( fprintf(
stderr, stderr,
"Attempting to reload config now (try %" PRIu32 " of %u)...\n", "Attempting to reload config now (try %u of %u)...\n",
config_try_reload_attempts, config_try_reload_attempts,
C_SIMPLE_HTTP_TRY_CONFIG_RELOAD_MAX_ATTEMPTS); C_SIMPLE_HTTP_TRY_CONFIG_RELOAD_MAX_ATTEMPTS);
C_SIMPLE_HTTP_ParsedConfig new_parsed_config = C_SIMPLE_HTTP_ParsedConfig new_parsed_config =
@ -534,7 +532,7 @@ int main(int argc, char **argv) {
} }
} else if (read_ret > 0) { } else if (read_ret > 0) {
#ifndef NDEBUG #ifndef NDEBUG
printf("DEBUG inotify_event->mask: %" PRIx32 "\n", inotify_event->mask); printf("DEBUG inotify_event->mask: %x\n", inotify_event->mask);
#endif #endif
if ((inotify_event->mask & IN_MODIFY) != 0 if ((inotify_event->mask & IN_MODIFY) != 0
|| (inotify_event->mask & IN_CLOSE_WRITE) != 0) { || (inotify_event->mask & IN_CLOSE_WRITE) != 0) {

View file

@ -421,8 +421,8 @@ int c_simple_http_static_copy_over_dir(const char *from,
if (fd) { if (fd) {
fprintf( fprintf(
stderr, stderr,
"WARNING \"%s\" already exists and " "WARNING \"%s\" already exists and --generate-enable-overwrite not "
"--generate-static-enable-overwrite not specified, skipping!\n", "specified, skipping!\n",
combined_to); combined_to);
continue; continue;
} }
@ -458,7 +458,7 @@ int c_simple_http_static_copy_over_dir(const char *from,
return 1; return 1;
} }
char buf[1024]; char *buf[1024];
size_t fread_ret; size_t fread_ret;
unsigned long fwrite_ret; unsigned long fwrite_ret;
while (!feof(from_file_fd) while (!feof(from_file_fd)

View file

@ -3,7 +3,6 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <inttypes.h>
// POSIX includes. // POSIX includes.
#include <unistd.h> #include <unistd.h>
@ -29,10 +28,7 @@ static int32_t checks_passed = 0;
#define RETURN() \ #define RETURN() \
do { \ do { \
fprintf(stderr, \ fprintf(stderr, "checked %d\npassed %d\n", checks_checked, checks_passed);\
"checked %" PRId32 "\npassed %" PRId32 "\n", \
checks_checked, \
checks_passed); \
return checks_checked == checks_passed ? 0 : 1; \ return checks_checked == checks_passed ? 0 : 1; \
} while (0); } while (0);
@ -103,13 +99,9 @@ void test_internal_cleanup_delete_temporary_file(const char **filename) {
} }
} }
int test_internal_check_matching_string_in_list( int test_internal_check_matching_string_in_list(void *value, void *ud) {
const void *key, if (value && ud) {
__attribute__((unused)) size_t key_size, if (strcmp(value, ud) == 0) {
__attribute__((unused)) const void *value,
void *ud) {
if (key && ud) {
if (strcmp(key, ud) == 0) {
return 1; return 1;
} }
} }
@ -181,53 +173,46 @@ int main(int argc, char **argv) {
simple_archiver_hash_map_get(templates.paths, "/", 2); simple_archiver_hash_map_get(templates.paths, "/", 2);
ASSERT_TRUE(first_path_map_wrapper); ASSERT_TRUE(first_path_map_wrapper);
C_SIMPLE_HTTP_ConfigValue *value = const char *value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "PATH", 5); simple_archiver_hash_map_get(first_path_map_wrapper->paths, "PATH", 5);
ASSERT_TRUE(value); ASSERT_TRUE(value);
ASSERT_TRUE(value->value); ASSERT_STREQ(value, "/");
ASSERT_STREQ(value->value, "/");
value = value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "HTML", 5); simple_archiver_hash_map_get(first_path_map_wrapper->paths, "HTML", 5);
ASSERT_TRUE(value); ASSERT_TRUE(value);
ASSERT_TRUE(value->value);
// printf("%s\n", value); // printf("%s\n", value);
ASSERT_STREQ(value->value, " one two three "); ASSERT_STREQ(value, " one two three ");
value = value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST", 5); simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST", 5);
ASSERT_TRUE(value); ASSERT_TRUE(value);
ASSERT_TRUE(value->value);
// printf("%s\n", value); // printf("%s\n", value);
ASSERT_STREQ(value->value, " \"one two \"three "); ASSERT_STREQ(value, " \"one two \"three ");
value = value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST2", 6); simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST2", 6);
ASSERT_TRUE(value); ASSERT_TRUE(value);
ASSERT_TRUE(value->value);
// printf("%s\n", value); // printf("%s\n", value);
ASSERT_STREQ(value->value, "'\"onetwo\"three''"); ASSERT_STREQ(value, "'\"onetwo\"three''");
value = value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST3", 6); simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST3", 6);
ASSERT_TRUE(value); ASSERT_TRUE(value);
ASSERT_TRUE(value->value);
// printf("%s\n", value); // printf("%s\n", value);
ASSERT_STREQ(value->value, " \"one two \"three ''"); ASSERT_STREQ(value, " \"one two \"three ''");
value = value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST4", 6); simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST4", 6);
ASSERT_TRUE(value); ASSERT_TRUE(value);
ASSERT_TRUE(value->value);
// printf("%s\n", value); // printf("%s\n", value);
ASSERT_STREQ(value->value, " \"\"\"one two \"\"\"three "); ASSERT_STREQ(value, " \"\"\"one two \"\"\"three ");
value = value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST5", 6); simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST5", 6);
ASSERT_TRUE(value); ASSERT_TRUE(value);
ASSERT_TRUE(value->value);
// printf("%s\n", value); // printf("%s\n", value);
ASSERT_STREQ(value->value, " '''one two '''three "); ASSERT_STREQ(value, " '''one two '''three ");
simple_archiver_list_free(&required_names); simple_archiver_list_free(&required_names);
required_names = simple_archiver_list_init(); required_names = simple_archiver_list_init();
@ -286,18 +271,18 @@ int main(int argc, char **argv) {
size_t output_buf_size; size_t output_buf_size;
__attribute__((cleanup(simple_archiver_hash_map_free))) __attribute__((cleanup(simple_archiver_list_free)))
SDArchiverHashMap *filenames_set = NULL; SDArchiverLinkedList *filenames_list = NULL;
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string))) __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *buf = c_simple_http_path_to_generated( char *buf = c_simple_http_path_to_generated(
"/", &config, &output_buf_size, &filenames_set); "/", &config, &output_buf_size, &filenames_list);
ASSERT_TRUE(buf != NULL); ASSERT_TRUE(buf != NULL);
ASSERT_TRUE(strcmp(buf, "<h1>Test</h1>") == 0); ASSERT_TRUE(strcmp(buf, "<h1>Test</h1>") == 0);
CHECK_TRUE(output_buf_size == 13); CHECK_TRUE(output_buf_size == 13);
CHECK_TRUE(filenames_set->count == 0); CHECK_TRUE(filenames_list->count == 0);
simple_archiver_helper_cleanup_c_string(&buf); simple_archiver_helper_cleanup_c_string(&buf);
simple_archiver_hash_map_free(&filenames_set); simple_archiver_list_free(&filenames_list);
__attribute__((cleanup(test_internal_cleanup_delete_temporary_file))) __attribute__((cleanup(test_internal_cleanup_delete_temporary_file)))
const char *test_http_template_filename2 = const char *test_http_template_filename2 =
@ -329,7 +314,7 @@ int main(int argc, char **argv) {
ASSERT_TRUE(config.paths != NULL); ASSERT_TRUE(config.paths != NULL);
buf = c_simple_http_path_to_generated( buf = c_simple_http_path_to_generated(
"/", &config, &output_buf_size, &filenames_set); "/", &config, &output_buf_size, &filenames_list);
ASSERT_TRUE(buf != NULL); ASSERT_TRUE(buf != NULL);
//printf("%s\n", buf); //printf("%s\n", buf);
ASSERT_TRUE( ASSERT_TRUE(
@ -338,9 +323,9 @@ int main(int argc, char **argv) {
"<h1> Some text. </h1><br><h2> More text. </h2>") "<h1> Some text. </h1><br><h2> More text. </h2>")
== 0); == 0);
CHECK_TRUE(output_buf_size == 46); CHECK_TRUE(output_buf_size == 46);
CHECK_TRUE(filenames_set->count == 0); CHECK_TRUE(filenames_list->count == 0);
simple_archiver_helper_cleanup_c_string(&buf); simple_archiver_helper_cleanup_c_string(&buf);
simple_archiver_hash_map_free(&filenames_set); simple_archiver_list_free(&filenames_list);
__attribute__((cleanup(test_internal_cleanup_delete_temporary_file))) __attribute__((cleanup(test_internal_cleanup_delete_temporary_file)))
const char *test_http_template_filename3 = const char *test_http_template_filename3 =
@ -395,7 +380,7 @@ int main(int argc, char **argv) {
ASSERT_TRUE(config.paths != NULL); ASSERT_TRUE(config.paths != NULL);
buf = c_simple_http_path_to_generated( buf = c_simple_http_path_to_generated(
"/", &config, &output_buf_size, &filenames_set); "/", &config, &output_buf_size, &filenames_list);
ASSERT_TRUE(buf != NULL); ASSERT_TRUE(buf != NULL);
//printf("%s\n", buf); //printf("%s\n", buf);
ASSERT_TRUE( ASSERT_TRUE(
@ -404,14 +389,14 @@ int main(int argc, char **argv) {
"<h1> testVar text. </h1><br><h2> testVar2 text. </h2>") "<h1> testVar text. </h1><br><h2> testVar2 text. </h2>")
== 0); == 0);
CHECK_TRUE(output_buf_size == 53); CHECK_TRUE(output_buf_size == 53);
CHECK_TRUE(filenames_set->count == 1); CHECK_TRUE(filenames_list->count == 1);
CHECK_TRUE(simple_archiver_hash_map_iter( CHECK_TRUE(simple_archiver_list_get(
filenames_set, filenames_list,
test_internal_check_matching_string_in_list, test_internal_check_matching_string_in_list,
(void*)test_http_template_html_filename) (void*)test_http_template_html_filename)
!= 0); != NULL);
simple_archiver_helper_cleanup_c_string(&buf); simple_archiver_helper_cleanup_c_string(&buf);
simple_archiver_hash_map_free(&filenames_set); simple_archiver_list_free(&filenames_list);
__attribute__((cleanup(test_internal_cleanup_delete_temporary_file))) __attribute__((cleanup(test_internal_cleanup_delete_temporary_file)))
const char *test_http_template_filename4 = const char *test_http_template_filename4 =
@ -486,7 +471,7 @@ int main(int argc, char **argv) {
ASSERT_TRUE(config.paths != NULL); ASSERT_TRUE(config.paths != NULL);
buf = c_simple_http_path_to_generated( buf = c_simple_http_path_to_generated(
"/", &config, &output_buf_size, &filenames_set); "/", &config, &output_buf_size, &filenames_list);
ASSERT_TRUE(buf != NULL); ASSERT_TRUE(buf != NULL);
//printf("%s\n", buf); //printf("%s\n", buf);
ASSERT_TRUE( ASSERT_TRUE(
@ -495,17 +480,17 @@ int main(int argc, char **argv) {
"<h1> some test text in test var file. </h1>") "<h1> some test text in test var file. </h1>")
== 0); == 0);
CHECK_TRUE(output_buf_size == 43); CHECK_TRUE(output_buf_size == 43);
CHECK_TRUE(filenames_set->count == 2); CHECK_TRUE(filenames_list->count == 2);
CHECK_TRUE(simple_archiver_hash_map_iter( CHECK_TRUE(simple_archiver_list_get(
filenames_set, filenames_list,
test_internal_check_matching_string_in_list, test_internal_check_matching_string_in_list,
(void*)test_http_template_html_filename2) (void*)test_http_template_html_filename2)
!= 0); != NULL);
CHECK_TRUE(simple_archiver_hash_map_iter( CHECK_TRUE(simple_archiver_list_get(
filenames_set, filenames_list,
test_internal_check_matching_string_in_list, test_internal_check_matching_string_in_list,
(void*)test_http_template_html_var_filename) (void*)test_http_template_html_var_filename)
!= 0); != NULL);
simple_archiver_helper_cleanup_c_string(&buf); simple_archiver_helper_cleanup_c_string(&buf);
} }
@ -628,46 +613,6 @@ int main(int argc, char **argv) {
CHECK_TRUE(ret == 0); CHECK_TRUE(ret == 0);
CHECK_TRUE(ret2 == 0); CHECK_TRUE(ret2 == 0);
CHECK_TRUE(ret3 == 0); CHECK_TRUE(ret3 == 0);
buf = strdup("EndingWithThreeTabs\t\t\t");
CHECK_TRUE(c_simple_http_trim_end_whitespace(buf) == 3);
CHECK_TRUE(buf[18] == 's');
CHECK_TRUE(buf[19] == 0);
CHECK_TRUE(buf[20] == 0);
CHECK_TRUE(buf[21] == 0);
CHECK_TRUE(buf[22] == 0);
free(buf);
buf = NULL;
buf = strdup("EndingWithThreeSpaces ");
CHECK_TRUE(c_simple_http_trim_end_whitespace(buf) == 3);
CHECK_TRUE(buf[20] == 's');
CHECK_TRUE(buf[21] == 0);
CHECK_TRUE(buf[22] == 0);
CHECK_TRUE(buf[23] == 0);
CHECK_TRUE(buf[24] == 0);
free(buf);
buf = NULL;
buf = strdup("EndingWithThreeNewlines\n\n\n");
CHECK_TRUE(c_simple_http_trim_end_whitespace(buf) == 3);
CHECK_TRUE(buf[22] == 's');
CHECK_TRUE(buf[23] == 0);
CHECK_TRUE(buf[24] == 0);
CHECK_TRUE(buf[25] == 0);
CHECK_TRUE(buf[26] == 0);
free(buf);
buf = NULL;
buf = strdup("EndingWithThreeCarraigeReturns\r\r\r");
CHECK_TRUE(c_simple_http_trim_end_whitespace(buf) == 3);
CHECK_TRUE(buf[29] == 's');
CHECK_TRUE(buf[30] == 0);
CHECK_TRUE(buf[31] == 0);
CHECK_TRUE(buf[32] == 0);
CHECK_TRUE(buf[33] == 0);
free(buf);
buf = NULL;
} }
// Test html_cache. // Test html_cache.

@ -1 +1 @@
Subproject commit 78a36b48dbd3888f56e26ac71115e5f775a74c2c Subproject commit b256350fbcf170ef3d70e9cf7c6dfa0618e47ef4