A small http server written in C
git clone git://git.janzachar.dev/shttp.git
0#include "super.h"1#include <sys/stat.h>2#include <string.h>3#include <time.h>456const char *MIME[][2] = {7 {".html", "text/html"},8 {".htm", "text/html"},9 {".css", "text/css"},10 {".js", "application/javascript"},11 {".json", "application/json"},12 {".xml", "application/xml"},13 {".txt", "text/plain"},14 {".csv", "text/csv"},15 {".svg", "image/svg+xml"},16 {".png", "image/png"},17 {".jpg", "image/jpeg"},18 {".jpeg", "image/jpeg"},19 {".gif", "image/gif"},20 {".webp", "image/webp"},21 {".ico", "image/x-icon"},22 {".avif", "image/avif"},23 {".mp4", "video/mp4"},24 {".webm", "video/webm"},25 {".ogg", "audio/ogg"},26 {".mp3", "audio/mpeg"},27 {".wav", "audio/wav"},28 {".pdf", "application/pdf"},29 {".zip", "application/zip"},30 {".gz", "application/gzip"},31 {".tar", "application/x-tar"},32 {".wasm", "application/wasm"},33 {".otf", "font/otf"},34 {".7z", "application/x-7z-compressed"},35 {NULL, NULL}36};3738int endswith(const char *str, const char *with) {39 int s = strlen(str);40 int w = strlen(with);41 if (s < w) return 0;42 return !strcmp(str + s - w, with);43}4445const char *guess_mime(const char *path)46{47 for (int i = 0; MIME[i][0] != NULL; i++) {48 if (endswith(path, MIME[i][0]))49 return MIME[i][1];50 }51 return "application/octet-stream";52}53const char *last_modified(const char *path)54{55 static char date[32];5657 struct stat st;58 if (stat(path, &st))59 return NULL;6061 struct tm tm;62 gmtime_r(&st.st_mtime, &tm);63 strftime(date, sizeof(date), TIMESTAMP_FORMAT, &tm);64 return date;65}6667int GET(int fd, struct HTTP_request *rq, FILE *fp, const char *path)68{69 freply(fd, 200, (struct header[]){70 {"Last-Modified", last_modified(path)},71 {"Content-Type", guess_mime(path)},72 {NULL, NULL}73 }, fp);74 fclose(fp);75 return 1;76}7778int HEAD(int fd, struct HTTP_request *rq, FILE *fp, const char *path)79{80 long s = getsize(fp);81 fclose(fp);82 if (s == -1) {83 reply(fd, 403, NULL);84 return 1;85 }8687 char out[16];88 out[sprintf(out, "%ld", s)] = '\0';8990 reply(fd, 200, (struct header[]){91 {"Last-Modified", last_modified(path)},92 {"Content-Type", guess_mime(path)},93 {"Content-Length", out},94 {NULL, NULL}95 });96 return 1;97}9899