8 #define HTTP_VERSION "HTTP/1.0"
9 #define SERVER_NAME "Webserver/0.0.1"
16 "301 Moved Permanently",
17 "302 Moved Temporarily",
23 "500 Internal Server Error",
24 "501 Not Implemented",
26 "503 Service Unavailable"};
29 c200
= 0, c201
, c202
, c204
,
30 c301
, c302
, c304
, c400
,
31 c401
, c403
, c404
, c500
,
36 not_supported_e
= 0, get_e
, head_e
, post_e
42 char *content_encoding
;
48 char *if_modified_since
;
55 char *www_authenticate
;
58 /* print header values */
60 void print_header_values (header_t
*header
)
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
);
82 char *find_sequence (char *data
, int len
, char *seq
, char **pdata
)
85 int size
= strlen (seq
);
88 for (i
= 0; i
< len
- size
+ 1; i
++) {
89 if (strncmp (data
+ i
, seq
, size
) == 0) {
92 *pdata
= data
+ i
+ size
;
101 /* response entity */
103 int add_status_line (char **buffer
, int len
)
108 int add_general_header (char **buffer
, int len
)
113 int add_response_header (char **buffer
, int len
)
118 int add_entity (char **buffer
, int len
, unsigned char *entity
, int size
, char *type
)
125 int error_400 (char **buffer
)
132 char *trim (char *str
)
135 while ((*str
== ' ') || (*str
== '\t')) {
142 /* main HTTP processing */
144 int processing (char *data
, int len
, char **pdata
)
146 char *saved_data
= data
;
147 VERBOSE (DEBUG
, PRINT ("Start processing\n"));
150 char *line
= find_sequence (data
, len
, "\r\n", &data
);
152 VERBOSE (WARNING
, PRINT ("Unknown received data\n"));
158 VERBOSE (DEBUG
, PRINT ("Command line: '%s'\n", line
));
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) {
166 } else if (strcmp ("HEAD", method
) == 0) {
168 } else if (strcmp ("POST", method
) == 0) {
171 VERBOSE (WARNING
, PRINT ("Unkown method: %s\n", method
));
174 return error_400 (pdata
);
176 VERBOSE (INFO
, PRINT ("%s %s (%s)\n", (type
== get_e
) ? "Get" : (type
== head_e
) ? "Head" : "Post", uri
, version
));
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
));
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) {
202 } else if (strcmp (field
, "Expires") == 0) {
203 header
.expires
= value
;
204 } else if (strcmp (field
, "From") == 0) {
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
;
223 VERBOSE (WARNING
, PRINT ("Unknown header field: '%s'\n", field
));
226 VERBOSE (DEBUG
, print_header_values (&header
));
228 /* processing data */
230 VERBOSE (DEBUG
, PRINT ("Processing data: %s\n", data
));
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
);
241 /* vim: set ts=4 sw=4 et: */