コード例 #1
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t01_create_add_free(){
	INIT_LOCAL();
	onion_dict *dict;
	const char *value;
	
	dict=onion_dict_new();
	FAIL_IF_EQUAL(dict,NULL);

	// Get before anything in
	value=onion_dict_get(dict, "Request");
	FAIL_IF_NOT_EQUAL(value,NULL);

	// basic add
	onion_dict_add(dict, "Request", "GET /", OD_DUP_ALL);
	value=onion_dict_get(dict, "Request");
	FAIL_IF_NOT_EQUAL_STR(value,"GET /");
	
	// basic remove
	onion_dict_remove(dict, "Request");
	value=onion_dict_get(dict, "Request");
	FAIL_IF_NOT_EQUAL(value,NULL);

	onion_dict_free(dict);
	
	END_LOCAL();
}
コード例 #2
0
ファイル: extended_html.c プロジェクト: IPInfusion/SDN-IP
void extended_html__block_body(onion_dict *context, onion_response *res){
#line 1
#line 8
  onion_response_write(res, "\n<h1>This is an extended template</h1>\n\n", 40);
#line 8
  {
#line 8
    void (*f)(onion_dict *context, onion_response *res);
#line 8
    f=(void*)onion_dict_get(context, "__block_body_in__");
#line 8
    if (f)
#line 8
      f(context, res);
#line 8
  }
#line 14
  onion_response_write(res, "\n\nIf you see this, <span style=\"color: green;\">OK</span>.\n<br>\nRandom (only at test2): ", 87);
#line 14
  {
#line 14
    const char *tmp;
#line 14
    tmp=onion_dict_get(context, "random");
#line 14
    if (tmp)
#line 14
      onion_response_write0(res, tmp);
#line 14
  }
#line 19
  onion_response_write(res, "\n<br>\n\nUnicode Chars: \342\202\254 \302\241 \303\241 \303\251 \303\255 \303\272 \303\263. \346\261\211\350\257\255/\346\274\242\350\252\236.\n\n", 61);
#line 1
}
コード例 #3
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t12_dict_in_dict(){
	INIT_LOCAL();
	
	onion_dict *A=onion_dict_new();
	onion_dict *B=onion_dict_new();
	onion_dict *C=onion_dict_new();
	onion_dict *D=onion_dict_new();
	
	int i;
	for (i=0;i<16;i++){
		char tmp[9];
		sprintf(tmp,"%08X",rand());
		onion_dict_add(A, tmp, tmp, OD_DUP_ALL);
		sprintf(tmp,"%08X",rand());
		onion_dict_add(B, tmp, tmp, OD_DUP_ALL);
		sprintf(tmp,"%08X",rand());
		onion_dict_add(C, tmp, tmp, OD_DUP_ALL);
		sprintf(tmp,"%08X",rand());
		onion_dict_add(D, tmp, tmp, OD_DUP_ALL);
	}

	onion_dict_add(A, "B", B, OD_DICT|OD_FREE_VALUE);
	onion_dict_add(A, "C", C, OD_DICT|OD_FREE_VALUE);
	onion_dict_add(A, "D", D, OD_DICT|OD_FREE_VALUE);

	FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get(A, "B"), NULL);
	FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get(A, "C"), NULL);
	FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get(A, "D"), NULL);

	FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get_dict(A, "B"), B);
	FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get_dict(A, "C"), C);
	FAIL_IF_NOT_EQUAL((onion_dict*)onion_dict_get_dict(A, "D"), D);
	
	{
		onion_block *tmpA=onion_dict_to_json(A);
		onion_block *tmpB=onion_dict_to_json(B);
		onion_block *tmpC=onion_dict_to_json(C);
		onion_block *tmpD=onion_dict_to_json(D);
		/*
		ONION_DEBUG("Json is: %s",tmpA);
		ONION_DEBUG("Json is: %s",tmpB);
		ONION_DEBUG("Json is: %s",tmpC);
		ONION_DEBUG("Json is: %s",tmpD);
		*/
		FAIL_IF_EQUAL( strstr(onion_block_data(tmpA), onion_block_data(tmpB)), NULL);
		FAIL_IF_EQUAL( strstr(onion_block_data(tmpA), onion_block_data(tmpC)), NULL);
		FAIL_IF_EQUAL( strstr(onion_block_data(tmpA), onion_block_data(tmpD)), NULL);
		onion_block_free(tmpA);
		onion_block_free(tmpB);
		onion_block_free(tmpC);
		onion_block_free(tmpD);
	}
	B=onion_dict_hard_dup(A);
	
	onion_dict_free(A);
	onion_dict_free(B);
	
	END_LOCAL();
}
コード例 #4
0
ファイル: request_parser.c プロジェクト: adnandzebic/onion
/**
 * @short Prepares the POST
 */
