Esempio n. 1
0
void t01_server_one(){
  INIT_LOCAL();

  o=onion_new(O_ONE);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set(1,0.1,1,0);
  onion_free(o);

  o=onion_new(O_ONE_LOOP);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set(1,0.1,1,1);
  onion_free(o);

  o=onion_new(O_ONE_LOOP);

  // change poller queue size
  onion_poller *p=onion_get_poller(o);
  onion_poller_set_queue_size_per_thread(p, 1);

  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set(1,0.001,100,1);
  onion_free(o);

  END_LOCAL();
}
Esempio n. 2
0
void t04_server_timeout_threaded(){
  INIT_LOCAL();
  CURL *curl=prepare_curl("http://localhost:8082");

  o=onion_new(O_THREADED | O_DETACH_LISTEN);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  onion_set_port(o,"8082");
  onion_set_timeout(o,2000);
  onion_listen(o);
  sleep(1);

  int fd=connect_to("localhost","8082");
  sleep(3);
  // Should have closed the connection
  int w=write(fd,"GET /\n\n",7);
  FAIL_IF_NOT_EQUAL_INT(w,7);
  char data[256];
  FAIL_IF(read(fd, data,sizeof(data))>0);
  close(fd);

  FAIL_IF_NOT(curl_get(curl, "http://localhost:8082"));

  onion_free(o);
	curl_easy_cleanup(curl);
  END_LOCAL();
}
Esempio n. 3
0
void t06_timeouts(){
  INIT_LOCAL();

  o=onion_new(O_POOL | O_DETACH_LISTEN);
  onion_set_timeout(o, 100);

  onion_set_root_handler(o, onion_handler_new((void*)wait_random, NULL, NULL));
  onion_set_port(o, "8081");
  onion_listen(o);
  sleep(1);

  int nthreads=10;
  pthread_t *thread=malloc(sizeof(pthread_t*)*nthreads);
  int i;
  for (i=0;i<nthreads;i++){
    pthread_create(&thread[i], NULL, (void*)do_timeout_request, NULL);
  }
  for (i=0;i<nthreads;i++){
    pthread_join(thread[i], NULL);
  }
  free(thread);


  onion_free(o);


  END_LOCAL();
}
Esempio n. 4
0
void t05_post_content_json(){
	INIT_LOCAL();

	onion *server=onion_new(0);
	onion_listen_point *lp=onion_buffer_listen_point_new();
	json_response post_json = { 0 };
	
	onion_add_listen_point(server,NULL,NULL,lp);
	onion_set_root_handler(server, onion_handler_new((void*)&post_json_check,&post_json,NULL));
	
	onion_request *req=onion_request_new(lp);
#define POST_HEADER "POST / HTTP/1.1\nContent-Type: application/json\nContent-Length: %d\n\n"
	char tmp[1024];
	int json_length=sizeof(JSON_EXAMPLE);
	ONION_DEBUG("Post size is about %d",json_length);
	snprintf(tmp, sizeof(tmp), POST_HEADER, json_length);
// 	ONION_DEBUG("%s",tmp);
	onion_request_write(req,tmp,strlen(tmp));
	onion_request_write(req,JSON_EXAMPLE,json_length);
// 	ONION_DEBUG("%s",JSON_EXAMPLE);
	
	FAIL_IF_NOT_EQUAL_INT(post_json.processed, 2);
	
	onion_request_free(req);
	onion_free(server);
	
	END_LOCAL();
}
Esempio n. 5
0
/**
 * @short Creates the onion structure to fill with the server data, and later do the onion_listen()
 * @memberof onion_t
 * 
 * Creates an onion structure that can be used to set the server, port, SSL and similar parameters. It works over 
 * the onion structure, which is the main structure to control the listening of new connections throught TCP/IP.
 * 
 * A normal usage would be like this:
 * 
 * @code
 * 
 * onion *o=onion_new(O_THREADED);
 * onion_set_root_handler(o, onion_handler_directory("."));
 * onion_listen(o);
 * 
 * @endcode
 * 
 * @param flags Or'ed flags to use at the listening daemon. Normally one of O_ONE, O_ONE_LOOP or O_THREADED.
 * 
 * @returns The onion structure.
 * 
 * @see onion_mode_e onion_t
 */
