-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhttpd.c
78 lines (64 loc) · 1.88 KB
/
httpd.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
/* 2.11BSD httpd */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/errno.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <netdb.h>
#include <stdio.h>
#include <strings.h>
int main(argc, argv)
int argc;
char *argv[];
{
char line[1024];
int fd;
struct stat st;
char path[200];
char *ext;
int c;
char req_verb[5];
strncpy(path, "/var/www/", 200);
while (fgets(line, sizeof(line), stdin) != NULL) {
/* Detect the double line break to end req header */
if (strlen(line) < 5) break;
/* Get the path from the GET or POST request */
if (strstr(line, "GET ") == line ||
strstr(line, "POST ") == line)
sscanf(line, "%s %s", req_verb, &path[strlen(path)]);
}
/* Check for parent directories in path */
if (strstr(path, "..") != NULL)
exit(1);
/* Check that we are not going to dump an inode */
if (path[strlen(path)-1] == '/')
strcat(path, "/index.html");
/* Request information about the file, such as the size... */
stat(path, &st);
/* Open file, 404 if not found. */
fd = fopen(path, "r");
if (fd == NULL) {
printf("HTTP/1.1 404 Not Found\r\n");
printf("Content-Type: text/plain\r\n\r\n");
printf("File not found.\r\n");
exit(1);
}
printf("HTTP/1.1 200 OK\r\n");
/* Extract file type and output content-type header */
ext = rindex(path, '.');
if (!ext) ext = rindex(path, NULL);
if (!strcmp(ext, ".html"))
printf("Content-Type: text/html\r\n");
else if (!strcmp(ext, ".jpg"))
printf("Content-Type: image/jpeg\r\n");
else
printf("Content-Type: text/plain\r\n");
printf("Content-Length: %ld\r\n", st.st_size);
printf("\r\n");
while (feof(fd) == 0 && (c = fgetc(fd)) != -1)
fputc(c, stdout);
fclose(fd);
return 0;
}