Example #1
0
static size_t string_table_read(apt_str_table_item_t table[], apr_size_t max_count, FILE *file, apr_pool_t *pool)
{
	apt_str_table_item_t *item;
	size_t count = 0;
	apt_str_t line;
	apt_text_stream_t text_stream;

	text_stream.text.length = fread(parse_buffer, 1, sizeof(parse_buffer)-1, file);
	parse_buffer[text_stream.text.length] = '\0';
	text_stream.text.buf = parse_buffer;
	text_stream.pos = parse_buffer;

	do {
		if(apt_text_line_read(&text_stream,&line) == FALSE || !line.length) {
			break;
		}
		item = &table[count];
		apt_string_copy(&item->value,&line,pool);
		item->key = 0;
		count++;
	}
	while(count < max_count);

	return count;
}
Example #2
0
/** Create message and read start line */
static apt_bool_t rtsp_parser_on_start(apt_message_parser_t *parser, apt_message_context_t *context, apt_text_stream_t *stream, apr_pool_t *pool)
{
	rtsp_message_t *message;
	apt_str_t start_line;
	/* read start line */
	if(apt_text_line_read(stream,&start_line) == FALSE) {
		return FALSE;
	}
	
	message = rtsp_message_create(RTSP_MESSAGE_TYPE_UNKNOWN,pool);
	if(rtsp_start_line_parse(&message->start_line,&start_line,message->pool) == FALSE) {
		return FALSE;
	}
	
	context->message = message;
	context->header = &message->header.header_section;
	context->body = &message->body;
	return TRUE;
}
Example #3
0
/** Parse MRCP start-line */
MRCP_DECLARE(apt_bool_t) mrcp_start_line_parse(mrcp_start_line_t *start_line, apt_text_stream_t *text_stream, apr_pool_t *pool)
{
	apt_text_stream_t line;
	apt_str_t field;
	apt_bool_t status = TRUE;
	start_line->message_type = MRCP_MESSAGE_TYPE_UNKNOWN;
	if(apt_text_line_read(text_stream,&line.text) == FALSE) {
		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse MRCP start-line");
		return FALSE;
	}
	
	apt_text_stream_reset(&line);
	if(apt_text_field_read(&line,APT_TOKEN_SP,TRUE,&field) == FALSE) {
		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot read the first field in start-line");
		return FALSE;
	}

	if(field.buf == strstr(field.buf,MRCP_NAME)) {
		start_line->version = mrcp_version_parse(&field);

		if(start_line->version == MRCP_VERSION_1) {
			/* parsing MRCP v1 response */
			start_line->message_type = MRCP_MESSAGE_TYPE_RESPONSE;
			status = mrcp_response_line_parse(start_line,&line);
		}
		else if(start_line->version == MRCP_VERSION_2) {
			/* parsing MRCP v2 start-line (request/response/event) */
			status = mrcp_v2_start_line_parse(start_line,&line,pool);
		}
		else {
			apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown MRCP version");
			return FALSE;
		}
	}
	else {
		/* parsing MRCP v1 request or event */
		apt_string_copy(&start_line->method_name,&field,pool);
		status = mrcp_request_line_parse(start_line,&line);
	}
	return status;
}
Example #4
0
static apt_bool_t resource_name_read(apr_file_t *file, mrcp_parser_t *parser)
{
	char buffer[100];
	apt_text_stream_t stream;
	apt_bool_t status = FALSE;
	apt_text_stream_init(&stream,buffer,sizeof(buffer)-1);
	if(apr_file_read(file,stream.pos,&stream.text.length) != APR_SUCCESS) {
		return FALSE;
	}

	/* skip the first line in a test file, which indicates resource name */
	if(*stream.pos =='/' && *(stream.pos+1)=='/') {
		apt_str_t line;
		stream.pos += 2;
		if(apt_text_line_read(&stream,&line) == TRUE) {
			apr_off_t offset = stream.pos - stream.text.buf;
			apr_file_seek(file,APR_SET,&offset);
			mrcp_parser_resource_name_set(parser,&line);
			status = TRUE;
		}
	}
	return status;
}
Example #5
0
/** Create message and read start line */
static apt_bool_t mrcp_parser_on_start(apt_message_parser_t *parser, apt_message_context_t *context, apt_text_stream_t *stream, apr_pool_t *pool)
{
	mrcp_message_t *mrcp_message;
	apt_str_t start_line;
	/* read start line */
	if(apt_text_line_read(stream,&start_line) == FALSE) {
		return FALSE;
	}

	/* create new MRCP message */
	mrcp_message = mrcp_message_create(pool);
	/* parse start-line */
	if(mrcp_start_line_parse(&mrcp_message->start_line,&start_line,mrcp_message->pool) == FALSE) {
		return FALSE;
	}

	if(mrcp_message->start_line.version == MRCP_VERSION_1) {
		mrcp_parser_t *mrcp_parser = apt_message_parser_object_get(parser);
		if(!mrcp_parser->resource) {
			return FALSE;
		}
		apt_string_copy(
			&mrcp_message->channel_id.resource_name,
			&mrcp_parser->resource->name,
			pool);

		if(mrcp_message_resource_set(mrcp_message,mrcp_parser->resource) == FALSE) {
			return FALSE;
		}
	}

	context->message = mrcp_message;
	context->header = &mrcp_message->header.header_section;
	context->body = &mrcp_message->body;
	return TRUE;
}
Example #6
0
/** Parse individual header field (name-value pair) */
APT_DECLARE(apt_header_field_t*) apt_header_field_parse(apt_text_stream_t *stream, apr_pool_t *pool)
{
	apr_size_t folding_length = 0;
	apr_array_header_t *folded_lines = NULL;
	apt_header_field_t *header_field;
	apt_str_t temp_line;
	apt_str_t *line;
	apt_pair_t pair;
	/* read name-value pair */
	if(apt_text_header_read(stream,&pair) == FALSE) {
		return NULL;
	}

	/* check folding lines (value spanning multiple lines) */
	while(stream->pos < stream->end) {
		if(apt_text_is_wsp(*stream->pos) == FALSE) {
			break;
		}

		stream->pos++;

		/* skip further white spaces (if any) */
		apt_text_white_spaces_skip(stream);

		if(!folded_lines) {
			folded_lines = apr_array_make(pool,1,sizeof(apt_str_t));
		}
		if(apt_text_line_read(stream,&temp_line) == TRUE) {
			line = apr_array_push(folded_lines);
			*line = temp_line;
			folding_length += line->length;
		}
	};

	header_field = apt_header_field_alloc(pool);
	/* copy parsed name of the header field */
	header_field->name.length = pair.name.length;
	header_field->name.buf = apr_palloc(pool, pair.name.length + 1);
	if(pair.name.length) {
		memcpy(header_field->name.buf, pair.name.buf, pair.name.length);
	}
	header_field->name.buf[header_field->name.length] = '\0';

	/* copy parsed value of the header field */
	header_field->value.length = pair.value.length + folding_length;
	header_field->value.buf = apr_palloc(pool, header_field->value.length + 1);
	if(pair.value.length) {
		memcpy(header_field->value.buf, pair.value.buf, pair.value.length);
	}

	if(folding_length) {
		int i;
		char *pos = header_field->value.buf + pair.value.length;
		/* copy parsed folding lines */
		for(i=0; i<folded_lines->nelts; i++) {
			line = &APR_ARRAY_IDX(folded_lines,i,apt_str_t);

			memcpy(pos,line->buf,line->length);
			pos += line->length;
		}
	}
	header_field->value.buf[header_field->value.length] = '\0';

	return header_field;
}
/** Get the next content part */
APT_DECLARE(apt_bool_t) apt_multipart_content_get(apt_multipart_content_t *multipart_content, apt_content_part_t *content_part, apt_bool_t *is_final)
{
	apt_str_t boundary;
	apt_header_field_t *header_field;
	apt_text_stream_t *stream = &multipart_content->stream;

	if(!content_part || !is_final) {
		return FALSE;
	}
	*is_final = FALSE;
	apt_content_part_reset(content_part);

	/* skip preamble */
	apt_text_skip_to_char(stream,'-');
	if(apt_text_is_eos(stream) == TRUE) {
		return FALSE;
	}

	/* skip initial hyphens */
	apt_text_chars_skip(stream,'-');
	if(apt_text_is_eos(stream) == TRUE) {
		return FALSE;
	}

	/* read line and the boundary */
	if(apt_text_line_read(stream,&boundary) == FALSE) {
		return FALSE;
	}

	/* remove optional trailing spaces */
	while(boundary.length && boundary.buf[boundary.length-1] == APT_TOKEN_SP) boundary.length--;

	/* check whether this is the final boundary */
	if(boundary.length >= 2) {
		if(boundary.buf[boundary.length-1] == '-' && boundary.buf[boundary.length-2] == '-') {
			/* final boundary */
			boundary.length -= 2;
			*is_final = TRUE;
		}
	}

	/* compare boundaries */
	if(apt_string_is_empty(&multipart_content->boundary) == TRUE) {
		/* no boundary was specified from user space, 
		learn boundary from the content */
		multipart_content->boundary = boundary;
	}
	else {
		if(apt_string_compare(&multipart_content->boundary,&boundary) == FALSE) {
			/* invalid boundary */
			return FALSE;
		}
	}

	if(*is_final == TRUE) {
		/* final boundary => return TRUE, content remains empty */
		return TRUE;
	}

	/* read header fields */
	if(apt_header_section_parse(&content_part->header,stream,multipart_content->pool) == FALSE) {
		return FALSE;
	}
	
	for(header_field = APR_RING_FIRST(&content_part->header.ring);
			header_field != APR_RING_SENTINEL(&content_part->header.ring, apt_header_field_t, link);
				header_field = APR_RING_NEXT(header_field, link)) {
		if(strncmp(header_field->name.buf,CONTENT_LENGTH_HEADER,header_field->name.length) == 0) {
			content_part->length = &header_field->value;
		}
		else if(strncmp(header_field->name.buf,CONTENT_TYPE_HEADER,header_field->name.length) == 0) {
			content_part->type = &header_field->value;
		}
		else if(strncmp(header_field->name.buf,CONTENT_ID_HEADER,header_field->name.length) == 0) {
			content_part->id = &header_field->value;
		}
	}

	if(content_part->length && apt_string_is_empty(content_part->length) == FALSE) {
		apr_size_t length = atoi(content_part->length->buf);
		if(length + stream->pos > stream->end) {
			return FALSE;
		}

		/* read content */
		apt_string_assign_n(&content_part->body,stream->pos,length,multipart_content->pool);
		stream->pos += length;
	}

	return TRUE;
}
/** Get the next content part */
APT_DECLARE(apt_bool_t) apt_multipart_content_get(apt_multipart_content_t *multipart_content, apt_str_t *content_type, apt_str_t *content)
{
	apt_str_t boundary;
	apt_pair_t header;
	apt_bool_t is_final = FALSE;
	apt_text_stream_t *stream = &multipart_content->stream;

	if(!content || !content_type) {
		return FALSE;
	}

	apt_string_reset(content);

	/* skip preamble */
	apt_text_skip_to_char(stream,'-');
	if(apt_text_is_eos(stream) == TRUE) {
		return FALSE;
	}

	/* skip initial hyphens */
	apt_text_chars_skip(stream,'-');
	if(apt_text_is_eos(stream) == TRUE) {
		return FALSE;
	}

	/* read line and the boundary */
	if(apt_text_line_read(stream,&boundary) == FALSE) {
		return FALSE;
	}

	/* remove optional trailing spaces */
	while(boundary.length && boundary.buf[boundary.length-1] == APT_TOKEN_SP) boundary.length--;

	/* check whether this is the final boundary */
	if(boundary.length >= 2) {
		if(boundary.buf[boundary.length-1] == '-' && boundary.buf[boundary.length-2] == '-') {
			/* final boundary */
			boundary.length -= 2;
			is_final = TRUE;
		}
	}

	/* compare boundaries */
	if(apt_string_is_empty(&multipart_content->boundary) == TRUE) {
		/* no boundary was specified from user space, 
		learn boundary from the content */
		multipart_content->boundary = boundary;
	}
	else {
		if(apt_string_compare(&multipart_content->boundary,&boundary) == FALSE) {
			/* invalid boundary */
			return FALSE;
		}
	}

	if(is_final == TRUE) {
		/* final boundary => return TRUE, content remains empty */
		return TRUE;
	}

	/* read header fields */
	do {
		if(apt_text_header_read(stream,&header) == TRUE) {
			if(header.name.length) {
				if(apt_string_compare(&multipart_content->content_type_header,&header.name) == TRUE) {
					apt_string_copy(content_type,&header.value,multipart_content->pool);
				}
				else if(apt_string_compare(&multipart_content->content_length_header,&header.name) == TRUE) {
					if(header.value.buf) {
						content->length = atol(header.value.buf);
						if(content->length) {
							content->buf = apr_palloc(multipart_content->pool,content->length+1);
							content->buf[content->length] = '\0';
						}
					}
				}
			}
			else {
				/* empty header => exit */
				break;
			}
		}
	}
	while(apt_text_is_eos(stream) == FALSE);

	if(!content->length || content->length + stream->pos > stream->end) {
		return FALSE;
	}

	/* read content */
	memcpy(content->buf,stream->pos,content->length);
	stream->pos += content->length;
	return TRUE;
}