onion *onion_new(int flags){
	ONION_DEBUG0("Some internal sizes: onion size: %d, request size %d, response size %d",sizeof(onion),sizeof(onion_request),sizeof(onion_response));
	if(SOCK_CLOEXEC == 0){
		ONION_WARNING("There is no support for SOCK_CLOEXEC compiled in libonion. This may be a SECURITY PROBLEM as connections may leak into executed programs.");
	}
	
	onion *o=calloc(1,sizeof(onion));
	o->flags=(flags&0x0FF)|O_SSL_AVAILABLE;
	o->timeout=5000; // 5 seconds of timeout, default.
	o->poller=onion_poller_new(15);
	if (!o->poller){
		free(o);
		return NULL;
	}
	o->sessions=onion_sessions_new();
	o->internal_error_handler=onion_handler_new((onion_handler_handler)onion_default_error, NULL, NULL);
	o->max_post_size=1024*1024; // 1MB
	o->max_file_size=1024*1024*1024; // 1GB
#ifdef HAVE_PTHREADS
	o->flags|=O_THREADS_AVALIABLE;
	o->nthreads=8;
	if (o->flags&O_THREADED)
		o->flags|=O_THREADS_ENABLED;
#endif
	return o;
}
Esempio n. 6
0
void t02_long_template(){
	INIT_LOCAL();
	int count=0;

	onion *s=onion_new(0);

	onion_set_root_handler(s, onion_handler_new((void*)AGPL_txt_handler_page, NULL, NULL));
	onion_listen_point *lp=onion_buffer_listen_point_new();
	onion_add_listen_point(s,NULL,NULL,lp);
	lp->write=count_bytes;


	onion_request *req=onion_request_new(lp);
	req->connection.listen_point->close(req);
	req->connection.user_data=&count;
	req->connection.listen_point->close=NULL;


  FAIL_IF_NOT_EQUAL_INT(onion_request_write0(req, "GET /\n\n"), OCS_REQUEST_READY);
  FAIL_IF_NOT_EQUAL_INT(onion_request_process(req), OCS_CLOSE_CONNECTION);

	FAIL_IF(count<30000);

	onion_request_free(req);
	onion_free(s);

	END_LOCAL();
}
Esempio n. 7
0
int main() {
  request_list_t request_list;
  request_list.reqres = onion_ptr_list_new();
  request_list.running = true;
  pthread_mutex_init(&request_list.lock, NULL);

  pthread_t long_process_thread;

  o = onion_new(O_POOL);

  pthread_create(&long_process_thread, NULL, (void *)&long_process,
                 &request_list);

  onion_set_root_handler(o, onion_handler_new(&handler, &request_list, NULL));

  ONION_INFO("Listening at http://localhost:8080");
  onion_listen(o);

  // Close
  request_list.running = false;

  onion_ptr_list_foreach(request_list.reqres, (void *)free_reqres);
  onion_ptr_list_free(request_list.reqres);

  pthread_join(long_process_thread, NULL);

  onion_free(o);
  return 0;
}
Esempio n. 8
0
void t05_server_timeout_threaded_ssl(){
  INIT_LOCAL();
  CURL *curl=prepare_curl("https://localhost:8081");

  ONION_DEBUG("%s",__FUNCTION__);
  o=onion_new(O_THREADED | O_DETACH_LISTEN);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  FAIL_IF_NOT_EQUAL_INT(onion_set_certificate(o, O_SSL_CERTIFICATE_KEY, "mycert.pem", "mycert.pem"),0);
  onion_set_port(o,"8081");
  onion_set_timeout(o,3000);
  onion_listen(o);
  sleep(1);

  int fd=connect_to("localhost","8081");
  sleep(4);
  // Should have closed the connection
  int w=write(fd,"GET /\n\n",7);
  FAIL_IF_NOT_EQUAL_INT(w,7);
  char data[256];
  FAIL_IF(read(fd, data,sizeof(data))>0);
  close(fd);

  FAIL_IF_NOT(curl_get(curl, "https://localhost:8081"));

	onion_free(o);

	curl_easy_cleanup(curl);
  END_LOCAL();
}
Esempio n. 9
0
/**
 * @short Creates an local filesystem handler.
 * 
 * Exports the given localpath and any file inside this localpath is returned.
 * 
 * It performs security checks, so that the returned data is saftly known to be inside 
 * that localpath. Normal permissions apply.
 */