static onion_connection_status prepare_POST(onion_request *req){
	// ok post
	onion_token *token=req->parser_data;
	const char *content_type=onion_dict_get(req->headers, "Content-Type");
	const char *content_size=onion_dict_get(req->headers, "Content-Length");
	
	if (!content_size){
		ONION_ERROR("I need the content size header to support POST data");
		return OCS_INTERNAL_ERROR;
	}
	size_t cl=atol(content_size);
	//ONION_DEBUG("Content type %s",content_type);
	if (!content_type || (strstr(content_type, "application/x-www-form-urlencoded"))){
		if (cl>req->connection.listen_point->server->max_post_size){
			ONION_ERROR("Asked to send much POST data. Limit %d. Failing.",req->connection.listen_point->server->max_post_size);
			return OCS_INTERNAL_ERROR;
		}
		token->extra=malloc(cl+1); // Cl + \0
		token->extra_size=cl;
		
		req->parser=parse_POST_urlencode;
		return OCS_NEED_MORE_DATA;
	}
	
	// multipart.
	
	const char *mp_token=strstr(content_type, "boundary=");
	if (!mp_token){
		ONION_ERROR("No boundary set at content-type");
		return OCS_INTERNAL_ERROR;
	}
	mp_token+=9;
	if (cl>req->connection.listen_point->server->max_post_size) // I hope the missing part is files, else error later.
		cl=req->connection.listen_point->server->max_post_size;
	
	int mp_token_size=strlen(mp_token);
	token->extra_size=cl; // Max size of the multipart->data
	onion_multipart_buffer *multipart=malloc(token->extra_size+sizeof(onion_multipart_buffer)+mp_token_size+2);
	token->extra=(char*)multipart;
	
	multipart->boundary=(char*)multipart+sizeof(onion_multipart_buffer)+1;
	multipart->size=mp_token_size+4;
	multipart->pos=2; // First boundary already have [\r]\n readen
	multipart->post_total_size=cl;
	multipart->file_total_size=0;
	multipart->boundary[0]='\r';
	multipart->boundary[1]='\n';
	multipart->boundary[2]='-';
	multipart->boundary[3]='-';
	strcpy(&multipart->boundary[4],mp_token);
	multipart->data=(char*)multipart+sizeof(onion_multipart_buffer)+multipart->size+1;
	
	//ONION_DEBUG("Multipart POST boundary '%s'",multipart->boundary);
	
	req->parser=parse_POST_multipart_start;
	
	return OCS_NEED_MORE_DATA;
}
コード例 #5
0
ファイル: extended_html.c プロジェクト: IPInfusion/SDN-IP
void extended_html_blocks_init(onion_dict *context){
#line 1
  if (!onion_dict_get(context, "__block_title__"))
    onion_dict_add(context, "__block_title__", extended_html__block_title, 0);
  if (!onion_dict_get(context, "__block_body__"))
    onion_dict_add(context, "__block_body__", extended_html__block_body, 0);
  if (!onion_dict_get(context, "__block_body_in__"))
    onion_dict_add(context, "__block_body_in__", extended_html__block_body_in, 0);
#line 1
}
コード例 #6
0
void base_html(onion_dict *context, onion_response *res){
#line 1
#line 1
  int has_context=(context!=NULL);
#line 1
  if (!has_context)
#line 1
    context=onion_dict_new();
#line 1
  
#line 1
  base_html_blocks_init(context);
  onion_response_write(res, "<!DOCTYPE html>\n"
      "<html>\n"
      "  <head>\n"
      "    <title>", 43);
#line 4
  {
#line 4
    const char *tmp;
#line 4
    tmp=onion_dict_get(context, "title");
#line 4
    if (tmp)
#line 4
      onion_response_write_html_safe(res, tmp);
#line 4
  }
  onion_response_write(res, "</title>\n"
      "  </head>\n"
      "  <body>\n"
      "", 28);
#line 7
  {
#line 7
    void (*f)(onion_dict *context, onion_response *res);
#line 7
    f=(void*)onion_dict_get(context, "__block_content__");
#line 7
    if (f)
#line 7
      f(context, res);
#line 7
  }
  onion_response_write(res, "  \n"
      "  </body>\n"
      "</html>\n"
      "", 21);
#line 10
  if (!has_context)
#line 10
    onion_dict_free(context);
#line 1
}
コード例 #7
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t03_create_and_free_a_lot_random(unsigned int n){
	INIT_LOCAL();
	onion_dict *dict;
	const char *value;
	unsigned int i;
	
	dict=onion_dict_new();
	FAIL_IF_EQUAL(dict,NULL);

	// Linear add
	for (i=0;i<n;i++){
		char key[16], val[16];
		sprintf(key,"key %d",R1(i));
		sprintf(val,"val %d",R2(i));
		
		onion_dict_add(dict, key, val, OD_DUP_ALL);
	}

	// Linear get
	for (i=0;i<n;i++){
		char key[16], val[16];
		sprintf(key,"key %d",R1(i));
		sprintf(val,"val %d",R2(i));
		
		value=onion_dict_get(dict, key);
		FAIL_IF_NOT_EQUAL_STR(val,value);
	}

	// remove all
	for (i=n;i>0;i--){
		char key[16];
		int removed;
		sprintf(key,"key %d",R1(i-1));
		//fprintf(stderr,"%s %d\n",key,i-1);
		removed=onion_dict_remove(dict, key);
		FAIL_IF_NOT_EQUAL(removed,1);
	}

	// check removed all
	for (i=0;i<n;i++){
		char key[16], val[16];
		sprintf(key,"key %d",R1(i));
		sprintf(val,"val %d",R1(i));
		
		value=onion_dict_get(dict, key);
		//fprintf(stderr,"%s %s\n",key,value);
		FAIL_IF_NOT_EQUAL(NULL,value);
		FAIL_IF_NOT_EQUAL_STR(NULL,value);
	}

	onion_dict_free(dict);
	
	END_LOCAL();
}
コード例 #8
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t06_null_add(){
	INIT_LOCAL();
	onion_dict *dict;
	dict=onion_dict_new();
	
	onion_dict_add(dict,"b",NULL,0);
	onion_dict_add(dict,"a",NULL,0);
	onion_dict_add(dict,"c","1",0);
	
	FAIL_IF_NOT_EQUAL_STR(onion_dict_get(dict,"c"),"1");
	FAIL_IF_NOT_EQUAL(onion_dict_get(dict,"a"),NULL);
	
	onion_dict_free(dict);
	END_LOCAL();
}
コード例 #9
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t14_dict_case_insensitive(){
  INIT_LOCAL();
  
  onion_dict *d=onion_dict_new();
  
  onion_dict_add(d,"Test","OK", 0);
  FAIL_IF_NOT_EQUAL(onion_dict_get(d,"test"),NULL);
  
  onion_dict_set_flags(d,OD_ICASE);
  FAIL_IF_NOT_EQUAL_STR(onion_dict_get(d,"test"),"OK");

	onion_dict_free(d);
	
  END_LOCAL();
}
コード例 #10
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
char *t08_thread_read(onion_dict *d){
	char done=0;
	char *ret=NULL;
	while (!done){
		//ONION_DEBUG("Lock read");
		onion_dict_lock_write(d);
		//ONION_DEBUG("Got read lock");
		const char *test=onion_dict_get(d,"test");
		if (test){
			//ONION_DEBUG("Unlock");
			
			//onion_dict_lock_write(d);
			//ONION_DEBUG("Got write lock");
			char tmp[16];
			snprintf(tmp,16,"%d",onion_dict_count(d));
			onion_dict_remove(d,"test");
			onion_dict_add(d,tmp,"test",OD_DUP_ALL);
			ONION_DEBUG("Write answer %d", onion_dict_count(d));
			done=1;
			//ONION_DEBUG("Unlock");
			onion_dict_unlock(d);
			ret=(char*)1;
			break;
		}
		//ONION_DEBUG("Unlock");
		onion_dict_unlock(d);
		usleep(200);
	}
	//ONION_DEBUG("dict free");
	onion_dict_free(d);
	return ret;
}
コード例 #11
0
ファイル: oterm_handler.c プロジェクト: Andrepuel/onion
/// Plexes the request depending on arguments.
int oterm_get_data(oterm_data *data, onion_request *req, onion_response *res){
  const char *username=onion_request_get_session(req,"username");
  if (!username){
    ONION_WARNING("Trying to enter authenticated area without username.");
    return OCS_FORBIDDEN;
  }
	oterm_session *o=(oterm_session*)onion_dict_get(data->sessions, onion_request_get_session(req,"username"));
	if (!o){
		o=oterm_session_new();
		onion_dict_lock_write(data->sessions);
		onion_dict_add(data->sessions,onion_request_get_session(req,"username"),o, 0);
		onion_dict_unlock(data->sessions);
	}
  const char *path=onion_request_get_path(req);

  ONION_DEBUG("Ask path %s (%p)", path, data);
  
  if (strcmp(path,"new")==0){
    if (onion_request_get_post(req, "command")){
      free(data->exec_command);
      data->exec_command=strdup(onion_request_get_post(req, "command"));
    }
    oterm_new(data, o, onion_request_get_session(req, "username"), onion_request_get_session(req, "nopam") ? 0 : 1 );
    return onion_shortcut_response("ok", 200, req, res);
  }
  if (strcmp(path,"status")==0)
    return oterm_status(o,req, res);

  return OCS_NOT_PROCESSED;
}
コード例 #12
0
ファイル: request.c プロジェクト: cemonds/onion
/**
 * @short Gets the sessionid cookie, if any, and sets it to req->session_id.
 * @memberof onion_request_t
 */
