コード例 #1
0
ファイル: request.c プロジェクト: Scarberian/onion
/**
 * @short Cleans a request object to reuse it.
 * @memberof onion_request_t
 */
void onion_request_clean(onion_request* req){
  ONION_DEBUG0("Clean request %p", req);
  onion_dict_free(req->headers);
  req->headers=onion_dict_new();
  onion_dict_set_flags(req->headers, OD_ICASE);
  req->flags&=OR_NO_KEEP_ALIVE; // I keep keep alive.
  if (req->parser_data){
    onion_request_parser_data_free(req->parser_data);
    req->parser_data=NULL;
  }
  if (req->fullpath){
    free(req->fullpath);
    req->path=req->fullpath=NULL;
  }
  if (req->GET){
    onion_dict_free(req->GET);
    req->GET=NULL;
  }
  if (req->POST){
    onion_dict_free(req->POST);
    req->POST=NULL;
  }
  if (req->FILES){
    onion_dict_preorder(req->FILES, unlink_files, NULL);
    onion_dict_free(req->FILES);
    req->FILES=NULL;
  }
  if (req->session_id){
    if (onion_dict_count(req->session)==0){
      onion_request_session_free(req);
    }
    else{
      onion_dict_free(req->session); // Not really remove, just dereference
      req->session=NULL;
      free(req->session_id);
      req->session_id=NULL;
    }
  }
  if (req->data){
    onion_block_free(req->data);
    req->data=NULL;
  }
	if (req->connection.cli_info){
		free(req->connection.cli_info);
		req->connection.cli_info=NULL;
	}
	if (req->cookies){
		onion_dict_free(req->cookies);
		req->cookies=NULL;
	}
}
コード例 #2
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;
}
コード例 #3
0
ファイル: request.c プロジェクト: scottrfrancis/onion
/**
 * @short Gets the dict with the cookies
 * @memberof onion_request_t
 *
 * @param req Request to get the cookies from
 *
 * @returns A dict with all the cookies. It might be empty.
 *
 * First call it generates the dict.
 */
onion_dict* onion_request_get_cookies_dict(onion_request* req) {
    if (req->cookies)
        return req->cookies;

    req->cookies=onion_dict_new();

    const char *ccookies=onion_request_get_header(req, "Cookie");
    if (!ccookies)
        return req->cookies;
    char *cookies=onion_low_strdup(ccookies); // I prepare a temporary string, will modify it.
    char *val=NULL;
    char *key=NULL;
    char *p=cookies;

    int first=1;
    while(*p) {
        if (*p!=' ' && !key && !val) {
            key=p;
        }
        else if (*p=='=' && key && !val) {
            *p=0;
            val=p+1;
        }
        else if (*p==';' && key && val) {
            *p=0;
            if (first) {
                // The first cookie is special as it is the pointer to the reserved area for all the keys and values
                // for all th eother cookies, to free at dict free.
                onion_dict_add(req->cookies, cookies, val, OD_FREE_KEY);
                first=0;
            }
            else
                onion_dict_add(req->cookies, key, val, 0); /// Can use as static data as will be freed at first cookie free
            ONION_DEBUG0("Add cookie <%s>=<%s> %d", key, val, first);
            val=NULL;
            key=NULL;
        }
        p++;
    }
    if (key && val && val<p) { // A final element, with value.
        if (first)
            onion_dict_add(req->cookies, cookies, val, OD_FREE_KEY);
        else
            onion_dict_add(req->cookies, key, val, 0);
        ONION_DEBUG0("Add cookie <%s>=<%s> %d", key, val, first);
    }

    return req->cookies;
}
コード例 #4
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();
}
コード例 #5
0
ファイル: OnionServer.cpp プロジェクト: SHINOTECH/TinyPrint
/*
 Replace some template variables (filename of last config) call index_html_template
*/
onion_connection_status OnionServer::index_html( Onion::Request &req, Onion::Response &res)
{
	/* Problem: This cause double free of mem because
	 * onion_dict_free will called twice: in index_html_template and deconstructor.
	 * Onion::Dict d;
	 std::string key("LAST_SETTING_FILENAME");
	 d.add(key,m_b9CreatorSettings.m_configFilename,0);
	 return index_html_template(d.c_handler(), req.c_handler(), res.c_handler() );
	 */
	onion_dict *d=onion_dict_new();//will free'd in template call
	onion_dict_add( d, "LAST_SETTING_FILENAME",
			m_b9CreatorSettings.m_configFilename.c_str(), 0);

	return index_html_template(d, req.c_handler(), res.c_handler() );
}
コード例 #6
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();
}
コード例 #7
0
ファイル: OnionServer.cpp プロジェクト: SHINOTECH/TinyPrint
/*
 Replace some template variables and send b9creator_settings.js
*/
onion_connection_status OnionServer::getB9CreatorSettingsWrapped(
		Onion::Request &req, Onion::Response &res)
{
	/*
		 std::string key("ONION_JSON");
		 std::string conf(m_b9CreatorSettings.getConfig());
		 Onion::Dict d;
		 d.add(key, conf, 0);
		 return b9creator_settings_js_template(d.c_handler(), req.c_handler(), res.c_handler());
		 */
	onion_dict *d=onion_dict_new();//will free'd in template call
	onion_dict_add( d, "ONION_JSON",
			m_b9CreatorSettings.getConfig(), 0);
	return b9creator_settings_js_template(d, req.c_handler(), res.c_handler());
}
コード例 #8
0
ファイル: request.c プロジェクト: cemonds/onion
/**
 *  @short Creates a request object
 * @memberof onion_request_t
 * 
 * @param server onion_server that will be used for writing and some other data
 * @param socket Socket as needed by onion_server write method.
 * @param client_info String that describes the client, for example, the IP address.
 */
