Line data Source code
1 : /*
2 : START OF LICENSE STUB
3 : DeDOS: Declarative Dispersion-Oriented Software
4 : Copyright (C) 2017 University of Pennsylvania, Georgetown University
5 :
6 : This program is free software: you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation, either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : END OF LICENSE STUB
19 : */
20 : #include "logging.h"
21 :
22 : #include "webserver/httpops.h"
23 :
24 : #define BASE_HTTP_HEADER\
25 : "HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %d\r\n\r\n"
26 :
27 : #define NOT_FOUND_HEADER\
28 : "HTTP/1.1 404 Not Found\r\n\r\n"
29 :
30 : #define NOT_IMPLEMENTED_HEADER\
31 : "HTTP/1.1 501 Not Implemented\r\n\r\n"
32 :
33 : #define DEFAULT_MIME_TYPE\
34 : "text/html"
35 :
36 119 : char *path_to_mimetype(char *path) {
37 119 : char *extension = path;
38 119 : for (; *extension != '.' && *extension != '\0'; extension++);
39 :
40 119 : if (*extension == '\0')
41 0 : return DEFAULT_MIME_TYPE;
42 :
43 119 : extension++; // Advance past the dot
44 :
45 : // TODO: Necessary to replace this by loading /etc/mime.types into hashmap?
46 238 : if (strcasecmp(extension, "html") == 0 ||
47 238 : strcasecmp(extension, "htm") == 0 ||
48 119 : strcasecmp(extension, "txt") == 0) {
49 0 : return "text/html";
50 119 : } else if (strcasecmp(extension, "png") == 0) {
51 0 : return "image/png";
52 238 : } else if (strcasecmp(extension, "jpg") == 0 ||
53 119 : strcasecmp(extension, "jpeg") == 0) {
54 0 : return "image/jpeg";
55 119 : } else if (strcasecmp(extension, "gif") == 0) {
56 0 : return "image/gif";
57 : }
58 :
59 119 : return DEFAULT_MIME_TYPE;
60 : }
61 :
62 134 : int url_to_path(char *url, char *dir, char *path, int capacity) {
63 134 : int len = 0;
64 134 : for (char *c = url; *c != '\0' && *c != '?'; c++, len++);
65 :
66 134 : int dir_len = strlen(dir);
67 134 : int dir_slash = (dir[dir_len - 1] == '/');
68 134 : int url_slash = (url[0] == '/');
69 134 : dir_len -= (dir_slash && url_slash);
70 134 : int both_missing_slash = (!dir_slash && !url_slash);
71 :
72 134 : if (dir_len + len + both_missing_slash >= capacity) {
73 0 : log_error("Path from url (%s) too large for buffer (%d)", url, capacity);
74 0 : return -1;
75 : }
76 :
77 134 : char *dest = path;
78 :
79 134 : strncpy(dest, dir, dir_len);
80 134 : if (both_missing_slash) {
81 0 : dest[dir_len] = '/';
82 : }
83 134 : strncpy(&dest[dir_len + both_missing_slash], url, len);
84 134 : dest[dir_len + both_missing_slash + len] = '\0';
85 134 : return dir_len + len;
86 : }
87 :
88 120 : int generate_header(char *dest, int code, int capacity, int body_len, char *mime_type) {
89 120 : if (code == 200) {
90 120 : return snprintf(dest, capacity, BASE_HTTP_HEADER, mime_type, body_len);
91 0 : } else if (code == 404) {
92 0 : return snprintf(dest, capacity, NOT_FOUND_HEADER);
93 : } else {
94 0 : return snprintf(dest, capacity, NOT_IMPLEMENTED_HEADER);
95 : }
96 : }
|