Beispiel #1
0
void t02_several_add_methods(){
	INIT_TEST();
	
	onion_block *block=onion_block_new();
	
	FAIL_IF_EQUAL(block, NULL);
	
	int i;
	for (i=0;i<1024;i++){
		onion_block_add_char(block, (char)i);
	}
	onion_block_clear(block);
	
	onion_block_add_str(block, "first ");
	for (i=0;i<1024;i++)
		onion_block_add_str(block, "test ");
	
	FAIL_IF_NOT_STRSTR(onion_block_data(block), "test");
	
	for (i=0;i<1024;i++)
		onion_block_add_data(block, "world", 4);
	
	FAIL_IF_STRSTR(onion_block_data(block), "world");
	FAIL_IF_NOT_STRSTR(onion_block_data(block), "worl");	
	
	int s=onion_block_size(block);
	
	onion_block_add_block(block, block);
	FAIL_IF_NOT_EQUAL(onion_block_size(block), s+s);
	
	onion_block_free(block);
	
	END_TEST();
}
Beispiel #2
0
/**
 * @short Helps to prepare each pair.
 */
static void onion_dict_json_preorder(onion_block *block, const char *key, const void *value, int flags){
	if (!onion_block_size(block)) // Error somewhere.
		return;
	char *s;
	s=onion_c_quote_new(key);
	if (s==NULL){
		onion_block_clear(block);
		return;
	}
	onion_block_add_str(block, s);
	free(s);
	onion_block_add_char(block, ':');
	if (flags&OD_DICT){
		onion_block *tmp;
		tmp=onion_dict_to_json((onion_dict*)value);
		if (!tmp){
			onion_block_clear(block);
			return;
		}
		onion_block_add_block(block, tmp);
		onion_block_free(tmp);
	}
	else{
		s=onion_c_quote_new(value);
		if (s==NULL){
			onion_block_clear(block);
			return;
		}
		onion_block_add_str(block, s);
		free(s);
	}
	onion_block_add_data(block, ", ",2);
}
Beispiel #3
0
/**
 * @short Helps to prepare each pair.
 */
static void onion_dict_json_preorder(onion_block *block, const char *key, const void *value, int flags){
	if (!onion_block_size(block)) // Error somewhere.
		return;
	onion_block_add_char(block,'\"');
	onion_json_quote_add(block, key);
	onion_block_add_data(block,"\":",2);
	if (flags&OD_DICT){
		onion_block *tmp;
		tmp=onion_dict_to_json((onion_dict*)value);
		if (!tmp){
			onion_block_clear(block);
			return;
		}
		onion_block_add_block(block, tmp);
		onion_block_free(tmp);
	}
	else{
		onion_block_add_char(block,'\"');
		onion_json_quote_add(block, value);
		onion_block_add_char(block,'\"');
	}
	onion_block_add_data(block, ", ",2);
}
Beispiel #4
0
/**
 * @short Reads from the data to fulfill content-length data.
 */
static onion_connection_status parse_CONTENT_LENGTH(onion_request *req, onion_buffer *data){
	onion_token *token=req->parser_data;
	int length=data->size-data->pos;
	int exit=0;
	
	if (length>=token->extra_size-token->pos){
		exit=1;
		length=token->extra_size-token->pos;
	}
	
	onion_block_add_data(req->data, &data->data[data->pos], length);
	data->pos+=length;
	
	if (exit)
		return onion_request_process(req);
	
	return OCS_NEED_MORE_DATA;
}
Beispiel #5
0
/**
 * @short Reads from the data to fulfill content-length data.
 */
static onion_connection_status parse_CONTENT_LENGTH(onion_request *req, onion_buffer *data){
	ONION_DEBUG0("Adding data to request->data (non form POST)");
	onion_token *token=req->parser_data;
	int length=data->size-data->pos;
	int exit=0;

	if (length>=token->extra_size-token->pos){
		exit=1;
		length=token->extra_size-token->pos;
	}

	onion_block_add_data(req->data, &data->data[data->pos], length);
	data->pos+=length;

	if (exit)
		return OCS_REQUEST_READY;

	return OCS_NEED_MORE_DATA;
}
Beispiel #6
0
/**
 * @short Adds some code to the top function
 */