void onion_request_guess_session_id(onion_request *req){
	if (req->session_id) // already known.
		return;
	const char *v=onion_dict_get(req->headers, "Cookie");
	ONION_DEBUG("Session ID, maybe from %s",v);
	char *r=NULL;
	onion_dict *session;
	
	do{ // Check all possible sessions
		if (r)
			free(r);
		if (!v)
			return;
		v=strstr(v,"sessionid=");
		if (!v) // exit point, no session found.
			return;
		v+=10;
		r=strdup(v); // Maybe allocated more memory, not much anyway.
		char *p=r;
		while (*p!='\0' && *p!=';') p++;
		*p='\0';
		ONION_DEBUG0("Checking if %s exists in sessions", r);
		session=onion_sessions_get(req->server->sessions, r);
	}while(!session);
	
	req->session_id=r;
	req->session=session;
	ONION_DEBUG("Session ID, from cookie, is %s",req->session_id);
}
コード例 #13
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void *t08_thread_write(onion_dict *d){
	int n=0;
	while (n!=N_READERS){
		int i;
		n=0;
		//ONION_DEBUG("Lock read");
		onion_dict_lock_read(d);
		//ONION_DEBUG("Got read lock");
		for (i=0;i<N_READERS;i++){
			char tmp[16];
			snprintf(tmp,16,"%d",i+1);
			const char *r=onion_dict_get(d,tmp);
			if (r)
				n++;
		}
		//ONION_DEBUG("Unlock");
		onion_dict_unlock(d);
		//ONION_DEBUG("Lock write");
		onion_dict_lock_write(d);
		//ONION_DEBUG("Got write lock");
		onion_dict_add(d, "test", "test", OD_DUP_ALL|OD_REPLACE);
		//ONION_DEBUG("Unlock");
		onion_dict_unlock(d);
		ONION_DEBUG("Found %d answers, should be %d.", n, N_READERS);
		usleep(200);
	}
	
	onion_dict_free(d);
	return (char*)1;
}
コード例 #14
0
ファイル: 01-hash.c プロジェクト: 1514louluo/onion
void cmpdict(onion_dict *d, const char *key, const char *value, int flags){
	if (flags&OD_DICT){
		onion_dict_preorder((onion_dict*)value, cmpdict, onion_dict_get_dict(d, key));
		onion_dict_preorder(onion_dict_get_dict(d, key), cmpdict, (onion_dict*)value);
	}
	else
		FAIL_IF_NOT_EQUAL_STR(value, onion_dict_get(d, key));
}
コード例 #15
0
ファイル: 02-request.c プロジェクト: Scarberian/onion
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();
}
コード例 #16
0
ファイル: 02-request.c プロジェクト: Scarberian/onion
void t11_cookies(){
	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="GET / HTTP/1.0\n"
											"Content-Type: application/x-www-form-urlencoded\n"
											"Host: 127.0.0.1\n\r"
											"Cookie: key1=value1; key2=value2;\n"
											"Accept-Language: en\n"; // Missing \n caused memleak, to check with valgrind
		
		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,"Cookie"), "key1=value1; key2=value2;");
	
	FAIL_IF_NOT_EQUAL_STR(onion_request_get_cookie(req,"key1"), "value1");
	FAIL_IF_NOT_EQUAL_STR(onion_request_get_cookie(req,"key2"), "value2");
	FAIL_IF_EQUAL_STR(onion_request_get_cookie(req," key2"), "value2");
	
	onion_dict *cookies=onion_request_get_cookies_dict(req);
	FAIL_IF_EQUAL(cookies, NULL);
	
	FAIL_IF_NOT_EQUAL_STR(onion_dict_get(cookies,"key1"), "value1");
	FAIL_IF_NOT_EQUAL_STR(onion_dict_get(cookies,"key2"), "value2");
	
	onion_request_free(req);
	
	
	END_LOCAL();
}
コード例 #17
0
/**
 * @short Prepares the PUT
 *
 * It saves the data to a temporal file, which name is stored at data.
 */
