diff options
Diffstat (limited to 'pjsip/src/test/multipart_test.c')
-rw-r--r-- | pjsip/src/test/multipart_test.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/pjsip/src/test/multipart_test.c b/pjsip/src/test/multipart_test.c new file mode 100644 index 00000000..bb56b8fe --- /dev/null +++ b/pjsip/src/test/multipart_test.c @@ -0,0 +1,264 @@ +/* $Id$ */ +/* + * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "test.h" +#include <pjsip.h> +#include <pjlib.h> + +#define THIS_FILE "" + +/* + * multipart tests + */ +typedef pj_status_t (*verify_ptr)(pj_pool_t*,pjsip_msg_body*); + +static pj_status_t verify1(pj_pool_t *pool, pjsip_msg_body *body); + +static struct test_t +{ + char *ctype; + char *csubtype; + char *boundary; + const char *msg; + verify_ptr verify; +} p_tests[] = +{ + { + /* Content-type */ + "multipart", "mixed", "12345", + + /* Body: */ + "This is the prolog, which should be ignored.\r\n" + "--12345\r\n" + "Content-Type: my/text\r\n" + "\r\n" + "Header and body\r\n" + "--12345 \t\r\n" + "Content-Type: hello/world\r\n" + "Content-Length: 0\r\n" + "\r\n" + "--12345\r\n" + "\r\n" + "Body only\r\n" + "--12345\r\n" + "Content-Type: multipart/mixed;boundary=6789\r\n" + "\r\n" + "Prolog of the subbody, should be ignored\r\n" + "--6789\r\n" + "\r\n" + "Subbody\r\n" + "--6789--\r\n" + "Epilogue of the subbody, should be ignored\r\n" + "--12345--\r\n" + "This is epilogue, which should be ignored too", + + &verify1 + } +}; + +static void init_media_type(pjsip_media_type *mt, + char *type, char *subtype, char *boundary) +{ + static pjsip_param prm; + + pjsip_media_type_init(mt, NULL, NULL); + if (type) mt->type = pj_str(type); + if (subtype) mt->subtype = pj_str(subtype); + if (boundary) { + pj_list_init(&prm); + prm.name = pj_str("boundary"); + prm.value = pj_str(boundary); + pj_list_push_back(&mt->param, &prm); + } +} + +static int verify_part(pjsip_multipart_part *part, + char *h_content_type, + char *h_content_subtype, + char *boundary, + int h_content_length, + const char *body) +{ + pjsip_ctype_hdr *ctype_hdr = NULL; + pjsip_clen_hdr *clen_hdr = NULL; + pjsip_hdr *hdr; + pj_str_t the_body; + + hdr = part->hdr.next; + while (hdr != &part->hdr) { + if (hdr->type == PJSIP_H_CONTENT_TYPE) + ctype_hdr = (pjsip_ctype_hdr*)hdr; + else if (hdr->type == PJSIP_H_CONTENT_LENGTH) + clen_hdr = (pjsip_clen_hdr*)hdr; + hdr = hdr->next; + } + + if (h_content_type) { + pjsip_media_type mt; + + if (ctype_hdr == NULL) + return -10; + + init_media_type(&mt, h_content_type, h_content_subtype, boundary); + + if (pjsip_media_type_cmp(&ctype_hdr->media, &mt) != 0) + return -20; + + } else { + if (ctype_hdr) + return -30; + } + + if (h_content_length >= 0) { + if (clen_hdr == NULL) + return -50; + if (clen_hdr->len != h_content_length) + return -60; + } else { + if (clen_hdr) + return -70; + } + + the_body.ptr = (char*)part->body->data; + the_body.slen = part->body->len; + + if (pj_strcmp2(&the_body, body) != 0) + return -90; + + return 0; +} + +static pj_status_t verify1(pj_pool_t *pool, pjsip_msg_body *body) +{ + pjsip_media_type mt; + pjsip_multipart_part *part; + int rc; + + /* Check content-type: "multipart/mixed;boundary=12345" */ + init_media_type(&mt, "multipart", "mixed", "12345"); + if (pjsip_media_type_cmp(&body->content_type, &mt) != 0) + return -200; + + /* First part: + "Content-Type: my/text\r\n" + "\r\n" + "Header and body\r\n" + */ + part = pjsip_multipart_get_first_part(body); + if (!part) + return -210; + if (verify_part(part, "my", "text", NULL, -1, "Header and body")) + return -220; + + /* Next part: + "Content-Type: hello/world\r\n" + "Content-Length: 0\r\n" + "\r\n" + */ + part = pjsip_multipart_get_next_part(body, part); + if (!part) + return -230; + if ((rc=verify_part(part, "hello", "world", NULL, 0, ""))!=0) { + PJ_LOG(3,(THIS_FILE, " err: verify_part rc=%d", rc)); + return -240; + } + + /* Next part: + "\r\n" + "Body only\r\n" + */ + part = pjsip_multipart_get_next_part(body, part); + if (!part) + return -260; + if (verify_part(part, NULL, NULL, NULL, -1, "Body only")) + return -270; + + /* Next part: + "Content-Type: multipart/mixed;boundary=6789\r\n" + "\r\n" + "Prolog of the subbody, should be ignored\r\n" + "--6789\r\n" + "\r\n" + "Subbody\r\n" + "--6789--\r\n" + "Epilogue of the subbody, should be ignored\r\n" + + */ + part = pjsip_multipart_get_next_part(body, part); + if (!part) + return -280; + if ((rc=verify_part(part, "multipart", "mixed", "6789", -1, + "Prolog of the subbody, should be ignored\r\n" + "--6789\r\n" + "\r\n" + "Subbody\r\n" + "--6789--\r\n" + "Epilogue of the subbody, should be ignored"))!=0) { + PJ_LOG(3,(THIS_FILE, " err: verify_part rc=%d", rc)); + return -290; + } + + return 0; +} + +static int parse_test(void) +{ + unsigned i; + + for (i=0; i<PJ_ARRAY_SIZE(p_tests); ++i) { + pj_pool_t *pool; + pjsip_media_type ctype; + pjsip_msg_body *body; + pj_str_t str; + int rc; + + pool = pjsip_endpt_create_pool(endpt, NULL, 512, 512); + + init_media_type(&ctype, p_tests[i].ctype, p_tests[i].csubtype, + p_tests[i].boundary); + + pj_strdup2_with_null(pool, &str, p_tests[i].msg); + body = pjsip_multipart_parse(pool, str.ptr, str.slen, &ctype, 0); + if (!body) + return -100; + + if (p_tests[i].verify) { + rc = p_tests[i].verify(pool, body); + } else { + rc = 0; + } + + pj_pool_release(pool); + if (rc) + return rc; + } + + return 0; +} + +int multipart_test(void) +{ + int rc; + + rc = parse_test(); + if (rc) + return rc; + + return rc; +} + |