onion_request *onion_request_new(onion_server *server, void *socket, const char *client_info){
	onion_request *req;
	req=malloc(sizeof(onion_request));
	memset(req,0,sizeof(onion_request));
	
	req->server=server;
	req->headers=onion_dict_new();
	req->socket=socket;
	if (client_info) // This is kept even on clean
		req->client_info=strdup(client_info);
	else
		req->client_info=NULL;

  ONION_DEBUG0("Create request %p", req);
	return req;
}
コード例 #9
0
ファイル: OnionServer.cpp プロジェクト: YggdrasiI/KinectGrid
/*
 Replace some template variables (filename of last config) call index_html_template
*/
onion_connection_status OnionServer::index_html( Onion::Request &req, Onion::Response &res)
{
	/* Issue note: The following cause double free of mem because
	 * onion_dict_free will called twice: in index_html_template and deconstructor.
	 * Onion::Dict d;
	 std::string key("LAST_SETTING_FILENAME");
	 d.add(key,m_settingKinect.m_configFilename,0);
	 return index_html_template(d.c_handler(), req.c_handler(), res.c_handler() );

	 => Thus, use pointer, but do not free here.
	 */
	onion_dict *d=onion_dict_new();//will free'd in template call
	onion_dict_add( d, "LAST_SETTING_FILENAME",
			m_settingKinect.m_configFilename.c_str(), 0);

	return index_html_template(d, req.c_handler(), res.c_handler() );
}
コード例 #10
0
ファイル: response.c プロジェクト: KokaKiwi/onion
/**
 * @short Generates a new response object
 * @memberof onion_response_t
 * 
 * This response is generated from a request, and gets from there the writer and writer data.
 * 
 * Also fills some important data, as server Id, License type, and the default content type.
 * 
 * Default content type is HTML, as normally this is what is needed. This is nontheless just 
 * the default, and can be changed to any other with a call to:
 * 
 *   onion_response_set_header(res, "Content-Type", my_type);
 * 
 * The response object must be freed with onion_response_free, which also returns the keep alive 
 * status.
 * 
 * onion_response objects are passed by onion internally to process the request, and should not be
 * created by user normally. Nontheless the option exist.
 * 
 * @returns An onion_response object for that request.
 */
