code not working
[webserver.git] / http.c
CommitLineData
d0b0d52b
ML
1#include <malloc.h>
2#include <string.h>
3
4#include "debug.h"
5
6#include "http.h"
7
bb0468a5
LM
8#define HTTP_VERSION "HTTP/1.0"
9#define SERVER_NAME "Webserver/0.0.1"
10
11char **codes = {
12 "200 OK",
13 "201 Created",
14 "202 Accepted",
15 "204 No Content",
16 "301 Moved Permanently",
17 "302 Moved Temporarily",
18 "304 Not Modified",
19 "400 Bad Request",
20 "401 Unauthorized",
21 "403 Forbidden",
22 "404 Not Found",
23 "500 Internal Server Error",
24 "501 Not Implemented",
25 "502 Bad Gateway",
26 "503 Service Unavailable"};
27
28typedef enum {
29 c200 = 0, c201, c202, c204,
30 c301, c302, c304, c400,
31 c401, c403, c404, c500,
32 c501, c502, c503
33} code_t;
34
35typedef enum {
36 not_supported_e = 0, get_e, head_e, post_e
37} method_t;
38
39typedef struct {
40 char *allow;
41 char *authorization;
42 char *content_encoding;
43 char *content_length;
44 char *content_type;
45 char *date;
46 char *expires;
47 char *from;
48 char *if_modified_since;
49 char *last_modified;
50 char *location;
51 char *pragma;
52 char *referer;
53 char *server;
54 char *user_agent;
55 char *www_authenticate;
56} header_t;
57
58/* print header values */
59
60void print_header_values (header_t *header)
61{
62 printf ("allow = '%s'\n", header->allow);
63 printf ("authorization = '%s'\n", header->authorization);
64 printf ("content_encoding = '%s'\n", header->content_encoding);
65 printf ("content_length = '%s'\n", header->content_length);
66 printf ("content_type = '%s'\n", header->content_type);
67 printf ("date = '%s'\n", header->date);
68 printf ("expires = '%s'\n", header->expires);
69 printf ("from = '%s'\n", header->from);
70 printf ("if_modified_since = '%s'\n", header->if_modified_since);
71 printf ("last_modified = '%s'\n", header->last_modified);
72 printf ("location = '%s'\n", header->location);
73 printf ("pragma = '%s'\n", header->pragma);
74 printf ("referer = '%s'\n", header->referer);
75 printf ("server = '%s'\n", header->server);
76 printf ("user_agent = '%s'\n", header->user_agent);
77 printf ("www_authenticate = '%s'\n", header->www_authenticate);
78}
79
80/* find sequence*/
81
82char *find_sequence (char *data, int len, char *seq, char **pdata)
83{
84
85 int size = strlen (seq);
86
87 int i;
88 for (i = 0; i < len - size + 1; i++) {
89 if (strncmp (data + i, seq, size) == 0) {
90 data[i] = 0;
91 if (pdata != NULL) {
92 *pdata = data + i + size;
93 }
94 return data;
95 }
96 }
97
98 return NULL;
99}
100
101/* response entity */
102
103int add_status_line (char **buffer, int len)
104{
d0b0d52b
ML
105 return len;
106}
107
bb0468a5
LM
108int add_general_header (char **buffer, int len)
109{
110 return len;
111}
112
113int add_response_header (char **buffer, int len)
114{
115 return len;
116}
117
118int add_entity (char **buffer, int len, unsigned char *entity, int size, char *type)
119{
120 return len;
121}
122
123/* error 400 */
124
125int error_400 (char **buffer)
126{
127
128}
129
130/* trim string */
131
132char *trim (char *str)
133{
134 if (str != NULL) {
135 while ((*str == ' ') || (*str == '\t')) {
136 str++;
137 }
138 }
139 return str;
140}
141
142/* main HTTP processing */
143
144int processing (char *data, int len, char **pdata)
145{
146 char *saved_data = data;
147 VERBOSE (DEBUG, PRINT ("Start processing\n"));
148
149 /* check method */
150 char *line = find_sequence (data, len, "\r\n", &data);
151 if (line == NULL) {
152 VERBOSE (WARNING, PRINT ("Unknown received data\n"));
153 if (pdata != NULL) {
154 *pdata = NULL;
155 }
156 return 0;
157 }
158 VERBOSE (DEBUG, PRINT ("Command line: '%s'\n", line));
159
160 char *method = strtok (line, " ");
161 char *uri = strtok (NULL, " ");
162 char *version = strtok (NULL, " ");
163 method_t type = not_supported_e;
164 if (strcmp (method, "GET") == 0) {
165 type = get_e;
166 } else if (strcmp ("HEAD", method) == 0) {
167 type = head_e;
168 } else if (strcmp ("POST", method) == 0) {
169 type = post_e;
170 } else {
171 VERBOSE (WARNING, PRINT ("Unkown method: %s\n", method));
172 } else {
173 free (saved_data);
174 return error_400 (pdata);
175 }
176 VERBOSE (INFO, PRINT ("%s %s (%s)\n", (type == get_e) ? "Get" : (type == head_e) ? "Head" : "Post", uri, version));
177
178 /* check header */
179 header_t header = {0};
180 while (strcmp (line = find_sequence (data, len, "\r\n", &data), "") != 0) {
181 VERBOSE (DEBUG, PRINT ("Header line: '%s'\n", line));
182 char *field = strtok (line, ":");
183 char *value = trim (strtok (NULL, "\r"));
184 VERBOSE (DEBUG, PRINT ("Field: %s\nValue: %s\n", field, value));
185 if (*line == 0) {
186 break;
187 }
188
189 VERBOSE (DEBUG, PRINT ("Analyse field\n"));
190 if (strcmp (field, "Allow") == 0) {
191 header.allow = value;
192 } else if (strcmp (field, "Authorization") == 0) {
193 header.authorization = value;
194 } else if (strcmp (field, "Content-Encoding") == 0) {
195 header.content_encoding = value;
196 } else if (strcmp (field, "Content-Length") == 0) {
197 header.content_length = value;
198 } else if (strcmp (field, "Content-Type") == 0) {
199 header.content_type = value;
200 } else if (strcmp (field, "Date") == 0) {
201 header.date = value;
202 } else if (strcmp (field, "Expires") == 0) {
203 header.expires = value;
204 } else if (strcmp (field, "From") == 0) {
205 header.from = value;
206 } else if (strcmp (field, "If-Modified-Since") == 0) {
207 header.if_modified_since = value;
208 } else if (strcmp (field, "Last-Modified") == 0) {
209 header.last_modified = value;
210 } else if (strcmp (field, "Location") == 0) {
211 header.location = value;
212 } else if (strcmp (field, "Pragma") == 0) {
213 header.pragma = value;
214 } else if (strcmp (field, "Referer") == 0) {
215 header.referer = value;
216 } else if (strcmp (field, "Server") == 0) {
217 header.server = value;
218 } else if (strcmp (field, "User-Agent") == 0) {
219 header.user_agent = value;
220 } else if (strcmp (field, "WWW-Authenticate") == 0) {
221 header.www_authenticate = value;
222 } else {
223 VERBOSE (WARNING, PRINT ("Unknown header field: '%s'\n", field));
224 }
225 }
226 VERBOSE (DEBUG, print_header_values (&header));
227
228 /* processing data */
229 if (data) {
230 VERBOSE (DEBUG, PRINT ("Processing data: %s\n", data));
231 }
232
233 /* cleaning */
234 free (saved_data);
235
236 /* response */
237 *pdata = strdup ("HTTP/1.0 200 OK\r\nDate: Sat, 20 May 2023 16:37:46 GMT\r\nServer: Webserver/0.0.1 (Debian)\r\nLocation: http://localhost/\r\nContent-Length: 77\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n<html><head><title>Test</title></head><body><p>This a test</p></body></html>");
238 return strlen (*pdata);
239}
240
d0b0d52b 241/* vim: set ts=4 sw=4 et: */