commit 8826009e9807a15f96ede86b1355106f56e4155f
parent 6e62158577100f0e2f7715a75e30e5a38b66284e
Author: FRIGN <dev@frign.de>
Date: Sat, 5 Dec 2015 23:08:16 +0100
Remove readline() and rather use fdopen+getline()
Drops a lot of LOC and boilerplate, even though readline() worked just
fine.
However, I was feeling bad about the 1-byte-reads, which are obviously
better handled in the libc-implementations.
Diffstat:
M | config.h | | | 7 | ++++--- |
M | higgs.c | | | 67 | +++++++++++++++---------------------------------------------------- |
2 files changed, 19 insertions(+), 55 deletions(-)
diff --git a/config.h b/config.h
@@ -1,5 +1,6 @@
/* higgs settings */
static const char *servername = "127.0.0.1";
-static const char *serverport = "8081";
-static const int maxnprocs = 512;
-static const int timeout = 2000; /* in ms */
+static const char *serverport = "8080";
+
+static const int maxnprocs = 512;
+static const struct timeval timeout = { 30, 0 };
diff --git a/higgs.c b/higgs.c
@@ -16,64 +16,16 @@
#include "config.h"
-int
-readline(char **buf, size_t *buflen, int fd)
-{
- /* todo: properly return I/O and internal errors differently, so it's
- * possible to give a 500-error when we have a malloc-problem
- * but a timeout error when the user timed out */
- struct pollfd pollit = { .fd = fd, .events = POLLIN | POLLPRI };
- size_t off = 0;
- int ret;
- char c;
-
- if (!*buf) {
- if (!(*buf = malloc(BUFSIZ)))
- return -1;
- *buflen = BUFSIZ;
- }
-again:
- switch (ret = poll(&pollit, 1, timeout)) {
- case 0: /* timeout */
- return -1;
- case -1: /* error */
- return -1;
- default: /* state change */
- if (!(pollit.revents & (POLLIN | POLLPRI)))
- return -1;
-
- while (read(fd, &c, 1) == 1) {
- if (c == '\n')
- goto end;
- if (c == '\r')
- continue;
- (*buf)[off] = c;
- off++;
- if (off >= *buflen) {
- if (!(*buf = realloc(*buf, *buflen + BUFSIZ)))
- return -1;
- *buflen += BUFSIZ;
- }
- }
-
- if (errno == EAGAIN || errno == EWOULDBLOCK)
- goto again;
- return -1;
- }
-end:
- (*buf)[off] = '\0';
- return off;
-}
-
void
handle(int fd)
{
+ FILE *fp;
size_t buflen = 0;
char *buf = NULL, *p, *url;
readline:
/* check "METHOD URL HTTP-VERSION" */
- if (readline(&buf, &buflen, fd) < 0)
+ if (!(fp = fdopen(fd, "r")) || getline(&buf, &buflen, fp) < 0)
goto servererr;
if (strncmp(buf, "GET ", 4))
goto clienterr;
@@ -84,7 +36,10 @@ readline:
if (strncmp(p + 1, "HTTP/", 5))
goto clienterr;
- printf("200 |%s|\n", url);
+ /* read other headers and pick those we care about */
+ while (getline(&buf, &buflen, fp) >= 0 && strcmp(buf, "\r\n")) {
+ printf("%s", buf);
+ }
return;
servererr:
/* 500 internal server error */
@@ -102,7 +57,6 @@ 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;
@@ -156,7 +110,16 @@ main()
continue;
} else if (pid == 0) {
close(listenfd);
+
+ /* close socket after timeout */
+ if (setsockopt(reqfd, SOL_SOCKET, SO_RCVTIMEO,
+ &timeout, sizeof(timeout)) < 0) {
+ fprintf(stderr, "error\tsetsockopt SO_RCVTIMEO"
+ "failed: %s\n", strerror(errno));
+ }
+
handle(reqfd);
+
shutdown(reqfd, SHUT_RD);
shutdown(reqfd, SHUT_WR);
close(reqfd);