Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
onion_connection_status method(void *ignore, onion_request *req, onion_response *res){
	if (onion_response_write_headers(res)==OR_SKIP_CONTENT) // Head
		return OCS_PROCESSED;
	
	onion_response_write0(res, "<html><body>\n<h1>Petition resume</h1>\n");
	int flags=onion_request_get_flags(req);
	if (flags&OR_GET)
		onion_response_write0(res,"<h2>GET");
	else if (flags&OR_POST)
		onion_response_write0(res,"<h2>POST");
	else 
		onion_response_write0(res,"<h2>UNKNOWN");
	
	onion_response_printf(res," %s</h2>\n<ul>",onion_request_get_path(req));

	const onion_dict *get=onion_request_get_query_dict(req);
	const onion_dict *post=onion_request_get_post_dict(req);
	const onion_dict *headers=onion_request_get_header_dict(req);
	
	onion_response_printf(res,"<li>Header %d elements<ul>",onion_dict_count(headers));
	if (headers) onion_dict_preorder(headers, print_dict_element, res);
	onion_response_printf(res,"</ul></li>\n");

	onion_response_printf(res,"<li>GET %d elements<ul>",onion_dict_count(get));
	if (get) onion_dict_preorder(get, print_dict_element, res);
	onion_response_printf(res,"</ul></li>\n");

	onion_response_printf(res,"<li>POST %d elements<ul>",onion_dict_count(post));
	if (post) onion_dict_preorder(post, print_dict_element, res);
	onion_response_printf(res,"</ul></li>\n");

	onion_response_write0(res,"<p>\n");
	onion_response_write0(res,"<form method=\"GET\">"
														"<input type=\"text\" name=\"test\">"
														"<input type=\"submit\" name=\"submit\" value=\"GET\">"
														"</form><p>\n");
	onion_response_write0(res,"<form method=\"POST\" enctype=\"application/x-www-form-urlencoded\">"
														"<textarea name=\"text\"></textarea>"
														"<input type=\"text\" name=\"test\">"
														"<input type=\"submit\" name=\"submit\"  value=\"POST urlencoded\">"
														"</form>"
														"<p>\n");
	onion_response_write0(res,"<form method=\"POST\" enctype=\"multipart/form-data\">"
														"<input type=\"file\" name=\"file\">"
														"<textarea name=\"text\"></textarea>"
														"<input type=\"text\" name=\"test\">"
														"<input type=\"submit\" name=\"submit\" value=\"POST multipart\">"
														"</form>"
														"<p>\n");
	
	onion_response_write0(res,"</body></html>");
	
	return OCS_PROCESSED;
}
Ejemplo n.º 3
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();
}
Ejemplo n.º 4
0
/**
 * @short Writes all the header to the given response
 * @memberof onion_response_t
 * @ingroup response
 *
 * It writes the headers and depending on the method, return OR_SKIP_CONTENT. this is set when in head mode. Handlers
 * should react to this return by not trying to write more, but if they try this object will just skip those writtings.
 *
 * Explicit calling to this function is not necessary, as as soon as the user calls any write function this will
 * be performed.
 *
 * As soon as the headers are written, any modification on them will be just ignored.
 *
 * @returns 0 if should procced to normal data write, or OR_SKIP_CONTENT if should not write content.
 */
