Exemplo n.º 1
0
void t04_websocket_server_close_handshake() {
  INIT_LOCAL();
  int length = 0;
  unsigned char *buffer = NULL, buffer2[8];
  onion *o = websocket_server_new();
  onion_request *req = websocket_start_handshake(o);
  req->connection.listen_point->read =
      (lpreader_sig_t *) websocket_data_buffer_read;
  req->connection.listen_point->write =
      (lpwriter_sig_t *) websocket_data_buffer_write;

  onion_response *res = onion_response_new(req);
  onion_websocket *ws = onion_websocket_new(req, res);

  length = websocket_forge_close_packet((char **)&buffer);
  websocket_data_buffer_write(req, (char *)buffer, length);
  onion_connection_status ret = onion_websocket_call(ws);
  FAIL_IF(ret != -2);
  websocket_data_buffer_read(req, (char *)&buffer2, 8);
  FAIL_IF_NOT(buffer2[0] == 0x88);
  FAIL_IF_NOT(buffer2[1] == 0x02);
  FAIL_IF_NOT(buffer2[2] == 0x03);
  FAIL_IF_NOT(buffer2[3] == 0xE8);

  onion_websocket_free(ws);
  onion_request_free(req);
  onion_free(o);
  END_LOCAL();
}
Exemplo n.º 2
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();
}
Exemplo n.º 3
0
/**
 * @short  Performs the processing of the request.
 * @memberof onion_server_t
 * 
 * Returns the OCS_KEEP_ALIVE or OCS_CLOSE_CONNECTION value. If on keep alive the struct is already reinitialized.
 * 
 * It calls the root_handler and if it returns an error of any type (or not processed), it calls the
 * default internal_error_handler.
 * 
 * Normally it could get the server from the request, but it is passed for homogenity, and
 * to allow unforseen posibilities.
 * 
 * @see onion_connection_status
 */
onion_connection_status onion_server_handle_request(onion_server *server, onion_request *req){
	onion_response *res=onion_response_new(req);
	
	// Call the main handler.
	onion_connection_status hs=onion_handler_handle(server->root_handler, req, res);

	if (hs==OCS_INTERNAL_ERROR || 
		hs==OCS_NOT_IMPLEMENTED || 
		hs==OCS_NOT_PROCESSED){
		if (hs==OCS_INTERNAL_ERROR)
			req->flags|=OR_INTERNAL_ERROR;
		if (hs==OCS_NOT_IMPLEMENTED)
			req->flags|=OR_NOT_IMPLEMENTED;
		if (hs==OCS_NOT_PROCESSED)
			req->flags|=OR_NOT_FOUND;
    if (hs==OCS_FORBIDDEN)
      req->flags|=OR_FORBIDDEN;
		
		hs=onion_handler_handle(server->internal_error_handler, req, res);
	}

	
	int rs=onion_response_free(res);
	if (hs>=0 && rs==OCS_KEEP_ALIVE) // if keep alive, reset struct to get the new petition.
		onion_request_clean(req);
	
	return hs>0 ? rs : hs;
}
Exemplo n.º 4
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();
}
Exemplo n.º 5
0
void t03_websocket_server_receive_small_packet() {
  INIT_LOCAL();
  int length = 0;
  char *buffer = NULL, buffer2[115];
  memset(&ws_status, 0, sizeof(ws_status));
  onion *o = websocket_server_new();
  onion_request *req = websocket_start_handshake(o);
  req->connection.listen_point->read =
      (lpreader_sig_t *) websocket_data_buffer_read;

  onion_response *res = onion_response_new(req);
  onion_websocket *ws = onion_websocket_new(req, res);

  length = websocket_forge_small_packet((char **)&buffer);
  websocket_data_buffer_write(req, buffer, length);

  onion_websocket_read(ws, (char *)&buffer2, 120);

  buffer2[114] = '\0';
  FAIL_IF_NOT_EQUAL_STR(buffer2,
                        "Some UTF-8-encoded chars which will be cut at the 117th char so I write some gap-filling text with no meaning unti");

  onion_websocket_free(ws);
  onion_request_free(req);
  onion_free(o);
  END_LOCAL();
}
Exemplo n.º 6
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();
}
Exemplo n.º 7
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();
}
Exemplo n.º 8
0
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();
}
Exemplo n.º 9
0
void t02_cookies(){
	INIT_LOCAL();
	
	onion_response *res=onion_response_new(NULL);
	onion_dict *h=onion_response_get_headers(res);
	
	onion_response_add_cookie(res, "key1", "value1", -1, NULL, NULL, 0);
	FAIL_IF_NOT_EQUAL_STR(onion_dict_get(h, "Set-Cookie"), "key1=value1");
	
	onion_dict_remove(h, "Set-Cookie");
	onion_response_add_cookie(res, "key2", "value2", -1, "/", "*.example.org", OC_HTTP_ONLY|OC_SECURE);
	FAIL_IF_NOT_EQUAL_STR(onion_dict_get(h, "Set-Cookie"), "key2=value2; path=/; domain=*.example.org; HttpOnly; Secure");

	onion_dict_remove(h, "Set-Cookie");
	onion_response_add_cookie(res, "key3", "value3", 0, "/", "*.example.org", OC_HTTP_ONLY|OC_SECURE);
	FAIL_IF_NOT_EQUAL_STR(onion_dict_get(h, "Set-Cookie"), "key3=value3; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=*.example.org; HttpOnly; Secure");
	
	onion_dict_remove(h, "Set-Cookie");
	onion_response_add_cookie(res, "key4", "value4", 60, "/", "*.example.org", OC_HTTP_ONLY|OC_SECURE);
	FAIL_IF_EQUAL_STR(onion_dict_get(h, "Set-Cookie"), "key4=value4; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=*.example.org; HttpOnly; Secure");
	FAIL_IF_EQUAL_STR(onion_dict_get(h, "Set-Cookie"), "key4=value4; domain=*.example.org; HttpOnly; path=/; Secure");
	
	int i;
	int valid_expires=0;
	char tmpdate[100];
	const char *setcookie=onion_dict_get(h, "Set-Cookie");
	for(i=59;i<62;i++){
		struct tm *tmp;
		time_t t=time(NULL) + i;
		tmp = localtime(&t);
		strftime(tmpdate, sizeof(tmpdate), "key4=value4; expires=%a, %d %b %Y %H:%M:%S %Z; path=/; domain=*.example.org; HttpOnly; Secure", tmp);
		ONION_DEBUG("\ntest  %s =? \nonion %s", tmpdate, setcookie);
		if (strcmp(tmpdate, setcookie)==0)
			valid_expires=1;
	}
	FAIL_IF_NOT(valid_expires);
	
	onion_response_free(res);
	
	END_LOCAL();
}
Exemplo n.º 10
0
/**
 * @short Handler that just echoes all data, writing what was a header, what the method...
 */
