void t01_create_add_free(){ INIT_LOCAL(); onion_dict *dict; const char *value; dict=onion_dict_new(); FAIL_IF_EQUAL(dict,NULL); // Get before anything in value=onion_dict_get(dict, "Request"); FAIL_IF_NOT_EQUAL(value,NULL); // basic add onion_dict_add(dict, "Request", "GET /", OD_DUP_ALL); value=onion_dict_get(dict, "Request"); FAIL_IF_NOT_EQUAL_STR(value,"GET /"); // basic remove onion_dict_remove(dict, "Request"); value=onion_dict_get(dict, "Request"); FAIL_IF_NOT_EQUAL(value,NULL); onion_dict_free(dict); END_LOCAL(); }
void extended_html__block_body(onion_dict *context, onion_response *res){ #line 1 #line 8 onion_response_write(res, "\n<h1>This is an extended template</h1>\n\n", 40); #line 8 { #line 8 void (*f)(onion_dict *context, onion_response *res); #line 8 f=(void*)onion_dict_get(context, "__block_body_in__"); #line 8 if (f) #line 8 f(context, res); #line 8 } #line 14 onion_response_write(res, "\n\nIf you see this, <span style=\"color: green;\">OK</span>.\n<br>\nRandom (only at test2): ", 87); #line 14 { #line 14 const char *tmp; #line 14 tmp=onion_dict_get(context, "random"); #line 14 if (tmp) #line 14 onion_response_write0(res, tmp); #line 14 } #line 19 onion_response_write(res, "\n<br>\n\nUnicode Chars: \342\202\254 \302\241 \303\241 \303\251 \303\255 \303\272 \303\263. \346\261\211\350\257\255/\346\274\242\350\252\236.\n\n", 61); #line 1 }
void t12_dict_in_dict(){ INIT_LOCAL(); onion_dict *A=onion_dict_new(); onion_dict *B=onion_dict_new(); onion_dict *C=onion_dict_new(); onion_dict *D=onion_dict_new(); int i; for (i=0;i<16;i++){ char tmp[9]; sprintf(tmp,"%08X",rand()); onion_dict_add(A, tmp, tmp, OD_DUP_ALL); sprintf(tmp,"%08X",rand()); onion_dict_add(B, tmp, tmp, OD_DUP_ALL); sprintf(tmp,"%08X",rand()); onion_dict_add(C, tmp, tmp, OD_DUP_ALL); sprintf(tmp,"%08X",rand()); onion_dict_add(D, tmp, tmp, OD_DUP_ALL); } onion_dict_add(A, "B", B, OD_DICT|OD_FREE_VALUE); onion_dict_add(A, "C", C, OD_DICT|OD_FREE_VALUE); onion_dict_add(A, "D", D, OD_DICT|OD_FREE_VALUE); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get(A, "B"), NULL); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get(A, "C"), NULL); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get(A, "D"), NULL); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get_dict(A, "B"), B); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get_dict(A, "C"), C); FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get_dict(A, "D"), D); { onion_block *tmpA=onion_dict_to_json(A); onion_block *tmpB=onion_dict_to_json(B); onion_block *tmpC=onion_dict_to_json(C); onion_block *tmpD=onion_dict_to_json(D); /* ONION_DEBUG("Json is: %s",tmpA); ONION_DEBUG("Json is: %s",tmpB); ONION_DEBUG("Json is: %s",tmpC); ONION_DEBUG("Json is: %s",tmpD); */ FAIL_IF_EQUAL( strstr(onion_block_data(tmpA), onion_block_data(tmpB)), NULL); FAIL_IF_EQUAL( strstr(onion_block_data(tmpA), onion_block_data(tmpC)), NULL); FAIL_IF_EQUAL( strstr(onion_block_data(tmpA), onion_block_data(tmpD)), NULL); onion_block_free(tmpA); onion_block_free(tmpB); onion_block_free(tmpC); onion_block_free(tmpD); } B=onion_dict_hard_dup(A); onion_dict_free(A); onion_dict_free(B); END_LOCAL(); }
/** * @short Prepares the POST */ static onion_connection_status prepare_POST(onion_request *req){ // ok post onion_token *token=req->parser_data; const char *content_type=onion_dict_get(req->headers, "Content-Type"); const char *content_size=onion_dict_get(req->headers, "Content-Length"); if (!content_size){ ONION_ERROR("I need the content size header to support POST data"); return OCS_INTERNAL_ERROR; } size_t cl=atol(content_size); //ONION_DEBUG("Content type %s",content_type); if (!content_type || (strstr(content_type, "application/x-www-form-urlencoded"))){ if (cl>req->connection.listen_point->server->max_post_size){ ONION_ERROR("Asked to send much POST data. Limit %d. Failing.",req->connection.listen_point->server->max_post_size); return OCS_INTERNAL_ERROR; } token->extra=malloc(cl+1); // Cl + \0 token->extra_size=cl; req->parser=parse_POST_urlencode; return OCS_NEED_MORE_DATA; } // multipart. const char *mp_token=strstr(content_type, "boundary="); if (!mp_token){ ONION_ERROR("No boundary set at content-type"); return OCS_INTERNAL_ERROR; } mp_token+=9; if (cl>req->connection.listen_point->server->max_post_size) // I hope the missing part is files, else error later. cl=req->connection.listen_point->server->max_post_size; int mp_token_size=strlen(mp_token); token->extra_size=cl; // Max size of the multipart->data onion_multipart_buffer *multipart=malloc(token->extra_size+sizeof(onion_multipart_buffer)+mp_token_size+2); token->extra=(char*)multipart; multipart->boundary=(char*)multipart+sizeof(onion_multipart_buffer)+1; multipart->size=mp_token_size+4; multipart->pos=2; // First boundary already have [\r]\n readen multipart->post_total_size=cl; multipart->file_total_size=0; multipart->boundary[0]='\r'; multipart->boundary[1]='\n'; multipart->boundary[2]='-'; multipart->boundary[3]='-'; strcpy(&multipart->boundary[4],mp_token); multipart->data=(char*)multipart+sizeof(onion_multipart_buffer)+multipart->size+1; //ONION_DEBUG("Multipart POST boundary '%s'",multipart->boundary); req->parser=parse_POST_multipart_start; return OCS_NEED_MORE_DATA; }
void extended_html_blocks_init(onion_dict *context){ #line 1 if (!onion_dict_get(context, "__block_title__")) onion_dict_add(context, "__block_title__", extended_html__block_title, 0); if (!onion_dict_get(context, "__block_body__")) onion_dict_add(context, "__block_body__", extended_html__block_body, 0); if (!onion_dict_get(context, "__block_body_in__")) onion_dict_add(context, "__block_body_in__", extended_html__block_body_in, 0); #line 1 }
void base_html(onion_dict *context, onion_response *res){ #line 1 #line 1 int has_context=(context!=NULL); #line 1 if (!has_context) #line 1 context=onion_dict_new(); #line 1 #line 1 base_html_blocks_init(context); onion_response_write(res, "<!DOCTYPE html>\n" "<html>\n" " <head>\n" " <title>", 43); #line 4 { #line 4 const char *tmp; #line 4 tmp=onion_dict_get(context, "title"); #line 4 if (tmp) #line 4 onion_response_write_html_safe(res, tmp); #line 4 } onion_response_write(res, "</title>\n" " </head>\n" " <body>\n" "", 28); #line 7 { #line 7 void (*f)(onion_dict *context, onion_response *res); #line 7 f=(void*)onion_dict_get(context, "__block_content__"); #line 7 if (f) #line 7 f(context, res); #line 7 } onion_response_write(res, " \n" " </body>\n" "</html>\n" "", 21); #line 10 if (!has_context) #line 10 onion_dict_free(context); #line 1 }
void t03_create_and_free_a_lot_random(unsigned int n){ INIT_LOCAL(); onion_dict *dict; const char *value; unsigned int i; dict=onion_dict_new(); FAIL_IF_EQUAL(dict,NULL); // Linear add for (i=0;i<n;i++){ char key[16], val[16]; sprintf(key,"key %d",R1(i)); sprintf(val,"val %d",R2(i)); onion_dict_add(dict, key, val, OD_DUP_ALL); } // Linear get for (i=0;i<n;i++){ char key[16], val[16]; sprintf(key,"key %d",R1(i)); sprintf(val,"val %d",R2(i)); value=onion_dict_get(dict, key); FAIL_IF_NOT_EQUAL_STR(val,value); } // remove all for (i=n;i>0;i--){ char key[16]; int removed; sprintf(key,"key %d",R1(i-1)); //fprintf(stderr,"%s %d\n",key,i-1); removed=onion_dict_remove(dict, key); FAIL_IF_NOT_EQUAL(removed,1); } // check removed all for (i=0;i<n;i++){ char key[16], val[16]; sprintf(key,"key %d",R1(i)); sprintf(val,"val %d",R1(i)); value=onion_dict_get(dict, key); //fprintf(stderr,"%s %s\n",key,value); FAIL_IF_NOT_EQUAL(NULL,value); FAIL_IF_NOT_EQUAL_STR(NULL,value); } onion_dict_free(dict); END_LOCAL(); }
void t06_null_add(){ INIT_LOCAL(); onion_dict *dict; dict=onion_dict_new(); onion_dict_add(dict,"b",NULL,0); onion_dict_add(dict,"a",NULL,0); onion_dict_add(dict,"c","1",0); FAIL_IF_NOT_EQUAL_STR(onion_dict_get(dict,"c"),"1"); FAIL_IF_NOT_EQUAL(onion_dict_get(dict,"a"),NULL); onion_dict_free(dict); END_LOCAL(); }
void t14_dict_case_insensitive(){ INIT_LOCAL(); onion_dict *d=onion_dict_new(); onion_dict_add(d,"Test","OK", 0); FAIL_IF_NOT_EQUAL(onion_dict_get(d,"test"),NULL); onion_dict_set_flags(d,OD_ICASE); FAIL_IF_NOT_EQUAL_STR(onion_dict_get(d,"test"),"OK"); onion_dict_free(d); END_LOCAL(); }
char *t08_thread_read(onion_dict *d){ char done=0; char *ret=NULL; while (!done){ //ONION_DEBUG("Lock read"); onion_dict_lock_write(d); //ONION_DEBUG("Got read lock"); const char *test=onion_dict_get(d,"test"); if (test){ //ONION_DEBUG("Unlock"); //onion_dict_lock_write(d); //ONION_DEBUG("Got write lock"); char tmp[16]; snprintf(tmp,16,"%d",onion_dict_count(d)); onion_dict_remove(d,"test"); onion_dict_add(d,tmp,"test",OD_DUP_ALL); ONION_DEBUG("Write answer %d", onion_dict_count(d)); done=1; //ONION_DEBUG("Unlock"); onion_dict_unlock(d); ret=(char*)1; break; } //ONION_DEBUG("Unlock"); onion_dict_unlock(d); usleep(200); } //ONION_DEBUG("dict free"); onion_dict_free(d); return ret; }
/// Plexes the request depending on arguments. int oterm_get_data(oterm_data *data, onion_request *req, onion_response *res){ const char *username=onion_request_get_session(req,"username"); if (!username){ ONION_WARNING("Trying to enter authenticated area without username."); return OCS_FORBIDDEN; } oterm_session *o=(oterm_session*)onion_dict_get(data->sessions, onion_request_get_session(req,"username")); if (!o){ o=oterm_session_new(); onion_dict_lock_write(data->sessions); onion_dict_add(data->sessions,onion_request_get_session(req,"username"),o, 0); onion_dict_unlock(data->sessions); } const char *path=onion_request_get_path(req); ONION_DEBUG("Ask path %s (%p)", path, data); if (strcmp(path,"new")==0){ if (onion_request_get_post(req, "command")){ free(data->exec_command); data->exec_command=strdup(onion_request_get_post(req, "command")); } oterm_new(data, o, onion_request_get_session(req, "username"), onion_request_get_session(req, "nopam") ? 0 : 1 ); return onion_shortcut_response("ok", 200, req, res); } if (strcmp(path,"status")==0) return oterm_status(o,req, res); return OCS_NOT_PROCESSED; }
/** * @short Gets the sessionid cookie, if any, and sets it to req->session_id. * @memberof onion_request_t */ void onion_request_guess_session_id(onion_request *req){ if (req->session_id) // already known. return; const char *v=onion_dict_get(req->headers, "Cookie"); ONION_DEBUG("Session ID, maybe from %s",v); char *r=NULL; onion_dict *session; do{ // Check all possible sessions if (r) free(r); if (!v) return; v=strstr(v,"sessionid="); if (!v) // exit point, no session found. return; v+=10; r=strdup(v); // Maybe allocated more memory, not much anyway. char *p=r; while (*p!='\0' && *p!=';') p++; *p='\0'; ONION_DEBUG0("Checking if %s exists in sessions", r); session=onion_sessions_get(req->server->sessions, r); }while(!session); req->session_id=r; req->session=session; ONION_DEBUG("Session ID, from cookie, is %s",req->session_id); }
void *t08_thread_write(onion_dict *d){ int n=0; while (n!=N_READERS){ int i; n=0; //ONION_DEBUG("Lock read"); onion_dict_lock_read(d); //ONION_DEBUG("Got read lock"); for (i=0;i<N_READERS;i++){ char tmp[16]; snprintf(tmp,16,"%d",i+1); const char *r=onion_dict_get(d,tmp); if (r) n++; } //ONION_DEBUG("Unlock"); onion_dict_unlock(d); //ONION_DEBUG("Lock write"); onion_dict_lock_write(d); //ONION_DEBUG("Got write lock"); onion_dict_add(d, "test", "test", OD_DUP_ALL|OD_REPLACE); //ONION_DEBUG("Unlock"); onion_dict_unlock(d); ONION_DEBUG("Found %d answers, should be %d.", n, N_READERS); usleep(200); } onion_dict_free(d); return (char*)1; }
void cmpdict(onion_dict *d, const char *key, const char *value, int flags){ if (flags&OD_DICT){ onion_dict_preorder((onion_dict*)value, cmpdict, onion_dict_get_dict(d, key)); onion_dict_preorder(onion_dict_get_dict(d, key), cmpdict, (onion_dict*)value); } else FAIL_IF_NOT_EQUAL_STR(value, onion_dict_get(d, key)); }
void t03_create_add_free_full_flow(){ INIT_LOCAL(); onion_request *req; int ok; req=onion_request_new(custom_io); FAIL_IF_EQUAL(req,NULL); FAIL_IF_NOT_EQUAL(req->connection.fd, -1); ok=REQ_WRITE(req,"GET /myurl%20/is/very/deeply/nested?test=test&query2=query%202&more_query=%20more%20query+10&empty&empty2 HTTP/1.0\n"); FAIL_IF_NOT(ok); ok=REQ_WRITE(req,"Host: 127.0.0.1\r\n"); FAIL_IF_NOT(ok); ok=REQ_WRITE(req,"Other-Header: My header is very long and with spaces...\n"); FAIL_IF_NOT(ok); ok=REQ_WRITE(req,"Final-Header: This header do not get into headers as a result of now knowing if its finished, or if its multiline.\n"); FAIL_IF_NOT(ok); FAIL_IF_EQUAL(req->flags,OR_GET|OR_HTTP11); FAIL_IF_EQUAL(req->headers, NULL); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->headers,"Host"), "127.0.0.1"); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->headers,"Other-Header"), "My header is very long and with spaces..."); FAIL_IF_NOT_EQUAL_STR(req->fullpath,"/myurl /is/very/deeply/nested"); FAIL_IF_NOT_EQUAL(req->path,NULL); onion_request_process(req); // this should set the req->path. FAIL_IF_NOT_EQUAL_STR(req->path,"myurl /is/very/deeply/nested"); FAIL_IF_EQUAL(req->GET, NULL); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->GET,"test"), "test"); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->GET,"query2"), "query 2"); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->GET,"more_query"), " more query 10"); FAIL_IF_EQUAL(onion_request_get_query(req, "empty"), NULL); FAIL_IF_EQUAL(onion_request_get_query(req, "empty2"), NULL); FAIL_IF_NOT_EQUAL(onion_request_get_query(req, "empty3"), NULL); onion_request_free(req); END_LOCAL(); }
void t11_cookies(){ INIT_LOCAL(); onion_request *req; int ok; req=onion_request_new(custom_io); FAIL_IF_EQUAL(req,NULL); FAIL_IF_NOT_EQUAL(req->connection.fd, -1); { const char *query="GET / HTTP/1.0\n" "Content-Type: application/x-www-form-urlencoded\n" "Host: 127.0.0.1\n\r" "Cookie: key1=value1; key2=value2;\n" "Accept-Language: en\n"; // Missing \n caused memleak, to check with valgrind ok=onion_request_write(req,query,strlen(query)); } FAIL_IF_EQUAL(ok,OCS_INTERNAL_ERROR); FAIL_IF_NOT_EQUAL_STR(onion_request_get_header(req,"Host"),"127.0.0.1"); FAIL_IF_NOT_EQUAL_STR(onion_request_get_header(req,"Cookie"), "key1=value1; key2=value2;"); FAIL_IF_NOT_EQUAL_STR(onion_request_get_cookie(req,"key1"), "value1"); FAIL_IF_NOT_EQUAL_STR(onion_request_get_cookie(req,"key2"), "value2"); FAIL_IF_EQUAL_STR(onion_request_get_cookie(req," key2"), "value2"); onion_dict *cookies=onion_request_get_cookies_dict(req); FAIL_IF_EQUAL(cookies, NULL); FAIL_IF_NOT_EQUAL_STR(onion_dict_get(cookies,"key1"), "value1"); FAIL_IF_NOT_EQUAL_STR(onion_dict_get(cookies,"key2"), "value2"); onion_request_free(req); END_LOCAL(); }
/** * @short Prepares the PUT * * It saves the data to a temporal file, which name is stored at data. */ static onion_connection_status prepare_PUT(onion_request *req){ onion_token *token=req->parser_data; const char *content_size=onion_dict_get(req->headers, "Content-Length"); if (!content_size){ ONION_ERROR("I need the Content-Length header to get data"); return OCS_INTERNAL_ERROR; } size_t cl=atol(content_size); if (cl>req->connection.listen_point->server->max_file_size){ ONION_ERROR("Trying to PUT a file bigger than allowed size"); return OCS_INTERNAL_ERROR; } req->data=onion_block_new(); char filename[]="/tmp/onion-XXXXXX"; int fd=mkstemp(filename); if (fd<0) ONION_ERROR("Could not create temporary file at %s.", filename); onion_block_add_str(req->data, filename); ONION_DEBUG0("Creating PUT file %s (%d bytes long)", filename, token->extra_size); if (!req->FILES){ req->FILES=onion_dict_new(); } { const char *filename=onion_block_data(req->data); onion_dict_add(req->FILES,"filename", filename, 0); } if (cl==0){ ONION_DEBUG0("Created 0 length file"); close(fd); return OCS_REQUEST_READY; } int *pfd=onion_low_scalar_malloc(sizeof(fd)); *pfd=fd; assert(token->extra==NULL); token->extra=(char*)pfd; token->extra_size=cl; token->pos=0; req->parser=parse_PUT; return OCS_NEED_MORE_DATA; }
void t01_create_add_free_10(){ INIT_LOCAL(); onion_dict *dict; const char *value; dict=onion_dict_new(); FAIL_IF_EQUAL(dict,NULL); // Get before anything in value=onion_dict_get(dict, "Request"); FAIL_IF_NOT_EQUAL(value,NULL); // basic add int i; char tmp[256]; for (i=0;i<10;i++){ snprintf(tmp,sizeof(tmp),"%d",(i*13)%10); ////ONION_DEBUG("add key %s",tmp); onion_dict_add(dict, tmp, "GET /", OD_DUP_ALL); value=onion_dict_get(dict, tmp); FAIL_IF_NOT_EQUAL_STR(value,"GET /"); //onion_dict_print_dot(dict); } for (i=0;i<10;i++){ snprintf(tmp,sizeof(tmp),"%d",i); ////ONION_DEBUG("rm key %s",tmp); onion_dict_remove(dict, tmp); value=onion_dict_get(dict, tmp); FAIL_IF_NOT_EQUAL(value,NULL); //onion_dict_print_dot(dict); } onion_dict_free(dict); END_LOCAL(); }
void t05_create_add_free_POST(){ INIT_LOCAL(); onion_request *req; int ok; req=onion_request_new(custom_io); FAIL_IF_EQUAL(req,NULL); FAIL_IF_NOT_EQUAL(req->connection.fd, -1); const char *query="POST /myurl%20/is/very/deeply/nested?test=test&query2=query%202&more_query=%20more%20query+10 HTTP/1.0\n" "Host: 127.0.0.1\n\rContent-Length: 50\n" "Other-Header: My header is very long and with spaces...\r\n\r\nempty_post=&post_data=1&post_data2=2&empty_post_2=\n"; int i; // Straight write, with clean (keep alive like) for (i=0;i<10;i++){ FAIL_IF_NOT_EQUAL(req->flags,0); ok=REQ_WRITE(req,query); FAIL_IF_NOT_EQUAL(ok, OCS_CLOSE_CONNECTION); FAIL_IF_EQUAL(req->flags,OR_GET|OR_HTTP11); FAIL_IF_EQUAL(req->headers, NULL); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->headers,"Host"), "127.0.0.1"); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->headers,"Other-Header"), "My header is very long and with spaces..."); FAIL_IF_NOT_EQUAL_STR(req->fullpath,"/myurl /is/very/deeply/nested"); FAIL_IF_NOT_EQUAL_STR(req->path,"myurl /is/very/deeply/nested"); FAIL_IF_EQUAL(req->GET,NULL); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->GET,"test"), "test"); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->GET,"query2"), "query 2"); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->GET,"more_query"), " more query 10"); const onion_dict *post=onion_request_get_post_dict(req); FAIL_IF_EQUAL(post,NULL); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(post,"post_data"), "1"); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(post,"post_data2"), "2"); FAIL_IF_NOT_EQUAL_STR( onion_request_get_post(req, "empty_post"), ""); FAIL_IF_NOT_EQUAL_STR( onion_request_get_post(req, "empty_post_2"), ""); onion_request_clean(req); FAIL_IF_NOT_EQUAL(req->GET,NULL); } onion_request_free(req); END_LOCAL(); }
void t17_merge(){ INIT_LOCAL(); onion_dict *a=onion_dict_from_json("{\"hello\":\"world\"}"); onion_dict *b=onion_dict_from_json("{\"bye\":\"_world_\", \"sub\": { \"hello\": \"world!\" } }"); onion_dict_merge(a,b); FAIL_IF_NOT_EQUAL_STR(onion_dict_get(a,"bye"), "_world_"); FAIL_IF_NOT_EQUAL_STR(onion_dict_rget(a,"sub","hello",NULL), "world!"); onion_dict_free(b); FAIL_IF_NOT_EQUAL_STR(onion_dict_rget(a,"sub","hello",NULL), "world!"); onion_dict_free(a); END_LOCAL(); }
void t01_create_add_free(){ INIT_LOCAL(); onion_response *res; res=onion_response_new(NULL); FAIL_IF_NOT_EQUAL(res->code, 200); FAIL_IF_EQUAL(res,NULL); onion_response_set_length(res,1024); FAIL_IF_NOT_EQUAL_STR(onion_dict_get(res->headers,"Content-Length"),"1024"); onion_response_free(res); END_LOCAL(); }
/** * @short Returns the language code of the current request * @memberof onion_request_t * * Returns the language code for the current request, from the header. * If none the returns "C". * * Language code is short code. No localization by the moment. * * @returns The language code for this request or C. Data must be freed. */ const char *onion_request_get_language_code(onion_request *req) { const char *lang=onion_dict_get(req->headers, "Accept-Language"); if (lang) { char *l=onion_low_strdup(lang); char *p=l; while (*p) { // search first part if (*p=='-' || *p==';' || *p==',') { *p=0; break; } p++; } //ONION_DEBUG("Language is %s", l); return l; } return onion_low_strdup("C"); }
void t09_thread_war_thread(onion_dict *d){ int i; char tmp[16]; for (i=0;i<WARLOOPS;i++){ snprintf(tmp,16,"%04X",i); if (rand()%1){ onion_dict_lock_read(d); onion_dict_get(d,tmp); onion_dict_unlock(d); } else{ onion_dict_lock_write(d); onion_dict_add(d,tmp,tmp,OD_DUP_ALL|OD_REPLACE); onion_dict_unlock(d); } } onion_dict_free(d); }
/** * @short Gets a dictionary string value, recursively * @memberof onion_dict_t * * Loops inside given dictionaries to get the given value * * @param dict The dictionary * @param key The key list, one per arg, end with NULL * @returns The const string if valid, or NULL */ const char *onion_dict_rget(const onion_dict *dict, const char *key, ...){ const onion_dict *d=dict; const char *k=key; const char *nextk; va_list va; va_start(va, key); while (d){ nextk=va_arg(va, const char *); if (!nextk){ va_end(va); return onion_dict_get(d, k); } d=onion_dict_get_dict(d, k); k=nextk; } va_end(va); return NULL; }
void t18_json_escape_codes(){ INIT_LOCAL(); onion_dict *d=onion_dict_from_json("{ \"hello\": \"Hello\\nworld\", \"second\":\"second\" }"); FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "Hello\nworld"); FAIL_IF_NOT_STRSTR(onion_dict_get(d, "second"), "second"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\uD83D\\uDE02\" }"); FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "😂"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\uD83D\\uDE03\" }"); // Another code point FAIL_IF_STRSTR(onion_dict_get(d, "hello"), "😂"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\u007b\" }"); // simple unicode FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "{"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\\"Quote\" }"); // Escape quote FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "\"Quote"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\"Quote\" }"); // Must fail FAIL_IF_NOT_EQUAL(d, NULL); d=onion_dict_new(); onion_dict_add(d, "hello", "Hello\nWorld\\", 0); onion_dict_add(d, "second", "123", 0); onion_block *b=onion_dict_to_json(d); FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"Hello\\nWorld\\\\\", \"second\":\"123\"}"); onion_block_free(b); onion_dict_free(d); d=onion_dict_new(); onion_dict_add(d, "hello", "😂\t\n😂", 0); b=onion_dict_to_json(d); FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"😂\\t\\n😂\"}"); onion_block_free(b); onion_dict_free(d); d=onion_dict_new(); onion_dict_add(d, "hello", "\02\03\x7f", 0); b=onion_dict_to_json(d); FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"\\u0002\\u0003\\u007F\"}"); onion_block_free(b); onion_dict_free(d); END_LOCAL(); }
void t01_basic(){ INIT_LOCAL(); Onion::Dict normal; normal.add("Hello", "World"); onion_dict *d=onion_dict_new(); onion_dict_add(d, "Hello", "2", 0); Onion::Dict non_owner(d); FAIL_IF_NOT_EQUAL_STRING(non_owner.get("Hello"), "2"); Onion::Dict owner(d, true); FAIL_IF_NOT_EQUAL_STRING(owner.get("Hello"), "2"); non_owner.add("non-owner", "true"); FAIL_IF_NOT_EQUAL_STRING(owner.get("non-owner"), "true"); FAIL_IF_NOT_EQUAL_STRING(onion_dict_get(d,"non-owner"), "true"); END_LOCAL(); }
/** * @short Given a filename or extensiton, it returns the proper mime type. * * If onion_mime_set was called before, it is used, else it reads mime types /etc/mime.types. * * Full mime catalog, from /etc/mime.types, takes about 36kb on ubuntu 10.10, may depend on * how many mime types are known. * * If none is found, returns text/plain. */ const char *onion_mime_get(const char *filename){ if (!onion_mime_dict) onion_mime_fill(); const char *extension=filename; int l=strlen(filename); int i; for (i=l;i--;){ if (extension[i]=='.'){ extension=&extension[i+1]; break; } } //ONION_DEBUG("I know %d mime types", onion_dict_count(onion_mime_dict)); const char *r=onion_dict_get(onion_mime_dict, extension); if (r) return r; //ONION_DEBUG("Mime type for extension '%s' %s",extension, r); return "text/plain"; }
/** * @short Gets the sessionid cookie, if any, and sets it to req->session_id. * @memberof onion_request_t */ void onion_request_guess_session_id(onion_request *req) { if (req->session_id) // already known. return; const char *ov=onion_dict_get(req->headers, "Cookie"); const char *v=ov; ONION_DEBUG("Session ID, maybe from %s",v); char *r=NULL; onion_dict *session=NULL; do { // Check all possible sessions if (r) { onion_low_free(r); r=NULL; } if (!v) return; v=strstr(v,"sessionid="); if (!v) // exit point, no session found. return; if (v>ov && isalnum(v[-1])) { ONION_DEBUG("At -1: %c %d (%p %p)",v[-1],isalnum(v[-1]),v,ov); v=strstr(v,";"); } else { v+=10; r=onion_low_strdup(v); // Maybe allocated more memory, not much anyway. char *p=r; while (*p!='\0' && *p!=';') p++; *p='\0'; ONION_DEBUG0("Checking if %s exists in sessions", r); session=onion_sessions_get(req->connection.listen_point->server->sessions, r); } } while(!session); req->session_id=r; req->session=session; ONION_DEBUG("Session ID, from cookie, is %s",req->session_id); }
onion_connection_status sessions(void *ignore, onion_request *req){ onion_response *res=onion_response_new(req); onion_dict *session=onion_request_get_session_dict(req); if (onion_request_get_query(req, "reset")){ onion_request_session_free(req); onion_response_write0(res, "ok"); return onion_response_free(res); } const char *n=onion_dict_get(session, "count"); int count; if (n){ count=atoi(n)+1; } else count=0; char tmp[16]; snprintf(tmp,sizeof(tmp),"%d",count); onion_dict_add(session, "count", tmp, OD_DUP_ALL|OD_REPLACE); if (onion_response_write_headers(res)==OR_SKIP_CONTENT) // Head return onion_response_free(res); onion_response_write0(res, "<html><body>\n<h1>Session data</h1>\n"); if (session){ onion_response_printf(res,"<ul>\n"); onion_dict_preorder(session, print_dict_element, res); onion_response_printf(res,"</ul>\n"); } else{ onion_response_printf(res,"No session data"); } onion_response_write0(res,"</body></html>"); return onion_response_free(res); }
/** * @short Prepares the CONTENT LENGTH */ static onion_connection_status prepare_CONTENT_LENGTH(onion_request *req){ onion_token *token=req->parser_data; const char *content_size=onion_dict_get(req->headers, "Content-Length"); if (!content_size){ ONION_ERROR("I need the Content-Length header to get data"); return OCS_INTERNAL_ERROR; } size_t cl=atol(content_size); if (cl>req->connection.listen_point->server->max_post_size){ ONION_ERROR("Trying to set more data at server than allowed %d", req->connection.listen_point->server->max_post_size); return OCS_INTERNAL_ERROR; } req->data=onion_block_new(); token->extra=NULL; token->extra_size=cl; token->pos=0; req->parser=parse_CONTENT_LENGTH; return OCS_NEED_MORE_DATA; }