onion_response *onion_response_new(onion_request *req){
	onion_response *res=malloc(sizeof(onion_response));
	
	res->request=req;
	res->headers=onion_dict_new();
	res->code=200; // The most normal code, so no need to overwrite it in other codes.
	res->flags=0;
	res->sent_bytes_total=res->length=res->sent_bytes=0;
	res->buffer_pos=0;
	
	// Sorry for the publicity.
	onion_dict_add(res->headers, "Server", "libonion v0.5 - coralbits.com", 0);
	onion_dict_add(res->headers, "Content-Type", "text/html", 0); // Maybe not the best guess, but really useful.
	//time_t t=time(NULL);
	//onion_dict_add(res->headers, "Date", asctime(localtime(&t)), OD_DUP_VALUE);
	
	return res;
}
コード例 #11
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t09_thread_war(){
	INIT_LOCAL();
	
	pthread_t thread[NWAR];
	int i;
	onion_dict *d=onion_dict_new();
	for (i=0;i<NWAR;i++){
		onion_dict *dup=onion_dict_dup(d);
		pthread_create(&thread[i], NULL, (void*)&t09_thread_war_thread, dup);
	}
	
	onion_dict_free(d);

	for (i=0;i<NWAR;i++){
		pthread_join(thread[i], NULL);
	}
	
	END_LOCAL();
}
コード例 #12
0
ファイル: external_html.c プロジェクト: IPInfusion/SDN-IP
void external_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
  external_html_blocks_init(context);
#line 2
  onion_response_write(res, "This code is in an external html.\n", 34);
#line 2
  if (!has_context)
#line 2
    onion_dict_free(context);
#line 1
}
コード例 #13
0
ファイル: extended_html.c プロジェクト: IPInfusion/SDN-IP
void extended_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
  extended_html_blocks_init(context);
#line 1
  base_html(context, res);
#line 20
  if (!has_context)
#line 20
    onion_dict_free(context);
#line 1
}
コード例 #14
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();
}
コード例 #15
0
ファイル: request.c プロジェクト: Scarberian/onion
/**
 * @short Gets the dict with the cookies
 * @memberof onion_request_t
 * 
 * @param req Request to get the cookies from
 * 
 * @returns A dict with all the cookies. It might be empty.
 * 
 * First call it generates the dict.
 */