onion_connection_status allinfo_handler(void *data, onion_request *req){
	onion_response *res=onion_response_new(req);
	onion_response_write_headers(res);
	
	int f=onion_request_get_flags(req);
	onion_response_printf(res, "Method: %s\n",(f&OR_GET) ? "GET" : (f&OR_HEAD) ? "HEAD" : "POST");
	onion_response_printf(res, "Path: %s\n",onion_request_get_path(req));
	onion_response_printf(res, "Version: %s\n",onion_request_get_flags(req)&OR_HTTP11 ? "HTTP/1.1" : "HTTP/1.0");

	allinfo_dict_print_t aid;
	aid.res=res;
	aid.part="Query";
	onion_dict_preorder(onion_request_get_query_dict(req),allinfo_query, &aid);
	aid.part="Header";
	onion_dict_preorder(onion_request_get_header_dict(req),allinfo_query, &aid);
	aid.part="POST";
	onion_dict_preorder(onion_request_get_post_dict(req),allinfo_query, &aid);
	aid.part="FILE";
	onion_dict_preorder(onion_request_get_file_dict(req),allinfo_query, &aid);
	
	return onion_response_free(res);;
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
0
/**
 * @short Launches one handler for the given request
 * @ingroup request
 *
 * Once the request is ready, launch it.
 *
 * @returns The connection status: if it should be closed, error codes...
 */
onion_connection_status onion_request_process(onion_request *req){
	onion_response *res=onion_response_new(req);
	if (!req->path){
		onion_request_polish(req);
	}
	// Call the main handler.
	onion_connection_status hs=onion_handler_handle(req->connection.listen_point->server->root_handler, req, res);

	if (hs==OCS_INTERNAL_ERROR ||
		hs==OCS_NOT_IMPLEMENTED ||
		hs==OCS_NOT_PROCESSED){
		if (hs==OCS_INTERNAL_ERROR)
			req->flags|=OR_INTERNAL_ERROR;
		if (hs==OCS_NOT_IMPLEMENTED)
			req->flags|=OR_NOT_IMPLEMENTED;
		if (hs==OCS_NOT_PROCESSED)
			req->flags|=OR_NOT_FOUND;
		if (hs==OCS_FORBIDDEN)
			req->flags|=OR_FORBIDDEN;

		hs=onion_handler_handle(req->connection.listen_point->server->internal_error_handler, req, res);
	}

	if (hs==OCS_YIELD){
		// Remove from the poller, and yield thread to poller. From now on it will be processed somewhere else (longpoll thread).
		onion_poller *poller=onion_get_poller(req->connection.listen_point->server);
		onion_poller_slot *slot=onion_poller_get(poller, req->connection.fd);
		onion_poller_slot_set_shutdown(slot, NULL, NULL);

		return hs;
	}
	int rs=onion_response_free(res);
	if (hs>=0 && rs==OCS_KEEP_ALIVE) // if keep alive, reset struct to get the new petition.
		onion_request_clean(req);
	return hs>0 ? rs : hs;
}
Exemplo n.º 13
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();
}