Example #1
0
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();
}
Example #2
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();
}
Example #3
0
                /**
		 * @short Adds a listen point
		 */
    void addListenPoint(const std::string & hostname, const std::string & port,
                        ListenPoint && protocol) {
      onion_add_listen_point(ptr, hostname.c_str(), port.c_str(),
                             protocol.c_handler());
      // Release ownership of the pointer
      protocol.release();
    }
Example #4
0
void t01_server_min(){
	INIT_LOCAL();
	
	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_static("Succedded", 200));
	
	onion_request *req=onion_request_new(lp);
	onion_request_write(req, "GET ",4);
	onion_request_write(req, "/",1);
	onion_request_write(req, " HTTP/1.1\r\n",11);
	
	onion_request_write(req, "\r\n",2);
	
	const char *buffer=onion_buffer_listen_point_get_buffer_data(req);
	
	FAIL_IF_EQUAL_STR(buffer,"");
	FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.1 200 OK\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "\r\nContent-Length: 9\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "libonion");
	FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\nSuccedded");
	
	onion_request_free(req);
	onion_free(server);
	
	END_LOCAL();
}
Example #5
0
void t02_server_full(){
	INIT_LOCAL();
	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_static("Succedded", 200));
	
	onion_request *req=onion_request_new(lp);
#define S "GET / HTTP/1.1\r\nHeader-1: This is header1\r\nHeader-2: This is header 2\r\n"
	onion_request_write(req, S,sizeof(S)-1); // send it all, but the final 0.
