📄 sip_parser.c
字号:
/* Parse generic string header. */
static void parse_generic_string_hdr( pjsip_generic_string_hdr *hdr,
pj_scanner *scanner )
{
if (pj_cis_match(&pjsip_NOT_NEWLINE, *scanner->curptr))
pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &hdr->hvalue);
else
hdr->hvalue.slen = 0;
parse_hdr_end(scanner);
}
/* Parse generic integer header. */
static void parse_generic_int_hdr( pjsip_generic_int_hdr *hdr,
pj_scanner *scanner )
{
pj_str_t tmp;
pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &tmp);
hdr->ivalue = pj_strtoul(&tmp);
parse_hdr_end(scanner);
}
/* Parse Accept header. */
static pjsip_hdr* parse_hdr_accept(pjsip_parse_ctx *ctx)
{
pjsip_accept_hdr *accept = pjsip_accept_hdr_create(ctx->pool);
parse_generic_array_hdr(accept, ctx->scanner);
return (pjsip_hdr*)accept;
}
/* Parse Allow header. */
static pjsip_hdr* parse_hdr_allow(pjsip_parse_ctx *ctx)
{
pjsip_allow_hdr *allow = pjsip_allow_hdr_create(ctx->pool);
parse_generic_array_hdr(allow, ctx->scanner);
return (pjsip_hdr*)allow;
}
/* Parse Call-ID header. */
static pjsip_hdr* parse_hdr_call_id(pjsip_parse_ctx *ctx)
{
pjsip_cid_hdr *hdr = pjsip_cid_hdr_create(ctx->pool);
pj_scan_get( ctx->scanner, &pjsip_NOT_NEWLINE, &hdr->id);
parse_hdr_end(ctx->scanner);
if (ctx->rdata)
ctx->rdata->msg_info.cid = hdr;
return (pjsip_hdr*)hdr;
}
/* Parse and interpret Contact param. */
static void int_parse_contact_param( pjsip_contact_hdr *hdr,
pj_scanner *scanner,
pj_pool_t *pool)
{
while ( *scanner->curptr == ';' ) {
pj_str_t pname, pvalue;
int_parse_param( scanner, pool, &pname, &pvalue);
if (!parser_stricmp(pname, pjsip_Q_STR) && pvalue.slen) {
char *dot_pos = pj_memchr(pvalue.ptr, '.', pvalue.slen);
if (!dot_pos) {
hdr->q1000 = pj_strtoul(&pvalue);
} else {
pvalue.slen = (pvalue.ptr+pvalue.slen) - (dot_pos+1);
pvalue.ptr = dot_pos + 1;
hdr->q1000 = pj_strtoul_mindigit(&pvalue, 3);
}
} else if (!parser_stricmp(pname, pjsip_EXPIRES_STR) && pvalue.slen) {
hdr->expires = pj_strtoul(&pvalue);
} else {
pjsip_param *p = pj_pool_alloc(pool, sizeof(pjsip_param));
p->name = pname;
p->value = pvalue;
pj_list_insert_before(&hdr->other_param, p);
}
}
}
/* Parse Contact header. */
static pjsip_hdr* parse_hdr_contact( pjsip_parse_ctx *ctx )
{
pjsip_contact_hdr *first = NULL;
pj_scanner *scanner = ctx->scanner;
do {
pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(ctx->pool);
if (first == NULL)
first = hdr;
else
pj_list_insert_before(first, hdr);
if (*scanner->curptr == '*') {
pj_scan_get_char(scanner);
hdr->star = 1;
} else {
hdr->star = 0;
hdr->uri = int_parse_uri_or_name_addr(scanner, ctx->pool,
PJSIP_PARSE_URI_AS_NAMEADDR |
PJSIP_PARSE_URI_IN_FROM_TO_HDR);
int_parse_contact_param(hdr, scanner, ctx->pool);
}
if (*scanner->curptr != ',')
break;
pj_scan_get_char(scanner);
} while (1);
parse_hdr_end(scanner);
return (pjsip_hdr*)first;
}
/* Parse Content-Length header. */
static pjsip_hdr* parse_hdr_content_len( pjsip_parse_ctx *ctx )
{
pj_str_t digit;
pjsip_clen_hdr *hdr;
hdr = pjsip_clen_hdr_create(ctx->pool);
pj_scan_get(ctx->scanner, &pjsip_DIGIT_SPEC, &digit);
hdr->len = pj_strtoul(&digit);
parse_hdr_end(ctx->scanner);
if (ctx->rdata)
ctx->rdata->msg_info.clen = hdr;
return (pjsip_hdr*)hdr;
}
/* Parse Content-Type header. */
static pjsip_hdr* parse_hdr_content_type( pjsip_parse_ctx *ctx )
{
pjsip_ctype_hdr *hdr;
pj_scanner *scanner = ctx->scanner;
hdr = pjsip_ctype_hdr_create(ctx->pool);
/* Parse media type and subtype. */
pj_scan_get(scanner, &pjsip_TOKEN_SPEC, &hdr->media.type);
pj_scan_get_char(scanner);
pj_scan_get(scanner, &pjsip_TOKEN_SPEC, &hdr->media.subtype);
/* Parse media parameters */
while (*scanner->curptr == ';') {
pj_str_t pname, pvalue;
int_parse_param(scanner, ctx->pool, &pname, &pvalue);
concat_param(&hdr->media.param, ctx->pool, &pname, &pvalue);
}
parse_hdr_end(ctx->scanner);
if (ctx->rdata)
ctx->rdata->msg_info.ctype = hdr;
return (pjsip_hdr*)hdr;
}
/* Parse CSeq header. */
static pjsip_hdr* parse_hdr_cseq( pjsip_parse_ctx *ctx )
{
pj_str_t cseq, method;
pjsip_cseq_hdr *hdr;
hdr = pjsip_cseq_hdr_create(ctx->pool);
pj_scan_get( ctx->scanner, &pjsip_DIGIT_SPEC, &cseq);
hdr->cseq = pj_strtoul(&cseq);
pj_scan_get( ctx->scanner, &pjsip_TOKEN_SPEC, &method);
pjsip_method_init_np(&hdr->method, &method);
parse_hdr_end( ctx->scanner );
if (ctx->rdata)
ctx->rdata->msg_info.cseq = hdr;
return (pjsip_hdr*)hdr;
}
/* Parse Expires header. */
static pjsip_hdr* parse_hdr_expires(pjsip_parse_ctx *ctx)
{
pjsip_expires_hdr *hdr = pjsip_expires_hdr_create(ctx->pool, 0);
parse_generic_int_hdr(hdr, ctx->scanner);
return (pjsip_hdr*)hdr;
}
/* Parse From: or To: header. */
static void parse_hdr_fromto( pj_scanner *scanner,
pj_pool_t *pool,
pjsip_from_hdr *hdr)
{
hdr->uri = int_parse_uri_or_name_addr(scanner, pool,
PJSIP_PARSE_URI_AS_NAMEADDR |
PJSIP_PARSE_URI_IN_FROM_TO_HDR);
while ( *scanner->curptr == ';' ) {
pj_str_t pname, pvalue;
int_parse_param( scanner, pool, &pname, &pvalue);
if (!parser_stricmp(pname, pjsip_TAG_STR)) {
hdr->tag = pvalue;
} else {
pjsip_param *p = pj_pool_alloc(pool, sizeof(pjsip_param));
p->name = pname;
p->value = pvalue;
pj_list_insert_before(&hdr->other_param, p);
}
}
parse_hdr_end(scanner);
}
/* Parse From: header. */
static pjsip_hdr* parse_hdr_from( pjsip_parse_ctx *ctx )
{
pjsip_from_hdr *hdr = pjsip_from_hdr_create(ctx->pool);
parse_hdr_fromto(ctx->scanner, ctx->pool, hdr);
if (ctx->rdata)
ctx->rdata->msg_info.from = hdr;
return (pjsip_hdr*)hdr;
}
/* Parse Require: header. */
static pjsip_hdr* parse_hdr_require( pjsip_parse_ctx *ctx )
{
pjsip_require_hdr *hdr = pjsip_require_hdr_create(ctx->pool);
parse_generic_array_hdr(hdr, ctx->scanner);
if (ctx->rdata && ctx->rdata->msg_info.require == NULL)
ctx->rdata->msg_info.require = hdr;
return (pjsip_hdr*)hdr;
}
/* Parse Retry-After: header. */
static pjsip_hdr* parse_hdr_retry_after(pjsip_parse_ctx *ctx)
{
pjsip_retry_after_hdr *hdr;
hdr = pjsip_retry_after_hdr_create(ctx->pool, 0);
parse_generic_int_hdr(hdr, ctx->scanner);
return (pjsip_hdr*)hdr;
}
/* Parse Supported: header. */
static pjsip_hdr* parse_hdr_supported(pjsip_parse_ctx *ctx)
{
pjsip_supported_hdr *hdr = pjsip_supported_hdr_create(ctx->pool);
parse_generic_array_hdr(hdr, ctx->scanner);
return (pjsip_hdr*)hdr;
}
/* Parse To: header. */
static pjsip_hdr* parse_hdr_to( pjsip_parse_ctx *ctx )
{
pjsip_to_hdr *hdr = pjsip_to_hdr_create(ctx->pool);
parse_hdr_fromto(ctx->scanner, ctx->pool, hdr);
if (ctx->rdata)
ctx->rdata->msg_info.to = hdr;
return (pjsip_hdr*)hdr;
}
/* Parse Unsupported: header. */
static pjsip_hdr* parse_hdr_unsupported(pjsip_parse_ctx *ctx)
{
pjsip_unsupported_hdr *hdr = pjsip_unsupported_hdr_create(ctx->pool);
parse_generic_array_hdr(hdr, ctx->scanner);
return (pjsip_hdr*)hdr;
}
/* Parse and interpret Via parameters. */
static void int_parse_via_param( pjsip_via_hdr *hdr, pj_scanner *scanner,
pj_pool_t *pool)
{
while ( *scanner->curptr == ';' ) {
pj_str_t pname, pvalue;
int_parse_param( scanner, pool, &pname, &pvalue);
if (!parser_stricmp(pname, pjsip_BRANCH_STR) && pvalue.slen) {
hdr->branch_param = pvalue;
} else if (!parser_stricmp(pname, pjsip_TTL_STR) && pvalue.slen) {
hdr->ttl_param = pj_strtoul(&pvalue);
} else if (!parser_stricmp(pname, pjsip_MADDR_STR) && pvalue.slen) {
hdr->maddr_param = pvalue;
} else if (!parser_stricmp(pname, pjsip_RECEIVED_STR) && pvalue.slen) {
hdr->recvd_param = pvalue;
} else if (!parser_stricmp(pname, pjsip_RPORT_STR)) {
if (pvalue.slen)
hdr->rport_param = pj_strtoul(&pvalue);
else
hdr->rport_param = 0;
} else {
pjsip_param *p = pj_pool_alloc(pool, sizeof(pjsip_param));
p->name = pname;
p->value = pvalue;
pj_list_insert_before(&hdr->other_param, p);
}
}
}
/* Parse Max-Forwards header. */
static pjsip_hdr* parse_hdr_max_forwards( pjsip_parse_ctx *ctx )
{
pjsip_max_fwd_hdr *hdr;
hdr = pjsip_max_fwd_hdr_create(ctx->pool, 0);
parse_generic_int_hdr(hdr, ctx->scanner);
if (ctx->rdata)
ctx->rdata->msg_info.max_fwd = hdr;
return (pjsip_hdr*)hdr;
}
/* Parse Min-Expires header. */
static pjsip_hdr* parse_hdr_min_expires(pjsip_parse_ctx *ctx)
{
pjsip_min_expires_hdr *hdr;
hdr = pjsip_min_expires_hdr_create(ctx->pool, 0);
parse_generic_int_hdr(hdr, ctx->scanner);
return (pjsip_hdr*)hdr;
}
/* Parse Route: or Record-Route: header. */
static void parse_hdr_rr_route( pj_scanner *scanner, pj_pool_t *pool,
pjsip_routing_hdr *hdr )
{
pjsip_name_addr *temp=int_parse_name_addr(scanner, pool);
pj_memcpy(&hdr->name_addr, temp, sizeof(*temp));
while (*scanner->curptr == ';') {
pjsip_param *p = pj_pool_alloc(pool, sizeof(pjsip_param));
int_parse_param(scanner, pool, &p->name, &p->value);
pj_list_insert_before(&hdr->other_param, p);
}
}
/* Parse Record-Route header. */
static pjsip_hdr* parse_hdr_rr( pjsip_parse_ctx *ctx)
{
pjsip_rr_hdr *first = NULL;
pj_scanner *scanner = ctx->scanner;
do {
pjsip_rr_hdr *hdr = pjsip_rr_hdr_create(ctx->pool);
if (!first) {
first = hdr;
} else {
pj_list_insert_before(first, hdr);
}
parse_hdr_rr_route(scanner, ctx->pool, hdr);
if (*scanner->curptr == ',') {
pj_scan_get_char(scanner);
} else {
break;
}
} while (1);
parse_hdr_end(scanner);
if (ctx->rdata && ctx->rdata->msg_info.record_route==NULL)
ctx->rdata->msg_info.record_route = first;
return (pjsip_hdr*)first;
}
/* Parse Route: header. */
static pjsip_hdr* parse_hdr_route( pjsip_parse_ctx *ctx )
{
pjsip_route_hdr *first = NULL;
pj_scanner *scanner = ctx->scanner;
do {
pjsip_route_hdr *hdr = pjsip_route_hdr_create(ctx->pool);
if (!first) {
first = hdr;
} else {
pj_list_insert_before(first, hdr);
}
parse_hdr_rr_route(scanner, ctx->pool, hdr);
if (*scanner->curptr == ',') {
pj_scan_get_char(scanner);
} else {
break;
}
} while (1);
parse_hdr_end(scanner);
if (ctx->rdata && ctx->rdata->msg_info.route==NULL)
ctx->rdata->msg_info.route = first;
return (pjsip_hdr*)first;
}
/* Parse Via: header. */
static pjsip_hdr* parse_hdr_via( pjsip_parse_ctx *ctx )
{
pjsip_via_hdr *first = NULL;
pj_scanner *scanner = ctx->scanner;
do {
pjsip_via_hdr *hdr = pjsip_via_hdr_create(ctx->pool);
if (!first)
first = hdr;
else
pj_list_insert_before(first, hdr);
if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION "/", 8) != 0)
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
pj_scan_advance_n( scanner, 8, 1);
pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hdr->transport);
pj_scan_get( scanner, &pjsip_HOST_SPEC, &hdr->sent_by.host);
if (*scanner->curptr==':') {
pj_str_t digit;
pj_scan_get_char(scanner);
pj_scan_get(scanner, &pjsip_DIGIT_SPEC, &digit);
hdr->sent_by.port = pj_strtoul(&digit);
}
int_parse_via_param(hdr, scanner, ctx->pool);
if (*scanner->curptr == '(') {
pj_scan_get_char(scanner);
pj_scan_get_until_ch( scanner, ')', &hdr->comment);
pj_scan_get_char( scanner );
}
if (*scanner->curptr != ',')
break;
pj_scan_get_char(scanner);
} while (1);
parse_hdr_end(scanner);
if (ctx->rdata && ctx->rdata->msg_info.via == NULL)
ctx->rdata->msg_info.via = first;
return (pjsip_hdr*)first;
}
/* Parse generic header. */
static pjsip_hdr* parse_hdr_generic_string( pjsip_parse_ctx *ctx )
{
pjsip_generic_string_hdr *hdr;
hdr = pjsip_generic_string_hdr_create(ctx->pool, NULL, NULL);
parse_generic_string_hdr(hdr, ctx->scanner);
return (pjsip_hdr*)hdr;
}
/* Public function to parse a header value. */
PJ_DEF(void*) pjsip_parse_hdr( pj_pool_t *pool, const pj_str_t *hname,
char *buf, pj_size_t size, int *parsed_len )
{
pj_scanner scanner;
pjsip_hdr *hdr = NULL;
pjsip_parse_ctx context;
PJ_USE_EXCEPTION;
pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER,
&on_syntax_error);
context.scanner = &scanner;
context.pool = pool;
context.rdata = NULL;
PJ_TRY {
pjsip_parse_hdr_func *handler = find_handler(hname);
if (handler) {
hdr = (*handler)(&context);
} else {
hdr = parse_hdr_generic_string(&context);
hdr->type = PJSIP_H_OTHER;
pj_strdup(pool, &hdr->name, hname);
hdr->sname = hdr->name;
}
}
PJ_CATCH_ANY {
hdr = NULL;
}
PJ_END
if (parsed_len) {
*parsed_len = (scanner.curptr - scanner.begin);
}
pj_scan_fini(&scanner);
return hdr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -