blob: 30d61261d9e6f1603e70fce7cf1721f388109d52 [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $Id: multipart_test.c 3553 2011-05-05 06:14:19Z nanang $ */
2/*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include "test.h"
20#include <pjsip.h>
21#include <pjlib.h>
22
23#define THIS_FILE ""
24
25/*
26 * multipart tests
27 */
28typedef pj_status_t (*verify_ptr)(pj_pool_t*,pjsip_msg_body*);
29
30static pj_status_t verify1(pj_pool_t *pool, pjsip_msg_body *body);
31
32static struct test_t
33{
34 char *ctype;
35 char *csubtype;
36 char *boundary;
37 const char *msg;
38 verify_ptr verify;
39} p_tests[] =
40{
41 {
42 /* Content-type */
43 "multipart", "mixed", "12345",
44
45 /* Body: */
46 "This is the prolog, which should be ignored.\r\n"
47 "--12345\r\n"
48 "Content-Type: my/text\r\n"
49 "\r\n"
50 "Header and body\r\n"
51 "--12345 \t\r\n"
52 "Content-Type: hello/world\r\n"
53 "Content-Length: 0\r\n"
54 "\r\n"
55 "--12345\r\n"
56 "\r\n"
57 "Body only\r\n"
58 "--12345\r\n"
59 "Content-Type: multipart/mixed;boundary=6789\r\n"
60 "\r\n"
61 "Prolog of the subbody, should be ignored\r\n"
62 "--6789\r\n"
63 "\r\n"
64 "Subbody\r\n"
65 "--6789--\r\n"
66 "Epilogue of the subbody, should be ignored\r\n"
67 "--12345--\r\n"
68 "This is epilogue, which should be ignored too",
69
70 &verify1
71 }
72};
73
74static void init_media_type(pjsip_media_type *mt,
75 char *type, char *subtype, char *boundary)
76{
77 static pjsip_param prm;
78
79 pjsip_media_type_init(mt, NULL, NULL);
80 if (type) mt->type = pj_str(type);
81 if (subtype) mt->subtype = pj_str(subtype);
82 if (boundary) {
83 pj_list_init(&prm);
84 prm.name = pj_str("boundary");
85 prm.value = pj_str(boundary);
86 pj_list_push_back(&mt->param, &prm);
87 }
88}
89
90static int verify_part(pjsip_multipart_part *part,
91 char *h_content_type,
92 char *h_content_subtype,
93 char *boundary,
94 int h_content_length,
95 const char *body)
96{
97 pjsip_ctype_hdr *ctype_hdr = NULL;
98 pjsip_clen_hdr *clen_hdr = NULL;
99 pjsip_hdr *hdr;
100 pj_str_t the_body;
101
102 hdr = part->hdr.next;
103 while (hdr != &part->hdr) {
104 if (hdr->type == PJSIP_H_CONTENT_TYPE)
105 ctype_hdr = (pjsip_ctype_hdr*)hdr;
106 else if (hdr->type == PJSIP_H_CONTENT_LENGTH)
107 clen_hdr = (pjsip_clen_hdr*)hdr;
108 hdr = hdr->next;
109 }
110
111 if (h_content_type) {
112 pjsip_media_type mt;
113
114 if (ctype_hdr == NULL)
115 return -10;
116
117 init_media_type(&mt, h_content_type, h_content_subtype, boundary);
118
119 if (pjsip_media_type_cmp(&ctype_hdr->media, &mt, 2) != 0)
120 return -20;
121
122 } else {
123 if (ctype_hdr)
124 return -30;
125 }
126
127 if (h_content_length >= 0) {
128 if (clen_hdr == NULL)
129 return -50;
130 if (clen_hdr->len != h_content_length)
131 return -60;
132 } else {
133 if (clen_hdr)
134 return -70;
135 }
136
137 the_body.ptr = (char*)part->body->data;
138 the_body.slen = part->body->len;
139
140 if (pj_strcmp2(&the_body, body) != 0)
141 return -90;
142
143 return 0;
144}
145
146static pj_status_t verify1(pj_pool_t *pool, pjsip_msg_body *body)
147{
148 pjsip_media_type mt;
149 pjsip_multipart_part *part;
150 int rc;
151
152 PJ_UNUSED_ARG(pool);
153
154 /* Check content-type: "multipart/mixed;boundary=12345" */
155 init_media_type(&mt, "multipart", "mixed", "12345");
156 if (pjsip_media_type_cmp(&body->content_type, &mt, 2) != 0)
157 return -200;
158
159 /* First part:
160 "Content-Type: my/text\r\n"
161 "\r\n"
162 "Header and body\r\n"
163 */
164 part = pjsip_multipart_get_first_part(body);
165 if (!part)
166 return -210;
167 if (verify_part(part, "my", "text", NULL, -1, "Header and body"))
168 return -220;
169
170 /* Next part:
171 "Content-Type: hello/world\r\n"
172 "Content-Length: 0\r\n"
173 "\r\n"
174 */
175 part = pjsip_multipart_get_next_part(body, part);
176 if (!part)
177 return -230;
178 if ((rc=verify_part(part, "hello", "world", NULL, 0, ""))!=0) {
179 PJ_LOG(3,(THIS_FILE, " err: verify_part rc=%d", rc));
180 return -240;
181 }
182
183 /* Next part:
184 "\r\n"
185 "Body only\r\n"
186 */
187 part = pjsip_multipart_get_next_part(body, part);
188 if (!part)
189 return -260;
190 if (verify_part(part, NULL, NULL, NULL, -1, "Body only"))
191 return -270;
192
193 /* Next part:
194 "Content-Type: multipart/mixed;boundary=6789\r\n"
195 "\r\n"
196 "Prolog of the subbody, should be ignored\r\n"
197 "--6789\r\n"
198 "\r\n"
199 "Subbody\r\n"
200 "--6789--\r\n"
201 "Epilogue of the subbody, should be ignored\r\n"
202
203 */
204 part = pjsip_multipart_get_next_part(body, part);
205 if (!part)
206 return -280;
207 if ((rc=verify_part(part, "multipart", "mixed", "6789", -1,
208 "Prolog of the subbody, should be ignored\r\n"
209 "--6789\r\n"
210 "\r\n"
211 "Subbody\r\n"
212 "--6789--\r\n"
213 "Epilogue of the subbody, should be ignored"))!=0) {
214 PJ_LOG(3,(THIS_FILE, " err: verify_part rc=%d", rc));
215 return -290;
216 }
217
218 return 0;
219}
220
221static int parse_test(void)
222{
223 unsigned i;
224
225 for (i=0; i<PJ_ARRAY_SIZE(p_tests); ++i) {
226 pj_pool_t *pool;
227 pjsip_media_type ctype;
228 pjsip_msg_body *body;
229 pj_str_t str;
230 int rc;
231
232 pool = pjsip_endpt_create_pool(endpt, NULL, 512, 512);
233
234 init_media_type(&ctype, p_tests[i].ctype, p_tests[i].csubtype,
235 p_tests[i].boundary);
236
237 pj_strdup2_with_null(pool, &str, p_tests[i].msg);
238 body = pjsip_multipart_parse(pool, str.ptr, str.slen, &ctype, 0);
239 if (!body)
240 return -100;
241
242 if (p_tests[i].verify) {
243 rc = p_tests[i].verify(pool, body);
244 } else {
245 rc = 0;
246 }
247
248 pj_pool_release(pool);
249 if (rc)
250 return rc;
251 }
252
253 return 0;
254}
255
256int multipart_test(void)
257{
258 int rc;
259
260 rc = parse_test();
261 if (rc)
262 return rc;
263
264 return rc;
265}
266