onion_dict* onion_request_get_cookies_dict(onion_request* req){
	if (req->cookies)
		return req->cookies;
	
	req->cookies=onion_dict_new();
	
	const char *ccookies=onion_request_get_header(req, "Cookie");
	if (!ccookies)
		return req->cookies;
	char *cookies=strdup(ccookies); // I prepare a temporal string, will modify it.
	char *val=NULL;
	char *key=NULL;
	char *p=cookies;
	
	int dflags=OD_FREE_KEY;
	while(*p){
		if (*p!=' ' && !key && !val){
			key=p;
		}
		else if (*p=='=' && key && !val){
			*p=0;
			val=p+1;
		}
		else if (*p==';' && key && val){
			*p=0;
			onion_dict_add(req->cookies, key, val, dflags); // I duplicate all as will free cookies string later. 
			ONION_DEBUG0("Add cookie <%s>=<%s> %X", key, val, dflags);
			dflags=0; // On the first element, remove all data as is in key.
			val=NULL;
			key=NULL;
		}
		p++;
	}
	if (key && val && val<p){ // A final element, with value.
		onion_dict_add(req->cookies, key, val, dflags);
		ONION_DEBUG0("Add cookie <%s>=<%s> %X", key, val, dflags);
	}
	
	return req->cookies;
}
コード例 #16
0
static onion_connection_status parse_headers_VERSION(onion_request *req, onion_buffer *data){
	onion_token *token=req->parser_data;
	int res=token_read_STRING(token, data);

	if (res<=1000)
		return res;

	if (strcmp(token->str,"HTTP/1.1")==0)
		req->flags|=OR_HTTP11;

	if (!req->GET)
		req->GET=onion_dict_new();

	if (res==STRING){
		req->parser=parse_headers_KEY_skip_NL;
		return parse_headers_KEY_skip_NL(req, data);
	}
	else{ // STRING_NEW_LINE, only when \n as STRING separator, not \r\n.
		req->parser=parse_headers_KEY;
		return parse_headers_KEY(req, data);
	}
}
コード例 #17
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t08_threaded_lock(){
	INIT_LOCAL();
	
	onion_dict *d=onion_dict_new();
	
	pthread_t thread[N_READERS];
	int i;
	for (i=0;i<N_READERS;i++){
		onion_dict *d2=onion_dict_dup(d);
		pthread_create(&thread[i], NULL, (void*)t08_thread_read, d2);
	}
	//sleep(1);
	t08_thread_write(d);
	
	for (i=0;i<N_READERS;i++){
		char *v;
		pthread_join(thread[i],(void**) &v);
		FAIL_IF_NOT_EQUAL(v, (char *)v);
	}
	
	END_LOCAL();
}
コード例 #18
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t07_replace(){
	INIT_LOCAL();
	onion_dict *dict=onion_dict_new();
	
	onion_dict_add(dict,"a","1", OD_DUP_ALL|OD_REPLACE);
	onion_dict_add(dict,"a","1", OD_REPLACE);
	onion_dict_add(dict,"a","1", OD_DUP_ALL|OD_REPLACE);
	onion_dict_add(dict,"a","1", OD_REPLACE);
	onion_dict_add(dict,"a","1", OD_DUP_ALL|OD_REPLACE);
	
	int n=0;
	onion_dict_preorder(dict, t07_sum, &n);
	FAIL_IF_NOT_EQUAL_INT(n,1);

	onion_dict_add(dict,"a","1", 0);
	n=0;
	onion_dict_preorder(dict, t07_sum, &n);
	FAIL_IF_NOT_EQUAL_INT(n,2);
	
	onion_dict_free(dict);
	
	END_LOCAL();
}
コード例 #19
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t05_preorder(){
	INIT_LOCAL();
	onion_dict *dict;
	dict=onion_dict_new();
	
	onion_dict_add(dict,"A","B",0);
	onion_dict_add(dict,"C","D",0);
	onion_dict_add(dict,"E","F",0);
	onion_dict_add(dict,"G","H",0);
	onion_dict_add(dict,"I","J",0);
	onion_dict_add(dict,"K","L",0);
	onion_dict_add(dict,"M","N",0);
	onion_dict_add(dict,"O","P",0);
	onion_dict_add(dict,"Q","R",0);
	onion_dict_add(dict,"S","T",0);
	
	char buffer[4096];
	memset(buffer,0,sizeof(buffer));
	onion_dict_preorder(dict, append_as_headers, buffer);
	FAIL_IF_NOT_EQUAL_STR(buffer,"A: B\nC: D\nE: F\nG: H\nI: J\nK: L\nM: N\nO: P\nQ: R\nS: T\n");
	
	onion_dict_free(dict);
	END_LOCAL();
}
コード例 #20
0
/**
 * @short Parses the query to unquote the path and get the query.
 */
static int onion_request_parse_query(onion_request *req){
	if (!req->fullpath)
		return 0;
	if (req->GET) // already done
		return 1;

	char *p=req->fullpath;
	char have_query=0;
	while(*p){
		if (*p=='?'){
			have_query=1;
			break;
		}
		p++;
	}
	*p='\0';
	onion_unquote_inplace(req->fullpath);
	if (have_query){ // There are querys.
		p++;
		req->GET=onion_dict_new();
		onion_request_parse_query_to_dict(req->GET, p);
	}
	return 1;
}
コード例 #21
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();
}
コード例 #22
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t11_hard_dup(){
	INIT_LOCAL();
	
	onion_dict *orig=onion_dict_new();
	
	char tmp[9];
	int i;
	for (i=0;i<256;i++){
		sprintf(tmp,"%08X",rand());
		onion_dict_add(orig, tmp, tmp, OD_DUP_ALL);
	}
	onion_dict_add(orig, "0", "no frees", 0);
	
	onion_dict *dest=onion_dict_hard_dup(orig);
	
	/// Check they have exactly the same keys.
	onion_dict_preorder(orig, cmpdict, dest);
	onion_dict_preorder(dest, cmpdict, orig);
	
	onion_dict_free(orig);
	onion_dict_free(dest);
	
	END_LOCAL();
}
コード例 #23
0
ファイル: dict.c プロジェクト: Sts0mrg0/onion
/**
 * @short Creates a full duplicate of the dict
 * @memberof onion_dict_t
 *
 * Its actually the same, but with refcount increased, so future frees will free the dict
 * only on latest one.
 *
 * Any change on one dict is made also on the other one, as well as rwlock... This is usefull on a multhreaded
 * environment so that multiple threads cna have the same dict and free it when not in use anymore.
 */