onion_handler *onion_handler_export_local_new(const char *localpath){
	char *rp=realpath(localpath, NULL);
	if (!rp){
		ONION_ERROR("Cant calculate the realpath of the given directory (%s).",localpath);
		return NULL;
	}
	struct stat st;
	if (stat(rp, &st)!=0){
		ONION_ERROR("Cant access to the exported directory/file (%s).",rp);
		free(rp);
		return NULL;
	}
	onion_handler_export_local_data *priv_data=malloc(sizeof(onion_handler_export_local_data));

	priv_data->localpath=rp;
	priv_data->renderer_header=onion_handler_export_local_header_default;
	priv_data->renderer_footer=onion_handler_export_local_footer_default;
	
	
	priv_data->is_file=S_ISREG(st.st_mode);
	
	onion_handler *ret=onion_handler_new((onion_handler_handler)onion_handler_export_local_handler,
																			 priv_data,(onion_handler_private_data_free) onion_handler_export_local_delete);
	return ret;
}
Esempio n. 10
0
File: url.c Progetto: cemonds/onion
/**
 * @short Creates the URL handler to map regex urls to handlers
 * @memberof onion_url_t
 *
 * The onion_url object can be used to add urls as needed using onion_url_add_*.
 * 
 * The URLs can be regular expressions or simple strings. The way to discriminate them is just
 * to check the first character; if its ^ its a regular expression.
 * 
 * If a string is passed then the full path must match. If its a regexp, just the begining is matched,
 * unless $ is set at the end. When matched, this is removed from the path.
 * 
 * It is important to note that when the user pretends to match the initial path elements, to later
 * pass to another handler that will do path transversal (another url object, for example), the
 * path must be written with a regular expression, for example: "^login/". If the user just writes 
 * the string it will match only for that specific URL, and subpaths are not in the definition.
 *  
 * When looking for a match, they are looked in order.
 * 
 * Examples::
 * 
 * @code
 *  onion_url_add(url, "index.html", index); // Matches the exact filename. Not compiled.
 *  onion_url_add(url, "^static/", onion_handler_export_local_new(".") ); // Export current directory at static
 *  onion_url_add(url, "^icons/(.*)", directory); // Compiles the regexp, and uses the .* as first argument.
 *  onion_url_add(url, "", redirect_to_index); // Matches an empty path. Not compiled.
 * @endcode
 * 
 * Regexp can have groups, and they will be added as request query parameters, with just the number of the 
 * group as key. The groups start at 1, as 0 should be the full match, but its not added for performance
 * reasons; its a very strange situation that user will need it, and always can access full path with
 * onion_request_get_fullpath. Also all expression can be a group, and passed as nr 1.:
 * 
 * @code
 *  onion_url_add(url, "^index(.html)", index);
 *  ...
 *  onion_request_get_query(req, "1") == ".html"
 * @endcode
 * 
 * Be careful as . means every character, and dots in URLs must be with a backslash \ (double because of
 * C escaping), if using regexps.
 * 
 * Regular expressions are used by the regexec(3) standard C library. Check that documentation to check
 * how to create proper regular expressions. They are compiled as REG_EXTENDED.
 */
onion_url *onion_url_new(){
	onion_url_data **priv_data=calloc(1,sizeof(onion_url_data*));
	*priv_data=NULL;
	
	onion_handler *ret=onion_handler_new((onion_handler_handler)onion_url_handler,
																			 priv_data,(onion_handler_private_data_free) onion_url_free_data);
	return (onion_url*)ret;
}
Esempio n. 11
0
/// Prepares the oterm handler
onion_handler *oterm_handler(onion *o, const char *exec_command){
	oterm_data *data=malloc(sizeof(oterm_data));
	data->sessions=onion_dict_new();
  data->processes=onion_dict_new();
	data->exec_command=strdup(exec_command);
	data->onion=o;
	
	return onion_handler_new((void*)oterm_get_data, data, (void*)oterm_free);
}
Esempio n. 12
0
int add_answer_redirect_page(onion_url *urls, trivia_question* const q)
{
	int r;
	char *uri;
	if((r = asprintf(&uri, "%s.data", q->uri)) == -1) {
		return r;
	}
	return onion_url_add_handler(urls, uri, onion_handler_new(check_answer, q, NULL));
}
Esempio n. 13
0
/**
 * @short Initializes the server data.
 * @memberof onion_server_t
 * 
 * This data is independant of communication channel, and its the data that should be alsays available, even shared between the channels.
 * 
 * All data have sensitive defaults, except write and root_handler, and can be modified with accessor functions.
 * 
 * These defaults include: 
 *  * internal_error_handler
 *  * max_post_size -- 1MB
 *  * max_file_size -- 1GB
 */