static onion_connection_status prepare_PUT(onion_request *req){
	onion_token *token=req->parser_data;
	const char *content_size=onion_dict_get(req->headers, "Content-Length");
	if (!content_size){
		ONION_ERROR("I need the Content-Length header to get data");
		return OCS_INTERNAL_ERROR;
	}
	size_t cl=atol(content_size);

	if (cl>req->connection.listen_point->server->max_file_size){
		ONION_ERROR("Trying to PUT a file bigger than allowed size");
		return OCS_INTERNAL_ERROR;
	}

	req->data=onion_block_new();

	char filename[]="/tmp/onion-XXXXXX";
	int fd=mkstemp(filename);
	if (fd<0)
		ONION_ERROR("Could not create temporary file at %s.", filename);

	onion_block_add_str(req->data, filename);
	ONION_DEBUG0("Creating PUT file %s (%d bytes long)", filename, token->extra_size);

	if (!req->FILES){
		req->FILES=onion_dict_new();
	}
	{
	const char *filename=onion_block_data(req->data);
	onion_dict_add(req->FILES,"filename", filename, 0);
	}


	if (cl==0){
		ONION_DEBUG0("Created 0 length file");
		close(fd);
		return OCS_REQUEST_READY;
	}

	int *pfd=onion_low_scalar_malloc(sizeof(fd));
	*pfd=fd;

	assert(token->extra==NULL);
	token->extra=(char*)pfd;
	token->extra_size=cl;
	token->pos=0;

	req->parser=parse_PUT;
	return OCS_NEED_MORE_DATA;
}
コード例 #18
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t01_create_add_free_10(){
	INIT_LOCAL();
	onion_dict *dict;
	const char *value;
	
	dict=onion_dict_new();
	FAIL_IF_EQUAL(dict,NULL);

	// Get before anything in
	value=onion_dict_get(dict, "Request");
	FAIL_IF_NOT_EQUAL(value,NULL);

	// basic add
	int i;
	char tmp[256];
	for (i=0;i<10;i++){
		snprintf(tmp,sizeof(tmp),"%d",(i*13)%10);
		////ONION_DEBUG("add key %s",tmp);
		onion_dict_add(dict, tmp, "GET /", OD_DUP_ALL);
		value=onion_dict_get(dict, tmp);
		FAIL_IF_NOT_EQUAL_STR(value,"GET /");
		//onion_dict_print_dot(dict);
	}
	for (i=0;i<10;i++){
		snprintf(tmp,sizeof(tmp),"%d",i);
		////ONION_DEBUG("rm key %s",tmp);
		onion_dict_remove(dict, tmp);
		value=onion_dict_get(dict, tmp);
		FAIL_IF_NOT_EQUAL(value,NULL);
		//onion_dict_print_dot(dict);
	}
	
	onion_dict_free(dict);
	
	END_LOCAL();
}
コード例 #19
0
ファイル: 02-request.c プロジェクト: Scarberian/onion
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
ファイル: 01-hash.c プロジェクト: 1514louluo/onion
void t17_merge(){
	INIT_LOCAL();

	onion_dict *a=onion_dict_from_json("{\"hello\":\"world\"}");
	onion_dict *b=onion_dict_from_json("{\"bye\":\"_world_\", \"sub\": { \"hello\": \"world!\" } }");

	onion_dict_merge(a,b);

	FAIL_IF_NOT_EQUAL_STR(onion_dict_get(a,"bye"), "_world_");
	FAIL_IF_NOT_EQUAL_STR(onion_dict_rget(a,"sub","hello",NULL), "world!");

	onion_dict_free(b);
	FAIL_IF_NOT_EQUAL_STR(onion_dict_rget(a,"sub","hello",NULL), "world!");
	onion_dict_free(a);

	END_LOCAL();
}
コード例 #21
0
ファイル: 03-response.c プロジェクト: Andrepuel/onion
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();
}
コード例 #22
0
ファイル: request.c プロジェクト: scottrfrancis/onion
/**
 * @short Returns the language code of the current request
 * @memberof onion_request_t
 *
 * Returns the language code for the current request, from the header.
 * If none the returns "C".
 *
 * Language code is short code. No localization by the moment.
 *
 * @returns The language code for this request or C. Data must be freed.
 */
