- Timestamp:
- Sep 14, 2024, 6:59:15 PM (2 months ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Common/cm_string.h
r16 r20 6 6 #include <stdbool.h> 7 7 8 int cm_hex(const char* str, int len); 9 char* cm_html_escape(const char* str); 8 10 char* cm_strcat(const char* a, const char* b); 9 11 char* cm_strcat3(const char* a, const char* b, const char* c); -
trunk/Common/string.c
r16 r20 4 4 #include <stdlib.h> 5 5 #include <stdbool.h> 6 #include <stdio.h> 6 7 #include <ctype.h> 7 8 … … 113 114 return true; 114 115 } 116 117 int cm_hex(const char* str, int len) { 118 int n = 0; 119 int i; 120 for(i = 0; i < len; i++) { 121 char c = str[i]; 122 n *= 16; 123 if('0' <= c && c <= '9') { 124 n += c - '0'; 125 } else if('a' <= c && c <= 'f') { 126 n += c - 'a' + 10; 127 } else if('A' <= c && c <= 'F') { 128 n += c - 'A' + 10; 129 } 130 } 131 return n; 132 } 133 134 char* cm_html_escape(const char* str) { 135 int i; 136 char* result = malloc(1); 137 result[0] = 0; 138 char cbuf[2]; 139 cbuf[1] = 0; 140 for(i = 0; str[i] != 0; i++) { 141 cbuf[0] = str[i]; 142 if(str[i] == '&') { 143 char* tmp = result; 144 result = cm_strcat(tmp, "&"); 145 free(tmp); 146 } else if(str[i] == '<') { 147 char* tmp = result; 148 result = cm_strcat(tmp, "<"); 149 free(tmp); 150 } else if(str[i] == '>') { 151 char* tmp = result; 152 result = cm_strcat(tmp, ">"); 153 free(tmp); 154 } else { 155 char* tmp = result; 156 result = cm_strcat(tmp, cbuf); 157 free(tmp); 158 } 159 } 160 return result; 161 } -
trunk/Module/mod_example.c
r18 r20 8 8 return 0; 9 9 } 10 11 int mod_request(struct tw_tool* tools, struct tw_http_request* req, struct tw_http_response* res) { return TW_MODULE_ERROR(403); } -
trunk/Server/config.c
r19 r20 11 11 #include <string.h> 12 12 #include <unistd.h> 13 14 #ifdef __MINGW32__ 15 #include <winsock2.h> 16 #endif 13 17 14 18 #include <cm_string.h> -
trunk/Server/http.c
r17 r20 23 23 if(req->method != NULL) free(req->method); 24 24 if(req->path != NULL) free(req->path); 25 if(req->query != NULL) free(req->query); 25 26 if(req->headers != NULL) { 26 27 int i; … … 44 45 req->method = NULL; 45 46 req->path = NULL; 47 req->query = NULL; 46 48 req->headers = NULL; 47 49 req->body = NULL; … … 246 248 return 1; 247 249 } 250 char* result = malloc(1); 251 result[0] = 0; 252 int i; 253 for(i = 0; req->path[i] != 0; i++) { 254 if(req->path[i] == '?') { 255 req->path[i] = 0; 256 req->query = cm_strdup(req->path + i + 1); 257 break; 258 } 259 } 260 for(i = 0; req->path[i] != 0; i++) { 261 if(req->path[i] == '%') { 262 if(req->path[i + 1] == 0) continue; 263 cbuf[0] = cm_hex(req->path + i + 1, 2); 264 char* tmp = result; 265 result = cm_strcat(tmp, cbuf); 266 free(tmp); 267 i += 2; 268 } else { 269 cbuf[0] = req->path[i]; 270 char* tmp = result; 271 result = cm_strcat(tmp, cbuf); 272 free(tmp); 273 } 274 } 275 free(req->path); 276 req->path = result; 248 277 return 0; 249 278 } -
trunk/Server/main.c
r18 r20 56 56 } 57 57 sprintf(tw_server, "Tewi/%s (%s)%s", tw_get_version(), tw_get_platform(), config.extension == NULL ? "" : config.extension); 58 cm_log("Daemon", "Ready ");58 cm_log("Daemon", "Ready, server: %s", tw_server); 59 59 #ifndef __MINGW32__ 60 60 signal(SIGCHLD, SIG_IGN); -
trunk/Server/server.c
r19 r20 14 14 #include <string.h> 15 15 #include <stdbool.h> 16 #include <stdarg.h> 16 17 17 18 #include <cm_string.h> … … 136 137 } 137 138 138 #define ERROR_ 400\139 #define ERROR_HTML \ 139 140 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \ 140 141 "<html>\n" \ 141 142 " <head>\n" \ 142 " <title> 400 Bad Request</title>" \143 " <title>%s</title>\n" \ 143 144 " </head>\n" \ 144 145 " <body>\n" \ 145 " <h1> Bad Request</h1>\n" \146 " <h1>%s</h1>\n" \ 146 147 " <hr>\n" \ 147 148 " ", \ … … 151 152 "</html>\n" 152 153 153 #define ERROR_401 \154 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \155 "<html>\n" \156 " <head>\n" \157 " <title>401 Unauthorized</title>" \158 " </head>\n" \159 " <body>\n" \160 " <h1>Unauthorized</h1>\n" \161 " <hr>\n" \162 " ", \163 address, \164 "\n" \165 " </body>\n" \166 "</html>\n"167 168 #define ERROR_403 \169 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \170 "<html>\n" \171 " <head>\n" \172 " <title>403 Forbidden</title>" \173 " </head>\n" \174 " <body>\n" \175 " <h1>Forbidden</h1>\n" \176 " <hr>\n" \177 " ", \178 address, \179 "\n" \180 " </body>\n" \181 "</html>\n"182 183 #define ERROR_404 \184 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \185 "<html>\n" \186 " <head>\n" \187 " <title>404 Not Found</title>" \188 " </head>\n" \189 " <body>\n" \190 " <h1>Not Found</h1>\n" \191 " <hr>\n" \192 " ", \193 address, \194 "\n" \195 " </body>\n" \196 "</html>\n"197 198 154 void tw_process_page(SSL* ssl, int sock, const char* status, const char* type, const unsigned char* doc, size_t size) { 199 155 char construct[512]; … … 222 178 223 179 const char* tw_http_status(int code) { 224 if(code == 400) { 180 if(code == 200) { 181 return "200 OK"; 182 } else if(code == 400) { 225 183 return "400 Bad Request"; 184 } else if(code == 401) { 185 return "401 Unauthorized"; 186 } else if(code == 403) { 187 return "403 Forbidden"; 188 } else if(code == 404) { 189 return "404 Not Found"; 226 190 } else { 227 191 return "400 Bad Request"; … … 232 196 char address[1024]; 233 197 sprintf(address, "<address>%s Server at %s Port %d</address>", tw_server, name, port); 234 if(code == 400) { 235 return cm_strcat3(ERROR_400); 236 } else { 237 return cm_strcat3(ERROR_400); 238 } 198 199 char* st = cm_strdup(tw_http_status(code)); 200 char* st2; 201 int i; 202 for(i = 0; st[i] != 0; i++) { 203 if(st[i] == ' ') { 204 st2 = cm_strdup(st + i + 1); 205 break; 206 } 207 } 208 char* buffer = malloc(4096); 209 char* str = cm_strcat3(ERROR_HTML); 210 sprintf(buffer, str, st, st2); 211 free(str); 212 free(st); 213 return buffer; 239 214 } 240 215 … … 243 218 tw_process_page(ssl, sock, tw_http_status(error), "text/html", str, strlen(str)); 244 219 free(str); 220 } 221 222 void addstring(char** str, const char* add, ...) { 223 int i; 224 char cbuf[2]; 225 cbuf[1] = 0; 226 va_list va; 227 va_start(va, add); 228 for(i = 0; add[i] != 0; i++) { 229 cbuf[0] = add[i]; 230 if(add[i] == '%') { 231 i++; 232 if(add[i] == 's') { 233 char* tmp = *str; 234 *str = cm_strcat(tmp, va_arg(va, const char*)); 235 free(tmp); 236 } else if(add[i] == 'h') { 237 char* h = cm_html_escape(va_arg(va, const char*)); 238 char* tmp = *str; 239 *str = cm_strcat(tmp, h); 240 free(tmp); 241 free(h); 242 } else if(add[i] == 'd') { 243 int n = va_arg(va, int); 244 char* h = malloc(512); 245 sprintf(h, "%d", n); 246 char* tmp = *str; 247 *str = cm_strcat(tmp, h); 248 free(tmp); 249 free(h); 250 } else if(add[i] == '%') { 251 char* tmp = *str; 252 *str = cm_strcat(tmp, "%"); 253 free(tmp); 254 } 255 } else { 256 char* tmp = *str; 257 *str = cm_strcat(tmp, cbuf); 258 free(tmp); 259 } 260 } 245 261 } 246 262 … … 273 289 } 274 290 struct tw_http_request req; 291 struct tw_http_response res; 292 struct tw_tool tools; 293 res._processed = false; 294 tw_init_tools(&tools); 275 295 int ret = tw_http_parse(s, sock, &req); 276 296 if(ret == 0) { 297 int i; 298 for(i = 0; i < config.module_count; i++) { 299 tw_mod_request_t mod_req = (tw_mod_request_t)tw_module_symbol(config.modules[i], "mod_request"); 300 if(mod_req != NULL) { 301 int ret = mod_req(&tools, &req, &res); 302 int co = ret & 0xff; 303 if(co == _TW_MODULE_PASS) continue; 304 if(co == _TW_MODULE_STOP) { 305 res._processed = true; 306 break; 307 } 308 if(co == _TW_MODULE_ERROR) { 309 tw_http_error(s, sock, (ret & 0xffff00) >> 8, name, port); 310 break; 311 } 312 } 313 } 314 if(!res._processed) { 315 char* str = malloc(1); 316 str[0] = 0; 317 addstring(&str, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"); 318 addstring(&str, "<html>\n"); 319 addstring(&str, " <head>\n"); 320 addstring(&str, " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"); 321 addstring(&str, " <title>Index of %h</title>\n", req.path); 322 addstring(&str, " </head>\n"); 323 addstring(&str, " <body>\n"); 324 addstring(&str, " <h1>Index of %h</h1>\n", req.path); 325 addstring(&str, " <hr>\n"); 326 addstring(&str, " <table border=\"0\">\n"); 327 addstring(&str, " <tr>\n"); 328 addstring(&str, " <th></th>\n"); 329 addstring(&str, " <th>Filename</th>\n"); 330 addstring(&str, " </tr>\n"); 331 addstring(&str, " </table>\n"); 332 addstring(&str, " <hr>\n"); 333 addstring(&str, " <address>%s Server at %s Port %d</address>\n", tw_server, name, port); 334 addstring(&str, " </body>\n"); 335 addstring(&str, "</html>\n"); 336 tw_process_page(s, sock, tw_http_status(200), "text/html", str, strlen(str)); 337 free(str); 338 } 277 339 } else { 278 340 tw_http_error(s, sock, 400, name, port); -
trunk/Server/ssl.c
r19 r20 29 29 SSL_use_PrivateKey_file(ssl, config.root.sslkey, SSL_FILETYPE_PEM); 30 30 SSL_use_certificate_file(ssl, config.root.sslcert, SSL_FILETYPE_PEM); 31 return 1; 31 32 } else { 32 33 return 0; -
trunk/Server/tw_http.h
r17 r20 4 4 #define __TW_HTTP_H__ 5 5 6 #include <stdbool.h> 7 6 8 struct tw_http_request { 7 9 char* method; 8 10 char* path; 11 char* query; 9 12 char* version; 10 13 char** headers; … … 14 17 struct tw_http_response { 15 18 char** headers; 19 int status; 20 bool _processed; /* Internal parameter */ 16 21 }; 17 22 -
trunk/Server/tw_module.h
r18 r20 13 13 14 14 enum TW_MODULE_RETURN { 15 TW_MODULE_PASS = 0, /* Pass to the next module. */16 TW_MODULE_STOP,/* Do not pass to the next module. */17 TW_MODULE_ERROR/* Error, and do not pass to the next module. */15 _TW_MODULE_PASS = 0, /* Pass to the next module. */ 16 _TW_MODULE_STOP, /* Do not pass to the next module. */ 17 _TW_MODULE_ERROR /* Error, and do not pass to the next module. */ 18 18 }; 19 20 #define TW_MODULE_PASS _TW_MODULE_PASS 21 #define TW_MODULE_STOP _TW_MODULE_STOP 22 #define TW_MODULE_ERROR(x) (_TW_MODULE_ERROR | ((x) << 8)) 19 23 20 24 typedef int (*tw_mod_init_t)(struct tw_config* config, struct tw_tool* tools); -
trunk/example.conf
r19 r20 2 2 # This is an example config 3 3 4 LoadModule /home/nishi/SVN/tewi/trunk/Module/mod_example.so4 #LoadModule /home/nishi/SVN/tewi/trunk/Module/mod_example.so 5 5 6 6 Listen 8000 8001 8002 8003 8004
Note:
See TracChangeset
for help on using the changeset viewer.