onion_server *onion_server_new(void){
	onion_server *ret=malloc(sizeof(onion_server));
	ret->root_handler=NULL;
	ret->write=NULL;
	ret->internal_error_handler=onion_handler_new((onion_handler_handler)onion_default_error, NULL, NULL);
	ret->max_post_size=1024*1024; // 1MB
	ret->max_file_size=1024*1024*1024; // 1GB
	ret->sessions=onion_sessions_new();
	return ret;
}
Esempio n. 14
0
/**
 * @short Creates an path handler. If the path matches the regex, it reomves that from the regexp and goes to the inside_level.
 *
 * If on the inside level nobody answers, it just returns NULL, so ->next can answer.
 */
onion_handler *onion_handler_auth_pam(const char *realm, const char *pamname, onion_handler *inside_level){
	onion_handler_auth_pam_data *priv_data=malloc(sizeof(onion_handler_auth_pam_data));

	priv_data->inside=inside_level;
	priv_data->pamname=strdup(pamname);
	priv_data->realm=strdup(realm);
	
	onion_handler *ret=onion_handler_new((onion_handler_handler)onion_handler_auth_pam_handler,
																			 priv_data, (onion_handler_private_data_free) onion_handler_auth_pam_delete);
	return ret;
}
Esempio n. 15
0
int main(int argc, char **argv){
	onion *onion=onion_new(O_ONE_LOOP);
	
	onion_handler *root=onion_handler_new((onion_handler_handler)method, NULL, NULL);

	onion_set_root_handler(onion, root);
	
	onion_listen(onion);
	
	return 0;
}
Esempio n. 16
0
/**
 * @short Creates an opack handler that calls the onion_opack_renderer with length data.
 *
 * If on the inside level nobody answers, it just returns NULL, so ->next can answer.
 * 
 * @param path Path of the current data, for example /. It is a normal string; no regular expressions are allowed.
 * @param render Function to call to render the response.
 * @param length Lenght of the data, or 0 if unknown. Needed to keep alive.
 */
onion_handler *onion_handler_opack(const char *path, onion_opack_renderer render, unsigned int length){
	onion_handler_opack_data *priv_data=malloc(sizeof(onion_handler_opack_data));

	priv_data->path=strdup(path);
	priv_data->length=length;
	priv_data->render=render;
	
	onion_handler *ret=onion_handler_new((onion_handler_handler)onion_handler_opack_handler,
																			 priv_data, (onion_handler_private_data_free) onion_handler_opack_delete);
	return ret;
}
Esempio n. 17
0
void t01_url() {
  INIT_LOCAL();

  onion_url *url = onion_url_new();
  onion_url_add_handler(url, "^handler1.$",
                        onion_handler_new((onion_handler_handler) handler1,
                                          NULL, NULL));
  onion_url_add(url, "handler2/", handler2);
  onion_url_add_with_data(url, "^handler(3|4)/", handler3, NULL, NULL);

  onion_set_root_handler(server, onion_url_to_handler(url));

  onion_request *req = onion_request_new(onion_get_listen_point(server, 0));

#define R "GET /handler1/ HTTP/1.1\n\n"
  onion_request_write(req, R, sizeof(R));
  onion_request_process(req);
  FAIL_IF_NOT_EQUAL_INT(handler_called, 1);
  FAIL_IF_NOT_EQUAL_STR(urltxt, "");
  free(urltxt);
  urltxt = NULL;

  onion_request_clean(req);
  onion_request_write(req, "GET /handler2/ HTTP/1.1\n\n", sizeof(R));
  onion_request_process(req);
  FAIL_IF_NOT_EQUAL_INT(handler_called, 2);
  ONION_DEBUG("%s", urltxt);
  FAIL_IF_NOT_EQUAL_STR(urltxt, "");
  free(urltxt);
  urltxt = NULL;

  onion_request_clean(req);
  onion_request_write(req, "GET /handler3/hello HTTP/1.1\n\n", sizeof(R) + 5);
  onion_request_process(req);
  FAIL_IF_NOT_EQUAL_INT(handler_called, 3);
  FAIL_IF_NOT_EQUAL_STR(urltxt, "hello");
  free(urltxt);
  urltxt = NULL;

  handler_called = 0;
  onion_request_clean(req);
  onion_request_write(req, "GET /handler2/hello HTTP/1.1\n\n", sizeof(R) + 5);
  onion_request_process(req);
  FAIL_IF_NOT_EQUAL_INT(handler_called, 0);
  FAIL_IF_EQUAL_STR(urltxt, "");
  free(urltxt);
  urltxt = NULL;

  onion_request_free(req);
  onion_url_free(url);
  onion_set_root_handler(server, NULL);

  END_LOCAL();
}
Esempio n. 18
0
/**
 * @short Creates a static handler that just writes some static data.
 *
 * Path is a regex for the url, as arrived here.
 */