const char *onion_request_get_language_code(onion_request *req) {
    const char *lang=onion_dict_get(req->headers, "Accept-Language");
    if (lang) {
        char *l=onion_low_strdup(lang);
        char *p=l;
        while (*p) { // search first part
            if (*p=='-' || *p==';' || *p==',') {
                *p=0;
                break;
            }
            p++;
        }
        //ONION_DEBUG("Language is %s", l);
        return l;
    }
    return onion_low_strdup("C");
}
コード例 #23
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t09_thread_war_thread(onion_dict *d){
	int i;
	char tmp[16];
	for (i=0;i<WARLOOPS;i++){
		snprintf(tmp,16,"%04X",i);
		if (rand()%1){
			onion_dict_lock_read(d);
			onion_dict_get(d,tmp);
			onion_dict_unlock(d);
		}
		else{
			onion_dict_lock_write(d);
			onion_dict_add(d,tmp,tmp,OD_DUP_ALL|OD_REPLACE);
			onion_dict_unlock(d);
		}
	}
	onion_dict_free(d);
}
コード例 #24
0
ファイル: dict.c プロジェクト: Sts0mrg0/onion
/**
 * @short Gets a dictionary string value, recursively
 * @memberof onion_dict_t
 *
 * Loops inside given dictionaries to get the given value
 *
 * @param dict The dictionary
 * @param key The key list, one per arg, end with NULL
 * @returns The const string if valid, or NULL
 */
