示例#1
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();
}
示例#2
0
// This fixes that whenever a session is created, but no new data is added, it does not set the proper cookie
void t04_lot_of_sessionid(){
  INIT_LOCAL();

  onion *o=onion_new(O_ONE_LOOP);
  onion_server_set_write(o->server, empty_write);
  
  onion_url *url=onion_root_url(o);
  onion_url_add(url, "^.*", ask_session);
  char sessionid[256];
  char tmp[1024];
  char tmp2[4096];
  onion_request *req;
  int i;
  set_data_on_session=1;

  req=onion_request_new(o->server, NULL, NULL);
  req->fullpath="/";
  onion_request_process(req);
  FAIL_IF_NOT_EQUAL_INT(onion_dict_count(o->server->sessions->sessions), 1);
  FAIL_IF_EQUAL_STR(lastsessionid,"");
  strcpy(sessionid, lastsessionid);
  req->fullpath=NULL;
  onion_request_free(req);

  req=onion_request_new(o->server, NULL, NULL);
  req->fullpath="/";
  snprintf(tmp,sizeof(tmp)," sessionid=xx%sxx;",lastsessionid);
  strcpy(tmp2,"Cookie:");
  for(i=0;i<64;i++)
    strncat(tmp2, tmp, sizeof(tmp2));
  snprintf(tmp,sizeof(tmp)," sessionid=%s\n",lastsessionid);
  strncat(tmp2, tmp, sizeof(tmp2));
  ONION_DEBUG("Set cookies (%d bytes): %s",strlen(tmp2),tmp2);
  strcpy(tmp,"GET /\n");
  onion_request_write(req,tmp,strlen(tmp)); // Here is the problem, at parsing too long headers
  onion_request_write(req,tmp2,strlen(tmp2)); // Here is the problem, at parsing too long headers
	onion_request_write(req,"\n",1);
  //onion_dict_add(req->headers, "Cookie", tmp2, 0);
  
  onion_request_process(req);
  FAIL_IF_NOT_EQUAL_INT(onion_dict_count(o->server->sessions->sessions), 1);
  FAIL_IF_EQUAL_STR(lastsessionid,"");
  FAIL_IF_NOT_EQUAL_STR(lastsessionid, sessionid);
  FAIL_IF_NOT(has_set_cookie);
  onion_request_free(req);
  
  onion_free(o);
  
  END_LOCAL();
}
示例#3
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();
}
示例#4
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();
}
示例#5
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();
}
示例#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();
}
示例#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();
}
示例#8
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();
}
示例#9
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();
}
示例#10
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();
}
示例#11
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();
}
示例#12
0
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();
}
示例#13
0
/**
 *  @short Creates a request object
 * @memberof onion_request_t
 *
 * @param op Listen point this request is listening to, to be able to read and write data
 */
onion_request *onion_request_new(onion_listen_point *op) {
    onion_request *req;
    req=onion_low_calloc(1, sizeof(onion_request));

    req->connection.listen_point=op;
    req->connection.fd=-1;

    //req->connection=con;
    req->headers=onion_dict_new();
    onion_dict_set_flags(req->headers, OD_ICASE);
    ONION_DEBUG0("Create request %p", req);

    if (op) {
        if (op->request_init) {
            if (op->request_init(req)<0) {
                ONION_DEBUG("Invalid request, closing");
                onion_request_free(req);
                return NULL;
            }
        }
        else
            onion_listen_point_request_init_from_socket(req);
    }
    return req;
}
示例#14
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();
}
示例#15
0
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();
}
示例#16
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();
}
示例#17
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();
}
示例#18
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();
}
示例#19
0
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();
}
示例#20
0
void t01_websocket_server_no_ws() {
  INIT_LOCAL();

  memset(&ws_status, 0, sizeof(ws_status));
  onion *o = websocket_server_new();
  onion_request *req = onion_request_new(onion_get_listen_point(o, 0));
  onion_request_write0(req, "GET /\n\n");
  onion_request_process(req);
  FAIL_IF(ws_status.is_connected);
  FAIL_IF_NOT_EQUAL_INT(ws_status.connected, 1);

  onion_request_free(req);
  onion_free(o);

  END_LOCAL();
}
示例#21
0
void t01_create_add_free(){
	INIT_LOCAL();
	
	onion_request *req;
	int ok;
	
	req=onion_request_new(custom_io);
	
	FAIL_IF_EQUAL(req,NULL);
	
	ok=REQ_WRITE(req, "GET / HTTP/1.1\n");
	FAIL_IF_NOT(ok);
	
	onion_request_free(req);
	
	END_LOCAL();
}
示例#22
0
void t02_websocket_server_w_ws() {
  INIT_LOCAL();

  memset(&ws_status, 0, sizeof(ws_status));
  onion *o = websocket_server_new();
  onion_request *req = onion_request_new(onion_get_listen_point(o, 0));
  onion_request_write0(req,
                       "GET /\nUpgrade: websocket\nSec-Websocket-Version: 13\nSec-Websocket-Key: My-key\n\n");
  onion_request_process(req);
  FAIL_IF_NOT(ws_status.is_connected);
  FAIL_IF_NOT_EQUAL_INT(ws_status.connected, 1);

  onion_request_free(req);
  onion_free(o);

  END_LOCAL();
}
示例#23
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();
}
示例#24
0
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();
}
示例#25
0
文件: 08-post.c 项目: Andrepuel/onion
/// 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();
}
示例#26
0
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();
}
示例#27
0
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();
}
示例#28
0
/**
 * @short Called when a new connection appears on the listenfd
 * @memberof onion_listen_point_t
 * 
 * When the new connection appears, creates the request and adds it to the pollers.
 * 
 * It returns always 1 as any <0 would detach from the poller and close the listen point, 
 * and not accepting a request does not mean the connection point is corrupted. If a 
 * connection point may become corrupted should be the connection point itself who detaches 
 * from the poller.
 * 
 * @param op The listen point from where the request must be built
 * @returns 1 always. The poller needs one to keep listening for connections.
 */
int onion_listen_point_accept(onion_listen_point *op){
	onion_request *req=onion_request_new(op);
	if (req){
		if (req->connection.fd>0){
			onion_poller_slot *slot=onion_poller_slot_new(req->connection.fd, (void*)onion_listen_point_read_ready, req);
			if (!slot)
				return 1;
			onion_poller_slot_set_timeout(slot, req->connection.listen_point->server->timeout);
			onion_poller_slot_set_shutdown(slot, (void*)onion_request_free, req);
			onion_poller_add(req->connection.listen_point->server->poller, slot);
			return 1;
		}
		// No fd. This could mean error, or not fd based. Normally error would not return a req.
		onion_request_free(req);
		ONION_ERROR("Error creating connection");
		return 1;
	}

	return 1;
}
示例#29
0
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();
}
示例#30
0
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();
}