onion_handler *onion_handler_static(const char *text, int code){
	onion_handler_static_data *priv_data=onion_low_malloc(sizeof(onion_handler_static_data));
	if (!priv_data)
		return NULL;

	priv_data->code=code;
	priv_data->data=onion_low_strdup(text);

	onion_handler *ret=onion_handler_new((onion_handler_handler)onion_handler_static_handler,
																			 priv_data,(onion_handler_private_data_free) onion_handler_static_delete);
	return ret;
}
Esempio n. 19
0
int main(int argc, char **argv){
	o=onion_new(O_ONE_LOOP);
	
	onion_handler *root=onion_handler_new((onion_handler_handler)sessions, NULL, NULL);

	onion_set_root_handler(o, root);
	signal(SIGINT, free_onion);
	
	onion_listen(o);
	
	return 0;
}
Esempio n. 20
0
void t02_server_epoll(){
  INIT_LOCAL();

  o=onion_new(O_POLL);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set(1,0.1,1,1);
  onion_free(o);

  o=onion_new(O_POLL);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set(1,0.001,100,1);
  onion_free(o);

  o=onion_new(O_POOL);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set(1,0.001,100,1);
  onion_free(o);

  o=onion_new(O_POOL);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set_threaded(1,0.001,100,2,10);
  onion_free(o);

  o=onion_new(O_POOL);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set_threaded(1,0.001,100,2,15);
  onion_free(o);

  o=onion_new(O_POOL);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set_threaded(1,0.001,100,2,100);
  onion_free(o);

  END_LOCAL();
}
Esempio n. 21
0
/**
 * @short In a simple loop asks the user for the answer of the query.
 */
int main(int argc, char **argv){
	onion *server;
	
	server=onion_new(O_ONE_LOOP);
	
	onion_set_hostname(server, "0.0.0.0");
	onion_set_root_handler(server, onion_handler_new((void*)ask_handler, NULL, NULL));
	
	onion_listen(server);
	
	onion_free(server);
	
	return 0;
}
Esempio n. 22
0
/**
 * @short Creates a webdav handler
 * 
 * The check_permissions parameter, if set, sets a custom security permission checker.
 * 
 * If not set, the default permissions apply, that will try to do not access files out of the restricted area.
 * 
 * This permission checker gets the exported path, the path to the file that wants to be exported/checked/moved.., 
 * and the request as it arrived to the handler.
 * 
 * The exported path and file path might be relative, if onion_handler_webdav was initialized so.
 * 
 * On move it will check for both the original and final files, on other methods, it will check just the file, and
 * the semantics is that the user is allowed to do that method.
 * 
 * It should return 0 on success, any other if error/not allowed.
 * 
 * @param path Path to share
 * @returns The onion handler.
 */
