Commit 8072be89 authored by jehan's avatar jehan

add support for escaped header in URI

parent 737afcd5
......@@ -887,6 +887,7 @@ int belle_sip_get_char (const char*a,int n,char*out);
/*return an escaped string*/
BELLESIP_INTERNAL_EXPORT char* belle_sip_uri_to_escaped_username(const char* buff) ;
BELLESIP_INTERNAL_EXPORT char* belle_sip_uri_to_escaped_parameter(const char* buff) ;
BELLESIP_INTERNAL_EXPORT char* belle_sip_uri_to_escaped_header(const char* buff) ;
BELLESIP_INTERNAL_EXPORT char* belle_sip_to_unescaped_string(const char* buff) ;
......
......@@ -1377,7 +1377,13 @@ headers[belle_sip_uri_t* uri]
scope { belle_sip_uri_t* current; }
@init {$headers::current=uri;}
: '?' header ( '&' header )* ;
header : hname EQUAL hvalue? {belle_sip_uri_set_header($headers::current,(const char *)$hname.text->chars,(const char *)$hvalue.text->chars);};
header : hname EQUAL hvalue? {
char* unescaped_hname = belle_sip_to_unescaped_string((const char *)$hname.text->chars);
char* unescaped_hvalue = $hvalue.text->chars?belle_sip_to_unescaped_string((const char *)$hvalue.text->chars):NULL;
belle_sip_uri_set_header($headers::current,unescaped_hname,unescaped_hvalue);
belle_sip_free(unescaped_hname);
if (unescaped_hvalue) belle_sip_free(unescaped_hvalue);
};
hname : ( hnv_unreserved | unreserved | escaped )+;
hvalue : ( hnv_unreserved | unreserved | escaped )+;
......
......@@ -75,8 +75,14 @@ static void encode_params(belle_sip_param_pair_t* container, belle_sip_list_t**
*newlist = belle_sip_list_append(*newlist, belle_sip_param_pair_new(escapedName, escapedValue));
}
static void encode_headers(belle_sip_param_pair_t* container, belle_sip_list_t** newlist) {
char *escapedName = belle_sip_uri_to_escaped_header(container->name);
char *escapedValue = container->value? belle_sip_uri_to_escaped_header(container->value) : NULL;
*newlist = belle_sip_list_append(*newlist, belle_sip_param_pair_new(escapedName, escapedValue));
}
belle_sip_error_code belle_sip_uri_marshal(const belle_sip_uri_t* uri, char* buff, size_t buff_size, size_t *offset) {
const belle_sip_list_t* list=belle_sip_parameters_get_parameters(uri->header_list);
const belle_sip_list_t* list;
belle_sip_error_code error=BELLE_SIP_OK;
error=belle_sip_snprintf(buff,buff_size,offset,"%s:",uri->secure?"sips":"sip");
......@@ -107,22 +113,26 @@ belle_sip_error_code belle_sip_uri_marshal(const belle_sip_uri_t* uri, char* buf
belle_sip_parameters_t *encparams = belle_sip_parameters_new();
belle_sip_list_for_each2((void*)uri->params.param_list, (void*)encode_params, &encparams->param_list);
error=belle_sip_parameters_marshal(encparams,buff,buff_size,offset);
// belle_sip_list_free_with_data(encparams->param_list, belle_sip_object_unref);
belle_sip_object_unref((void*)encparams);
if (error!=BELLE_SIP_OK) return error;
}
for(;list!=NULL;list=list->next){
belle_sip_parameters_t *encheaders = belle_sip_parameters_new();
belle_sip_list_for_each2((void*)uri->header_list->param_list, (void*)encode_headers, &encheaders->param_list);
for(list=encheaders->param_list;list!=NULL;list=list->next){
belle_sip_param_pair_t* container = list->data;
if (list == belle_sip_parameters_get_parameters(uri->header_list)) {
if (list == encheaders->param_list) {
//first case
error=belle_sip_snprintf(buff,buff_size,offset,"?%s=%s",container->name,container->value);
} else {
//subsequent headers
error=belle_sip_snprintf(buff,buff_size,offset,"&%s=%s",container->name,container->value);
}
if (error!=BELLE_SIP_OK) return error;
if (error!=BELLE_SIP_OK) break;
}
belle_sip_object_unref((void*)encheaders);
return error;
}
......
......@@ -841,19 +841,6 @@ static const char *get_uri_parameter_noescapes() {
static char noescapes[BELLE_SIP_NO_ESCAPES_SIZE] = {0};
if (noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] == 0) {
/*
uri-parameters = *( ";" uri-parameter)
uri-parameter = transport-param / user-param / method-p*aram
/ ttl-param / maddr-param / lr-param / other-param
transport-param = "transport="
( "udp" / "tcp" / "sctp" / "tls"
/ other-transport)
other-transport = token
user-param = "user=" ( "phone" / "ip" / other-user)
other-user = token
method-param = "method=" Method
ttl-param = "ttl=" ttl
maddr-param = "maddr=" host
lr-param = "lr"
other-param = pname [ "=" pvalue ]
pname = 1*paramchar
pvalue = 1*paramchar
......@@ -878,6 +865,36 @@ static const char *get_uri_parameter_noescapes() {
}
return noescapes;
}
static const char *get_uri_header_noescapes() {
static char noescapes[BELLE_SIP_NO_ESCAPES_SIZE] = {0};
if (noescapes[BELLE_SIP_NO_ESCAPES_SIZE] == 0) {
/*
unreserved = alphanum / mark
mark = "-" / "_" / "." / "!" / "~" / "*" / "'"
/ "(" / ")"
escaped = "%" HEXDIG HEXDIG
//....
header = hname "=" hvalue
hname = 1*( hnv-unreserved / unreserved / escaped )
hvalue = *( hnv-unreserved / unreserved / escaped )
hnv-unreserved = "[" / "]" / "/" / "?" / ":" / "+" / "$"
*/
// unreserved
//alphanum
noescapes_add_alfanums(noescapes);
//mark
noescapes_add_list(noescapes, "-_.!~*'()");
noescapes_add_list(noescapes, "[]/?:+$");
//hnv-unreserved
noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] = 1; // initialized
// print_noescapes_map(noescapes, "uri_parameter");
}
return noescapes;
}
static char* belle_sip_escape(const char* buff, const char *noescapes) {
char output_buff[BELLE_SIP_MAX_TO_STRING_SIZE];
......@@ -903,3 +920,6 @@ char* belle_sip_uri_to_escaped_username(const char* buff) {
char* belle_sip_uri_to_escaped_parameter(const char* buff) {
return belle_sip_escape(buff, get_uri_parameter_noescapes());
}
char* belle_sip_uri_to_escaped_header(const char* buff) {
return belle_sip_escape(buff, get_uri_header_noescapes());
}
......@@ -163,7 +163,7 @@ static void test_headers(void) {
CU_ASSERT_PTR_NULL(belle_sip_uri_get_header(L_uri,"bla"));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
L_uri = belle_sip_uri_parse("sip:192.168.0.1?toto=titi&header2=popo");
L_uri = belle_sip_uri_parse("sip:192.168.0.1?toto=titi&header2=popo&header3=");
l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
L_uri = belle_sip_uri_parse(l_raw_uri);
......@@ -173,6 +173,17 @@ static void test_headers(void) {
CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_header(L_uri,"header2"), "popo");
belle_sip_object_unref(L_uri);
}
static void test_escaped_headers(void) {
belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:toto@sip.linhone.org?User-to-User=323a313030363a3230385a48363039313941364b4342463845495936%3Bencoding%3Dhex");
char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
L_uri = belle_sip_uri_parse(l_raw_uri);
belle_sip_free(l_raw_uri);
CU_ASSERT_PTR_NOT_NULL_FATAL(belle_sip_uri_get_header(L_uri,"User-to-User"));
CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_header(L_uri,"User-to-User"), "323a313030363a3230385a48363039313941364b4342463845495936;encoding=hex");
belle_sip_object_unref(L_uri);
}
static void testSIMPLEURI_error(void) {
belle_sip_uri_t* L_uri = belle_sip_uri_parse("siptcom");
......@@ -334,6 +345,7 @@ test_t uri_tests[] = {
{ "lr", test_lr },
{ "maddr", test_maddr },
{ "headers", test_headers },
{ "Escaped headers", test_escaped_headers},
{ "URI parameters", test_uri_parameters },
{ "SIPS URI", testSIPSURI },
{ "URI equals", test_uri_equals },
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment