Compare commits
No commits in common. "67f59e1354b5c435c64ac6858f93fffed8ae1236" and "86bfb5aa91bc623043aae56de6cee29632a16324" have entirely different histories.
67f59e1354
...
86bfb5aa91
10 changed files with 110 additions and 254 deletions
|
@ -69,8 +69,6 @@ HTML='''
|
|||
<h1>Nested inner: further<h1>
|
||||
{{{VAR}}}
|
||||
<br>
|
||||
<img src="/silly.jpg" />
|
||||
<br>
|
||||
<a href="/inner">back</a>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 16 KiB |
|
@ -43,7 +43,6 @@ void print_usage(void) {
|
|||
puts(" --enable-reload-config-on-change");
|
||||
puts(" --enable-cache-dir=<DIR>");
|
||||
puts(" --cache-entry-lifetime-seconds=<SECONDS>");
|
||||
puts(" --enable-static-dir=<DIR>");
|
||||
}
|
||||
|
||||
Args parse_args(int32_t argc, char **argv) {
|
||||
|
@ -129,29 +128,6 @@ Args parse_args(int32_t argc, char **argv) {
|
|||
"NOTICE set cache-entry-lifetime to %lu\n",
|
||||
args.cache_lifespan_seconds);
|
||||
}
|
||||
} else if (strncmp(argv[0], "--enable-static-dir=", 20) == 0) {
|
||||
args.static_dir = argv[0] + 20;
|
||||
// Check if it actually is an existing directory.
|
||||
DIR *d = opendir(args.static_dir);
|
||||
if (d == NULL) {
|
||||
if (errno == ENOENT) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"ERROR Directory \"%s\" does not exist!\n",
|
||||
args.static_dir);
|
||||
exit(1);
|
||||
} else {
|
||||
fprintf(
|
||||
stderr,
|
||||
"ERROR Failed to open directory \"%s\" (errno %d)!\n",
|
||||
args.static_dir,
|
||||
errno);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
printf("Directory \"%s\" exists.\n", args.static_dir);
|
||||
}
|
||||
closedir(d);
|
||||
} else {
|
||||
fprintf(stderr, "ERROR: Invalid args!\n");
|
||||
print_usage();
|
||||
|
|
|
@ -38,9 +38,6 @@ typedef struct Args {
|
|||
// Does not need to be free'd since it points to a string in argv.
|
||||
const char *cache_dir;
|
||||
size_t cache_lifespan_seconds;
|
||||
// Non-NULL if static-dir is specified and files in the dir are to be served.
|
||||
// Does not need to be free'd since it points to a string in argv.
|
||||
const char *static_dir;
|
||||
} Args;
|
||||
|
||||
void print_usage(void);
|
||||
|
|
11
src/http.c
11
src/http.c
|
@ -65,8 +65,7 @@ char *c_simple_http_request_response(
|
|||
C_SIMPLE_HTTP_HTTPTemplates *templates,
|
||||
size_t *out_size,
|
||||
enum C_SIMPLE_HTTP_ResponseCode *out_response_code,
|
||||
const Args *args,
|
||||
char **request_path_out) {
|
||||
const Args *args) {
|
||||
if (out_size) {
|
||||
*out_size = 0;
|
||||
}
|
||||
|
@ -177,11 +176,6 @@ char *c_simple_http_request_response(
|
|||
|
||||
char *generated_buf = NULL;
|
||||
|
||||
if (request_path_out) {
|
||||
*request_path_out =
|
||||
strdup(stripped_path ? stripped_path : request_path_unescaped);
|
||||
}
|
||||
|
||||
if (args->cache_dir) {
|
||||
int ret = c_simple_http_cache_path(
|
||||
stripped_path ? stripped_path : request_path_unescaped,
|
||||
|
@ -218,8 +212,7 @@ char *c_simple_http_request_response(
|
|||
}
|
||||
|
||||
if (!generated_buf || generated_size == 0) {
|
||||
fprintf(stderr,
|
||||
"WARNING Unable to generate response html for path \"%s\"!\n",
|
||||
fprintf(stderr, "ERROR Unable to generate response html for path \"%s\"!\n",
|
||||
request_path);
|
||||
if (out_response_code) {
|
||||
if (
|
||||
|
|
|
@ -50,8 +50,7 @@ char *c_simple_http_request_response(
|
|||
C_SIMPLE_HTTP_HTTPTemplates *templates,
|
||||
size_t *out_size,
|
||||
enum C_SIMPLE_HTTP_ResponseCode *out_response_code,
|
||||
const Args *args,
|
||||
char **request_path_out
|
||||
const Args *args
|
||||
);
|
||||
|
||||
/// Takes a PATH string and returns a "bare" path.
|
||||
|
|
137
src/main.c
137
src/main.c
|
@ -42,16 +42,8 @@
|
|||
#include "constants.h"
|
||||
#include "http.h"
|
||||
#include "helpers.h"
|
||||
#include "static.h"
|
||||
|
||||
#define CHECK_ERROR_WRITE(write_expr) \
|
||||
if (write_expr < 0) { \
|
||||
close(connection_fd); \
|
||||
fprintf(stderr, "ERROR Failed to write to connected peer, closing...\n"); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define CHECK_ERROR_WRITE_CONTINUE(write_expr) \
|
||||
if (write_expr < 0) { \
|
||||
close(connection_fd); \
|
||||
fprintf(stderr, "ERROR Failed to write to connected peer, closing...\n"); \
|
||||
|
@ -82,31 +74,6 @@ void c_simple_http_inotify_fd_cleanup(int *fd) {
|
|||
}
|
||||
}
|
||||
|
||||
int c_simple_http_on_error(
|
||||
enum C_SIMPLE_HTTP_ResponseCode response_code,
|
||||
int connection_fd
|
||||
) {
|
||||
const char *response = c_simple_http_response_code_error_to_response(
|
||||
response_code);
|
||||
size_t response_size;
|
||||
if (response) {
|
||||
response_size = strlen(response);
|
||||
CHECK_ERROR_WRITE(write(connection_fd, response, response_size));
|
||||
} else {
|
||||
CHECK_ERROR_WRITE(write(
|
||||
connection_fd, "HTTP/1.1 500 Internal Server Error\n", 35));
|
||||
CHECK_ERROR_WRITE(write(connection_fd, "Allow: GET\n", 11));
|
||||
CHECK_ERROR_WRITE(write(connection_fd, "Connection: close\n", 18));
|
||||
CHECK_ERROR_WRITE(write(
|
||||
connection_fd, "Content-Type: text/html\n", 24));
|
||||
CHECK_ERROR_WRITE(write(connection_fd, "Content-Length: 35\n", 19));
|
||||
CHECK_ERROR_WRITE(write(
|
||||
connection_fd, "\n<h1>500 Internal Server Error</h1>\n", 36));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
__attribute__((cleanup(c_simple_http_free_args)))
|
||||
Args args = parse_args(argc, argv);
|
||||
|
@ -387,23 +354,18 @@ int main(int argc, char **argv) {
|
|||
|
||||
size_t response_size = 0;
|
||||
enum C_SIMPLE_HTTP_ResponseCode response_code;
|
||||
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
|
||||
char *request_path = NULL;
|
||||
const char *response = c_simple_http_request_response(
|
||||
(const char*)recv_buf,
|
||||
(uint32_t)read_ret,
|
||||
&parsed_config,
|
||||
&response_size,
|
||||
&response_code,
|
||||
&args,
|
||||
&request_path);
|
||||
&args);
|
||||
if (response && response_code == C_SIMPLE_HTTP_Response_200_OK) {
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(
|
||||
connection_fd, "HTTP/1.1 200 OK\n", 16));
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(connection_fd, "Allow: GET\n", 11));
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(
|
||||
connection_fd, "Connection: close\n", 18));
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(
|
||||
CHECK_ERROR_WRITE(write(connection_fd, "HTTP/1.1 200 OK\n", 16));
|
||||
CHECK_ERROR_WRITE(write(connection_fd, "Allow: GET\n", 11));
|
||||
CHECK_ERROR_WRITE(write(connection_fd, "Connection: close\n", 18));
|
||||
CHECK_ERROR_WRITE(write(
|
||||
connection_fd, "Content-Type: text/html\n", 24));
|
||||
char content_length_buf[128];
|
||||
size_t content_length_buf_size = 0;
|
||||
|
@ -424,83 +386,28 @@ int main(int argc, char **argv) {
|
|||
continue;
|
||||
}
|
||||
content_length_buf_size += (size_t)written;
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(
|
||||
CHECK_ERROR_WRITE(write(
|
||||
connection_fd, content_length_buf, content_length_buf_size));
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(connection_fd, "\n", 1));
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(
|
||||
connection_fd, response, response_size));
|
||||
CHECK_ERROR_WRITE(write(connection_fd, "\n", 1));
|
||||
CHECK_ERROR_WRITE(write(connection_fd, response, response_size));
|
||||
|
||||
free((void*)response);
|
||||
} else if (
|
||||
response_code == C_SIMPLE_HTTP_Response_404_Not_Found
|
||||
&& args.static_dir) {
|
||||
__attribute__((cleanup(c_simple_http_cleanup_static_file_info)))
|
||||
C_SIMPLE_HTTP_StaticFileInfo file_info =
|
||||
c_simple_http_get_file(args.static_dir, request_path, 0);
|
||||
if (file_info.result == STATIC_FILE_RESULT_NoXDGMimeAvailable) {
|
||||
file_info = c_simple_http_get_file(args.static_dir, request_path, 1);
|
||||
}
|
||||
|
||||
if (file_info.result != STATIC_FILE_RESULT_OK
|
||||
|| !file_info.buf
|
||||
|| file_info.buf_size == 0
|
||||
|| !file_info.mime_type) {
|
||||
if (file_info.result == STATIC_FILE_RESULT_FileError
|
||||
|| file_info.result == STATIC_FILE_RESULT_InternalError) {
|
||||
response_code = C_SIMPLE_HTTP_Response_500_Internal_Server_Error;
|
||||
} else if (file_info.result == STATIC_FILE_RESULT_InvalidParameter) {
|
||||
response_code = C_SIMPLE_HTTP_Response_400_Bad_Request;
|
||||
} else {
|
||||
response_code = C_SIMPLE_HTTP_Response_500_Internal_Server_Error;
|
||||
}
|
||||
|
||||
if (c_simple_http_on_error(response_code, connection_fd)) {
|
||||
continue;
|
||||
}
|
||||
const char *response = c_simple_http_response_code_error_to_response(
|
||||
response_code);
|
||||
if (response) {
|
||||
response_size = strlen(response);
|
||||
CHECK_ERROR_WRITE(write(connection_fd, response, response_size));
|
||||
} else {
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(
|
||||
connection_fd, "HTTP/1.1 200 OK\n", 16));
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(connection_fd, "Allow: GET\n", 11));
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(
|
||||
connection_fd, "Connection: close\n", 18));
|
||||
uint64_t mime_length = strlen(file_info.mime_type);
|
||||
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
|
||||
char *mime_type_buf = malloc(mime_length + 1 + 14 + 1);
|
||||
snprintf(
|
||||
mime_type_buf,
|
||||
mime_length + 1 + 14 + 1,
|
||||
"Content-Type: %s\n",
|
||||
file_info.mime_type);
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(
|
||||
connection_fd, mime_type_buf, mime_length + 1 + 14));
|
||||
uint64_t content_str_len = 0;
|
||||
for(uint64_t buf_size_temp = file_info.buf_size;
|
||||
buf_size_temp > 0;
|
||||
buf_size_temp /= 10) {
|
||||
++content_str_len;
|
||||
}
|
||||
if (content_str_len == 0) {
|
||||
content_str_len = 1;
|
||||
}
|
||||
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
|
||||
char *content_length_buf = malloc(content_str_len + 1 + 16 + 1);
|
||||
snprintf(
|
||||
content_length_buf,
|
||||
content_str_len + 1 + 16 + 1,
|
||||
"Content-Length: %lu\n",
|
||||
file_info.buf_size);
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(
|
||||
connection_fd, content_length_buf, content_str_len + 1 + 16));
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(connection_fd, "\n", 1));
|
||||
CHECK_ERROR_WRITE_CONTINUE(write(
|
||||
connection_fd, file_info.buf, file_info.buf_size));
|
||||
fprintf(stderr,
|
||||
"NOTICE Found static file for path \"%s\"\n",
|
||||
request_path);
|
||||
}
|
||||
} else {
|
||||
if (c_simple_http_on_error(response_code, connection_fd)) {
|
||||
continue;
|
||||
CHECK_ERROR_WRITE(write(
|
||||
connection_fd, "HTTP/1.1 500 Internal Server Error\n", 35));
|
||||
CHECK_ERROR_WRITE(write(connection_fd, "Allow: GET\n", 11));
|
||||
CHECK_ERROR_WRITE(write(connection_fd, "Connection: close\n", 18));
|
||||
CHECK_ERROR_WRITE(write(
|
||||
connection_fd, "Content-Type: text/html\n", 24));
|
||||
CHECK_ERROR_WRITE(write(connection_fd, "Content-Length: 35\n", 19));
|
||||
CHECK_ERROR_WRITE(write(
|
||||
connection_fd, "\n<h1>500 Internal Server Error</h1>\n", 36));
|
||||
}
|
||||
}
|
||||
close(connection_fd);
|
||||
|
|
10
src/static.c
10
src/static.c
|
@ -109,15 +109,15 @@ void c_simple_http_cleanup_static_file_info(
|
|||
}
|
||||
}
|
||||
|
||||
C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(
|
||||
const char *static_dir, const char *path, int_fast8_t ignore_mime_type) {
|
||||
C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(const char *static_dir,
|
||||
const char *path) {
|
||||
C_SIMPLE_HTTP_StaticFileInfo file_info;
|
||||
memset(&file_info, 0, sizeof(C_SIMPLE_HTTP_StaticFileInfo));
|
||||
|
||||
if (!static_dir || !path) {
|
||||
file_info.result = STATIC_FILE_RESULT_InvalidParameter;
|
||||
return file_info;
|
||||
} else if (!ignore_mime_type && !c_simple_http_is_xdg_mime_available()) {
|
||||
} else if (!c_simple_http_is_xdg_mime_available()) {
|
||||
file_info.result = STATIC_FILE_RESULT_NoXDGMimeAvailable;
|
||||
return file_info;
|
||||
}
|
||||
|
@ -202,9 +202,6 @@ C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(
|
|||
|
||||
simple_archiver_helper_cleanup_FILE(&fd);
|
||||
|
||||
if (ignore_mime_type) {
|
||||
file_info.mime_type = strdup("application/octet-stream");
|
||||
} else {
|
||||
int from_xdg_mime_pipe[2];
|
||||
ret = pipe(from_xdg_mime_pipe);
|
||||
|
||||
|
@ -291,7 +288,6 @@ C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(
|
|||
}
|
||||
|
||||
file_info.mime_type = buf;
|
||||
}
|
||||
|
||||
file_info.result = STATIC_FILE_RESULT_OK;
|
||||
return file_info;
|
||||
|
|
|
@ -41,10 +41,8 @@ int_fast8_t c_simple_http_is_xdg_mime_available(void);
|
|||
void c_simple_http_cleanup_static_file_info(
|
||||
C_SIMPLE_HTTP_StaticFileInfo *file_info);
|
||||
|
||||
/// If ignore_mime_type is non-zero, then mime information will not be fetched.
|
||||
/// The mime_type string will therefore default to "application/octet-stream".
|
||||
C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(
|
||||
const char *static_dir, const char *path, int_fast8_t ignore_mime_type);
|
||||
const char *static_dir, const char *path);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
10
src/test.c
10
src/test.c
|
@ -984,7 +984,7 @@ int main(int argc, char **argv) {
|
|||
if (is_xdg_mime_exists) {
|
||||
CHECK_TRUE(c_simple_http_is_xdg_mime_available());
|
||||
|
||||
C_SIMPLE_HTTP_StaticFileInfo info = c_simple_http_get_file(".", argv[0], 0);
|
||||
C_SIMPLE_HTTP_StaticFileInfo info = c_simple_http_get_file(".", argv[0]);
|
||||
CHECK_TRUE(info.buf);
|
||||
CHECK_TRUE(info.buf_size > 0);
|
||||
CHECK_TRUE(info.mime_type);
|
||||
|
@ -994,14 +994,6 @@ int main(int argc, char **argv) {
|
|||
} else {
|
||||
CHECK_FALSE(c_simple_http_is_xdg_mime_available());
|
||||
}
|
||||
|
||||
C_SIMPLE_HTTP_StaticFileInfo info = c_simple_http_get_file(".", argv[0], 1);
|
||||
CHECK_TRUE(info.buf);
|
||||
CHECK_TRUE(info.buf_size > 0);
|
||||
CHECK_TRUE(info.mime_type);
|
||||
CHECK_TRUE(info.result == STATIC_FILE_RESULT_OK);
|
||||
CHECK_STREQ(info.mime_type, "application/octet-stream");
|
||||
c_simple_http_cleanup_static_file_info(&info);
|
||||
}
|
||||
|
||||
RETURN()
|
||||
|
|
Loading…
Reference in a new issue