void t02_full_cycle_http10(){ INIT_LOCAL(); onion *server=onion_new(0); onion_add_listen_point(server,NULL,NULL,onion_buffer_listen_point_new()); onion_request *request; char buffer[4096]; memset(buffer,0,sizeof(buffer)); request=onion_request_new(server->listen_points[0]); onion_response *response=onion_response_new(request); onion_response_set_length(response, 30); FAIL_IF_NOT_EQUAL(response->length,30); onion_response_write_headers(response); onion_response_write0(response,"123456789012345678901234567890"); onion_response_flush(response); FAIL_IF_NOT_EQUAL(response->sent_bytes,30); onion_response_free(response); strncpy(buffer,onion_buffer_listen_point_get_buffer_data(request),sizeof(buffer)); onion_request_free(request); onion_free(server); FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.0 200 OK\r\n"); FAIL_IF_NOT_STRSTR(buffer, "Connection: Keep-Alive\r\n"); FAIL_IF_NOT_STRSTR(buffer, "Content-Length: 30\r\n"); FAIL_IF_NOT_STRSTR(buffer, "Server: libonion"); FAIL_IF_NOT_STRSTR(buffer, "coralbits"); FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\n123456789012345678901234567890"); END_LOCAL(); }
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 t06_create_add_free_POST_toobig(){ 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); onion_set_max_post_size(server, 10); // Very small limit 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: 24\n" "Other-Header: My header is very long and with spaces...\r\n\r\npost_data=1&post_data2=2&post_data=1&post_data2=2"; 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_INTERNAL_ERROR); onion_request_clean(req); FAIL_IF_NOT_EQUAL(req->GET,NULL); } onion_request_free(req); END_LOCAL(); }
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 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(); }
int curl_get(CURL *curl, const char *url){ CURLcode res=curl_easy_perform(curl); FAIL_IF_NOT_EQUAL((int)res,0); if (res!=0){ ONION_ERROR("%s",curl_easy_strerror(res)); } long int http_code; res=curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &http_code); FAIL_IF_NOT_EQUAL((int)res,0); char buffer[1024]; size_t l; curl_easy_recv(curl,buffer,sizeof(buffer),&l); FAIL_IF_NOT_EQUAL_INT((int)http_code, HTTP_OK); return http_code; }
void t02_several_add_methods(){ INIT_TEST(); onion_block *block=onion_block_new(); FAIL_IF_EQUAL(block, NULL); int i; for (i=0;i<1024;i++){ onion_block_add_char(block, (char)i); } onion_block_clear(block); onion_block_add_str(block, "first "); for (i=0;i<1024;i++) onion_block_add_str(block, "test "); FAIL_IF_NOT_STRSTR(onion_block_data(block), "test"); for (i=0;i<1024;i++) onion_block_add_data(block, "world", 4); FAIL_IF_STRSTR(onion_block_data(block), "world"); FAIL_IF_NOT_STRSTR(onion_block_data(block), "worl"); int s=onion_block_size(block); onion_block_add_block(block, block); FAIL_IF_NOT_EQUAL(onion_block_size(block), s+s); onion_block_free(block); END_TEST(); }
void t10_repeated_header(){ INIT_LOCAL(); onion_request *req; int ok; onion_set_max_post_size(server, 1024); 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" "Content-Length: 24\n" "Accept-Language: en\n" "Content-Type: application/x-www-form-urlencoded-bis\n\n"; 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,"Content-Length"),"24"); FAIL_IF_NOT_EQUAL_STR(onion_request_get_header(req,"Content-Type"),"application/x-www-form-urlencoded"); onion_request_free(req); END_LOCAL(); }
void t01_handle_static_request(){ INIT_LOCAL(); char ok; onion *server=onion_new(0); onion_listen_point *lp=onion_buffer_listen_point_new(); onion_add_listen_point(server, NULL, NULL, lp); onion_request *request=onion_request_new(lp); FILL(request,"GET / HTTP/1.1\n"); onion_handler *handler=onion_handler_static("Not ready",302); FAIL_IF_NOT(handler); onion_set_root_handler(server, handler); onion_response *response=onion_response_new(request); ok=onion_handler_handle(handler, request, response); FAIL_IF_NOT_EQUAL(ok, OCS_PROCESSED); onion_response_free(response); const char *buffer=onion_buffer_listen_point_get_buffer_data(request); FAIL_IF_EQUAL_STR(buffer,""); FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.1 302 REDIRECT\r\n"); FAIL_IF_NOT_STRSTR(buffer, "\r\nContent-Length: 9\r\n"); FAIL_IF_NOT_STRSTR(buffer, "libonion"); FAIL_IF_STRSTR(buffer, "License: AGPL"); // License is now LGPL, no need to advertise FAIL_IF_STRSTR(buffer, "License"); FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\nNot ready"); onion_request_free(request); onion_free(server); END_LOCAL(); }
void t01_codecs_base64_decode(){ INIT_LOCAL(); { /// Text from wikipedia. Leviathan by Hobbes. char *orig ="dGVzdDphYWE="; char *realtext="test:aaa"; char *res=onion_base64_decode(orig, NULL); FAIL_IF_NOT_EQUAL_STR(res,realtext); free(res); } { /// Text from wikipedia. Leviathan by Hobbes. char *orig ="TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz\n" "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg\n" "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu\n" "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo\n" "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=\n"; char *realtext="Man is distinguished, not only by his reason, but by this singular passion from other animals," " which is a lust of the mind, that by a perseverance of delight in the continued and" " indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."; int l; char *res=onion_base64_decode(orig, &l); //fprintf(stderr,"l %d len %ld\n",l,strlen(realtext)); FAIL_IF_NOT_EQUAL(l,strlen(realtext)); FAIL_IF_NOT_EQUAL_STR(res,realtext); free(res); } END_LOCAL(); }
/// A BUG were detected: transformed \n to \r\n on files. void t03_post_carriage_return_new_lines_file(){ INIT_LOCAL(); buffer *b=buffer_new(1024); expected_post post={};; post.filename="file.dat"; post.test_ok=0; // Not ok as not called processor yet post.tmpfilename=NULL; post.size=3; onion_server *server=onion_server_new(); onion_server_set_write(server, (void*)&buffer_append); onion_server_set_root_handler(server, onion_handler_new((void*)&post_check,&post,NULL)); onion_request *req=onion_request_new(server,b,"test"); #define POST_EMPTY "POST / HTTP/1.1\nContent-Type: multipart/form-data; boundary=end\nContent-Length:81\n\n--end\nContent-Disposition: text/plain; name=\"file\"; filename=\"file.dat\"\n\n\n\r\n\n--end--" //ONION_DEBUG("%s",POST_EMPTY); onion_request_write(req,POST_EMPTY,sizeof(POST_EMPTY)); FAIL_IF_NOT_EQUAL(post.test_ok,1); #undef POST_EMPTY onion_request_clean(req); post.test_ok=0; // Not ok as not called processor yet #define POST_EMPTYR "POST / HTTP/1.1\r\nContent-Type: multipart/form-data; boundary=end\r\nContent-Length:85\r\n\r\n--end\r\nContent-Disposition: text/plain; name=\"file\"; filename=\"file.dat\"\r\n\r\n\n\r\n\r\n--end--" onion_request_write(req,POST_EMPTYR,sizeof(POST_EMPTYR)); FAIL_IF_NOT_EQUAL(post.test_ok,1); #undef POST_EMPTYR onion_request_free(req); if (post.tmpfilename){ struct stat st; FAIL_IF_EQUAL(stat(post.tmpfilename,&st), 0); // Should not exist free(post.tmpfilename); } if (post.tmplink) free(post.tmplink); onion_server_free(server); buffer_free(b); END_LOCAL(); }
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(); }
/// A BUG were detected: transformed \n to \r\n on files. void t02_post_new_lines_file(){ INIT_LOCAL(); expected_post post={};; post.filename="file.dat"; post.test_ok=0; // Not ok as not called processor yet post.tmpfilename=NULL; post.size=1; onion *server=onion_new(0); onion_listen_point *lp=onion_buffer_listen_point_new(); onion_add_listen_point(server,NULL,NULL,lp); onion_set_root_handler(server, onion_handler_new((void*)&post_check,&post,NULL)); onion_request *req=onion_request_new(lp); #define POST_EMPTY "POST / HTTP/1.1\nContent-Type: multipart/form-data; boundary=end\nContent-Length:81\n\n--end\nContent-Disposition: text/plain; name=\"file\"; filename=\"file.dat\"\n\n\n\n--end--" onion_request_write(req,POST_EMPTY,sizeof(POST_EMPTY)); FAIL_IF_NOT_EQUAL(post.test_ok,1); #undef POST_EMPTY onion_request_clean(req); post.test_ok=0; // Not ok as not called processor yet #define POST_EMPTYR "POST / HTTP/1.1\r\nContent-Type: multipart/form-data; boundary=end\r\nContent-Length:85\r\n\r\n--end\r\nContent-Disposition: text/plain; name=\"file\"; filename=\"file.dat\"\r\n\r\n\n\r\n--end--" onion_request_write(req,POST_EMPTYR,sizeof(POST_EMPTYR)); FAIL_IF_NOT_EQUAL(post.test_ok,1); #undef POST_EMPTYR onion_request_free(req); if (post.tmpfilename){ struct stat st; FAIL_IF_EQUAL(stat(post.tmpfilename,&st), 0); // Should not exist free(post.tmpfilename); } if (post.tmplink) free(post.tmplink); onion_free(server); END_LOCAL(); }
void t07_multiline_headers(){ INIT_LOCAL(); onion_request *req; int ok; onion_set_max_post_size(server, 1024); 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" "Host: 127.0.0.1\n\rContent-Length: 24\n" "Other-Header: My header is very long and with several\n lines\n" "Extra-Other-Header: My header is very long and with several\n \n lines\n" "My-Other-Header: My header is very long and with several\n\tlines\n\n"; 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,"other-header"),"My header is very long and with several lines"); FAIL_IF_NOT_EQUAL_STR(onion_request_get_header(req,"extra-other-header"),"My header is very long and with several lines"); FAIL_IF_NOT_EQUAL_STR(onion_request_get_header(req,"My-other-header"),"My header is very long and with several lines"); onion_request_clean(req); { const char *query="GET / HTTP/1.0\n" "Host: 127.0.0.1\n\rContent-Length: 24\n" "Other-Header: My header is very long and with several\n lines\n" "My-Other-Header: My header is very long and with several\nlines\n\n"; ok=onion_request_write(req,query,strlen(query)); } FAIL_IF_NOT_EQUAL(ok,OCS_INTERNAL_ERROR); // No \t at my-other-header onion_request_free(req); END_LOCAL(); }
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(); }
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 t02_create_add_free_overflow(){ INIT_LOCAL(); onion_request *req; int ok, i; req=onion_request_new(custom_io); FAIL_IF_NOT_EQUAL(req->connection.fd, -1); FAIL_IF_EQUAL(req,NULL); char of[14096]; for (i=0;i<sizeof(of);i++) of[i]='a'+i%26; of[i-1]='\0'; char get[14096*4]; sprintf(get,"%s %s %s",of,of,of); ok=REQ_WRITE(req,get); FAIL_IF_NOT_EQUAL(ok,OCS_INTERNAL_ERROR); onion_request_clean(req); sprintf(get,"%s %s %s\n",of,of,of); ok=REQ_WRITE(req,get); FAIL_IF_NOT_EQUAL(ok,OCS_INTERNAL_ERROR); onion_request_clean(req); sprintf(get,"GET %s %s\n",of,of); ok=REQ_WRITE(req,get); printf("%d\n",ok); FAIL_IF_NOT_EQUAL(ok,OCS_INTERNAL_ERROR); onion_request_free(req); END_LOCAL(); }
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 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(); }
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 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(); }
void t06_create_add_free_bad_method(){ INIT_LOCAL(); onion_request *req; int ok; req=onion_request_new(custom_io); //FAIL_IF_NOT_EQUAL(req->socket, (void*)111); FAIL_IF_EQUAL(req,NULL); ok=REQ_WRITE(req,"XGETX / HTTP/1.1\n"); FAIL_IF_NOT_EQUAL(ok,OCS_NOT_IMPLEMENTED); onion_request_free(req); END_LOCAL(); }
void t13_dict_rget(){ 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); onion_dict_add(B, "C", C, OD_DICT); onion_dict_add(C, "a", "hello", 0); FAIL_IF_NOT_EQUAL(onion_dict_rget(A, "B", NULL), NULL); FAIL_IF_NOT_EQUAL(onion_dict_rget(A, "C", NULL), NULL); FAIL_IF_NOT_EQUAL(onion_dict_rget(A, "B", "C", NULL), NULL); FAIL_IF_NOT_EQUAL(onion_dict_rget_dict(A, "B", NULL), B); FAIL_IF_NOT_EQUAL(onion_dict_rget_dict(A, "C", NULL), C); FAIL_IF_NOT_EQUAL(onion_dict_rget_dict(A, "B", "C", NULL), C); FAIL_IF_NOT_EQUAL_STR(onion_dict_rget(A, "B", "C", "a", NULL), "hello"); FAIL_IF_NOT_EQUAL(onion_dict_rget_dict(A, "B", "C", "a", NULL), NULL); // This should remove all the others, as they hang from it. onion_dict_free(A); END_LOCAL(); }
void t09_very_long_header(){ INIT_LOCAL(); onion_request *req; int ok; onion_set_max_post_size(server, 1024); req=onion_request_new(custom_io); FAIL_IF_EQUAL(req,NULL); FAIL_IF_NOT_EQUAL(req->connection.fd, -1); { const char *query_t="GET / HTTP/1.0\n" "Content-Type: application/x-www-form-urlencoded\n" "Host: 127.0.0.1\n\r" "Content-Length: 24\n" "Accept-Language: en\n" "Content-Type: "; const int longsize=strlen(query_t)+16; char *query=malloc(longsize); // 1MB enought? strcpy(query, query_t); int i; for (i=strlen(query); i<longsize -2; i++) // fill with crap query[i]='a'+(i%30); query[longsize-3]='\n'; query[longsize-2]='\n'; query[longsize-1]=0; FAIL_IF_NOT_EQUAL_INT(strlen(query), longsize-1); ok=onion_request_write(req, query, longsize); free(query); } FAIL_IF_EQUAL_INT(ok,OCS_INTERNAL_ERROR); onion_request_free(req); END_LOCAL(); }
void t08_threaded_lock(){ INIT_LOCAL(); onion_dict *d=onion_dict_new(); pthread_t thread[N_READERS]; int i; for (i=0;i<N_READERS;i++){ onion_dict *d2=onion_dict_dup(d); pthread_create(&thread[i], NULL, (void*)t08_thread_read, d2); } //sleep(1); t08_thread_write(d); for (i=0;i<N_READERS;i++){ char *v; pthread_join(thread[i],(void**) &v); FAIL_IF_NOT_EQUAL(v, (char *)v); } END_LOCAL(); }
void t04_codecs_base64_encode_decode(){ INIT_LOCAL(); char text[1025]; int tlength=0; int i,j; int l; for (i=0;i<100;i++){ tlength=1024*(rand()/((double)RAND_MAX)); for (j=0;j<tlength;j++) text[j]=rand()&0x0FF; text[j]=0; char *enc=onion_base64_encode(text, tlength); char *res=onion_base64_decode(enc, &l); FAIL_IF_NOT_EQUAL(l,tlength); FAIL_IF( memcmp(res,text, l)!=0 ); free(res); free(enc); } END_LOCAL(); }
onion_connection_status post_check(expected_post *post, onion_request *req){ const char *filename=onion_request_get_post(req,"file"); const char *tmpfilename=onion_request_get_file(req,"file"); post->test_ok=1; ONION_DEBUG("Got filename %s, expected %s",filename,post->filename); if (strcmp(filename, post->filename)!=0){ ONION_ERROR("File names do not match: %s %s", filename, post->filename); post->test_ok=0; } ONION_DEBUG("Temporal file %s",tmpfilename); struct stat st; if (stat(tmpfilename, &st)!=0){ ONION_ERROR("Could not stat temp file"); post->test_ok=0; } if (st.st_size!=post->size){ ONION_ERROR("Size do not match, expected %d, got %d",post->size,st.st_size); post->test_ok=0; } char tmp[256]; snprintf(tmp,sizeof(tmp),"%s-",tmpfilename); ONION_DEBUG("Linking to %s", tmp); FAIL_IF_NOT_EQUAL(link(tmpfilename, tmp),0); if (post->tmplink) free(post->tmplink); post->tmplink=strdup(tmp); if (post->tmpfilename) free(post->tmpfilename); post->tmpfilename=strdup(tmpfilename); return OCS_INTERNAL_ERROR; }
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(); }
void t03_codecs_base64_encode_decode_10(){ INIT_LOCAL(); char text[11]; int i,j; int l; for (i=0;i<10;i++){ //memset(text,0,sizeof(text)); for (j=0;j<i;j++) text[j]='1'+j; text[j]='\0'; char *enc=onion_base64_encode(text, i); char *res=onion_base64_decode(enc, &l); //fprintf(stderr, "%s:%d Encoded '%s', is '%s', decoded as '%s'\n",__FILE__,__LINE__,text, enc, res); FAIL_IF_NOT_EQUAL(l,i); FAIL_IF( memcmp(res,text, l)!=0 ); free(res); free(enc); } END_LOCAL(); }
void t10_tojson(){ INIT_LOCAL(); onion_dict *d=onion_dict_new(); const char *tmp; int s; onion_block *b; b=onion_dict_to_json(d); tmp=onion_block_data(b); ONION_DEBUG("Json returned is '%s'", tmp); FAIL_IF_NOT_EQUAL_STR(tmp,"{}"); onion_block_free(b); onion_dict_add(d, "test", "json", 0); b=onion_dict_to_json(d); tmp=onion_block_data(b); s=onion_block_size(b); ONION_DEBUG("Json returned is '%s'", tmp); FAIL_IF(s<=0); FAIL_IF_EQUAL(strstr(tmp,"{"), NULL); FAIL_IF_EQUAL(strstr(tmp,"}"), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"test\""), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"json\""), NULL); FAIL_IF_NOT_EQUAL(strstr(tmp,","), NULL); onion_block_free(b); onion_dict_add(d, "other", "data", 0); b=onion_dict_to_json(d); tmp=onion_block_data(b); s=onion_block_size(b); ONION_DEBUG("Json returned is '%s'", tmp); FAIL_IF(s<=0); FAIL_IF_EQUAL(strstr(tmp,"{"), NULL); FAIL_IF_EQUAL(strstr(tmp,"}"), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"test\""), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"json\""), NULL); FAIL_IF_EQUAL(strstr(tmp,","), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"other\""), NULL); FAIL_IF_EQUAL(strstr(tmp,"\"data\""), NULL); onion_block_free(b); onion_dict_add(d, "with\"", "data\n", 0); b=onion_dict_to_json(d); tmp=onion_block_data(b); s=onion_block_size(b); ONION_DEBUG("Json returned is '%s'", tmp); FAIL_IF(s<=0); FAIL_IF_EQUAL(strstr(tmp,"\\n"), NULL); FAIL_IF_EQUAL(strstr(tmp,"\\\""), NULL); onion_block_free(b); onion_dict_free(d); END_LOCAL(); }