#undef S
	const char *buffer=onion_buffer_listen_point_get_buffer_data(req);
	FAIL_IF_NOT_EQUAL_STR(buffer,"");
	onion_request_write(req, "\n",1); // finish this request. no \n\n before to check possible bugs.

	buffer=onion_buffer_listen_point_get_buffer_data(req);
	
	FAIL_IF_EQUAL_STR(buffer,"");
	FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.1 200 OK\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "\r\nContent-Length: 9\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "libonion");
	FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\nSuccedded");

	onion_request_free(req);
	onion_free(server);

	END_LOCAL();
}
Example #6
0
void t08_server_with_error_404(){
	INIT_LOCAL();
	onion *server=onion_new(0);
  onion_listen_point *lp=onion_buffer_listen_point_new();
  onion_add_listen_point(server,NULL,NULL,lp);
	onion_url *urls=onion_url_new();
	onion_set_root_handler(server, onion_url_to_handler(urls));
	
	onion_request *req=onion_request_new(lp);
#define S "GET / HTTP/1.1"
	onion_request_write(req, S,sizeof(S)-1); // send it all, but the final 0.
#undef S
	const char *buffer=onion_buffer_listen_point_get_buffer_data(req);
	FAIL_IF_NOT_EQUAL_STR(buffer,"");
	onion_request_write(req, "\n",1); // finish this request. no \n\n before to check possible bugs.
	onion_request_write(req, "\n",1); // finish this request. no \n\n before to check possible bugs. The last \n was not processed, as was overflowing.
	
	buffer=onion_buffer_listen_point_get_buffer_data(req);
	FAIL_IF_EQUAL_STR(buffer,"");
	FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.1 404 NOT FOUND\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "libonion");

	onion_request_free(req);
	onion_free(server);

	END_LOCAL();
}
Example #7
0
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();
}
Example #8
0
void t04_server_overflow(){
	INIT_LOCAL();
	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_static("Succedded", 200));
	
	onion_block *long_req=onion_block_new();
	
	onion_block_add_str(long_req,"GET / HTTP/1.1\n");
	int i;
	for(i=0;i<1000;i++){
		onion_block_add_str(long_req,"Header-1: This is header1 Header-2: This is header 2 ");
	}
	onion_request *req=onion_request_new(lp);
	onion_request_write(req, onion_block_data(long_req),onion_block_size(long_req)-1); // send it all, but the final 0.
	const char *buffer=onion_buffer_listen_point_get_buffer_data(req);
	FAIL_IF_NOT_EQUAL_STR(buffer,"");
	onion_request_write(req, "\n\n",2); // finish this request. no \n\n before to check possible bugs.

	buffer=onion_buffer_listen_point_get_buffer_data(req);
	FAIL_IF_EQUAL_STR(buffer,"");
	FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.1 200 OK\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "\r\nContent-Length: 9\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "libonion");
	FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\nSuccedded");

	onion_block_free(long_req);
	onion_request_free(req);
	onion_free(server);

	END_LOCAL();
}
Example #9
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();
}
Example #10
0
void t06_empty(){
	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_write_headers(response);
	
	onion_response_flush(response);
	onion_response_free(response);

	buffer[sizeof(buffer)-1]=0;
	strncpy(buffer,onion_buffer_listen_point_get_buffer_data(request),sizeof(buffer)-1);
	onion_request_free(request);
	onion_free(server);
	
	FAIL_IF_NOT_STRSTR(buffer, "Server:");
	FAIL_IF_NOT_STRSTR(buffer, "Content-Type:");
	
// 	ONION_DEBUG(buffer);

	END_LOCAL();
}
Example #11
0
void t05_printf(){
	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_printf(response, "%s %d %p", "Hello world", 123, NULL);
	onion_response_flush(response);
	onion_response_free(response);
	buffer[sizeof(buffer)-1]=0;
	strncpy(buffer,onion_buffer_listen_point_get_buffer_data(request),sizeof(buffer)-1);
	onion_request_free(request);
	onion_free(server);
	
	FAIL_IF_NOT_STRSTR(buffer, "Hello world 123 (nil)");
	
	END_LOCAL();
}
Example #12
0
/// Sets the hostname on which to listen
void onion_set_hostname(onion *server, const char *hostname){
	if (server->listen_points){
		free(server->listen_points[0]->hostname);
		server->listen_points[0]->hostname=strdup(hostname);
	}
	else{
		onion_add_listen_point(server, hostname, NULL, onion_http_new());
	}
}
Example #13
0
/// Sets the port to listen
void onion_set_port(onion *server, const char *port){
	if (server->listen_points){
		free(server->listen_points[0]->port);
		server->listen_points[0]->port=strdup(port);
	}
	else{
		onion_add_listen_point(server, NULL, port, onion_http_new());
	}
}
Example #14
0
void t02_handle_generic_request(){
	INIT_LOCAL();

	onion *server=onion_new(0);
	onion_listen_point *lp=onion_buffer_listen_point_new();
	onion_add_listen_point(server, NULL, NULL, lp);
	
	onion_url *url=onion_url_new();
	int error;
	error=onion_url_add_handler(url, "^$", onion_handler_static("Not ready",302));
	FAIL_IF(error);

	error=onion_url_add_handler(url, "^a.*$", onion_handler_static("any",200));
	FAIL_IF(error);

	error=onion_url_add_static(url, "^.*", "Internal error", 500);
	FAIL_IF(error);

	onion_set_root_handler(server, onion_url_to_handler(url));
	
	onion_request *request;


	request=onion_request_new(lp);
	FILL(request,"GET / HTTP/1.1\n");
	onion_request_process(request);
	const char *buffer=onion_buffer_listen_point_get_buffer_data(request);
	FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.1 302 REDIRECT\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "Content-Length: 9\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\nNot ready");
	onion_request_free(request);
	
	// gives error, as such url does not exist.
	request=onion_request_new(lp);
	FILL(request,"GET /error HTTP/1.1\n");
	onion_request_process(request);
	buffer=onion_buffer_listen_point_get_buffer_data(request);
	ONION_DEBUG("<%s>", buffer);
	FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.1 500 INTERNAL ERROR\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "Content-Length: 14\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\nInternal error");
	onion_request_free(request);

	request=onion_request_new(lp);
	FILL(request,"GET /any HTTP/1.1\n");
	onion_request_process(request);
	buffer=onion_buffer_listen_point_get_buffer_data(request);
	FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.1 200 OK\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "Content-Length: 3\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\nany");
	onion_request_free(request);

	onion_free(server);

	END_LOCAL();
}
Example #15
0
onion *websocket_server_new() {
  onion *o = onion_new(0);
  onion_url *urls = onion_root_url(o);
  onion_url_add(urls, "", ws_handler);

  onion_listen_point *lp = onion_buffer_listen_point_new();
  onion_add_listen_point(o, NULL, NULL, lp);

  return o;
}
Example #16
0
int main(int argc, char **argv){
	o=onion_new(O_THREADED);
	signal(SIGINT, free_onion);

	onion_set_root_handler(o, onion_handler_export_local_new("."));
	onion_add_listen_point(o, "localhost", "8080", onion_http_new());
	onion_add_listen_point(o, "localhost", "8081", onion_http_new());
	
	onion_add_listen_point(o, "localhost", "4443", onion_https_new(O_SSL_CERTIFICATE_KEY, "cert.pem", "cert.key"));
	
	
	
	/**
	onion_set_port(o, "localhost", "6121", onion_protocol_spdy());
	*/
	onion_listen(o);
	onion_free(o);
	return 0;
}
Example #17
0
int main(int argc, char **argv){
	o=onion_new(O_THREADED);
	signal(SIGINT, free_onion);

	onion_set_root_handler(o, onion_handler_export_local_new("."));
	onion_add_listen_point(o, "localhost", "8080", onion_http_new());
	onion_add_listen_point(o, "localhost", "8081", onion_http_new());
#ifdef HAVE_GNUTLS
	onion_add_listen_point(o, "localhost", "4443", onion_https_new(O_SSL_CERTIFICATE_KEY, "cert.pem", "cert.key"));
#else
	ONION_WARNING("HTTPS support is not enabled. Recompile with gnutls");
#endif
	
	
	
	/**
	onion_set_port(o, "localhost", "6121", onion_protocol_spdy());
	*/
	onion_listen(o);
	onion_free(o);
	return 0;
}
Example #18
0
int trivia(void)
{
	printf("creating web-server\n");
	o=onion_new(O_ONE_LOOP);

	printf("obtaining root url\n");
	onion_url *urls=onion_root_url(o);

	printf("adding css skeleton\n");
	if(add_css_page(urls)) {
		printf("error: add_questions(): %s\n", strerror(errno));
		exit(1);
	}

	printf("adding questions\n");
	if(add_questions(urls)) {
		printf("error: add_questions(): %s\n", strerror(errno));
		exit(1);
	}
	printf("adding landing page\n");
	if(add_start_page(urls)) {
		printf("error: add_landing_page(): %s\n", strerror(errno));
		exit(1);
	}
	printf("adding done page\n");
	if(add_done_page(urls)) {
		printf("error: add_done_page(): %s\n", strerror(errno));
		exit(1);
	}
	printf("adding reset page\n");
	if(add_reset_page(urls)) {
		printf("error: add_landing_page(): %s\n", strerror(errno));
		exit(1);
	}

	printf("adding signal handlers\n");
	signal(SIGTERM, onexit);
	signal(SIGINT, onexit);

	printf("adding listening point\n");
	onion_add_listen_point(o, NULL, "80", onion_http_new());

	printf("listening\n");
	onion_listen(o);

	printf("freeing\n");
	onion_free(o);
	return 0;
}
Example #19
0
/// A BUG were detected: transformed \n to \r\n on files.
void t03_post_carriage_return_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=3;
	
	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\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_free(server);
	END_LOCAL();
}
Example #20
0
void t00_server_empty(){
	INIT_LOCAL();
	
	onion *server=onion_new(0);
  onion_listen_point *lp=onion_buffer_listen_point_new();
  onion_add_listen_point(server,NULL,NULL,lp);
	
	onion_request *req=onion_request_new(lp);
	onion_request_write(req, "GET ",4);
	onion_request_write(req, "/",1);
	onion_request_write(req, " HTTP/1.1\r\n",11);
	onion_request_write(req, "\r\n",2);
	
	const char *buffer=onion_buffer_listen_point_get_buffer_data(req);
	
	FAIL_IF_EQUAL_STR(buffer,"");
	FAIL_IF_NOT_STRSTR(buffer,"404");
	
	onion_request_free(req);
	onion_free(server);
	
	END_LOCAL();
}
Example #21
0
/// Set a certificate for use in the connection
int onion_set_certificate(onion *onion, onion_ssl_certificate_type type, const char *filename,...){
#ifdef HAVE_GNUTLS
	if (!onion->listen_points){
		onion_add_listen_point(onion,NULL,NULL,onion_https_new());
	}
	else{
		onion_listen_point *first_listen_point=onion->listen_points[0];
		if (first_listen_point->write!=onion_https_write){
			if (first_listen_point->write!=onion_http_write){
				ONION_ERROR("First listen point is not HTTP not HTTPS. Refusing to promote it to HTTPS. Use proper onion_https_new.");
				return -1;
			}
			ONION_DEBUG("Promoting from HTTP to HTTPS");
			char *port=first_listen_point->port ? strdup(first_listen_point->port) : NULL;
			char *hostname=first_listen_point->hostname ? strdup(first_listen_point->hostname) : NULL;
			onion_listen_point_free(first_listen_point);
			onion_listen_point *https=onion_https_new();
			if (NULL==https){
				ONION_ERROR("Could not promote from HTTP to HTTPS. Certificate not set.");
			}
			https->port=port;
			https->hostname=hostname;
			onion->listen_points[0]=https;
			first_listen_point=https;
		}
	}
	va_list va;
	va_start(va, filename);
	int r=onion_https_set_certificate_argv(onion->listen_points[0], type, filename,va);
	va_end(va);

	return r;
#else
	ONION_ERROR("GNUTLS is not enabled. Recompile onion with GNUTLS support");
	return -1;
#endif
}
Example #22
0
void t01_call_otemplate(){
  INIT_LOCAL();


  onion *s=onion_new(0);

  onion_set_root_handler(s, onion_handler_new((void*)_13_otemplate_html_handler_page, NULL, NULL));
	onion_listen_point *lp=onion_buffer_listen_point_new();
	onion_add_listen_point(s,NULL,NULL,lp);

	struct tests_call_otemplate tests;

  onion_request *req=onion_request_new(lp);
  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);

  ONION_INFO("Got %s",onion_buffer_listen_point_get_buffer_data(req));
  check_tests(onion_buffer_listen_point_get_buffer(req), &tests);

  FAIL_IF_NOT_EQUAL_INT(tests.ok_hello,1);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_list,0);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_title,0);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_title_title,0);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_encoding,0);


  onion_dict *d=onion_dict_new();
  onion_dict_add(d, "title", "TITLE",0);
  onion_dict_add(d, "hello", "SHOULD NOT APPEAR",0);
	onion_dict_add(d, "quoted", "<\"Hello>",0);

  onion_request_clean(req);
	onion_handler_free(onion_get_root_handler(s));
  onion_set_root_handler(s, onion_handler_new((void*)_13_otemplate_html_handler_page, d, 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);

  ONION_INFO("Got %s",onion_buffer_listen_point_get_buffer_data(req));
  check_tests(onion_buffer_listen_point_get_buffer(req), &tests);

  FAIL_IF_NOT_EQUAL_INT(tests.ok_hello,1);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_list,0);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_title,1);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_title_title,1);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_encoding,1);


  onion_dict *d2=onion_dict_new();
  onion_dict_add(d2,"0","LIST 1",0);
  onion_dict_add(d2,"1","LIST 2",0);
  onion_dict_add(d2,"2","LIST 3",0);
  onion_dict_add(d,"list",d2, OD_DICT|OD_FREE_VALUE);

	onion_dict *f1=onion_dict_new();
	onion_dict *f2=onion_dict_new();
	onion_dict_add(f2, "0", "internal",0);
	onion_dict_add(f2, "1", "loop",0);
	onion_dict_add(f1, "loop", f2, OD_DICT|OD_FREE_VALUE);

	onion_dict_add(d, "loop", f1, OD_DICT|OD_FREE_VALUE);

  onion_request_clean(req);
	onion_handler_free(onion_get_root_handler(s));
  onion_set_root_handler(s, onion_handler_new((void*)_13_otemplate_html_handler_page, d, (void*)onion_dict_free));
    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);
  check_tests(onion_buffer_listen_point_get_buffer(req), &tests);
  ONION_INFO("Got %s",onion_buffer_listen_point_get_buffer_data(req));

	FAIL_IF_NOT_EQUAL_INT(tests.ok_hello,1);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_list,1);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_title,1);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_title_title,1);
  FAIL_IF_NOT_EQUAL_INT(tests.ok_internal_loop,1);


  onion_request_free(req);
  onion_free(s);

  END_LOCAL();
}
Example #23
0
void t03_handle_path_request(){
	INIT_LOCAL();

	onion *server=onion_new(0);
	onion_listen_point *lp=onion_buffer_listen_point_new();
	onion_add_listen_point(server, NULL, NULL, lp);

	onion_url *urls=onion_url_new();
	
	onion_url_add_static(urls, "^$", "Test index\n", HTTP_OK);
	onion_url_add_static(urls, "^index.html$", "Index test", 200);

	onion_url *pathu=onion_url_new();
	onion_handler *path=onion_url_to_handler(pathu);
	onion_url_add_url(pathu, "^test/", urls);
	onion_handler_add(path, onion_handler_static("Internal error", 500 ) );
	onion_set_root_handler(server, path);
	
	onion_request *request;
	onion_response *response;
	
	request=onion_request_new(lp);
	FILL(request,"GET / HTTP/1.1\n");
  onion_request_polish(request);
	response=onion_response_new(request);
	onion_handler_handle(path, request, response);
	onion_response_free(response);
	const char *buffer=onion_buffer_listen_point_get_buffer_data(request);
	FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.1 500 INTERNAL ERROR\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "Content-Length: 14\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\nInternal error");
	onion_request_free(request);
	
	// gives error, as such url does not exist.
	request=onion_request_new(lp);
	FILL(request,"GET /test/ HTTP/1.1\n");
  onion_request_polish(request);
	response=onion_response_new(request);
	onion_handler_handle(path, request, response);
	onion_response_free(response);
	buffer=onion_buffer_listen_point_get_buffer_data(request);
	FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.1 200 OK\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "Content-Length: 11\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\nTest index\n");
	onion_request_free(request);

	request=onion_request_new(lp);
	FILL(request,"GET /test/index.html HTTP/1.1\n");
  onion_request_polish(request);
	response=onion_response_new(request);
	onion_handler_handle(path, request, response);
	onion_response_free(response);
	buffer=onion_buffer_listen_point_get_buffer_data(request);
	FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.1 200 OK\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "Content-Length: 10\r\n");
	FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\nIndex test");
	onion_request_free(request);

	onion_free(server);

	END_LOCAL();
}
Example #24
0
void setup(){
	server=onion_new(O_ONE);
	custom_io=onion_buffer_listen_point_new();
	onion_add_listen_point(server, NULL, NULL, custom_io);
}
Example #25
0
/**
 * @short Performs the listening with the given mode
 * @memberof onion_t
 *
 * This is the main loop for the onion server.
 * 
 * It initiates the listening on all the selected ports and addresses.
 *
 * @returns !=0 if there is any error. It returns actualy errno from the network operations. See socket for more information.
 */
