diff --git a/README.md b/README.md index 374f84b..13b9d89 100644 --- a/README.md +++ b/README.md @@ -53,3 +53,9 @@ autoconf automake --add-missing make distcheck ``` + + +### To do +- variable size dictionary +- refactoring libantd API, remove unused functions +- remove static strings, replace it by configurations diff --git a/antd-config.ini b/antd-config.ini index 0de4146..817ad5b 100644 --- a/antd-config.ini +++ b/antd-config.ini @@ -25,7 +25,7 @@ ssl.enable=0 ; the SSL cert and key files ; ssl.cert=fullchain.pem ; ssl.key=privkey.pem - +; ssl.cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 ; This enable some plugins to be initialised at server startup [AUTOSTART] ; to start a plugin at server statup use: @@ -44,6 +44,33 @@ ssl.enable=0 ; ^([a-zA-Z][a-zA-Z0-9]*)\.[a-zA-Z0-9]+\..*$ = /<1>? ; Sytax: [regular expression on the original request]=[new request rule] +[MIMES] +image/bmp=bmp +image/jpeg=jpg,jpeg +text/css=css +text/markdown=md +text/csv=csv +application/pdf=pdf +image/gif=gif +text/html=html,htm,chtml +application/json=json +application/javascript=js +image/png=png +image/x-portable-pixmap=ppm +application/x-rar-compressed=rar +image/tiff=tiff +application/x-tar=tar +text/plain=txt +application/x-font-ttf=ttf +application/xhtml+xml=xhtml +application/xml=xml +application/zip=zip +image/svg+xml=svg +application/vnd.ms-fontobject=eot +application/x-font-woff=woff,woff2 +application/x-font-otf=otf +audio/mpeg=mp3,mpeg + [FILEHANDLER] ; specify a plugin for handling ; a file type diff --git a/dist/antd-1.0.4b.tar.gz b/dist/antd-1.0.4b.tar.gz index f9da7a4..6a890c7 100644 Binary files a/dist/antd-1.0.4b.tar.gz and b/dist/antd-1.0.4b.tar.gz differ diff --git a/http_server.c b/http_server.c index ba2b8a4..c74fb86 100644 --- a/http_server.c +++ b/http_server.c @@ -1,4 +1,26 @@ #include "http_server.h" + +//define all basic mime here +static mime_t _mimes[] = { + {"image/bmp","bmp"}, + {"image/jpeg","jpg,jpeg"}, + {"text/css","css"}, + {"text/markdown","md"}, + {"text/csv","csv"}, + {"application/pdf","pdf"}, + {"image/gif","gif"}, + {"text/html","html"}, + {"application/json","json"}, + {"application/javascript","js"}, + {"image/png","png"}, + {"text/plain","txt"}, + {"application/xhtml+xml","xhtml"}, + {"application/xml","xml"}, + {"image/svg+xml","svg"}, + {NULL,NULL} +}; + + static pthread_mutex_t server_mux = PTHREAD_MUTEX_INITIALIZER; config_t server_config; config_t *config() @@ -64,6 +86,8 @@ void destroy_config() free(server_config.htdocs); if (server_config.tmpdir) free(server_config.tmpdir); + if(server_config.ssl_cipher) + free(server_config.ssl_cipher); if(server_config.errorfp) { fclose(server_config.errorfp); @@ -74,6 +98,8 @@ void destroy_config() fclose(server_config.logfp); } #endif + if(server_config.mimes) + freedict(server_config.mimes); LOG("Unclosed connection: %d", server_config.connection); } @@ -141,6 +167,10 @@ static int config_handler(void *conf, const char *section, const char *name, { pconfig->sslkey = strdup(value); } + else if(MATCH("SERVER","ssl.cipher")) + { + pconfig->ssl_cipher = strdup(value); + } #endif else if (strcmp(section, "RULES") == 0) { @@ -157,6 +187,10 @@ static int config_handler(void *conf, const char *section, const char *name, // auto start plugin plugin_load((char *)value); } + else if(strcmp(section, "MIMES") == 0) + { + dput(pconfig->mimes,name,strdup(value)); + } else { return 0; /* unknown section/name, error */ @@ -193,11 +227,18 @@ void load_config(const char *file) server_config.handlers = dict(); server_config.maxcon = 1000; server_config.connection = 0; -#ifdef USE_OPENSSL + server_config.errorfp = NULL; + server_config.logfp = NULL; + server_config.mimes = dict(); server_config.usessl = 0; server_config.sslcert = "cert.pem"; server_config.sslkey = "key.pem"; -#endif + server_config.ssl_cipher = NULL; + // put it default mimes + for(int i = 0; _mimes[i].type != NULL; i++) + { + dput(server_config.mimes,_mimes[i].type, strdup(_mimes[i].ext)); + } if (ini_parse(file, config_handler, &server_config) < 0) { ERROR("Can't load '%s'. Used defaut configuration", file); @@ -209,9 +250,13 @@ void load_config(const char *file) LOG("SSL enable %d", server_config.usessl); LOG("SSL cert %s", server_config.sslcert); LOG("SSL key %s", server_config.sslkey); + if(!server_config.ssl_cipher) + LOG("SSL Cipher suite: %s", "HIGH"); + else + LOG("SSL Cipher suite: %s", server_config.ssl_cipher); #endif } - init_file_system(); + LOG("%d mimes entries found", server_config.mimes->size); } void *accept_request(void *data) @@ -238,7 +283,7 @@ void *accept_request(void *data) int sel = select(client->sock + 1, &read_flags, &write_flags, (fd_set *)0, &timeout); if (sel == -1) { - unknow(rq->client); + antd_error(rq->client, 400, "Bad request"); return task; } if (sel == 0 || (!FD_ISSET(client->sock, &read_flags) && !FD_ISSET(client->sock, &write_flags))) @@ -285,7 +330,7 @@ void *accept_request(void *data) ERROR("Error performing SSL handshake %d %d %lu", stat, ret, ERR_get_error()); //server_config.connection++; ERR_print_errors_fp(stderr); - unknow(rq->client); + antd_error(rq->client, 400, "Invalid SSL request"); return task; } } @@ -320,7 +365,7 @@ void *accept_request(void *data) if (!line) { LOG("No method found"); - unknow(rq->client); + antd_error(rq->client, 405, "No method found"); return task; } trim(token, ' '); @@ -331,7 +376,7 @@ void *accept_request(void *data) if (!line) { LOG("No request found"); - unknow(rq->client); + antd_error(rq->client, 400, "Bad request"); return task; } trim(token, ' '); @@ -388,7 +433,7 @@ void *resolve_request(void *data) strcat(path, "/index.html"); if (stat(path, &st) == -1) { - association it; + chain_t it; for_each_assoc(it, server_config.handlers) { newurl = __s("%s/index.%s", url, it->key); @@ -408,7 +453,7 @@ void *resolve_request(void *data) } if (!newurl) { - notfound(rq->client); + antd_error(rq->client, 404, "Resource Not Found"); return task; } //if(url) free(url); this is freed in the dput function @@ -439,7 +484,7 @@ void *resolve_request(void *data) return execute_plugin(rq, h); } else - unknow(rq->client); + antd_error(rq->client, 403, "Access forbidden"); } else { @@ -553,15 +598,21 @@ void *serve_file(void *data) int s = stat(path, &st); if(s == -1) { - notfound(rq->client); + antd_error(rq->client, 404, "File not found"); } else { int size = (int)st.st_size; - set_status(rq->client,200,"OK"); - __t(rq->client,"Content-Type: %s",mime_type); - __t(rq->client,"Content-Length: %d",size); - response(rq->client,""); + char ibuf[20]; + snprintf (ibuf, sizeof(ibuf), "%d",size); + antd_response_header_t rhd; + rhd.cookie = NULL; + rhd.status = 200; + rhd.header = dict(); + dput(rhd.header, "Content-Type", strdup(mime_type)); + dput(rhd.header, "Content-Length", strdup(ibuf)); + antd_send_header(rq->client, &rhd); + __f(rq->client, path); } @@ -637,15 +688,15 @@ char *apply_rules(const char *host, char *url) void *decode_request_header(void *data) { antd_request_t *rq = (antd_request_t *)data; - dictionary cookie = NULL; + dictionary_t cookie = NULL; char *line; char *token; char *query = NULL; char *host = NULL; char buf[2 * BUFFLEN]; char *url = (char *)dvalue(rq->request, "REQUEST_QUERY"); - dictionary xheader = dict(); - dictionary request = dict(); + dictionary_t xheader = dict(); + dictionary_t request = dict(); dput(rq->request, "REQUEST_HEADER", xheader); dput(rq->request, "REQUEST_DATA", request); // first real all header @@ -700,7 +751,7 @@ void *decode_request_header(void *data) void *decode_request(void *data) { antd_request_t *rq = (antd_request_t *)data; - dictionary headers = dvalue(rq->request, "REQUEST_HEADER"); + dictionary_t headers = dvalue(rq->request, "REQUEST_HEADER"); int ws = 0; char *ws_key = NULL; char *method = NULL; @@ -736,7 +787,7 @@ void *decode_request(void *data) } else { - unimplemented(rq->client); + antd_error(rq->client,501, "Request Method Not Implemented"); return task; } } @@ -744,8 +795,8 @@ void *decode_request(void *data) void *decode_post_request(void *data) { antd_request_t *rq = (antd_request_t *)data; - dictionary request = dvalue(rq->request, "REQUEST_DATA"); - dictionary headers = dvalue(rq->request, "REQUEST_HEADER"); + dictionary_t request = dvalue(rq->request, "REQUEST_DATA"); + dictionary_t headers = dvalue(rq->request, "REQUEST_HEADER"); char *ctype = NULL; int clen = -1; char *tmp; @@ -762,8 +813,7 @@ void *decode_post_request(void *data) return task; if (ctype == NULL || clen == -1) { - LOG("Bad request"); - badrequest(rq->client); + antd_error(rq->client, 400, "Bad Request, missing content description"); return task; } // decide what to do with the data @@ -787,8 +837,11 @@ void *decode_post_request(void *data) key++; else key = ctype; - dput(request, key, strdup(pquery)); - free(pquery); + if(pquery) + { + dput(request, key, strdup(pquery)); + free(pquery); + } } return task; } @@ -837,7 +890,7 @@ void ws_confirm_request(void *client, const char *key) * @param client The client socket * @return The Dictionary socket or NULL */ -dictionary decode_cookie(const char *line) +dictionary_t decode_cookie(const char *line) { char *token, *token1; char *cpstr = strdup(line); @@ -846,7 +899,7 @@ dictionary decode_cookie(const char *line) trim(cpstr, '\n'); trim(cpstr, '\r'); - dictionary dic = NULL; + dictionary_t dic = NULL; while ((token = strsep(&cpstr, ";"))) { trim(token, ' '); @@ -915,7 +968,7 @@ void *decode_multi_part_request_data(void *data) antd_task_t *task = antd_create_task(NULL, (void *)rq, NULL, rq->client->last_io); task->priority++; char *boundary = (char *)dvalue(rq->request, "MULTI_PART_BOUNDARY"); - dictionary dic = (dictionary)dvalue(rq->request, "REQUEST_DATA"); + dictionary_t dic = (dictionary_t)dvalue(rq->request, "REQUEST_DATA"); char *boundend = __s("%s--", boundary); // search for content disposition: while ((line = read_line(rq->client)) && @@ -1063,7 +1116,7 @@ void *decode_multi_part_request_data(void *data) * @param query : the query string * @return a dictionary of key-value */ -void decode_url_request(const char *query, dictionary dic) +void decode_url_request(const char *query, dictionary_t dic) { if (query == NULL) return; @@ -1156,7 +1209,7 @@ void *execute_plugin(void *data, const char *pname) pthread_mutex_unlock(&server_mux); if (plugin == NULL) { - unknow(rq->client); + antd_error(rq->client, 503, "Requested service not found"); return task; } } @@ -1171,7 +1224,7 @@ void *execute_plugin(void *data, const char *pname) if ((error = dlerror()) != NULL) { ERROR("Problem when finding %s method from %s : %s", PLUGIN_HANDLER, pname, error); - unknow(rq->client); + antd_error(rq->client, 503, "Requested service not found"); return task; } // check if we need the raw data or not @@ -1195,3 +1248,8 @@ int usessl() return server_config.usessl; } #endif + +dictionary_t mimes_list() +{ + return server_config.mimes; +} \ No newline at end of file diff --git a/http_server.h b/http_server.h index 88371bb..134bff4 100644 --- a/http_server.h +++ b/http_server.h @@ -35,14 +35,14 @@ void badrequest(void*); int rule_check(const char*, const char*, const char* , const char* , const char* , char*); void ws_confirm_request(void*, const char*); char* post_url_decode(void* client,int len); -void decode_url_request(const char* query, dictionary); +void decode_url_request(const char* query, dictionary_t); void* decode_request_header(void* data); void* decode_request(void* data); void* decode_post_request(void* data); void* resolve_request(void* data); void* decode_multi_part_request(void*,const char*); void* decode_multi_part_request_data(void* data); -dictionary decode_cookie(const char*); +dictionary_t decode_cookie(const char*); char* post_data_decode(void*,int); void set_nonblock(int); void* execute_plugin(void* data, const char *path); diff --git a/httpd.c b/httpd.c index e348759..46ffdc9 100644 --- a/httpd.c +++ b/httpd.c @@ -10,8 +10,8 @@ static int server_sock = -1; // define the cipher suit used // dirty hack, this should be configured by the configuration file -#define CIPHER_SUIT "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256" - +// #define CIPHER_SUIT "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256" +#define CIPHER_SUIT "HIGH" static int ssl_session_ctx_id = 1; SSL_CTX *ctx; diff --git a/lib/dictionary.c b/lib/dictionary.c index d39a540..961ed90 100644 --- a/lib/dictionary.c +++ b/lib/dictionary.c @@ -22,19 +22,33 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "dictionary.h" +#include "utils.h" -dictionary dict() +dictionary_t dict() { - dictionary d = (dictionary)malloc(DHASHSIZE*sizeof(association)); - for(int i=0; i< DHASHSIZE;i++) - d[i] = NULL; + return dict_n(DHASHSIZE); +} +dictionary_t dict_n(unsigned int size) +{ + dictionary_t d = (dictionary_t) malloc(sizeof(struct __dict)); + if(!d) return NULL; + d->map= (map_t)malloc(size*sizeof(chain_t)); + if(!d->map) + { + free(d); + return NULL; + } + d->cap = size; + d->size = 0; + for(unsigned int i=0; i< size;i++) + d->map[i] = NULL; return d; } -association dlookup(dictionary dic,const char* key) +chain_t dlookup(dictionary_t dic,const char* key) { - association np; - if(dic == NULL) return NULL; - for (np = dic[hash(key,DHASHSIZE)]; np != NULL; np = np->next) + chain_t np; + if(dic->map == NULL) return NULL; + for (np = dic->map[hash(key,dic->cap)]; np != NULL; np = np->next) { if(!np || !np->key) { @@ -45,26 +59,27 @@ association dlookup(dictionary dic,const char* key) } return NULL; /* not found */ } -association __put_el_with_key(dictionary dic, const char* key) +chain_t __put_el_with_key(dictionary_t dic, const char* key) { - association np; + chain_t np; unsigned hashval; - if(dic == NULL) return NULL; + if(dic->map == NULL) return NULL; if ((np = dlookup(dic,key)) == NULL) { /* not found */ - np = (association) malloc(sizeof(*np)); - np->value = NULL; + np = (chain_t) malloc(sizeof(*np)); if (np == NULL || (np->key = strdup(key)) == NULL) return NULL; - hashval = hash(key, DHASHSIZE); - np->next = dic[hashval]; - dic[hashval] = np; + np->value = NULL; + hashval = hash(key, dic->cap); + np->next = dic->map[hashval]; + dic->map[hashval] = np; + dic->size++; } // found return np; } -association dput(dictionary dic,const char* key, void* value) +chain_t dput(dictionary_t dic,const char* key, void* value) { - association np = __put_el_with_key(dic,key); + chain_t np = __put_el_with_key(dic,key); if(np == NULL) { if(value) free(value); @@ -74,38 +89,43 @@ association dput(dictionary dic,const char* key, void* value) np->value = value; return np; } -int dremove(dictionary dic, const char* key) +chain_t dremove(dictionary_t dic, const char* key) { - if(dic == NULL) return 0; - int hashval = hash(key, DHASHSIZE); - association np = dic[hashval]; + if(dic->map == NULL) return 0; + int hashval = hash(key, dic->cap); + chain_t np = dic->map[hashval]; if(np!=NULL && strcmp(key,np->key)==0) { - dic[hashval] = np->next; - return 1; + dic->size--; + dic->map[hashval] = np->next; + np->next = NULL; + return np; } - for (np= dic[hashval]; np != NULL; np = np->next) + for (np= dic->map[hashval]; np != NULL; np = np->next) if (np->next!=NULL&&strcmp(key, np->next->key) == 0) { + chain_t ret = np->next; np->next = np->next->next; /* found */ - return 1; + dic->size--; + ret->next = NULL; + return ret; } - return 0; /* not found */ + return NULL; /* not found */ } -void* dvalue(dictionary dic, const char* key) +void* dvalue(dictionary_t dic, const char* key) { - association as = dlookup(dic,key); + chain_t as = dlookup(dic,key); if(as == NULL) return NULL; return as->value; } -void free_association(association * asoc) +void free_association(chain_t * asoc) { while( (*asoc) != NULL ) { - association a = *asoc; + chain_t a = *asoc; (* asoc) = (*asoc) ->next; if(a->key) @@ -118,11 +138,11 @@ void free_association(association * asoc) } -void freedict(dictionary dic){ - for(int i = 0; i < DHASHSIZE; i++) - free_association(&(dic[i])); +void freedict(dictionary_t dic){ + for(unsigned int i = 0; i < dic->cap; i++) + free_association(&(dic->map[i])); + free(dic->map); free(dic); - } diff --git a/lib/dictionary.h b/lib/dictionary.h index 814dfe0..9f65b92 100644 --- a/lib/dictionary.h +++ b/lib/dictionary.h @@ -24,10 +24,10 @@ THE SOFTWARE. #ifndef DICTIONARY_H #define DICTIONARY_H -#include "utils.h" +#define DHASHSIZE 16 #define for_each_assoc(assoc, dic) \ - for(int i = 0; i < DHASHSIZE; i++) \ - for(assoc = dic[i];assoc!= NULL; assoc = assoc->next) + for(unsigned int i = 0; i < dic->cap; i++) \ + for(assoc = dic->map[i];assoc!= NULL; assoc = assoc->next) /** * Dictionary for header @@ -37,14 +37,22 @@ typedef struct __assoc{ char *key; void* value; //char *value; -} * association; +} * chain_t; -typedef association* dictionary; -dictionary dict(); -association dlookup(dictionary,const char*); -void* dvalue(dictionary, const char*); -association dput(dictionary,const char*, void*); -int dremove(dictionary, const char*); -void freedict(dictionary); +typedef chain_t* map_t; + +typedef struct __dict{ + unsigned int cap; + map_t map; + unsigned int size; +}* dictionary_t; + +dictionary_t dict(); +dictionary_t dict_n(unsigned int n); +chain_t dlookup(dictionary_t,const char*); +void* dvalue(dictionary_t, const char*); +chain_t dput(dictionary_t,const char*, void*); +chain_t dremove(dictionary_t, const char*); +void freedict(dictionary_t); #endif \ No newline at end of file diff --git a/lib/handle.c b/lib/handle.c index f0e93c2..fd053d2 100644 --- a/lib/handle.c +++ b/lib/handle.c @@ -1,4 +1,5 @@ #include "handle.h" +#define HTML_TPL "%s

%s

" #ifdef USE_OPENSSL int usessl() { @@ -18,36 +19,110 @@ void server_log(const char* fmt, ...) return; } #endif -void set_status(void* client,int code,const char* msg) + +const char* get_status_str(int stat) { - char *s = __s("HTTP/1.1 %d %s", code, msg); - response(client, s); - free(s); - s = __s("Server: %s ", SERVER_NAME); - response(client, s); - free(s); -} -void redirect(void* client,const char*path) -{ - __t(client,"",path); + switch(stat) + { + case 100: return "Continue"; + case 101: return "Switching Protocols"; + case 102: return "Processing"; + case 103: return "Early Hints"; + + case 200: return "OK"; + case 201: return "Created"; + case 202: return "Accepted"; + case 203: return "Non-Authoritative Information"; + case 204: return "No Content"; + case 205: return "Reset Content"; + case 206: return "Partial Content"; + case 207: return "Multi-Status"; + case 208: return "Already Reported"; + case 226: return "IM Used"; + + case 300: return "Multiple Choices"; + case 301: return "Moved Permanently"; + case 302: return "Found"; + case 303: return "See Other"; + case 304: return "Not Modified"; + case 305: return "Use Proxy"; + case 306: return "Switch Proxy"; + case 307: return "Temporary Redirect"; + case 308: return "Permanent Redirect"; + + case 400: return "Bad Request"; + case 401: return "Unauthorized"; + case 402: return "Payment Required"; + case 403: return "Forbidden"; + case 404: return "Not Found"; + case 405: return "Method Not Allowed"; + case 406: return "Not Acceptable"; + case 407: return "Proxy Authentication Required"; + case 408: return "Request Timeout"; + case 409: return "Conflict"; + case 410: return "Gone"; + case 411: return "Length Required"; + case 412: return "Precondition Failed"; + case 413: return "Payload Too Large"; + case 414: return "URI Too Long"; + case 415: return "Unsupported Media Type"; + case 416: return "Range Not Satisfiable"; + case 417: return "Expectation Failed"; + case 421: return "Misdirected Request"; + case 422: return "Unprocessable Entity"; + case 423: return "Locked"; + case 424: return "Failed Dependency"; + case 425: return "Too Early"; + case 426: return "Upgrade Required"; + case 428: return "Precondition Required"; + case 429: return "Too Many Requests"; + case 431: return "Request Header Fields Too Large"; + case 451: return "Unavailable For Legal Reasons"; + + case 500: return "Internal Server Error"; + case 501: return "Not Implemented"; + case 502: return "Bad Gateway"; + case 503: return "Service Unavailable"; + case 504: return "Gateway Timeout"; + case 505: return "HTTP Version Not Supported"; + case 506: return "Variant Also Negotiates"; + case 507: return "Insufficient Storage"; + case 508: return "Loop Detected"; + case 510: return "Not Extended"; + case 511: return "Network Authentication Required"; + default: return "Unofficial Status"; + } } -void html(void* client) +void antd_send_header(void* client, antd_response_header_t* res) { - ctype(client,"text/html; charset=utf-8"); -} -void text(void* client) -{ - ctype(client,"text/plain; charset=utf-8"); -} -void json(void* client) -{ - ctype(client,"application/json"); -} -void textstream(void* client) -{ - ctype(client, "text/event-stream"); + if(!res->header) + res->header = dict(); + dput(res->header,"Server", strdup(SERVER_NAME)); + const char* stat_str = get_status_str(res->status); + __t(client, "HTTP/1.1 %d %s", res->status, stat_str); + chain_t it; + for_each_assoc(it, res->header) + { + __t(client,"%s: %s", it->key, (const char*)it->value); + } + // send out cookie + if(res->cookie) + { + int size = list_size(res->cookie); + for (int i = 0; i < size; i++) + { + __t(client,"Set-Cookie: %s", list_at(res->cookie, i)->value.s); + } + list_free(&res->cookie); + res->cookie = NULL; + } + __b(client, (unsigned char*)"\r\n", 2); + freedict(res->header); + res->header = NULL; } + +/* void octstream(void* client, char* name) { set_status(client,200,"OK"); @@ -55,38 +130,15 @@ void octstream(void* client, char* name) __t(client,"Content-Disposition: attachment; filename=\"%s\"", name); response(client,""); //Content-Disposition: attachment; filename="fname.ext" -} -void jpeg(void* client) -{ - ctype(client,"image/jpeg"); -} -void ctype(void* client, const char* type) -{ - set_status(client,200,"OK"); - __t(client,"Content-Type: %s",type); - response(client,""); -} +}*/ -int response(void* client, const char* data) -{ - char buf[BUFFLEN+3]; - strcpy(buf, data); - int nbytes; - int size = strlen(data); - buf[size] = '\r'; - buf[size+1] = '\n'; - buf[size+2] = '\0'; - - nbytes = antd_send(client, buf, strlen(buf)); - return (nbytes ==-1?0:1); -} int antd_send(void *src, const void* data, int len) { if(!src || !data) return -1; int written; antd_client_t * source = (antd_client_t *) src; char* ptr; - int writelen; + int writelen = 0; int count; #ifdef USE_OPENSSL if(usessl()) @@ -200,7 +252,9 @@ int antd_send(void *src, const void* data, int len) } else if(count == -1 && errno != EAGAIN && errno != EWOULDBLOCK) { - return written; + ERROR("Error while writing: %s", strerror(errno)); + break; + //return written; } } #ifdef USE_OPENSSL @@ -351,6 +405,7 @@ int antd_recv(void *src, void* data, int len) } else if(errno != EAGAIN && errno != EWOULDBLOCK) { + ERROR("Error while writing: %s", strerror(errno)); break; } } @@ -408,66 +463,27 @@ int antd_close(void* src) src = NULL; return ret; } -int __ti(void* client,int data) -{ - char str[15]; - sprintf(str, "%d", data); - return response(client,str); -} int __t(void* client, const char* fstring,...) { - int nbytes; int dlen; - int sent = 0; - int buflen = 0; + int st; va_list arguments; char * data; - char* chunk; va_start( arguments, fstring); - dlen = vsnprintf(0,0,fstring,arguments) + 1; + dlen = vsnprintf(0,0,fstring,arguments)+1; va_end(arguments); if ((data = (char*)malloc(dlen*sizeof(char))) != 0) { va_start(arguments, fstring); vsnprintf(data, dlen, fstring, arguments); va_end(arguments); - - if(dlen < BUFFLEN) - { - int ret = response(client,data); - free(data); - return ret; - } - else - { - while(sent < dlen - 1) - { - if(dlen - sent > BUFFLEN) - buflen = BUFFLEN; - else - buflen = dlen - sent - 1; - //LOG("BUFFLEN %d\n",buflen); - chunk = (char*) malloc((buflen)*sizeof(char)); - memcpy(chunk,data+sent,buflen); - //chunk[buflen-1] = '\0'; - //response(client,chunk); - sent += buflen; - nbytes = antd_send(client, chunk, buflen); - free(chunk); - if(nbytes == -1) - { - //free(data); - //return 0; - break; - } - } - chunk = "\r\n"; - antd_send(client, chunk, strlen(chunk)); - } + st = __b(client, (const unsigned char*)data, strlen(data)); + __b(client, (unsigned char*)"\r\n", 2); free(data); + return st; } - return 1; + return 0; // } int __b(void* client, const unsigned char* data, int size) @@ -475,15 +491,15 @@ int __b(void* client, const unsigned char* data, int size) char buf[BUFFLEN]; int sent = 0; int buflen = 0; - int nbytes; + int nbytes = 0; - if(size <= BUFFLEN) + /*if(size <= BUFFLEN) { nbytes = antd_send(client,data,size); return (nbytes==-1?0:1); } else - { + {*/ while(sent < size) { if(size - sent > BUFFLEN) @@ -492,10 +508,13 @@ int __b(void* client, const unsigned char* data, int size) buflen = size - sent; memcpy(buf,data+sent,buflen); nbytes = antd_send(client,buf,buflen); - sent += buflen; - if(nbytes == -1) return 0; + if(nbytes == -1) + { + return 0; + } + sent += nbytes; } - } + //} return 1; } int __f(void* client, const char* file) @@ -517,95 +536,64 @@ int __f(void* client, const char* file) fclose(ptr); return 1; } -/* -int __f(void* client, const char* file) -{ - char buf[BUFFLEN]; - FILE *ptr; - int nbytes; - ptr = fopen(file,"r"); - if(!ptr) - { - LOG("Cannot read : %s\n", file); - return 0; - } - memset(buf,0, sizeof(buf)); - while(fgets(buf, sizeof(buf) - 1, ptr) != NULL) - { - nbytes = antd_send(client, buf, strlen(buf)); - if(nbytes == -1) return 0; - memset(buf,0, sizeof(buf)); - //LOG("READ : %s\n", buf); - //fgets(buf, sizeof(buf), ptr); - } - fclose(ptr); - return 1; -} -*/ + int upload(const char* tmp, const char* path) { return !rename(tmp, path); } -// __plugin__.name -void set_cookie(void* client,const char* type, dictionary dic, const char* name) + +/* +void set_cookie(void* client,const char* type, dictionary_t dic, const char* name) { set_status(client,200,"OK"); __t(client,"Content-Type: %s",type); - association assoc; + chain_t assoc; for_each_assoc(assoc,dic){ __t(client,"Set-Cookie: %s=%s; Path=/%s",assoc->key, (char*)assoc->value, name); } response(client,""); } -void clear_cookie(void* client, dictionary dic) +void clear_cookie(void* client, dictionary_t dic) { set_status(client,200,"OK"); __t(client,"Content-Type: text/html; charset=utf-8"); - association assoc; + chain_t assoc; for_each_assoc(assoc,dic){ - __t(client,"Set-Cookie: %s=%s;expires=",assoc->key, (char*)assoc->value, server_time()); + __t(client,"Set-Cookie: %s=%s;expires=%s",assoc->key, (char*)assoc->value, server_time()); } response(client,""); } -void unknow(void* client) +*/ + +void antd_error(void* client, int status, const char* msg) { - set_status(client,520,"Unknown Error"); - __t(client,"Content-Type: text/html; charset=utf-8"); - response(client,""); - __t(client,"520 Unknow request"); + antd_response_header_t rsh; + rsh.header = dict(); + rsh.cookie = NULL; + const char* stat_str = get_status_str(status); + rsh.status = status; + dput(rsh.header, "Content-Type", strdup("text/html; charset=utf-8")); + char * res_str = __s(HTML_TPL, stat_str, msg); + int clen = 0; + if(res_str) + { + clen = strlen(res_str); + } + char ibuf[20]; + snprintf (ibuf, sizeof(ibuf), "%d",clen); + dput(rsh.header, "Content-Length", strdup(ibuf)); + antd_send_header(client, &rsh); + if(res_str) + { + //printf("%s\n", res_str); + __b(client, (unsigned char*)res_str, clen); + //__t(client, HTML_TPL, stat_str, msg); + free(res_str); + } } -void notfound(void* client) -{ - set_status(client,404,"Not found"); - __t(client,"Content-Type: text/html; charset=utf-8"); - response(client,""); - __t(client,"Resource not found"); -} -void badrequest(void* client) -{ - set_status(client,400,"Bad request"); - __t(client,"Content-Type: text/html; charset=utf-8"); - response(client,""); - __t(client,"400 Bad request"); -} -void unimplemented(void* client) -{ - set_status(client,501,"Method Not Implemented"); - __t(client,"Content-Type: text/html"); - response(client,""); - __t(client, "Method Not Implemented"); - __t(client, ""); - __t(client, "

HTTP request method not supported."); - __t(client, ""); -} -void cannot_execute(void* client) -{ - set_status(client,500,"Internal Server Error"); - __t(client,"Content-Type: text/html"); - response(client,""); - __t(client, "

Error prohibited CGI execution."); -} -int ws_enable(dictionary dic) + + +int ws_enable(dictionary_t dic) { if(!dic) return 0; char*v = (char*)dvalue(dic, "__web_socket__"); @@ -667,7 +655,7 @@ void destroy_request(void *data) // free all other thing if (rq->request) { - dictionary tmp = dvalue(rq->request, "COOKIE"); + dictionary_t tmp = dvalue(rq->request, "COOKIE"); if (tmp) freedict(tmp); tmp = dvalue(rq->request, "REQUEST_HEADER"); diff --git a/lib/handle.h b/lib/handle.h index 6bc1f76..1fa1e82 100644 --- a/lib/handle.h +++ b/lib/handle.h @@ -13,6 +13,7 @@ #include "dbhelper.h" #endif #include +#include #include "dictionary.h" #include "list.h" #include "ini.h" @@ -48,9 +49,17 @@ typedef struct{ typedef struct { antd_client_t* client; - dictionary request; + dictionary_t request; } antd_request_t; +typedef struct +{ + dictionary_t header; + list_t cookie; + int status; + +} antd_response_header_t; + typedef struct { int port; @@ -59,8 +68,8 @@ typedef struct { char *db_path; char* htdocs; char* tmpdir; - list rules; - dictionary handlers; + list_t rules; + dictionary_t handlers; int backlog; int maxcon; int connection; @@ -73,6 +82,8 @@ typedef struct { int usessl; char* sslcert; char* sslkey; + char* ssl_cipher; + dictionary_t mimes; // #endif }config_t; @@ -90,31 +101,19 @@ typedef struct { void set_nonblock(int socket); //void set_block(int socket); -int response(void*, const char*); -void ctype(void*,const char*); -void redirect(void*,const char*); -void html(void*); -void text(void*); -void json(void*); -void jpeg(void*); -void octstream(void*, char*); -void textstream(void*); -int __ti(void*,int); + +void antd_send_header(void*,antd_response_header_t*); +const char* get_status_str(int stat); int __t(void*, const char*,...); int __b(void*, const unsigned char*, int); int __f(void*, const char*); -//int __fb(void*, const char*); + int upload(const char*, const char*); -void set_cookie(void*, const char*,dictionary,const char*); -void set_status(void*,int,const char*); -void clear_cookie(void*, dictionary); /*Default function for plugin*/ -void unknow(void*); -void badrequest(void* client); -void unimplemented(void* client); -void notfound(void* client); -int ws_enable(dictionary); +void antd_error(void* client, int status, const char* msg); + +int ws_enable(dictionary_t); char* read_line(void* sock); int read_buf(void* sock,char* buf,int i); int antd_send( void *source, const void* data, int len); diff --git a/lib/list.c b/lib/list.c index 8e7a562..dd8965a 100644 --- a/lib/list.c +++ b/lib/list.c @@ -23,52 +23,52 @@ THE SOFTWARE. */ #include "list.h" -list list_init() +list_t list_init() { - list ret = (list)malloc(sizeof *ret); - ret->type = RPC_TYPE_NIL; + list_t ret = (list_t)malloc(sizeof *ret); + ret->type = LIST_TYPE_NIL; ret->next = NULL; return ret; } -void list_put(list* l, item it) +void list_put(list_t* l, item_t it) { - if(*l == NULL || (*l)->type == RPC_TYPE_NIL) + if(*l == NULL || (*l)->type == LIST_TYPE_NIL) { free(*l); *l = it; return ; } - item np = list_last(*l); + item_t np = list_last(*l); np->next = it; } -void list_put_special(list* l, const char* str) +void list_put_special(list_t* l, const char* str) { - item v; + item_t v; if(IS_INT(str)) { - v = list_item(RPC_TYPE_INT); + v = list_item(LIST_TYPE_INT); v->value.i = atoi(str); } else if(IS_FLOAT(str)) { - v = list_item(RPC_TYPE_DOUBLE); + v = list_item(LIST_TYPE_DOUBLE); v->value.d = (double)atof(str); } else { - v = list_item(RPC_TYPE_STRING); + v = list_item(LIST_TYPE_STRING); v->value.s = strdup(str); } list_put(l,v); } -item list_last(list l) +item_t list_last(list_t l) { - item p = l; + item_t p = l; while(p && p->next != NULL) p = p->next; return p; } -int list_remove(list l,int idx) +int list_remove(list_t l,int idx) { if(l==NULL) return 0; if(idx <0 || idx >= list_size(l)) return 0; @@ -77,17 +77,17 @@ int list_remove(list l,int idx) l=l->next; return 1; } - item np = list_at(l,idx-1); + item_t np = list_at(l,idx-1); if(np == NULL) return 0; if(np->next == NULL) return 1; np->next = np->next->next; return 1; } -int list_size(list l) +int list_size(list_t l) { - if(l == NULL || l->type == RPC_TYPE_NIL) return 0; + if(l == NULL || l->type == LIST_TYPE_NIL) return 0; int i=0; - item np = l; + item_t np = l; while(np) { np = np->next; @@ -95,46 +95,46 @@ int list_size(list l) } return i; } -char* as_string(list l) +char* as_string(list_t l) { char* str = ""; - if(l != NULL && l->type != RPC_TYPE_NIL) + if(l != NULL && l->type != LIST_TYPE_NIL) { switch(l->type) { - case RPC_TYPE_BASE64: + case LIST_TYPE_BASE64: str = __s("b64:%s", l->value.b64); break; - case RPC_TYPE_BOOL: + case LIST_TYPE_BOOL: str = __s("bool:%d", l->value.b); break; - case RPC_TYPE_DOUBLE: + case LIST_TYPE_DOUBLE: str = __s("double:%lf", l->value.d); break; - case RPC_TYPE_DATE: + case LIST_TYPE_DATE: str = __s("date:%s", l->value.date); break; - case RPC_TYPE_INT: - case RPC_TYPE_I4: + case LIST_TYPE_INT: + case LIST_TYPE_I4: str = __s("int:%d", l->value.i); break; - case RPC_TYPE_STRING: + case LIST_TYPE_STRING: str = __s("string:%s", l->value.s); break; - case RPC_TYPE_ARRAY: + case LIST_TYPE_ARRAY: str = __s("[%s]", as_string(l->value.array)); break; default: str = ""; break; } - item np = l->next; + item_t np = l->next; if(np) { str = __s("%s,\n%s", str, as_string(np)); @@ -143,12 +143,12 @@ char* as_string(list l) } return "[empty]"; } -item list_at(list l,int idx) +item_t list_at(list_t l,int idx) { if(l == NULL || idx<0 || idx>= list_size(l)) return NULL; int i=0; - item np = l; + item_t np = l; while(np) { if(i==idx) @@ -158,20 +158,20 @@ item list_at(list l,int idx) } return NULL; } -item list_item(int type) +item_t list_item(int type) { - item ret = (item)malloc(sizeof *ret); + item_t ret = (item_t)malloc(sizeof *ret); ret->type = type; ret->next = NULL; return ret; } -list split(const char* str, const char* delim) +list_t split(const char* str, const char* delim) { if(str == NULL || delim == NULL) return NULL; char* str_cpy = strdup(str); char* org_str = str_cpy; char* token; - list l = list_init(); + list_t l = list_init(); while((token = strsep(&str_cpy,delim))) { if(strlen(token) > 0) @@ -180,69 +180,72 @@ list split(const char* str, const char* delim) } } free(org_str); - if(l->type== RPC_TYPE_NIL) + if(l->type== LIST_TYPE_NIL) + { + free(l); return NULL; + } return l; } -void list_put_i(list* l,int v) +void list_put_i(list_t* l,int v) { - item it = list_item(RPC_TYPE_INT); + item_t it = list_item(LIST_TYPE_INT); it->value.i = v; list_put(l,it); } -void list_put_d(list* l,double v) +void list_put_d(list_t* l,double v) { - item it = list_item(RPC_TYPE_DOUBLE); + item_t it = list_item(LIST_TYPE_DOUBLE); it->value.d = v; list_put(l,it); } -void list_put_b(list* l,int v) +void list_put_b(list_t* l,int v) { - item it = list_item(RPC_TYPE_BOOL); + item_t it = list_item(LIST_TYPE_BOOL); it->value.b = v; list_put(l,it); } -void list_put_b64(list* l,const char* v) +void list_put_b64(list_t* l,const char* v) { - item it = list_item(RPC_TYPE_BASE64); + item_t it = list_item(LIST_TYPE_BASE64); it->value.b64 = strdup(v); list_put(l,it); } -void list_put_date(list* l,const char* v) +void list_put_date(list_t* l,const char* v) { - item it = list_item(RPC_TYPE_DATE); + item_t it = list_item(LIST_TYPE_DATE); it->value.date = strdup(v); list_put(l,it); } -void list_put_s(list* l,const char* v) +void list_put_s(list_t* l,const char* v) { - item it = list_item(RPC_TYPE_STRING); + item_t it = list_item(LIST_TYPE_STRING); it->value.s = strdup(v); list_put(l,it); } -void list_put_array(list* l,list v) +void list_put_array(list_t* l,list_t v) { - item it = list_item(RPC_TYPE_ARRAY); + item_t it = list_item(LIST_TYPE_ARRAY); it->value.array = v; list_put(l,it); } -void list_free(list *l) +void list_free(list_t *l) { - item curr; + item_t curr; while ((curr = (*l)) != NULL) { (*l) = (*l)->next; - if(curr->type == RPC_TYPE_ARRAY) + if(curr->type == LIST_TYPE_ARRAY) list_free(&curr->value.array); - else if(curr->type == RPC_TYPE_STRING) + else if(curr->type == LIST_TYPE_STRING) free(curr->value.s); - else if(curr->type == RPC_TYPE_DATE) + else if(curr->type == LIST_TYPE_DATE) free(curr->value.date); - else if(curr->type == RPC_TYPE_BASE64) + else if(curr->type == LIST_TYPE_BASE64) free(curr->value.b64); free (curr); } } -int list_empty(list l) +int list_empty(list_t l) { - return l== NULL || l->type == RPC_TYPE_NIL; + return l== NULL || l->type == LIST_TYPE_NIL; } \ No newline at end of file diff --git a/lib/list.h b/lib/list.h index af9ffc9..617f8bf 100644 --- a/lib/list.h +++ b/lib/list.h @@ -24,7 +24,17 @@ THE SOFTWARE. #ifndef LIST_H #define LIST_H #include "utils.h" -#define list item + +#define LIST_TYPE_ARRAY 601//hash("array") +#define LIST_TYPE_BASE64 335//hash("base64") +#define LIST_TYPE_BOOL 40//hash("boolean") +#define LIST_TYPE_DOUBLE 977//hash("double") +#define LIST_TYPE_DATE 49//hash("dateTime.iso8601") +#define LIST_TYPE_INT 1007//hash("int") +#define LIST_TYPE_I4 235//hash("i4") +#define LIST_TYPE_STRING 17//hash("string") +#define LIST_TYPE_NIL 529//hash("nil") + typedef struct __item{ int type; union{ @@ -37,25 +47,25 @@ typedef struct __item{ struct __item* array; } value; struct __item* next; -}*item; - -list list_init(); -void list_put(list*,item); -void list_put_i(list*,int); -void list_put_d(list*,double); -void list_put_b(list*,int); -void list_put_b64(list*,const char*); -void list_put_date(list*,const char*); -void list_put_s(list*,const char*); -void list_put_array(list*,list); -item list_last(list); -int list_remove(list,int); -int list_size(list); -item list_at(list,int); -int list_empty(list); -item list_item(int type); -list split(const char*, const char*); -char* as_string(list); -void list_put_special(list*, const char*); -void list_free(list *); +}*item_t; +typedef item_t list_t; +list_t list_init(); +void list_put(list_t*,item_t); +void list_put_i(list_t*,int); +void list_put_d(list_t*,double); +void list_put_b(list_t*,int); +void list_put_b64(list_t*,const char*); +void list_put_date(list_t*,const char*); +void list_put_s(list_t*,const char*); +void list_put_array(list_t*,list_t); +item_t list_last(list_t); +int list_remove(list_t,int); +int list_size(list_t); +item_t list_at(list_t,int); +int list_empty(list_t); +item_t list_item(int type); +list_t split(const char*, const char*); +char* as_string(list_t); +void list_put_special(list_t*, const char*); +void list_free(list_t *); #endif \ No newline at end of file diff --git a/lib/utils.c b/lib/utils.c index c60ea54..617c596 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -23,58 +23,6 @@ THE SOFTWARE. */ #include "utils.h" -//define all basic mime here - -static mime_t _mimes[] = { - {"image/bmp",(const char *[]){"bmp",NULL},1}, - {"image/jpeg",(const char *[]){"jpg","jpeg",NULL},1}, - {"text/css",(const char *[]){"css",NULL},0}, - {"text/markdown",(const char *[]){"md",NULL},0}, - {"text/csv",(const char *[]){"csv",NULL},0}, - {"application/pdf",(const char *[]){"pdf",NULL},1}, - {"image/gif",(const char *[]){"gif",NULL},1}, - {"text/html",(const char *[]){"html","htm",NULL},0}, - {"application/json",(const char *[]){"json",NULL},0}, - {"application/javascript",(const char *[]){"js",NULL},0}, - {"image/png",(const char *[]){"png",NULL},1}, - {"image/x-portable-pixmap",(const char *[]){"ppm",NULL},1}, - {"application/x-rar-compressed",(const char *[]){"rar",NULL},1}, - {"image/tiff",(const char *[]){"tiff",NULL},1}, - {"application/x-tar",(const char *[]){"tar",NULL},1}, - {"text/plain",(const char *[]){"txt",NULL},0}, - {"application/x-font-ttf",(const char *[]){"ttf",NULL},1}, - {"application/xhtml+xml",(const char *[]){"xhtml",NULL},0}, - {"application/xml",(const char *[]){"xml",NULL},0}, - {"application/zip",(const char *[]){"zip",NULL},1}, - {"image/svg+xml",(const char *[]){"svg",NULL},0}, - {"application/vnd.ms-fontobject",(const char *[]){"eot",NULL},1}, - {"application/x-font-woff",(const char *[]){"woff","woff2",NULL},1}, - {"application/x-font-otf",(const char *[]){"otf",NULL},1}, - {"audio/mpeg",(const char *[]){"mp3","mpeg",NULL},1}, - {NULL,NULL,0} -}; - - -char* __s(const char* fstring,...) -{ - char* data; - va_list arguments; - int dlen; - va_start( arguments, fstring); - dlen = vsnprintf(0,0,fstring,arguments) + 1; - va_end(arguments); - va_end(arguments); - if ((data = (char*)malloc(dlen*sizeof(char))) != 0) - { - va_start(arguments, fstring); - vsnprintf(data, dlen, fstring, arguments); - va_end(arguments); - return data; - } else - return ""; -} - - /** * Trim a string by a character on both ends * @param str The target string @@ -162,21 +110,47 @@ char* ext(const char* file) /*get mime file info from extension*/ mime_t mime_from_ext(const char* ex) { - for(int i = 0; _mimes[i].type != NULL; i++) - for(int j = 0; _mimes[i].ext[j] != NULL; j++) - { - if(IEQU(ex,_mimes[i].ext[j])) return _mimes[i]; - } - - return (mime_t){"application/octet-stream",(const char *[]){(char*)ext,NULL},1}; + dictionary_t mime_list = mimes_list(); + mime_t ret = (mime_t){"application/octet-stream",NULL}; + if(!mime_list) + return ret; + chain_t it; + char * pattern = __s("(^\\s*%s\\s*,)|(\\s*,\\s*%s\\s*,\\s*)|(^\\s*%s\\s*$)|(,\\s*%s\\s*$)", ex, ex, ex, ex); + if(pattern) + { + for_each_assoc(it,mime_list) + { + + if(regex_match(pattern,it->value,0, NULL)) + { + ret.type = it->key; + ret.ext = it->value; + free(pattern); + return ret; + } + } + free(pattern); + } + return ret; +} +dictionary_t mimes_list() +{ + return NULL; } /*get mime file info from type*/ mime_t mime_from_type(const char* type) { - for(int i = 0; _mimes[i].type != NULL; i++) - if(strstr(type, _mimes[i].type) != NULL) - return _mimes[i]; - return (mime_t){NULL,NULL,0}; + dictionary_t mime_list = mimes_list(); + mime_t ret = (mime_t){NULL,NULL}; + if(!mime_list) + return ret; + chain_t it = dlookup(mime_list, type); + if(it) + { + ret.type = it->key; + ret.ext = it->value; + } + return ret; } /** * Get correct HTTP mime type of a file @@ -194,18 +168,7 @@ char* mime(const char* file) { free(ex); } - return (char*)m.type; -} - -int is_bin(const char* file) -{ - char * ex = ext(file); - mime_t m = mime_from_ext(ex); - if(ex) - { - free(ex); - } - return m.bin; + return (char*)m.type; } int match_int(const char* search) @@ -475,3 +438,23 @@ void sha1(const char* text, char* out) SHA1_Final(d, &context); digest_to_hex(d,out); } + + +char* __s(const char* fstring,...) +{ + char* data; + va_list arguments; + int dlen; + va_start( arguments, fstring); + dlen = vsnprintf(0,0,fstring,arguments) + 1; + va_end(arguments); + va_end(arguments); + if ((data = (char*)malloc(dlen*sizeof(char))) != 0) + { + va_start(arguments, fstring); + vsnprintf(data, dlen, fstring, arguments); + va_end(arguments); + return data; + } else + return ""; +} \ No newline at end of file diff --git a/lib/utils.h b/lib/utils.h index ee57e30..0323234 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -43,6 +43,7 @@ THE SOFTWARE. #include "sha1.h" #endif #include "base64.h" +#include "dictionary.h" #define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) #define EQU(a,b) (strcmp(a,b) == 0) @@ -54,36 +55,25 @@ THE SOFTWARE. #define true 1 #define false 0 #ifdef DEBUG - #define LOG(a,...) server_log("%s:%d: " a "\n", __FILE__, \ + #define LOG(a,...) server_log("[%s: %d]: " a "\n", __FILE__, \ __LINE__, ##__VA_ARGS__) #else #define LOG(a,...) do{}while(0) #endif -#define ERROR(a,...) error_log("%s:%d: " a "\n", __FILE__, \ +#define ERROR(a,...) error_log("[%s: %d]: " a "\n", __FILE__, \ __LINE__, ##__VA_ARGS__) // add this to the utils #define UNUSED(x) (void)(x) #define BUFFLEN 1024 #define HASHSIZE 1024 -#define DHASHSIZE 50 - -#define RPC_TYPE_ARRAY 601//hash("array") -#define RPC_TYPE_BASE64 335//hash("base64") -#define RPC_TYPE_BOOL 40//hash("boolean") -#define RPC_TYPE_DOUBLE 977//hash("double") -#define RPC_TYPE_DATE 49//hash("dateTime.iso8601") -#define RPC_TYPE_INT 1007//hash("int") -#define RPC_TYPE_I4 235//hash("i4") -#define RPC_TYPE_STRING 17//hash("string") -#define RPC_TYPE_NIL 529//hash("nil") typedef struct{ const char* type; - const char** ext; - int bin; + const char* ext; } mime_t; +dictionary_t __attribute__((weak)) mimes_list(); char* __s(const char*,...); void trim(char*,const char); void removeAll(const char* path,int mode); @@ -91,7 +81,6 @@ char* __time(time_t time); char* server_time(); char* ext(const char*); char* mime(const char*); -int is_bin(const char*); int match_int(const char*); int match_float(const char*); int regex_match(const char*,const char*, int, regmatch_t*);