int onion_response_write_headers(onion_response * res) {
  if (!res->request) {
    ONION_ERROR
        ("Bad formed response. Need a request at creation. Will not write headers.");
    return -1;
  }

  res->flags |= OR_HEADER_SENT; // I Set at the begining so I can do normal writing.
  res->request->flags |= OR_HEADER_SENT;
  char chunked = 0;

  if (res->request->flags & OR_HTTP11) {
    onion_response_printf(res, "HTTP/1.1 %d %s\r\n", res->code,
                          onion_response_code_description(res->code));
    //ONION_DEBUG("Response header: HTTP/1.1 %d %s\n",res->code, onion_response_code_description(res->code));
    if (!(res->flags & OR_LENGTH_SET) && onion_request_keep_alive(res->request)) {
      onion_response_write(res, CONNECTION_CHUNK_ENCODING,
                           sizeof(CONNECTION_CHUNK_ENCODING) - 1);
      chunked = 1;
    }
  } else {
    onion_response_printf(res, "HTTP/1.0 %d %s\r\n", res->code,
                          onion_response_code_description(res->code));
    //ONION_DEBUG("Response header: HTTP/1.0 %d %s\n",res->code, onion_response_code_description(res->code));
    if (res->flags & OR_LENGTH_SET)     // On HTTP/1.0, i need to state it. On 1.1 it is default.
      onion_response_write(res, CONNECTION_KEEP_ALIVE,
                           sizeof(CONNECTION_KEEP_ALIVE) - 1);
  }

  if (!(res->flags & OR_LENGTH_SET) && !chunked
      && !(res->flags & OR_CONNECTION_UPGRADE))
    onion_response_write(res, CONNECTION_CLOSE, sizeof(CONNECTION_CLOSE) - 1);

  if (res->flags & OR_CONNECTION_UPGRADE)
    onion_response_write(res, CONNECTION_UPGRADE,
                         sizeof(CONNECTION_UPGRADE) - 1);

  onion_dict_preorder(res->headers, write_header, res);

  if (res->request->session_id && (onion_dict_count(res->request->session) > 0))        // I have session with something, tell user
    onion_response_printf(res, "Set-Cookie: sessionid=%s; httponly; Path=/\n",
                          res->request->session_id);

  onion_response_write(res, "\r\n", 2);

  ONION_DEBUG0("Headers written");
  res->sent_bytes = -res->buffer_pos;   // the header size is not counted here. It will add again so start negative.

  if ((res->request->flags & OR_METHODS) == OR_HEAD) {
    onion_response_flush(res);
    res->flags |= OR_SKIP_CONTENT;
    return OR_SKIP_CONTENT;
  }
  if (chunked) {
    onion_response_flush(res);
    res->flags |= OR_CHUNKED;
  }

  return 0;
}
Ejemplo n.º 5
0
/**
 * @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) {
        onion_low_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_sessions_save(req->connection.listen_point->server->sessions, req->session_id, req->session);
            onion_dict_free(req->session); // Not really remove, just dereference
            req->session=NULL;
            onion_low_free(req->session_id);
            req->session_id=NULL;
        }
    }
    if (req->data) {
        onion_block_free(req->data);
        req->data=NULL;
    }
    if (req->connection.cli_info) {
        onion_low_free(req->connection.cli_info);
        req->connection.cli_info=NULL;
    }
    if (req->cookies) {
        onion_dict_free(req->cookies);
        req->cookies=NULL;
    }
    if (req->free_list) {
        onion_ptr_list_foreach(req->free_list, onion_low_free);
        onion_ptr_list_free(req->free_list);
        req->free_list=NULL;
    }
}
Ejemplo n.º 6
0
static onion_connection_status ask_session(void *_, onion_request *req, onion_response *res){
  onion_dict *session=onion_request_get_session_dict(req);
  if (set_data_on_session)
    onion_dict_add(session,"Test","New data to create the session",0);
  has_set_cookie=0;
  onion_response_write0(res, "If I write before getting session, then there is no Set-Cookie.\n");
  onion_response_printf(res, "%d elements at the session.\n", onion_dict_count(session));
  ONION_DEBUG("Session ID is %s, cookies %s",req->session_id, onion_request_get_header(req, "Cookie"));
  strcpy(lastsessionid, req->session_id);
  
  return OCS_PROCESSED;
}
Ejemplo n.º 7
0
/**
 * @short Deletes a request and all its data
 * @memberof onion_request_t
 */