onion_dict *onion_dict_hard_dup(onion_dict *dict){
	onion_dict *d=onion_dict_new();
	onion_dict_preorder(dict, onion_dict_hard_dup_helper, d);
	return d;
}
コード例 #24
0
ファイル: tags.c プロジェクト: Paxa/onion
/**
 * @short Inits the tag dict
 * 
 * It calls the init_tag_builtins to fill the builtins tags.
 */
void tag_init(){
	tag_free();
	tags=onion_dict_new();
	tag_init_builtins();
}
コード例 #25
0
ファイル: 13-otemplates.c プロジェクト: 1514louluo/onion
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();
}
コード例 #26
0
ファイル: response.c プロジェクト: scottrfrancis/onion
/**
 * @short Generates a new response object
 * @memberof onion_response_t
 *
 * This response is generated from a request, and gets from there the writer and writer data.
 *
 * Also fills some important data, as server Id, License type, and the default content type.
 *
 * Default content type is HTML, as normally this is what is needed. This is nontheless just
 * the default, and can be changed to any other with a call to:
 *
 *   onion_response_set_header(res, "Content-Type", my_type);
 *
 * The response object must be freed with onion_response_free, which also returns the keep alive
 * status.
 *
 * onion_response objects are passed by onion internally to process the request, and should not be
 * created by user normally. Nontheless the option exist.
 *
 * @returns An onion_response object for that request.
 */
onion_response *onion_response_new(onion_request *req){
	onion_response *res=onion_low_malloc(sizeof(onion_response));

	res->request=req;
	res->headers=onion_dict_new();
	res->code=200; // The most normal code, so no need to overwrite it in other codes.
	res->flags=0;
	res->sent_bytes_total=res->length=res->sent_bytes=0;
	res->buffer_pos=0;

#ifndef DONT_USE_DATE_HEADER
	{
		time_t t;
		struct tm *tmp;

		t = time(NULL);

		// onion_response_last_date_header is set to t later. It should be more or less atomic.
		// If not no big deal, as we will just use slightly more CPU on those "ephemeral" moments.

		if (t!=onion_response_last_time){
			ONION_DEBUG("Recalculating date header");
			char current_datetime[200];

			tmp = localtime(&t);
			if (tmp == NULL) {
					perror("localtime");
					exit(EXIT_FAILURE);
			}

			if (strftime(current_datetime, sizeof(current_datetime), "%a, %d %b %Y %H:%M:%S %Z", tmp) == 0) {
					fprintf(stderr, "strftime returned 0");
					exit(EXIT_FAILURE);
			}
			// Risky, not using mutex...
#ifdef HAVE_PTHREAD
			pthread_rwlock_wrlock(&onion_response_date_lock);
#endif
			onion_response_last_time=t;
			if (onion_response_last_date_header)
				onion_low_free(onion_response_last_date_header);
			onion_response_last_date_header=onion_low_strdup(current_datetime);
#ifdef HAVE_PTHREAD
			pthread_rwlock_unlock(&onion_response_date_lock);
#endif
		}
	}
#ifdef HAVE_PTHREAD
	pthread_rwlock_rdlock(&onion_response_date_lock);
#endif
	assert(onion_response_last_date_header);
	onion_dict_add(res->headers, "Date", onion_response_last_date_header, OD_DUP_VALUE);
#ifdef HAVE_PTHREAD
	pthread_rwlock_unlock(&onion_response_date_lock);
#endif
#endif // USE_DATE_HEADER
	// Sorry for the advertisment.
	onion_dict_add(res->headers, "Server", "libonion v" ONION_VERSION " - coralbits.com", 0);
	onion_dict_add(res->headers, "Content-Type", "text/html", 0); // Maybe not the best guess, but really useful.
	//time_t t=time(NULL);
	//onion_dict_add(res->headers, "Date", asctime(localtime(&t)), OD_DUP_VALUE);

	return res;
}
コード例 #27
0
ファイル: dict.hpp プロジェクト: MariadeAnton/onion
		/**
		 * @short Creates an empty Onion::Dict
		 */
    Dict() : ptr(onion_dict_new()){
// 			ONION_DEBUG0("Dict %p:%p", this, ptr);
		}
