Skip to content

Instantly share code, notes, and snippets.

@izabera
Last active November 11, 2021 23:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save izabera/771993f4612424170e338fadcd922a06 to your computer and use it in GitHub Desktop.
Save izabera/771993f4612424170e338fadcd922a06 to your computer and use it in GitHub Desktop.
#include <ctype.h>
#include <fcntl.h>
#include <linux/openat2.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
if (argc > 2) if (chdir(argv[2])) return 1;
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sock = {
.sin_family = AF_INET,
.sin_port = htons(argc > 1 ? atoi(argv[1]) : 80),
};
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));
bind(listenfd, (struct sockaddr*)&sock, sizeof(sock));
listen(listenfd, 10);
signal(SIGCHLD, SIG_IGN);
while (1) {
int fd = accept(listenfd, 0, 0);
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &(struct timeval){ .tv_sec = 10 }, sizeof(struct timeval));
if (!fork()) {
static char buf[4096];
read(fd, buf, sizeof buf - 1);
if (strchr(buf, '\n')) *strchr(buf, '\n') = 0;
if (strchr(buf, '\r')) *strchr(buf, '\r') = 0;
if (strrchr(buf, ' ')) *strrchr(buf, ' ') = 0;
if (!strncmp(buf, "GET ", 4) || !strncmp(buf, "HEAD ", 5)) {
char *path = buf + 5 + (buf[0] == 'H'), *rptr = path, *wptr = path;
for ( ; *rptr; rptr++) {
if (*rptr != '%') *wptr++ = *rptr;
else if (isxdigit(rptr[1]) && isxdigit(rptr[2])) {
#define fromhex(x) (x >= '0' && x <= '9' ? x - '0' : (x|32) - 'a' + 10)
*wptr++ = (fromhex(rptr[1]) << 4) | fromhex(rptr[2]);
rptr += 2;
}
else { /* no */ }
}
*wptr = 0;
struct open_how how = {
.flags = O_RDONLY,
.resolve = RESOLVE_BENEATH,
};
int f = syscall(SYS_openat2, AT_FDCWD, path, &how, sizeof how);
if (f < 0) write(fd, "HTTP/1.0 404 Not Found\r\n\r\n", 26);
else write(fd, "HTTP/1.0 200 OK\r\n\r\n", 19);
if (buf[0] == 'G') for (long l; (l = read(f, buf, sizeof buf)) > 0; ) write(fd, buf, l);
}
else write(fd, "HTTP/1.0 501 Not Implemented\r\n\r\n", 32);
break;
}
close(fd);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment