-
Notifications
You must be signed in to change notification settings - Fork 0
/
echoaddr.c
75 lines (57 loc) · 1.75 KB
/
echoaddr.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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/*
CGI standard compliant program to return the client address and current local time.
Can be used with any CGI-enabled httpd to setup a lightweight MyIP service.
*/
/* Handle general errors as Status 500 */
void internal_server_error() {
printf("Status: 500 Internal Server Error\r\n");
exit(5);
}
/* RFC 3875 section 6.1 requires to check for accepted request methods. */
void allow_get_request() {
const char *method = getenv("REQUEST_METHOD");
if (method == NULL) {
internal_server_error();
}
if (strcmp(method, "GET") != 0) {
printf(
"Status: 405 Method Not Allowed\r\n"
"Allow: GET\r\n"
);
exit(4);
}
}
/* Get current local time in RFC 2822 format. */
void get_current_time(char *timebuf, size_t bufsize) {
const time_t current_time = time(NULL);
const struct tm *timeinfo = localtime(¤t_time);
if (timeinfo == NULL) {
internal_server_error();
}
if (strftime(timebuf, bufsize, "%a, %d %b %Y %T %z", timeinfo) == 0) {
internal_server_error();
}
}
int main() {
allow_get_request();
/* get server time */
char timebuf[64];
get_current_time(timebuf, sizeof(timebuf));
/* get client address */
const char *remote_addr = getenv("REMOTE_ADDR");
if (remote_addr == NULL) {
internal_server_error();
}
printf(
/* "Status: 200 OK\r\n" -> default by CGI */
/* "Cache-Control: no-store\r\n" -> should be set by the httpd */
"Content-Type: text/plain; charset=utf-8\r\n"
"\r\n"
"Local time: %s\r\n"
"Remote address: %s\r\n",
timebuf, remote_addr);
}