onion_handler *onion_handler_webdav(const char *path, onion_webdav_permissions_check perm){
	xmlInitParser();
	LIBXML_TEST_VERSION

	onion_webdav *wd=malloc(sizeof(onion_webdav));
	wd->path=strdup(path);
	
	if (perm)
		wd->check_permissions=perm;
	else
		wd->check_permissions=onion_webdav_default_check_permissions;

	onion_handler *ret=onion_handler_new((void*)onion_webdav_handler, wd, (void*)onion_webdav_free);
	return ret;
}
Esempio n. 23
0
void t02_post_a_lot() {
  INIT_LOCAL();

  onion *o = onion_new(O_ONE);
  onion_set_root_handler(o,
                         onion_handler_new((void *)return_length, NULL, NULL));

  pthread_t pt;
  pthread_create(&pt, NULL, (void *)POST_a_lot, NULL);
  onion_listen(o);

  pthread_join(pt, NULL);

  onion_free(o);

  END_LOCAL();
}
Esempio n. 24
0
/// 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();
}
Esempio n. 25
0
void t01_post_no_type() {
  INIT_LOCAL();

  onion *o = onion_new(O_ONE);
  onion_set_root_handler(o,
                         onion_handler_new((void *)process_request, NULL,
                                           NULL));

  pthread_t pt;
  pthread_create(&pt, NULL, (void *)POST_json, NULL);
  onion_listen(o);

  pthread_join(pt, NULL);

  onion_free(o);

  END_LOCAL();
}
Esempio n. 26
0
int main(int argc, char **argv){
	o=onion_new(O_ONE_LOOP);

#ifdef HAVE_REDIS
	onion_sessions *session_backend=onion_sessions_redis_new("localhost",6379);
	onion_set_session_backend(o, session_backend);
#endif

	onion_url *root=onion_root_url(o);

  onion_url_add_handler(root, "status",onion_internal_status());
  onion_url_add_handler(root, "^.*", onion_handler_new((onion_handler_handler)sessions, NULL, NULL));

	signal(SIGINT, free_onion);

	onion_listen(o);

	return 0;
}
Esempio n. 27
0
void t03_server_https(){
  INIT_LOCAL();
  CURL *curl=prepare_curl("https://localhost:8080");

  o=onion_new(O_ONE_LOOP | O_DETACH_LISTEN);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  FAIL_IF_NOT_EQUAL_INT(onion_set_certificate(o, O_SSL_CERTIFICATE_KEY, "mycert.pem", "mycert.pem"),0);
  FAIL_IF_NOT_EQUAL_INT(onion_listen(o),0);
  //do_petition_set(1,1,1,1);
  sleep(1);
  //FAIL_IF_EQUAL_INT(  curl_get_to_fail("http://localhost:8080"), HTTP_OK);
  sleep(1);
  FAIL_IF_NOT_EQUAL_INT(  curl_get(curl, "https://localhost:8080"), HTTP_OK);
  sleep(1);
  onion_free(o);

	curl_easy_cleanup(curl);
  END_LOCAL();
}
Esempio n. 28
0
/// 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();
}
Esempio n. 29
0
File: onion.c Progetto: Nov11/onion
/**
 * @short Creates the onion structure to fill with the server data, and later do the onion_listen()
 * @memberof onion_t
 *
 * Creates an onion structure that can be used to set the server, port, SSL and similar parameters. It works over
 * the onion structure, which is the main structure to control the listening of new connections throught TCP/IP.
 *
 * A normal usage would be like this:
 *
 * @code
 *
 * onion *o=onion_new(O_THREADED);
 * onion_set_root_handler(o, onion_handler_directory("."));
 * onion_listen(o);
 *
 * @endcode
 *
 * @param flags Or'ed flags to use at the listening daemon. Normally one of O_ONE, O_ONE_LOOP or O_THREADED.
 *
 * @returns The onion structure.
 *
 * @see onion_mode_e onion_t
 */
onion *onion_new(int flags){
	ONION_DEBUG0("Some internal sizes: onion size: %d, request size %d, response size %d",sizeof(onion),sizeof(onion_request),sizeof(onion_response));
	if(SOCK_CLOEXEC == 0){
		ONION_WARNING("There is no support for SOCK_CLOEXEC compiled in libonion. This may be a SECURITY PROBLEM as connections may leak into executed programs.");
	}

	if (!(flags&O_NO_SIGPIPE)){
		ONION_DEBUG("Ignoring SIGPIPE");
		signal(SIGPIPE, SIG_IGN);
	}


	onion *o=onion_low_calloc(1,sizeof(onion));
	if (!o){
		return NULL;
	}
	o->flags=(flags&0x0FF)|O_SSL_AVAILABLE;
	o->timeout=5000; // 5 seconds of timeout, default.
	o->poller=onion_poller_new(15);
	if (!o->poller){
		onion_low_free(o);
		return NULL;
	}
	o->sessions=onion_sessions_new();
	o->internal_error_handler=onion_handler_new((onion_handler_handler)onion_default_error, NULL, NULL);
	o->max_post_size=1024*1024; // 1MB
	o->max_file_size=1024*1024*1024; // 1GB
#ifdef HAVE_PTHREADS
	o->flags|=O_THREADS_AVAILABLE;
	o->nthreads=8;
	if (o->flags&O_THREADED)
		o->flags|=O_THREADS_ENABLED;
	pthread_mutex_init (&o->mutex, NULL);
#endif
	if (!(o->flags&O_NO_SIGTERM)){
		signal(SIGINT,shutdown_server);
		signal(SIGTERM,shutdown_server);
	}
	last_onion=o;
	return o;
}
Esempio n. 30
0
/**
 * @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();
}