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); }
/** 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; }