int onion_listen(onion *o){
#ifdef HAVE_PTHREADS
	if (!(o->flags&O_DETACHED) && (o->flags&O_DETACH_LISTEN)){ // Must detach and return
		o->flags|=O_DETACHED;
		pthread_create(&o->listen_thread,NULL, (void*)onion_listen, o);
		return 0;
	}
#endif
	
	if (!o->listen_points){
		onion_add_listen_point(o,NULL,NULL,onion_http_new());
		ONION_DEBUG("Created default HTTP listen port");
	}

	/// Start listening
	size_t successful_listened_points=0;
	onion_listen_point **lp=o->listen_points;
	while (*lp){
		int listen_result=onion_listen_point_listen(*lp);
		if (!listen_result) {
			successful_listened_points++;
		}
		lp++;
	}
	if (!successful_listened_points){
		ONION_ERROR("There are no available listen points");
		return 1;
	}

	
	if (o->flags&O_ONE){
		onion_listen_point **listen_points=o->listen_points;
		if (listen_points[1]!=NULL){
			ONION_WARNING("Trying to use non-poll and non-thread mode with several listen points. Only the first will be listened");
		}
		onion_listen_point *op=listen_points[0];
		do{
			onion_request *req=onion_request_new(op);
			if (!req)
				continue;
			ONION_DEBUG("Accepted request %p", req);
			onion_request_set_no_keep_alive(req);
			int ret;
			do{
				ret=req->connection.listen_point->read_ready(req);
			}while(ret>=0);
			ONION_DEBUG("End of request %p", req);
			onion_request_free(req);
			//req->connection.listen_point->close(req);
		}while(((o->flags&O_ONE_LOOP) == O_ONE_LOOP) && op->listenfd>0);
	}
	else{
		onion_listen_point **listen_points=o->listen_points;
		while (*listen_points){
			onion_listen_point *p=*listen_points;
			ONION_DEBUG("Adding listen point fd %d to poller", p->listenfd);
			onion_poller_slot *slot=onion_poller_slot_new(p->listenfd, (void*)onion_listen_point_accept, p);
			onion_poller_slot_set_type(slot, O_POLL_ALL);
			onion_poller_add(o->poller, slot);
			listen_points++;
		}

#ifdef HAVE_PTHREADS
		ONION_DEBUG("Start polling / listening %p, %p, %p", o->listen_points, *o->listen_points, *(o->listen_points+1));
		if (o->flags&O_THREADED){
			o->threads=malloc(sizeof(pthread_t)*(o->nthreads-1));
			int i;
			for (i=0;i<o->nthreads-1;i++){
				pthread_create(&o->threads[i],NULL,(void*)onion_poller_poll, o->poller);
			}
			
			// Here is where it waits.. but eventually it will exit at onion_listen_stop
			onion_poller_poll(o->poller);
			ONION_DEBUG("Closing onion_listen");
			
			for (i=0;i<o->nthreads-1;i++){
				pthread_join(o->threads[i],NULL);
			}
		}
		else
#endif
			onion_poller_poll(o->poller);

		listen_points=o->listen_points;
		while (*listen_points){
			onion_listen_point *p=*listen_points;
			if (p->listenfd>0){
				ONION_DEBUG("Removing %d from poller", p->listenfd);
				onion_poller_remove(o->poller, p->listenfd);
			}
			listen_points++;
		}
	}
	return 0;
}
Example #26
0
/// 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);
	
	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=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_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
	onion_request_clean(req);


	//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_free(req);

	if (post.tmpfilename){
		struct stat st;
		FAIL_IF_EQUAL(stat(post.tmpfilename,&st), 0); // Should not exist
	}
	
	onion_free(server);
	if (post.tmpfilename)
		free(post.tmpfilename);
	if (post.tmplink)
		free(post.tmplink);
	
	END_LOCAL();
}
Example #27
0
void init() {
  server = onion_new(0);
  onion_add_listen_point(server, NULL, NULL, onion_buffer_listen_point_new());
}