/// 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 t05_server_with_pipes(){ INIT_LOCAL(); onion_server *server=onion_server_new(); onion_server_set_write(server, (onion_write)write_p); onion_server_set_root_handler(server, onion_handler_static("Works with pipes", 200)); int p[2]; int error=pipe(p); if (error){ FAIL("Could not create pipe."); END_LOCAL(); } onion_request *req=onion_request_new(server, &p[1], NULL); #define S "GET / HTTP/1.1\n\n" onion_request_write(req, S,sizeof(S)-1); // send it all, but the final 0. #undef S close(p[1]); //fcntl(p[0],F_SETFL, O_NONBLOCK); // read from the pipe char buffer[1024]; memset(buffer,0,sizeof(buffer)); // better clean it, because if this does not work, it might get an old value int r=read(p[0], buffer, sizeof(buffer)); if (r<0){ ONION_DEBUG("Read %d bytes",r); perror("Error"); } FAIL_IF_EQUAL_STR(buffer,""); FAIL_IF_NOT_STRSTR(buffer,"HTTP/1.1 200 OK\r\n"); FAIL_IF_NOT_STRSTR(buffer,"Content-Length: 16\r\n"); FAIL_IF_NOT_STRSTR(buffer,"\r\n\r\nWorks with pipes"); onion_request_free(req); onion_server_free(server); END_LOCAL(); }
/** * @short Executes each script file passed as argument. * * Optionally a -r sets the new lines to \r\n. It takes care of not changing content types. */ int main(int argc, char **argv){ server=onion_server_new(); onion_server_set_root_handler(server,onion_handler_new((void*)allinfo_handler,NULL,NULL)); onion_server_set_write(server,(void*)buffer_append); int i; int do_r=0; for (i=1;i<argc;i++){ if (strcmp(argv[i],"-r")==0){ ONION_WARNING("Setting the end of lines to \\r\\n"); do_r=1; } else{ ONION_INFO("Launching test %s",argv[i]); prerecorded(argv[i], do_r); } } onion_server_free(server); END(); }
/** * @short Removes the allocated data * @memberof onion_t */ void onion_free(onion *onion){ ONION_DEBUG("Onion free"); #ifdef HAVE_PTHREADS if (onion->flags&O_THREADS_ENABLED){ int ntries=5; int c; for(;ntries--;){ sem_getvalue(&onion->thread_count,&c); if (c==onion->max_threads){ break; } ONION_INFO("Still some petitions on process (%d). Wait a little bit (%d).",c,ntries); sleep(1); } } #endif close(onion->listenfd); if (onion->poller) onion_poller_free(onion->poller); if (onion->username) free(onion->username); #ifdef HAVE_GNUTLS if (onion->flags&O_SSL_ENABLED){ gnutls_certificate_free_credentials (onion->x509_cred); gnutls_dh_params_deinit(onion->dh_params); gnutls_priority_deinit (onion->priority_cache); if (!(onion->flags&O_SSL_NO_DEINIT)) gnutls_global_deinit(); // This may cause problems if several characters use the gnutls on the same binary. } #endif if (onion->port) free(onion->port); if (onion->hostname) free(onion->hostname); onion_server_free(onion->server); free(onion); }
/// There is a bug when posting large files. Introduced when change write 1 by 1, to write by blocks on the FILE parser void t04_post_largefile(){ INIT_LOCAL(); int postfd=open(BIG_FILE, O_RDONLY); off_t filesize=lseek(postfd, 0, SEEK_END); lseek(postfd, 0, SEEK_SET); buffer *b=buffer_new(1024); expected_post post={};; post.filename=BIG_FILE_BASE; post.test_ok=0; // Not ok as not called processor yet post.tmpfilename=NULL; post.size=filesize; 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_HEADER "POST / HTTP/1.1\nContent-Type: multipart/form-data; boundary=end\nContent-Length: %d\n\n--end\nContent-Disposition: text/plain; name=\"file\"; filename=\"" BIG_FILE_BASE "\"\n\n" char tmp[1024]; ONION_DEBUG("Post size is about %d",filesize+73); snprintf(tmp, sizeof(tmp), POST_HEADER, (int)filesize+73); ONION_DEBUG("%s",tmp); onion_request_write(req,tmp,strlen(tmp)); int r=read(postfd, tmp, sizeof(tmp)); while ( r>0 ){ onion_request_write(req, tmp, r); r=read(postfd, tmp, sizeof(tmp)); } onion_request_write(req,"\n--end--",8); FAIL_IF_NOT_EQUAL_INT(post.test_ok,1); #undef POST_HEADER post.test_ok=0; // Not ok as not called processor yet lseek(postfd, 0, SEEK_SET); int difffd=open(post.tmpfilename, O_RDONLY); FAIL_IF_NOT_EQUAL_INT(difffd,-1); // Orig file is removed at handler returns. But i have a copy difffd=open(post.tmplink, O_RDONLY); FAIL_IF_EQUAL_INT(difffd,-1); ONION_DEBUG("tmp filename %s",post.tmpfilename); int r1=1, r2=1; char c1=0, c2=0; int p=0; while ( r1 && r2 && c1==c2){ r1=read(difffd, &c1, 1); r2=read(postfd, &c2, 1); //ONION_DEBUG("%d %d",c1,c2); FAIL_IF_NOT_EQUAL_INT(c1,c2); p++; } if ( r1 || r2 ){ ONION_ERROR("At %d",p); FAIL_IF_NOT_EQUAL_INT(r1,0); FAIL_IF_NOT_EQUAL_INT(r2,0); FAIL_IF_NOT_EQUAL_INT(c1,c2); FAIL("Files are different"); } else ONION_DEBUG("Files are ok"); close(difffd); close(postfd); onion_request_clean(req); onion_request_free(req); if (post.tmpfilename){ struct stat st; FAIL_IF_EQUAL(stat(post.tmpfilename,&st), 0); // Should not exist } onion_server_free(server); buffer_free(b); if (post.tmpfilename) free(post.tmpfilename); if (post.tmplink) free(post.tmplink); END_LOCAL(); }