@@ 3,6 3,7 @@
#include <string.h>
#include <errno.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/socket.h>
#include <unistd.h>
#include <getopt.h>
@@ 51,6 52,52 @@ struct Request {
};
int
+append_index_rel(char *relpath)
+{
+ size_t len = strlen(relpath);
+ if (relpath[len - 1] == '/') {
+ strcat(relpath, "index.gmi");
+ return 1;
+
+ }
+ return 0;
+}
+
+int
+append_index_abs(char *abspath)
+{
+ struct stat path_stat;
+ stat(path, &path_stat);
+ size_t len = strlen(abspath);
+
+ if (!S_ISREG(path_stat.st_mode)) {
+ if (abspath[len - 1] != '/') {
+ strcat(abspath, "/");
+ }
+ strcat(abspath, "index.gmi");
+ }
+
+ return 1;
+}
+
+char *get_mimetype(char *path) {
+ char *ext = get_path_ext(path);
+ if (!ext) {
+ return "text/gemini";
+ }
+
+ if (strcmp(ext, "gmi") == 0) {
+ return "text/gemini";
+ }
+
+ if (strcmp(ext, "txt") == 0) {
+ return "text/plain";
+ }
+
+ return "text/plain";
+}
+
+int
init_socket()
{
sockfd = socket(AF_INET, SOCK_STREAM, 0);
@@ 258,10 305,13 @@ read_request(struct bufferevent *bev, void *ctx)
char datebuf[20];
strftime (datebuf, sizeof(datebuf), "%Y-%m-%d %H:%M:%S", reqtime);
printf("%s Serving request: %s\n", datebuf, line);
+
+ char *mimetype = get_mimetype(url.route);
strcpy(path, rootdir);
- append_index(url.route);
+ append_index_rel(url.route);
strcat(path, url.route);
+ append_index_abs(path);
int filefd = open(path, O_RDONLY);
if (filefd == -1) {
write_header(output, 51, "File not found");
@@ 273,7 323,7 @@ read_request(struct bufferevent *bev, void *ctx)
fsize = lseek(filefd, 0, SEEK_END);
lseek(filefd, 0, SEEK_SET);
- write_header(output, 20, "text/gemini");
+ write_header(output, 20, mimetype);
evbuffer_add_file(output, filefd, 0, fsize);
}
@@ 142,14 142,27 @@ relpath_is_safe(char *relpath)
return check_segment(relpath, s, i);
}
-int
-append_index(char *relpath)
+char *
+get_path_ext(char *relpath)
{
- size_t len = strlen(relpath);
- if (relpath[len - 1] == '/') {
- strcat(relpath, "index.gmi");
- return 1;
+ size_t i = 0;
+ size_t s = 0;
+
+ while (relpath[i] != '\0') {
+ if (relpath[i] == '/') {
+ s = i + 1;
+ }
+ i++;
+ }
+
+ size_t len = i;
+
+ for (i = s; i < len; i++) {
+ if (relpath[i] == '.') {
+ return relpath + i + 1;
+ }
}
return 0;
}
+
@@ 6,4 6,4 @@ typedef struct URL {
int parse_url(char *urlstring, URL *url);
int relpath_is_safe(char *relpath);
-int append_index(char *relpath);
+char *get_path_ext(char *relpath);