Fixed ticket #940: Multiple header rows with the same name may not be completely processed by PJSIP modules
- the parser now collect and aggregate all Supported/Require header fields into single header git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2985 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
8db270b0fe
commit
611083d09e
|
@ -385,9 +385,16 @@ struct pjsip_rx_data
|
|||
/** Content-length header. */
|
||||
pjsip_clen_hdr *clen;
|
||||
|
||||
/** The first Require header. */
|
||||
/** "Require" header containing aggregates of all Require
|
||||
* headers found in the message, or NULL.
|
||||
*/
|
||||
pjsip_require_hdr *require;
|
||||
|
||||
/** "Supported" header containing aggregates of all Supported
|
||||
* headers found in the message, or NULL.
|
||||
*/
|
||||
pjsip_supported_hdr *supported;
|
||||
|
||||
/** The list of error generated by the parser when parsing
|
||||
this message.
|
||||
*/
|
||||
|
|
|
@ -1007,11 +1007,17 @@ parse_headers:
|
|||
if (handler) {
|
||||
hdr = (*handler)(ctx);
|
||||
|
||||
/* Note:
|
||||
* hdr MAY BE NULL, if parsing does not yield a new header
|
||||
* instance, e.g. the values have been added to existing
|
||||
* header. See http://trac.pjsip.org/repos/ticket/940
|
||||
*/
|
||||
|
||||
/* Check if we've just parsed a Content-Type header.
|
||||
* We will check for a message body if we've got Content-Type
|
||||
* header.
|
||||
*/
|
||||
if (hdr->type == PJSIP_H_CONTENT_TYPE) {
|
||||
if (hdr && hdr->type == PJSIP_H_CONTENT_TYPE) {
|
||||
ctype_hdr = (pjsip_ctype_hdr*)hdr;
|
||||
}
|
||||
|
||||
|
@ -1027,7 +1033,8 @@ parse_headers:
|
|||
* different Contact headers.
|
||||
* So here we must insert list instead of just insert one header.
|
||||
*/
|
||||
pj_list_insert_nodes_before(&msg->hdr, hdr);
|
||||
if (hdr)
|
||||
pj_list_insert_nodes_before(&msg->hdr, hdr);
|
||||
|
||||
/* Parse until EOF or an empty line is found. */
|
||||
} while (!pj_scan_is_eof(scanner) && !IS_NEWLINE(*scanner->curptr));
|
||||
|
@ -1639,7 +1646,14 @@ static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr,
|
|||
goto end;
|
||||
}
|
||||
|
||||
pj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE, &hdr->values[0]);
|
||||
if (hdr->count >= PJ_ARRAY_SIZE(hdr->values)) {
|
||||
/* Too many elements */
|
||||
on_syntax_error(scanner);
|
||||
return;
|
||||
}
|
||||
|
||||
pj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE,
|
||||
&hdr->values[hdr->count]);
|
||||
hdr->count++;
|
||||
|
||||
while (*scanner->curptr == ',') {
|
||||
|
@ -1917,13 +1931,19 @@ static pjsip_hdr* parse_hdr_from( pjsip_parse_ctx *ctx )
|
|||
/* Parse Require: header. */
|
||||
static pjsip_hdr* parse_hdr_require( pjsip_parse_ctx *ctx )
|
||||
{
|
||||
pjsip_require_hdr *hdr = pjsip_require_hdr_create(ctx->pool);
|
||||
pjsip_require_hdr *hdr;
|
||||
pj_bool_t new_hdr = (ctx->rdata->msg_info.require == NULL);
|
||||
|
||||
if (ctx->rdata && ctx->rdata->msg_info.require) {
|
||||
hdr = ctx->rdata->msg_info.require;
|
||||
} else {
|
||||
hdr = pjsip_require_hdr_create(ctx->pool);
|
||||
ctx->rdata->msg_info.require = hdr;
|
||||
}
|
||||
|
||||
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;
|
||||
return new_hdr ? (pjsip_hdr*)hdr : NULL;
|
||||
}
|
||||
|
||||
/* Parse Retry-After: header. */
|
||||
|
@ -1960,11 +1980,19 @@ static pjsip_hdr* parse_hdr_retry_after(pjsip_parse_ctx *ctx)
|
|||
/* 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;
|
||||
}
|
||||
pjsip_supported_hdr *hdr;
|
||||
pj_bool_t new_hdr = (ctx->rdata->msg_info.supported == NULL);
|
||||
|
||||
if (ctx->rdata && ctx->rdata->msg_info.supported) {
|
||||
hdr = ctx->rdata->msg_info.supported;
|
||||
} else {
|
||||
hdr = pjsip_supported_hdr_create(ctx->pool);
|
||||
ctx->rdata->msg_info.supported = hdr;
|
||||
}
|
||||
|
||||
parse_generic_array_hdr(hdr, ctx->scanner);
|
||||
return new_hdr ? (pjsip_hdr*)hdr : NULL;
|
||||
}
|
||||
|
||||
/* Parse To: header. */
|
||||
static pjsip_hdr* parse_hdr_to( pjsip_parse_ctx *ctx )
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||
|
||||
|
||||
<scenario name="Multiple Require header fields">
|
||||
<!-- UAC with bad ACK causes assertion with pjsip 1.4 -->
|
||||
<send retrans="500">
|
||||
<![CDATA[
|
||||
|
||||
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>
|
||||
Call-ID: [call_id]
|
||||
CSeq: 1 INVITE
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Require: timer
|
||||
Require: toto
|
||||
Subject: Performance Test
|
||||
Content-Type: application/sdp
|
||||
Content-Length: [len]
|
||||
|
||||
v=0
|
||||
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
|
||||
s=-
|
||||
c=IN IP[media_ip_type] [media_ip]
|
||||
t=0 0
|
||||
m=audio [media_port] RTP/AVP 0
|
||||
a=rtpmap:0 PCMU/8000
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<recv response="100"
|
||||
optional="true">
|
||||
</recv>
|
||||
|
||||
<recv response="180" optional="true">
|
||||
</recv>
|
||||
|
||||
<recv response="200" rtd="true">
|
||||
</recv>
|
||||
|
||||
<send>
|
||||
<![CDATA[
|
||||
|
||||
ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||
Call-ID: [call_id]
|
||||
CSeq: 1 ACK
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Length: 0
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<pause/>
|
||||
|
||||
<send retrans="500">
|
||||
<![CDATA[
|
||||
|
||||
BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=z9hG4bK-1
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||
Call-ID: [call_id]
|
||||
CSeq: 2 BYE
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Length: 0
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<recv response="200" crlf="true">
|
||||
</recv>
|
||||
|
||||
<!-- definition of the response time repartition table (unit is ms) -->
|
||||
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
|
||||
|
||||
<!-- definition of the call length repartition table (unit is ms) -->
|
||||
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
|
||||
|
||||
</scenario>
|
||||
|
Loading…
Reference in New Issue