const char *onion_dict_rget(const onion_dict *dict, const char *key, ...){
	const onion_dict *d=dict;
	const char *k=key;
	const char *nextk;
	va_list va;
	va_start(va, key);
	while (d){
		nextk=va_arg(va, const char *);
		if (!nextk){
			va_end(va);
			return onion_dict_get(d, k);
		}
		d=onion_dict_get_dict(d, k);
		k=nextk;
	}
	va_end(va);
	return NULL;
}
コード例 #25
0
ファイル: 01-hash.c プロジェクト: 1514louluo/onion
void t18_json_escape_codes(){
	INIT_LOCAL();

	onion_dict *d=onion_dict_from_json("{ \"hello\": \"Hello\\nworld\", \"second\":\"second\" }");
	FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "Hello\nworld");
	FAIL_IF_NOT_STRSTR(onion_dict_get(d, "second"), "second");
	onion_dict_free(d);

	d=onion_dict_from_json("{ \"hello\": \"\\uD83D\\uDE02\" }");
	FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "😂");
	onion_dict_free(d);

	d=onion_dict_from_json("{ \"hello\": \"\\uD83D\\uDE03\" }"); // Another code point
	FAIL_IF_STRSTR(onion_dict_get(d, "hello"), "😂");
	onion_dict_free(d);

	d=onion_dict_from_json("{ \"hello\": \"\\u007b\" }"); // simple unicode
	FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "{");
	onion_dict_free(d);

	d=onion_dict_from_json("{ \"hello\": \"\\\"Quote\" }"); // Escape quote
	FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "\"Quote");
	onion_dict_free(d);

	d=onion_dict_from_json("{ \"hello\": \"\"Quote\" }"); // Must fail
	FAIL_IF_NOT_EQUAL(d, NULL);

	d=onion_dict_new();
	onion_dict_add(d, "hello", "Hello\nWorld\\", 0);
	onion_dict_add(d, "second", "123", 0);
	onion_block *b=onion_dict_to_json(d);
	FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"Hello\\nWorld\\\\\", \"second\":\"123\"}");
	onion_block_free(b);
	onion_dict_free(d);

	d=onion_dict_new();
	onion_dict_add(d, "hello", "😂\t\n😂", 0);
	b=onion_dict_to_json(d);
	FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"😂\\t\\n😂\"}");
	onion_block_free(b);
	onion_dict_free(d);

	d=onion_dict_new();
	onion_dict_add(d, "hello", "\02\03\x7f", 0);
	b=onion_dict_to_json(d);
	FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"\\u0002\\u0003\\u007F\"}");
	onion_block_free(b);
	onion_dict_free(d);

	END_LOCAL();
}
コード例 #26
0
ファイル: 02-dict.cpp プロジェクト: andrew-aladev/onion
void t01_basic(){ 
	INIT_LOCAL();
	
	Onion::Dict normal;
	normal.add("Hello", "World");
	
	onion_dict *d=onion_dict_new();
	onion_dict_add(d, "Hello", "2", 0);
	
	Onion::Dict non_owner(d);
	FAIL_IF_NOT_EQUAL_STRING(non_owner.get("Hello"), "2");
	
	Onion::Dict owner(d, true);
	FAIL_IF_NOT_EQUAL_STRING(owner.get("Hello"), "2");
	
	non_owner.add("non-owner", "true");
	FAIL_IF_NOT_EQUAL_STRING(owner.get("non-owner"), "true");
	FAIL_IF_NOT_EQUAL_STRING(onion_dict_get(d,"non-owner"), "true");
	
	END_LOCAL();
}
コード例 #27
0
ファイル: mime.c プロジェクト: Sts0mrg0/onion
/**
 * @short Given a filename or extensiton, it returns the proper mime type.
 * 
 * If onion_mime_set was called before, it is used, else it reads mime types /etc/mime.types.
 * 
 * Full mime catalog, from /etc/mime.types, takes about 36kb on ubuntu 10.10, may depend on
 * how many mime types are known.
 * 
 * If none is found, returns text/plain.
 */
