aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2023-01-28 00:36:27 +0200
committerkartofen <mladenovnasko0@gmail.com>2023-01-28 00:36:27 +0200
commit9ac597d24336586421d994a8b1201aa3f0127827 (patch)
treec228f5902ba1c8d8a67b4ee7027806b4a8e2974e /src
parente0a039ad08fc16773cee43e68f92b632a4540bce (diff)
now using libmagic and its optional
Diffstat (limited to 'src')
-rw-r--r--src/main.c121
1 files changed, 75 insertions, 46 deletions
diff --git a/src/main.c b/src/main.c
index 9420c47..8817b83 100644
--- a/src/main.c
+++ b/src/main.c
@@ -13,7 +13,7 @@
#define PORT "8079"
#define RM_LF(str) do { \
- signed long len = strlen(str)-1; \
+ signed long len = strlen(str)-1; \
if(len >= 0 && str[len] == '\n') str[len] = '\0'; \
} while(0)
@@ -35,58 +35,60 @@
SEND_BUF_ADD("\r\n"); \
} while(0)
-#define LOAD_FILE() do { \
- if(is_binary) { \
- fseek(fp, 0, SEEK_END); \
- size_t file_sz = ftell(fp); \
- rewind(fp); \
- \
- fread(&send_buf[*send_buf_sz], sizeof(char), file_sz, fp); \
- *send_buf_sz += file_sz; \
- } else { \
- char line[BUF_CAP]; \
- while(fgets(line, sizeof(line), fp) != NULL) \
- { \
- RM_LF(line); \
- SEND_BUF_ADD_LINE(line); \
- } \
- } \
+#define SEND_BUF_ADD_LINE_LONG(lon) do { \
+ char str[COMMON_CAP]; \
+ sprintf(str, "%ld", lon); \
+ SEND_BUF_ADD_LINE(str); \
} while(0)
+#ifdef USE_LIBMAGIC
+#include <magic.h>
static int get_content_type(char *file_path, char *content_type)
{
- char cmd[COMMON_CAP + 64];
- sprintf(cmd, "/usr/bin/file -ib %s", file_path);
+ int ret = 1;
+ magic_t magic;
- FILE *fp = popen(cmd, "r");
- if(!fp) {
- err("popen: cmd %s: %s", cmd, strerror(errno));
- return 1;
+ if((magic = magic_open(MAGIC_MIME)) == NULL) {
+ err("magic_open: %s", magic_error(magic));
+ return ret;
}
- if(fgets(content_type, COMMON_CAP, fp) == NULL) {
- err("get_mime_type: no output from fgets");
- return 1;
+ if(magic_load(magic, NULL) != 0) {
+ err("magic_load: %s", magic_error(magic));
+ goto close;
}
- pclose(fp);
- RM_LF(content_type);
-
- char ct_cpy[COMMON_CAP];
- strcpy(ct_cpy, content_type);
- strtok(ct_cpy, "=");
-
- // the only thing after the '=' should be the either binary or something else (text)
- char *charset = strtok(NULL, "=");
- if(charset == NULL || strcmp(charset, "binary") != 0) {
- return 0;
+ const char *mime = magic_file(magic, file_path);
+ if(mime == NULL) {
+ err("magic_file: %s", magic_error(magic));
+ goto close;
}
- return -1;
+ memcpy(content_type, mime, strlen(mime));
+
+ ret = 0;
+close:
+ magic_close(magic);
+ return ret;
+}
+#else
+static int get_content_type(char *file_path, char *content_type)
+{
+ (void)file_path;
+ (void)content_type;
+ return 0;
}
+#endif
static int try_file(char *req_path, FILE **fp, char *content_type)
{
+ for(size_t i = 1; i < strlen(req_path); i++) {
+ if(req_path[i-1] == '.' && req_path[i] == '.') {
+ err("try_file: the requested path %s includes ..", req_path);
+ return 1;
+ }
+ }
+
char file_path[COMMON_CAP];
sprintf(file_path, "%s%s", FILES,
(strlen(req_path) == 1) ? "/index.html" : req_path);
@@ -96,24 +98,31 @@ static int try_file(char *req_path, FILE **fp, char *content_type)
err("fopen: file %s: %s", file_path, strerror(errno));
return 1;
}
+
info("fopen: file %s was opened", file_path);
- return get_content_type(file_path, content_type);
+ if(get_content_type(file_path, content_type) != 0) {
+ err("get_content_type: failed");
+ fclose(*fp);
+ return 1;
+ }
+
+ return 0;
}
static int on_get(char *send_buf, ssize_t *send_buf_sz, char *req_path)
{
- char content_type[COMMON_CAP];
- int is_binary; // 0 - no; -1 - yes; 1 - error
+ int ret = 1;
+ char content_type[COMMON_CAP] = {0};
FILE *fp;
- if((is_binary = try_file(req_path, &fp, content_type)) == 1) {
+ if(try_file(req_path, &fp, content_type) != 0) {
if(errno == 2) { // 2 is 'No such file or directory'
SEND_BUF_ADD_LINE("404");
- if((is_binary = try_file("/404.html", &fp, content_type)) != 0) return 1;
+ if(try_file("/404.html", &fp, content_type) != 0) return ret;
} else {
SEND_BUF_ADD_LINE("500");
- if((is_binary = try_file("/500.html", &fp, content_type)) != 0) return 1;
+ if(try_file("/500.html", &fp, content_type) != 0) return ret;
}
} else {
SEND_BUF_ADD_LINE("200");
@@ -122,11 +131,31 @@ static int on_get(char *send_buf, ssize_t *send_buf_sz, char *req_path)
SEND_BUF_ADD_LINE("Server: potato");
SEND_BUF_ADD("Content-Type: ");
SEND_BUF_ADD_LINE(content_type);
+
+ if(fseek(fp, 0, SEEK_END) != 0) {
+ err("fseek: %s", strerror(errno));
+ goto close;
+ }
+
+ size_t file_sz = ftell(fp);
+ if(file_sz == 0) {
+ err("ftell: %s", strerror(errno));
+ goto close;
+ }
+
+ rewind(fp);
+
+ SEND_BUF_ADD("Content-Lenght: ");
+ SEND_BUF_ADD_LINE_LONG(file_sz);
SEND_BUF_ADD("\r\n");
- LOAD_FILE();
+ fread(&send_buf[*send_buf_sz], sizeof(char), file_sz, fp);
+ *send_buf_sz += file_sz;
+
+ ret = 0;
+close:
fclose(fp);
- return 0;
+ return ret;
}
static int handle_connection(sock_t *conn)