コード例 #28
0
ファイル: 01-hash.c プロジェクト: 511860050/onion
void t10_tojson(){
	INIT_LOCAL();
	
	onion_dict *d=onion_dict_new();
	const char *tmp;
	int s;
	onion_block *b;
	b=onion_dict_to_json(d);
	tmp=onion_block_data(b);
	ONION_DEBUG("Json returned is '%s'", tmp);
	FAIL_IF_NOT_EQUAL_STR(tmp,"{}");
	onion_block_free(b);
	
	onion_dict_add(d, "test", "json", 0);
	
	b=onion_dict_to_json(d);
	tmp=onion_block_data(b);
	s=onion_block_size(b);
	ONION_DEBUG("Json returned is '%s'", tmp);
	FAIL_IF(s<=0);
	FAIL_IF_EQUAL(strstr(tmp,"{"), NULL);
	FAIL_IF_EQUAL(strstr(tmp,"}"), NULL);

	FAIL_IF_EQUAL(strstr(tmp,"\"test\""), NULL);
	FAIL_IF_EQUAL(strstr(tmp,"\"json\""), NULL);
	FAIL_IF_NOT_EQUAL(strstr(tmp,","), NULL);
	onion_block_free(b);
	
	onion_dict_add(d, "other", "data", 0);

	b=onion_dict_to_json(d);
	tmp=onion_block_data(b);
	s=onion_block_size(b);
	ONION_DEBUG("Json returned is '%s'", tmp);
	FAIL_IF(s<=0);
	FAIL_IF_EQUAL(strstr(tmp,"{"), NULL);
	FAIL_IF_EQUAL(strstr(tmp,"}"), NULL);

	FAIL_IF_EQUAL(strstr(tmp,"\"test\""), NULL);
	FAIL_IF_EQUAL(strstr(tmp,"\"json\""), NULL);
	FAIL_IF_EQUAL(strstr(tmp,","), NULL);
	FAIL_IF_EQUAL(strstr(tmp,"\"other\""), NULL);
	FAIL_IF_EQUAL(strstr(tmp,"\"data\""), NULL);
	onion_block_free(b);
	
	onion_dict_add(d, "with\"", "data\n", 0);

	b=onion_dict_to_json(d);
	tmp=onion_block_data(b);
	s=onion_block_size(b);
	ONION_DEBUG("Json returned is '%s'", tmp);
	FAIL_IF(s<=0);

	FAIL_IF_EQUAL(strstr(tmp,"\\n"), NULL);
	FAIL_IF_EQUAL(strstr(tmp,"\\\""), NULL);
	onion_block_free(b);
	
	onion_dict_free(d);
	
	END_LOCAL();
}
コード例 #29
0
ファイル: mime.c プロジェクト: Sts0mrg0/onion
/**
 * @short Reads the /etc/mime.types file
 * 
 * 
 */