const char *onion_mime_get(const char *filename){
	if (!onion_mime_dict)
		onion_mime_fill();
	
	const char *extension=filename;
	int l=strlen(filename);
	int i;
	for (i=l;i--;){
		if (extension[i]=='.'){
			extension=&extension[i+1];
			break;
		}
	}
	
	//ONION_DEBUG("I know %d mime types", onion_dict_count(onion_mime_dict));
	
	const char *r=onion_dict_get(onion_mime_dict, extension);
	if (r)
		return r;
	//ONION_DEBUG("Mime type for extension '%s' %s",extension, r);
	return "text/plain";
}
コード例 #28
0
ファイル: request.c プロジェクト: scottrfrancis/onion
/**
 * @short Gets the sessionid cookie, if any, and sets it to req->session_id.
 * @memberof onion_request_t
 */
void onion_request_guess_session_id(onion_request *req) {
    if (req->session_id) // already known.
        return;
    const char *ov=onion_dict_get(req->headers, "Cookie");
    const char *v=ov;
    ONION_DEBUG("Session ID, maybe from %s",v);
    char *r=NULL;
    onion_dict *session=NULL;

    do { // Check all possible sessions
        if (r) {
            onion_low_free(r);
            r=NULL;
        }
        if (!v)
            return;
        v=strstr(v,"sessionid=");
        if (!v) // exit point, no session found.
            return;
        if (v>ov && isalnum(v[-1])) {
            ONION_DEBUG("At -1: %c %d (%p %p)",v[-1],isalnum(v[-1]),v,ov);
            v=strstr(v,";");
        }
        else {
            v+=10;
            r=onion_low_strdup(v); // Maybe allocated more memory, not much anyway.
            char *p=r;
            while (*p!='\0' && *p!=';') p++;
            *p='\0';
            ONION_DEBUG0("Checking if %s exists in sessions", r);
            session=onion_sessions_get(req->connection.listen_point->server->sessions, r);
        }
    } while(!session);

    req->session_id=r;
    req->session=session;
    ONION_DEBUG("Session ID, from cookie, is %s",req->session_id);
}
コード例 #29
0
ファイル: sessions.c プロジェクト: cemonds/onion
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);
}
コード例 #30
0
ファイル: request_parser.c プロジェクト: adnandzebic/onion
/**
 * @short Prepares the CONTENT LENGTH
 */
static onion_connection_status prepare_CONTENT_LENGTH(onion_request *req){
	onion_token *token=req->parser_data;
	const char *content_size=onion_dict_get(req->headers, "Content-Length");
	if (!content_size){
		ONION_ERROR("I need the Content-Length header to get data");
		return OCS_INTERNAL_ERROR;
	}
	size_t cl=atol(content_size);
	
	if (cl>req->connection.listen_point->server->max_post_size){
		ONION_ERROR("Trying to set more data at server than allowed %d", req->connection.listen_point->server->max_post_size);
		return OCS_INTERNAL_ERROR;
	}

	req->data=onion_block_new();
	
	token->extra=NULL;
	token->extra_size=cl;
	token->pos=0;

	req->parser=parse_CONTENT_LENGTH;
	return OCS_NEED_MORE_DATA;
}