-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathaccess_log.c
94 lines (76 loc) · 2.57 KB
/
access_log.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/* access logging writes timestamped info after connection finishes */
#include "access_log.h"
#define ACCESS_LOG_BUF_SIZE 1024
void
log_connection(FILE *access_log_file, struct client_connection *con) {
char buf[ACCESS_LOG_BUF_SIZE];
int len = 0; /* len of chars written */
char *empty_field = "-"; /* filler where no con state for field */
char *method;
int log_response_code = 404; /* default resp code 404 */
void *addr; /* socket addr, ipv6 or ipv4 */
long response_bytes_size;
/* zero out buf to start */
memset(buf, 0, ACCESS_LOG_BUF_SIZE);
/* get string of method name */
switch(con->parser.method) {
case HTTP_GET:
method = "GET";
break;
case HTTP_HEAD:
method = "HEAD";
break;
default:
method = empty_field;
}
/* unpack ip address (could be ipv6 or ipv4) */
addr = &((struct sockaddr_in*)(&con->client_addr))->sin_addr;
/* write ip address */
if(inet_ntop(con->client_addr.ss_family, addr, buf + len,
sizeof(struct sockaddr_storage)) == NULL) {
err(1, "ip address conversion failed during logging");
}
/* since ip address length is variable, jump forward until we get back
* at the end of the string */
while(buf[len] != '\0') {
len++;
}
/* write space and open bracket */
len += snprintf(buf + len, ACCESS_LOG_BUF_SIZE - len, " [");
/* write timestamp */
len += write_rfc1123_date(buf + len, time(NULL),
ACCESS_LOG_BUF_SIZE - len);
/* write close bracket, method name, space */
len += snprintf(buf + len, ACCESS_LOG_BUF_SIZE - len, "] \"%s ",
method);
/* write URL, or if no URL use default */
if(con->url == NULL) {
/* no URL parsed */
len += snprintf(buf + len, ACCESS_LOG_BUF_SIZE - len, "%s",
empty_field);
} else {
memcpy(buf + len, con->url, con->url_length);
len += con->url_length;
}
/* write close quote, response code. default response code 404 for
* connections where response was not generated */
if(con->resp_code == RESPONSE_CODE_UNINITIALISED) {
log_response_code = 404;
} else {
log_response_code = con->resp_code;
}
/* response size is 0 if not a 200 OK */
if(con->resp_code != RESPONSE_CODE_OK) {
response_bytes_size = 0;
} else {
response_bytes_size = con->file_size;
}
len += snprintf(buf + len, ACCESS_LOG_BUF_SIZE - len, "\" %d %ld\n",
log_response_code, response_bytes_size);
/* terminate string and write log line */
buf[len] = '\0';
if(fputs(buf, access_log_file) == EOF) {
err(1, "error writing access log line");
}
fflush(access_log_file); /* flush just in case */
}