Changeset 3243 for pjproject/trunk/pjsip/src/pjsip/sip_parser.c
- Timestamp:
- Aug 1, 2010 9:48:51 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_parser.c
r3003 r3243 21 21 #include <pjsip/sip_uri.h> 22 22 #include <pjsip/sip_msg.h> 23 #include <pjsip/sip_multipart.h> 23 24 #include <pjsip/sip_auth_parser.h> 24 25 #include <pjsip/sip_errno.h> … … 34 35 #include <pj/ctype.h> 35 36 #include <pj/assert.h> 37 38 #define THIS_FILE "sip_parser.c" 36 39 37 40 #define ALNUM … … 269 272 } 270 273 271 /* Concatenate unrecognized params into single string. */272 static void concat_param( pj_str_t *param, pj_pool_t *pool,273 const pj_str_t *pname, const pj_str_t *pvalue )274 {275 pjsip_concat_param_imp(param, pool, pname, pvalue, ';');276 }277 278 274 /* Initialize static properties of the parser. */ 279 275 static pj_status_t init_parser() … … 1053 1049 */ 1054 1050 if (ctype_hdr && scanner->curptr!=scanner->end) { 1055 pjsip_msg_body *body = PJ_POOL_ALLOC_T(pool, pjsip_msg_body); 1056 body->content_type.type = ctype_hdr->media.type; 1057 body->content_type.subtype = ctype_hdr->media.subtype; 1058 body->content_type.param = ctype_hdr->media.param; 1059 1060 body->data = scanner->curptr; 1061 body->len = scanner->end - scanner->curptr; 1062 body->print_body = &pjsip_print_text_body; 1063 body->clone_data = &pjsip_clone_text_data; 1051 /* New: if Content-Type indicates that this is a multipart 1052 * message body, parse it. 1053 */ 1054 const pj_str_t STR_MULTIPART = { "multipart", 9 }; 1055 pjsip_msg_body *body; 1056 1057 if (pj_stricmp(&ctype_hdr->media.type, &STR_MULTIPART)==0) { 1058 body = pjsip_multipart_parse(pool, scanner->curptr, 1059 scanner->end - scanner->curptr, 1060 &ctype_hdr->media, 0); 1061 } else { 1062 body = PJ_POOL_ALLOC_T(pool, pjsip_msg_body); 1063 body->content_type.type = ctype_hdr->media.type; 1064 body->content_type.subtype = ctype_hdr->media.subtype; 1065 body->content_type.param = ctype_hdr->media.param; 1066 1067 body->data = scanner->curptr; 1068 body->len = scanner->end - scanner->curptr; 1069 body->print_body = &pjsip_print_text_body; 1070 body->clone_data = &pjsip_clone_text_data; 1071 } 1064 1072 1065 1073 msg->body = body; … … 1848 1856 /* Parse media parameters */ 1849 1857 while (*scanner->curptr == ';') { 1850 pj _str_t pname, pvalue;1851 int_parse_param(scanner, ctx->pool, &p name, &pvalue, 0);1852 concat_param(&hdr->media.param, ctx->pool, &pname, &pvalue);1858 pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param); 1859 int_parse_param(scanner, ctx->pool, ¶m->name, ¶m->value, 0); 1860 pj_list_push_back(&hdr->media.param, param); 1853 1861 } 1854 1862 … … 2265 2273 } 2266 2274 2275 /* Parse multiple header lines */ 2276 PJ_DEF(pj_status_t) pjsip_parse_headers( pj_pool_t *pool, char *input, 2277 pj_size_t size, pjsip_hdr *hlist, 2278 unsigned options) 2279 { 2280 enum { STOP_ON_ERROR = 1 }; 2281 pj_scanner scanner; 2282 pjsip_parse_ctx ctx; 2283 pj_str_t hname; 2284 PJ_USE_EXCEPTION; 2285 2286 pj_scan_init(&scanner, input, size, PJ_SCAN_AUTOSKIP_WS_HEADER, 2287 &on_syntax_error); 2288 2289 pj_bzero(&ctx, sizeof(ctx)); 2290 ctx.scanner = &scanner; 2291 ctx.pool = pool; 2292 2293 retry_parse: 2294 PJ_TRY 2295 { 2296 /* Parse headers. */ 2297 do { 2298 pjsip_parse_hdr_func * handler; 2299 pjsip_hdr *hdr = NULL; 2300 2301 /* Init hname just in case parsing fails. 2302 * Ref: PROTOS #2412 2303 */ 2304 hname.slen = 0; 2305 2306 /* Get hname. */ 2307 pj_scan_get( &scanner, &pconst.pjsip_TOKEN_SPEC, &hname); 2308 if (pj_scan_get_char( &scanner ) != ':') { 2309 PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 2310 } 2311 2312 /* Find handler. */ 2313 handler = find_handler(&hname); 2314 2315 /* Call the handler if found. 2316 * If no handler is found, then treat the header as generic 2317 * hname/hvalue pair. 2318 */ 2319 if (handler) { 2320 hdr = (*handler)(&ctx); 2321 } else { 2322 hdr = parse_hdr_generic_string(&ctx); 2323 hdr->name = hdr->sname = hname; 2324 } 2325 2326 /* Single parse of header line can produce multiple headers. 2327 * For example, if one Contact: header contains Contact list 2328 * separated by comma, then these Contacts will be split into 2329 * different Contact headers. 2330 * So here we must insert list instead of just insert one header. 2331 */ 2332 if (hdr) 2333 pj_list_insert_nodes_before(hlist, hdr); 2334 2335 /* Parse until EOF or an empty line is found. */ 2336 } while (!pj_scan_is_eof(&scanner) && !IS_NEWLINE(*scanner.curptr)); 2337 2338 /* If empty line is found, eat it. */ 2339 if (!pj_scan_is_eof(&scanner)) { 2340 if (IS_NEWLINE(*scanner.curptr)) { 2341 pj_scan_get_newline(&scanner); 2342 } 2343 } 2344 } 2345 PJ_CATCH_ANY 2346 { 2347 PJ_LOG(4,(THIS_FILE, "Error parsing header: '%.*s' line %d col %d", 2348 (int)hname.slen, hname.ptr, scanner.line, 2349 pj_scan_get_col(&scanner))); 2350 2351 /* Exception was thrown during parsing. */ 2352 if ((options & STOP_ON_ERROR) == STOP_ON_ERROR) { 2353 pj_scan_fini(&scanner); 2354 return PJSIP_EINVALIDHDR; 2355 } 2356 2357 /* Skip until newline, and parse next header. */ 2358 if (!pj_scan_is_eof(&scanner)) { 2359 /* Skip until next line. 2360 * Watch for header continuation. 2361 */ 2362 do { 2363 pj_scan_skip_line(&scanner); 2364 } while (IS_SPACE(*scanner.curptr)); 2365 } 2366 2367 /* Restore flag. Flag may be set in int_parse_sip_url() */ 2368 scanner.skip_ws = PJ_SCAN_AUTOSKIP_WS_HEADER; 2369 2370 /* Continue parse next header, if any. */ 2371 if (!pj_scan_is_eof(&scanner) && !IS_NEWLINE(*scanner.curptr)) { 2372 goto retry_parse; 2373 } 2374 2375 } 2376 PJ_END; 2377 2378 return PJ_SUCCESS; 2379 } 2380
Note: See TracChangeset
for help on using the changeset viewer.