void function_add_code(parser_status *st, const char *fmt, ...){
	function_data *p=(function_data*)st->function_stack->tail->data;
	if (p->flags&F_NO_MORE_WRITE)
		return;
	
	char tmp[4096];
	
	va_list ap;
	va_start(ap, fmt);
	vsnprintf(tmp, sizeof(tmp), fmt, ap);
	va_end(ap);

	if (use_orig_line_numbers){
		char line[32];
		int p=onion_block_size(st->current_code);
		if (p && onion_block_data(st->current_code)[p-1]!='\n')
			onion_block_add_char(st->current_code, '\n');
		snprintf(line,sizeof(line),"#line %d\n", st->line);
		// I have to do it for every \n too. This is going to be slow.
		const char *orig=tmp;
		int lorig=strlen(orig);
		int i=0, li=0;
		for (i=0;i<lorig;i++){
			if (orig[i]=='\n'){
				onion_block_add_str(st->current_code, line);
				onion_block_add_data(st->current_code, &orig[li], i-li+1);
				li=i;
			}
		}
		if (i-1!=li){
			onion_block_add_str(st->current_code, line);
			onion_block_add_str(st->current_code, &orig[li]);
		}
	}
	else{
		//ONION_DEBUG("Add to level %d text %s",list_count(st->function_stack), tmp);
		onion_block_add_str(st->current_code, tmp);
	}
}
Beispiel #7
0
/**
 * @short Reads from the data to fulfill content-length data.
 */
static onion_connection_status parse_CONTENT_LENGTH(onion_request *req, onion_buffer *data){
	onion_token *token=req->parser_data;
	size_t skip=data->pos; // First packet will be headers + some data, later ony data
	int length=data->size-skip;
	bool exit=false;
	size_t current_size=onion_block_size(req->data);

	ONION_DEBUG0("Adding data to request->data (non form POST) %d + %d / %d [%d/%d] %p",
		current_size, length, token->extra_size, skip, data->size, data->data+current_size);

	if (length + current_size >= token->extra_size){
		ONION_DEBUG0("Done");
		exit=true;
		length=token->extra_size - current_size;
	}

	onion_block_add_data(req->data, &data->data[skip], length);
	data->pos+=length; // done

	if (exit)
		return OCS_REQUEST_READY;

	return OCS_NEED_MORE_DATA;
}
Beispiel #8
0
onion_block *connect_and_send(const char *ip, const char *port,
                              const onion_block * msg, size_t maxsize) {
  int fd;
  {
    struct addrinfo hints;
    struct addrinfo *server;

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_family = AF_UNSPEC;
    hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;

    if (getaddrinfo(ip, port, &hints, &server) < 0) {
      ONION_ERROR("Error getting server info");
      return NULL;
    }
    fd = socket(server->ai_family, server->ai_socktype | SOCK_CLOEXEC,
                server->ai_protocol);

    if (connect(fd, server->ai_addr, server->ai_addrlen) == -1) {
      close(fd);
      fd = -1;
      ONION_ERROR("Error connecting to server %s:%s", ip, port);
      return NULL;
    }

    freeaddrinfo(server);
  }

  size_t left = onion_block_size(msg);
  const char *data = onion_block_data(msg);
  while (left > 0) {
    ONION_DEBUG(".");
    int towrite = (left > maxsize) ? maxsize : left;
    int ret = write(fd, data, towrite);
    FAIL_IF(ret <= 0);
    if (ret <= 0) {
      ONION_ERROR("Error sending data.");
      return NULL;
    }
    left -= ret;
    data += ret;
  }
  onion_block *bl = onion_block_new();
  char tmp[256];
  int r = 0;
  int total = 0;
  do {
    r = read(fd, tmp, sizeof(tmp));
    ONION_DEBUG("+ %d", r);
    if (r > 0) {
      total += r;
      onion_block_add_data(bl, tmp, r);
    }
  } while (r > 0);
  ONION_DEBUG("Total %d", total);

  FAIL_IF(total == 0);

  close(fd);

  return bl;
}
Beispiel #9
0
/**
 * @short Appends both blocks on the first.
 * @memberof onion_block_t
 */
int onion_block_add_block(onion_block *b, onion_block *toadd){
	return onion_block_add_data(b, toadd->data, toadd->size);
}
Beispiel #10
0
/**
 * @short Adds a string to the block
 * @memberof onion_block_t
 */
int onion_block_add_str(onion_block *b, const char *str){
	int l=strlen(str)+1;
	onion_block_add_data(b, str, l);
	b->size--;
	return l;
}