void onion_request_free(onion_request *req) {
    ONION_DEBUG0("Free request %p", req);
    onion_dict_free(req->headers);

    if (req->connection.listen_point!=NULL && req->connection.listen_point->close)
        req->connection.listen_point->close(req);
    if (req->fullpath)
        onion_low_free(req->fullpath);
    if (req->GET)
        onion_dict_free(req->GET);
    if (req->POST)
        onion_dict_free(req->POST);
    if (req->FILES) {
        onion_dict_preorder(req->FILES, unlink_files, NULL);
        onion_dict_free(req->FILES);
    }
    if (req->session) {
        if (onion_dict_count(req->session)==0)
            onion_request_session_free(req);
        else {
            onion_sessions_save(req->connection.listen_point->server->sessions, req->session_id, req->session);
            onion_dict_free(req->session); // Not really remove, just dereference
            onion_low_free(req->session_id);
        }
    }
    if (req->data)
        onion_block_free(req->data);
    if (req->connection.cli_info)
        onion_low_free(req->connection.cli_info);

    if (req->websocket)
        onion_websocket_free(req->websocket);

    if (req->parser_data) {
        onion_low_free(req->parser_data);
    }
    if (req->cookies)
        onion_dict_free(req->cookies);
    if (req->free_list) {
        onion_ptr_list_foreach(req->free_list, onion_low_free);
        onion_ptr_list_free(req->free_list);
    }
    onion_low_free(req);
}
Ejemplo n.º 8
0
/**
 * @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));
}
Ejemplo n.º 9
0
		/**
		 * @short Count of elements on the dictionary.
		 */
		size_t count() const{
			return onion_dict_count(ptr);
		}
Ejemplo n.º 10
0
// This fixes that whenever a session is created, but no new data is added, it does not set the proper cookie, and should not create a new session.
void t03_bug_empty_session_is_new_session(){
  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[256];

  set_data_on_session=1;
  onion_request *req=onion_request_new(o->server, NULL, NULL);
  req->fullpath="/";
  onion_request_process(req);
  FAIL_IF_EQUAL_STR(lastsessionid,"");
  strcpy(sessionid, lastsessionid);
  req->fullpath=NULL;
  onion_request_free(req);
  FAIL_IF_NOT_EQUAL_INT(onion_dict_count(o->server->sessions->sessions), 1);
  
  req=onion_request_new(o->server, NULL, NULL);
  req->fullpath="/";
  onion_dict_add(req->headers, "Cookie", "sessionid=xxx", 0);
  onion_request_process(req);
  FAIL_IF_EQUAL_STR(lastsessionid,"");
  FAIL_IF_EQUAL_STR(lastsessionid, sessionid);
  FAIL_IF_NOT(has_set_cookie);
  req->fullpath=NULL;
  onion_request_free(req);
  FAIL_IF_NOT_EQUAL_INT(onion_dict_count(o->server->sessions->sessions), 2);
  
  req=onion_request_new(o->server, NULL, NULL);
  req->fullpath="/";
  snprintf(tmp,sizeof(tmp),"sessionid=%s",lastsessionid);
  onion_dict_add(req->headers, "Cookie", tmp, 0);
  onion_request_process(req);
  FAIL_IF_EQUAL_STR(lastsessionid,"");
  FAIL_IF_EQUAL_STR(lastsessionid, sessionid);
  FAIL_IF_NOT(has_set_cookie);
  strcpy(sessionid, lastsessionid);
  req->fullpath=NULL;
  onion_request_free(req);
  FAIL_IF_NOT_EQUAL_INT(onion_dict_count(o->server->sessions->sessions), 2);
  
  req=onion_request_new(o->server, NULL, NULL);
  req->fullpath="/";
  snprintf(tmp,sizeof(tmp),"sessionid=%sxx",lastsessionid);
  onion_dict_add(req->headers, "Cookie", tmp, 0);
  onion_request_process(req);
  FAIL_IF_EQUAL_STR(lastsessionid,"");
  FAIL_IF_EQUAL_STR(lastsessionid, sessionid);
  FAIL_IF_NOT(has_set_cookie);
  req->fullpath=NULL;
  onion_request_free(req);
  FAIL_IF_NOT_EQUAL_INT(onion_dict_count(o->server->sessions->sessions), 3);

  // Ask for new, without session data, but I will not set data on session, so session is not created.
  set_data_on_session=0;
  req=onion_request_new(o->server, NULL, NULL);
  req->fullpath="/";
  onion_request_process(req);
  FAIL_IF_EQUAL_STR(lastsessionid,"");
  strcpy(sessionid, lastsessionid);
  req->fullpath=NULL;
  FAIL_IF_NOT_EQUAL_INT(onion_dict_count(o->server->sessions->sessions), 4); // For a moment it exists, until onion realizes is not necesary.
  onion_request_free(req);
  FAIL_IF_NOT_EQUAL_INT(onion_dict_count(o->server->sessions->sessions), 3);

  
  onion_free(o);
  
  END_LOCAL();
}