static apt_bool_t multipart_content_parse(apt_test_suite_t *suite, apt_str_t *body)
{
	apt_multipart_content_t *multipart = apt_multipart_content_assign(body,NULL,suite->pool);
	if(multipart) {
		apt_bool_t is_final;
		apt_content_part_t content_part;
		while(apt_multipart_content_get(multipart,&content_part,&is_final) == TRUE) {
			if(is_final == TRUE) {
				break;
			}
			if(content_part.type && apt_string_is_empty(content_part.type) == FALSE) {
				apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Content Part Type: %.*s",
					content_part.type->length,
					content_part.type->buf);
			}
			if(content_part.id && apt_string_is_empty(content_part.id) == FALSE) {
				apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Content Part Id: %.*s",
					content_part.id->length,
					content_part.id->buf);
			}
			if(content_part.length && apt_string_is_empty(content_part.length) == FALSE) {
				apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Content Part Length: %.*s\n%.*s",
					content_part.length->length,
					content_part.length->buf,
					content_part.body.length,
					content_part.body.buf);
			}
		}
	}
	return TRUE;
}
/** Parse header section */
APT_DECLARE(apt_bool_t) apt_header_section_parse(apt_header_section_t *header, apt_text_stream_t *stream, apr_pool_t *pool)
{
	apt_header_field_t *header_field;
	apt_bool_t result = FALSE;

	do {
		header_field = apt_header_field_parse(stream,pool);
		if(header_field) {
			if(apt_string_is_empty(&header_field->name) == FALSE) {
				/* normal header */
				apt_header_section_field_add(header,header_field);
			}
			else {
				/* empty header => exit */
				result = TRUE;
				break;
			}
		}
		else {
			/* malformed header => skip to the next one */
		}
	}
	while(apt_text_is_eos(stream) == FALSE);

	return result;
}
/** Generate name-value pair line */
APT_DECLARE(apt_bool_t) apt_text_name_value_insert(apt_text_stream_t *stream, const apt_str_t *name, const apt_str_t *value)
{
	char *pos = stream->pos;
	if(pos + name->length + value->length + 2 >= stream->end) {
		return FALSE;
	}
	memcpy(pos,name->buf,name->length);
	pos += name->length;
	*pos++ = ':';
	*pos++ = APT_TOKEN_SP;
	if(apt_string_is_empty(value) == FALSE) {
		memcpy(pos,value->buf,value->length);
		pos += value->length;
	}
	stream->pos = pos;
	return apt_text_eol_insert(stream);
}
Exemple #4
0
/** Add MRCP header field */
MRCP_DECLARE(apt_bool_t) mrcp_header_field_add(mrcp_message_header_t *header, apt_header_field_t *header_field, apr_pool_t *pool)
{
	apt_bool_t status = FALSE;
	if(apt_string_is_empty(&header_field->name) == FALSE) {
		/* normal header */
		if(mrcp_header_field_value_parse(&header->resource_header_accessor,header_field,pool) == TRUE) {
			header_field->id += GENERIC_HEADER_COUNT;
		}
		else if(mrcp_header_field_value_parse(&header->generic_header_accessor,header_field,pool) == TRUE) {
			status = apt_header_section_field_add(&header->header_section,header_field);
		}
		else { 
			apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Unknown MRCP header field: %s",header_field->name.buf);
		}
		status = apt_header_section_field_add(&header->header_section,header_field);
	}
	return status;
}
/** 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;
}