higgs

httpd experiment
git clone git://git.2f30.org/higgs
Log | Files | Refs

commit 42f02badb681823743ce1105ddfffcb90dd1e92a
Author: FRIGN <dev@frign.de>
Date:   Thu,  3 Dec 2015 18:36:51 +0100

Initial commit

Always wanted to do that :D

Working branch for a simplification of quark which has grown too much
in the last few years.

Diffstat:
Aconfig.h | 4++++
Ahiggs.c | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 118 insertions(+), 0 deletions(-)

diff --git a/config.h b/config.h @@ -0,0 +1,4 @@ +/* higgs settings */ +static const char *servername = "127.0.0.1"; +static const char *serverport = "8081"; +static const int maxnprocs = 512; diff --git a/higgs.c b/higgs.c @@ -0,0 +1,114 @@ +#include <errno.h> +#include <limits.h> +#include <netdb.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/resource.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/types.h> + +#include "config.h" + +char response[] = "HTTP/1.1 200 OK\r\n" +"Connection: close\r\n" +"Date: Thu, 03 Dec 2015 15:18:45 GMT\r\n" +"Content-Type: text/html; charset=UTF-8\r\n\r\n" +"<!DOCTYPE html><html><head><title>Bye-bye baby bye-bye</title>" +"<style>body { background-color: #111 }" +"h1 { font-size:4cm; text-align: center; color: black;" +" text-shadow: 0 0 2mm red}</style></head>" +"<body><h1>Goodbye, world!</h1></body></html>\r\n"; + +int +main() +{ + struct addrinfo hints, *ai = NULL; + struct rlimit rlim; + struct sockaddr sa; + struct timeval tv; + pid_t pid; + socklen_t salen; + int i, listenfd, reqfd, running = 1; + + if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) { + fprintf(stderr, "signal: Failed to set SIG_IGN on SIGCHLD\n"); + return 1; + } + + /*setbuf(stdout, NULL);*/ /* unbuffered stdout */ + + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + if ((i = getaddrinfo(servername, serverport, &hints, &ai))) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(i)); + return 1; + } + if ((listenfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) { + fprintf(stderr, "tsocket: %s\n", strerror(errno)); + return 1; + } + if (bind(listenfd, ai->ai_addr, ai->ai_addrlen) == -1) { + fprintf(stderr, "bind: %s\n", strerror(errno)); + return 1; + } + if (listen(listenfd, SOMAXCONN) == -1) { + fprintf(stderr, "listen: %s\n", strerror(errno)); + return 1; + } + + rlim.rlim_cur = rlim.rlim_max = maxnprocs; + if (setrlimit(RLIMIT_NPROC, &rlim) < 0) { + fprintf(stderr, "setrlimit RLIMIT_NPROC: %s\n", strerror(errno)); + return 1; + } + + while (running) { + salen = sizeof(sa); + if ((reqfd = accept(listenfd, &sa, &salen)) < 0) { + fprintf(stderr, "accept: %s\n", strerror(errno)); + continue; + } + + pid = fork(); + + if (pid < 0) { + fprintf(stderr, "fork: %s\n", strerror(errno)); + /* error-message? */ + continue; + } else if (pid == 0) { + close(listenfd); + + /* close socket after timeout */ + tv.tv_sec = 30; + tv.tv_usec = 0; + if (setsockopt(reqfd, SOL_SOCKET, SO_RCVTIMEO, + &tv, sizeof(tv)) < 0) { + fprintf(stderr, "error\tsetsockopt SO_RCVTIMEO" + "failed: %s\n", strerror(errno)); + } + + write(reqfd, response, sizeof(response) - 1); + + shutdown(reqfd, SHUT_RD); + shutdown(reqfd, SHUT_WR); + close(reqfd); + printf("request:\n"); + exit(0); + } else { + close(reqfd); + } + } + + close(listenfd); + freeaddrinfo(ai); + + return 0; +}