Add logmsg() and refactor connection handling

Also use compound literals for immediate pointers we don't use later
(same as with setsockopt() in 32223c96bd).

Signed-off-by: Laslo Hunhold <dev@frign.de>
This commit is contained in:
Laslo Hunhold 2020-08-29 13:02:51 +02:00
parent a36b901d40
commit 0823ba4c3e
No known key found for this signature in database
GPG key ID: 69576BD24CFCB980
2 changed files with 45 additions and 36 deletions

2
http.h
View file

@ -3,6 +3,7 @@
#define HTTP_H #define HTTP_H
#include <limits.h> #include <limits.h>
#include <sys/socket.h>
#include "util.h" #include "util.h"
@ -95,6 +96,7 @@ enum conn_state {
struct connection { struct connection {
enum conn_state state; enum conn_state state;
int fd; int fd;
struct sockaddr_storage ia;
char header[HEADER_MAX]; /* general req/res-header buffer */ char header[HEADER_MAX]; /* general req/res-header buffer */
size_t off; /* general offset (header/file/dir) */ size_t off; /* general offset (header/file/dir) */
struct request req; struct request req;

79
main.c
View file

@ -24,49 +24,57 @@
static char *udsname; static char *udsname;
static void static void
serve(int infd, const struct sockaddr_storage *in_sa, const struct server *srv) logmsg(const struct connection *c)
{ {
struct connection c = { .fd = infd }; char inaddr_str[INET6_ADDRSTRLEN /* > INET_ADDRSTRLEN */];
time_t t;
enum status s;
char inaddr[INET6_ADDRSTRLEN /* > INET_ADDRSTRLEN */];
char tstmp[21]; char tstmp[21];
/* create timestamp */
if (!strftime(tstmp, sizeof(tstmp), "%Y-%m-%dT%H:%M:%SZ",
gmtime(&(time_t){time(NULL)}))) {
warn("strftime: Exceeded buffer capacity");
/* continue anyway (we accept the truncation) */
}
/* generate address-string */
if (sock_get_inaddr_str(&c->ia, inaddr_str, LEN(inaddr_str))) {
warn("sock_get_inaddr_str: Couldn't generate adress-string");
inaddr_str[0] = '\0';
}
printf("%s\t%s\t%d\t%s\t%s\n", tstmp, inaddr_str, c->res.status,
c->req.field[REQ_HOST], c->req.uri);
}
static void
serve(struct connection *c, const struct server *srv)
{
enum status s;
/* set connection timeout */ /* set connection timeout */
if (sock_set_timeout(c.fd, 30)) { if (sock_set_timeout(c->fd, 30)) {
goto cleanup; goto cleanup;
} }
/* handle request */ /* handle request */
if ((s = http_recv_header(c.fd, c.header, LEN(c.header), &c.off)) || if ((s = http_recv_header(c->fd, c->header, LEN(c->header), &c->off)) ||
(s = http_parse_header(c.header, &c.req))) { (s = http_parse_header(c->header, &c->req))) {
http_prepare_error_response(&c.req, &c.res, s); http_prepare_error_response(&c->req, &c->res, s);
} else { } else {
http_prepare_response(&c.req, &c.res, srv); http_prepare_response(&c->req, &c->res, srv);
} }
if ((s = http_send_header(c.fd, &c.res)) || if ((s = http_send_header(c->fd, &c->res)) ||
(s = http_send_body(c.fd, &c.res, &c.req))) { (s = http_send_body(c->fd, &c->res, &c->req))) {
c.res.status = s; c->res.status = s;
} }
/* write output to log */ logmsg(c);
t = time(NULL);
if (!strftime(tstmp, sizeof(tstmp), "%Y-%m-%dT%H:%M:%SZ",
gmtime(&t))) {
warn("strftime: Exceeded buffer capacity");
goto cleanup;
}
if (sock_get_inaddr_str(in_sa, inaddr, LEN(inaddr))) {
goto cleanup;
}
printf("%s\t%s\t%d\t%s\t%s\n", tstmp, inaddr, c.res.status,
c.req.field[REQ_HOST], c.req.uri);
cleanup: cleanup:
/* clean up and finish */ /* clean up and finish */
shutdown(c.fd, SHUT_RD); shutdown(c->fd, SHUT_RD);
shutdown(c.fd, SHUT_WR); shutdown(c->fd, SHUT_WR);
close(c.fd); close(c->fd);
} }
static void static void
@ -189,10 +197,8 @@ main(int argc, char *argv[])
struct server srv = { struct server srv = {
.docindex = "index.html", .docindex = "index.html",
}; };
struct sockaddr_storage in_sa;
size_t i; size_t i;
socklen_t in_sa_len; int insock, status = 0;
int insock, status = 0, infd;
const char *err; const char *err;
char *tok[4]; char *tok[4];
@ -367,9 +373,10 @@ main(int argc, char *argv[])
/* accept incoming connections */ /* accept incoming connections */
while (1) { while (1) {
in_sa_len = sizeof(in_sa); struct connection c = { 0 };
if ((infd = accept(insock, (struct sockaddr *)&in_sa,
&in_sa_len)) < 0) { if ((c.fd = accept(insock, (struct sockaddr *)&c.ia,
&(socklen_t){sizeof(c.ia)})) < 0) {
warn("accept:"); warn("accept:");
continue; continue;
} }
@ -377,7 +384,7 @@ main(int argc, char *argv[])
/* fork and handle */ /* fork and handle */
switch (fork()) { switch (fork()) {
case 0: case 0:
serve(infd, &in_sa, &srv); serve(&c, &srv);
exit(0); exit(0);
break; break;
case -1: case -1:
@ -385,7 +392,7 @@ main(int argc, char *argv[])
/* fallthrough */ /* fallthrough */
default: default:
/* close the connection in the parent */ /* close the connection in the parent */
close(infd); close(c.fd);
} }
} }
exit(0); exit(0);