static void onion_mime_fill(){
	onion_mime_set(NULL);
	onion_mime_dict=onion_dict_new();
	//ONION_DEBUG("Filling mime types");
	
	FILE *fd=fopen("/etc/mime.types", "rt");
	if (!fd){
		ONION_WARNING("Could not read MIME types (etc/mime.types), returned mime types may be incorrect. Adding minimal set.");
		onion_dict_add(onion_mime_dict, "html", "text/html",0);
		onion_dict_add(onion_mime_dict, "htm", "text/html",0);
		onion_dict_add(onion_mime_dict, "js", "application/javascript",0);
		onion_dict_add(onion_mime_dict, "css", "text/css",0);
		onion_dict_add(onion_mime_dict, "png", "image/png",0);
		onion_dict_add(onion_mime_dict, "jpg", "image/jpeg",0);
		return;
	}
	char mimetype[128];
	char extension[8];
	int mode=0; // 0 mimetype, 1 extension
	int i=0;
	int c;
	
	while ( (c=getc(fd)) >= 0){
		if (c=='#'){
			while ( (c=getc(fd)) >= 0 && c!='\n');
		}
		if (c=='\n'){
			if (mode==1 && i!=0){
				extension[i]=0;
				onion_dict_add(onion_mime_dict, extension, mimetype, OD_DUP_ALL);
				//ONION_DEBUG("Add mimetype '%s' (%s).", extension, mimetype);
			}
			mode=0;
			i=0;
		}
		else{
			if (is_space(c)){
				if (mode==0){
					mimetype[i]='\0';
					mode=1;
					i=0;
				}
				else if (i!=0){
					extension[i]='\0';
					i=0;
					onion_dict_add(onion_mime_dict, extension, mimetype, OD_DUP_ALL);
					//ONION_DEBUG("Add mimetype '%s' (%s)", extension, mimetype);
				}
			}
			else{
				if (mode==0){
					if (i>=sizeof(mimetype)-1){
						while ( (c=getc(fd)) >= 0 && c!='\n');
					}
					else
						mimetype[i++]=c;
				}
				else{
					if (i>=sizeof(extension)-1){
						while ( (c=getc(fd)) >= 0 && c!='\n');
						extension[i]='\0';
						i=0;
						mode=0;
						onion_dict_add(onion_mime_dict, extension, mimetype,  OD_DUP_ALL);
						//ONION_DEBUG("Add mimetype '%s' (%s)..", extension, mimetype);
					}
					else
						extension[i++]=c;
				}
			}
		}
	}
	fclose(fd);
	
	ONION_DEBUG("I know %d mime types", onion_dict_count(onion_mime_dict));
}
コード例 #30
0
ファイル: dict.c プロジェクト: Sts0mrg0/onion
onion_dict *onion_dict_from_json_(const char **_data){
	const char *data=*_data;
	ONION_DEBUG("Parse %s", *_data);
	while (is_json_space(*data))
		++data;
	if (*data!='{')
		return NULL;
	++data;

	while (is_json_space(*data))
		++data;
	;
	onion_dict *ret=onion_dict_new();
	onion_block *key=onion_block_new();
	onion_block *value=onion_block_new();
	while (*data!='}'){
		// Get Key
		ssize_t read_bytes=onion_json_unquote_add(key, data);
		if (read_bytes<0)
			goto error;
		data+=read_bytes;

		while (is_json_space(*data))
			++data;

		/// Get :
		if (*data!=':'){ // Includes \0
			ONION_DEBUG("Expected : got %c", *data);
			goto error;
		}
		++data;
		while (is_json_space(*data))
			++data;

		/// Get Value
		if (*data=='{'){ // Includes \0
			*_data=data;

			onion_dict *sub=onion_dict_from_json_(_data);
			if (!sub){
				goto error;
			}
			onion_dict_add(ret, onion_block_data(key), sub, OD_DUP_KEY|OD_DICT|OD_FREE_VALUE);
			data=*_data;
		}
		else if (is_json_digit(*data)){
			while(is_json_digit(*data)){
				onion_block_add_char(value, *data);
				++data;
			}
			onion_dict_add(ret, onion_block_data(key), onion_block_data(value), OD_DUP_ALL);
		}
		else if (*data=='"'){ // parse string
			ssize_t read_bytes=onion_json_unquote_add(value, data);
			if (read_bytes<0)
				goto error;
			data+=read_bytes;
			onion_dict_add(ret, onion_block_data(key), onion_block_data(value), OD_DUP_ALL);
			onion_block_clear(value);
		}
		else { // Includes \0
			ONION_DEBUG("Expected \" got %c", *data);
			goto error;
		}
		onion_block_clear(key);

		while (is_json_space(*data))
			++data;
		if (*data=='}'){
			++data;
			*_data=data;
			onion_block_free(key);
			onion_block_free(value);
			return ret;
		}
		if (*data!=','){
			ONION_DEBUG("Expected , got %c", *data);
			goto error;
		}
		++data;
		while (is_json_space(*data))
			++data;
	}
	++data;
	*_data=data;
	onion_block_free(key);
	onion_block_free(value);
	return ret;
error:
	onion_block_free(key);
	onion_block_free(value);
	onion_dict_free(ret);
	return NULL;
}