summaryrefslogtreecommitdiff
path: root/pjsip/src/test
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2010-08-01 09:48:51 +0000
committerBenny Prijono <bennylp@teluu.com>2010-08-01 09:48:51 +0000
commit059d687249f0f95e0b30785c418e1aa47555615a (patch)
tree792e10acf82954faca0a2b7fe937064a1ecb81d8 /pjsip/src/test
parent1426b8301e4d99837bd70ce73b350d03fafbfd45 (diff)
Implemented core multipart support and support in the invite session (re #1070)
- incoming multipart message will be handled automatically - for testing, enable HAVE_MULTIPART_TEST in pjsua_app.c git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3243 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src/test')
-rw-r--r--pjsip/src/test/multipart_test.c264
-rw-r--r--pjsip/src/test/test.c4
-rw-r--r--pjsip/src/test/test.h2
3 files changed, 270 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;
+}
+
diff --git a/pjsip/src/test/test.c b/pjsip/src/test/test.c
index df5523a7..01163249 100644
--- a/pjsip/src/test/test.c
+++ b/pjsip/src/test/test.c
@@ -301,6 +301,10 @@ int test_main(void)
DO_TEST(msg_err_test());
#endif
+#if INCLUDE_MULTIPART_TEST
+ DO_TEST(multipart_test());
+#endif
+
#if INCLUDE_TXDATA_TEST
DO_TEST(txdata_test());
#endif
diff --git a/pjsip/src/test/test.h b/pjsip/src/test/test.h
index 6c695725..18d28b75 100644
--- a/pjsip/src/test/test.h
+++ b/pjsip/src/test/test.h
@@ -56,6 +56,7 @@ extern pjsip_endpoint *endpt;
#define INCLUDE_URI_TEST INCLUDE_MESSAGING_GROUP
#define INCLUDE_MSG_TEST INCLUDE_MESSAGING_GROUP
+#define INCLUDE_MULTIPART_TEST INCLUDE_MESSAGING_GROUP
#define INCLUDE_TXDATA_TEST INCLUDE_MESSAGING_GROUP
#define INCLUDE_TSX_BENCH INCLUDE_MESSAGING_GROUP
#define INCLUDE_UDP_TEST INCLUDE_TRANSPORT_GROUP
@@ -71,6 +72,7 @@ extern pjsip_endpoint *endpt;
int uri_test(void);
int msg_test(void);
int msg_err_test(void);
+int multipart_test(void);
int txdata_test(void);
int tsx_bench(void);
int transport_udp_test(void);