Commit a2141123 authored by jehan's avatar jehan

better handling of uknown header

parent 29f687e7
......@@ -3,7 +3,9 @@ SUBDIRS=include src tester
EXTRA_DIST = belle-sip.spec
test:
cd tester && $(MAKE) test
cd tester
$(MAKE) -C tester test
rpm:
$(MAKE) dist
TAR_OPTIONS=--wildcards rpmbuild -ta --clean --rmsource --rmspec $(PACKAGE)-$(VERSION).tar.gz
......
......@@ -75,8 +75,9 @@ BELLESIP_EXPORT void belle_sip_header_address_set_displayname(belle_sip_header_a
*
**************************************************************************************/
BELLESIP_EXPORT belle_sip_header_t* belle_sip_header_parse (const char* header);
BELLESIP_EXPORT belle_sip_header_t* belle_sip_header_create (const char* name,const char* value);
BELLESIP_EXPORT belle_sip_header_t* belle_http_header_create (const char* name,const char* value);
BELLESIP_EXPORT const char* belle_sip_header_get_name (const belle_sip_header_t* obj);
BELLESIP_EXPORT void belle_sip_header_set_name (belle_sip_header_t* obj,const char* value);
BELLESIP_EXPORT belle_sip_error_code belle_sip_header_marshal(belle_sip_header_t* header, char* buff, size_t buff_size, size_t *offset);
......@@ -378,6 +379,7 @@ BELLESIP_EXPORT unsigned char belle_sip_header_record_route_get_auto_outgoing(co
BELLESIP_EXPORT void belle_sip_header_user_agent_set_products(belle_sip_header_user_agent_t* user_agent,belle_sip_list_t* value);
BELLESIP_EXPORT void belle_sip_header_user_agent_add_product(belle_sip_header_user_agent_t* user_agent,const char* product);
#define BELLE_SIP_HEADER_USER_AGENT(t) BELLE_SIP_CAST(t,belle_sip_header_user_agent_t)
#define BELLE_SIP_USER_AGENT "User-Agent"
/******************************
* Content length inherent from object
......@@ -492,20 +494,6 @@ BELLESIP_EXPORT belle_sip_header_proxy_authenticate_t* belle_sip_header_proxy_au
#define BELLE_SIP_HEADER_PROXY_AUTHENTICATE(t) BELLE_SIP_CAST(t,belle_sip_header_proxy_authenticate_t)
#define BELLE_SIP_PROXY_AUTHENTICATE "Proxy-Authenticate"
/******************************
*
* Extension header inherit from header
*
******************************/
typedef struct _belle_sip_header_extension belle_sip_header_extension_t;
BELLESIP_EXPORT belle_sip_header_extension_t* belle_sip_header_extension_new();
BELLESIP_EXPORT belle_sip_header_extension_t* belle_sip_header_extension_parse (const char* extension) ;
BELLESIP_EXPORT belle_sip_header_extension_t* belle_sip_header_extension_create (const char* name,const char* value);
BELLESIP_EXPORT const char* belle_sip_header_extension_get_value(const belle_sip_header_extension_t* extension);
BELLESIP_EXPORT void belle_sip_header_extension_set_value(belle_sip_header_extension_t* extension,const char* value);
#define BELLE_SIP_HEADER_EXTENSION(t) BELLE_SIP_CAST(t,belle_sip_header_extension_t)
/******************************
*
* Max forward inherit from header
......
......@@ -34,9 +34,78 @@
***********************/
GET_SET_STRING(belle_sip_header,name);
#define PROTO_SIP 0x1
#define PROTO_HTTP 0x1<<1
typedef belle_sip_header_t* (*header_parse_func)(const char*) ;
struct header_name_func_pair {
int protocol;
const char* name;
header_parse_func func;
};
static struct header_name_func_pair header_table[] = {
{PROTO_SIP, "m", (header_parse_func)belle_sip_header_contact_parse}
,{PROTO_SIP, BELLE_SIP_CONTACT, (header_parse_func)belle_sip_header_contact_parse}
,{PROTO_SIP, "f", (header_parse_func)belle_sip_header_from_parse}
,{PROTO_SIP, BELLE_SIP_FROM, (header_parse_func)belle_sip_header_from_parse}
,{PROTO_SIP, "t", (header_parse_func)belle_sip_header_to_parse}
,{PROTO_SIP, BELLE_SIP_TO, (header_parse_func)belle_sip_header_to_parse}
,{PROTO_SIP, "i", (header_parse_func)belle_sip_header_call_id_parse}
,{PROTO_SIP, BELLE_SIP_CALL_ID, (header_parse_func)belle_sip_header_call_id_parse}
,{PROTO_SIP, "l", (header_parse_func)belle_sip_header_content_length_parse}
,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_CONTENT_LENGTH, (header_parse_func)belle_sip_header_content_length_parse}
,{PROTO_SIP, "c", (header_parse_func)belle_sip_header_content_type_parse}
,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_CONTENT_TYPE, (header_parse_func)belle_sip_header_content_type_parse}
,{PROTO_SIP, BELLE_SIP_CSEQ, (header_parse_func)belle_sip_header_cseq_parse}
,{PROTO_SIP, BELLE_SIP_ROUTE, (header_parse_func)belle_sip_header_route_parse}
,{PROTO_SIP, BELLE_SIP_RECORD_ROUTE, (header_parse_func)belle_sip_header_record_route_parse}
,{PROTO_SIP, "v", (header_parse_func)belle_sip_header_via_parse}
,{PROTO_SIP, BELLE_SIP_VIA, (header_parse_func)belle_sip_header_via_parse}
,{PROTO_SIP, BELLE_SIP_AUTHORIZATION, (header_parse_func)belle_sip_header_authorization_parse}
,{PROTO_SIP, BELLE_SIP_PROXY_AUTHORIZATION, (header_parse_func)belle_sip_header_proxy_authorization_parse}
,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_WWW_AUTHENTICATE, (header_parse_func)belle_sip_header_www_authenticate_parse}
,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_PROXY_AUTHENTICATE, (header_parse_func)belle_sip_header_proxy_authenticate_parse}
,{PROTO_SIP, BELLE_SIP_MAX_FORWARDS, (header_parse_func)belle_sip_header_max_forwards_parse}
,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_USER_AGENT, (header_parse_func)belle_sip_header_user_agent_parse}
,{PROTO_SIP, BELLE_SIP_EXPIRES, (header_parse_func)belle_sip_header_expires_parse}
,{PROTO_SIP|PROTO_HTTP, BELLE_SIP_ALLOW, (header_parse_func)belle_sip_header_allow_parse}
,{PROTO_SIP, BELLE_SIP_SUBSCRIPTION_STATE, (header_parse_func)belle_sip_header_subscription_state_parse}
,{PROTO_SIP, BELLE_SIP_SERVICE_ROUTE, (header_parse_func)belle_sip_header_service_route_parse}
,{PROTO_SIP, BELLE_SIP_REFER_TO, (header_parse_func)belle_sip_header_refer_to_parse}
,{PROTO_SIP, BELLE_SIP_REFERRED_BY, (header_parse_func)belle_sip_header_referred_by_parse}
,{PROTO_SIP, BELLE_SIP_REPLACES, (header_parse_func)belle_sip_header_replaces_parse}
,{PROTO_SIP, BELLE_SIP_DATE, (header_parse_func)belle_sip_header_date_parse}
,{PROTO_SIP, BELLE_SIP_P_PREFERRED_IDENTITY, (header_parse_func)belle_sip_header_p_preferred_identity_parse}
,{PROTO_SIP, BELLE_SIP_PRIVACY, (header_parse_func)belle_sip_header_privacy_parse}
};
static belle_sip_header_t* belle_header_create(const char* name,const char* value,int protocol) {
int i;
belle_sip_header_t* ret;
size_t elements =sizeof(header_table)/sizeof(struct header_name_func_pair);
belle_sip_header_t* belle_sip_header_create (const char* name,const char* value) {
if (!name || name[0]=='0') {
belle_sip_error("Cannot crate header without name");
return NULL;
}
for(i=0;i<elements;i++) {
if ((header_table[i].protocol & protocol) && strcasecmp(header_table[i].name,name)==0) {
char* raw = belle_sip_strdup_printf("%s:%s",name,value);
ret=header_table[i].func(raw);
belle_sip_free(raw);
return ret;
}
}
/*not a known header*/
return BELLE_SIP_HEADER(belle_sip_header_extension_create(name,value));
}
belle_sip_header_t* belle_sip_header_create(const char* name, const char* value) {
return belle_header_create(name,value,PROTO_SIP);
}
belle_sip_header_t* belle_http_header_create (const char* name,const char* value) {
return belle_header_create(name,value,PROTO_HTTP);
}
void belle_sip_header_init(belle_sip_header_t *header) {
......@@ -67,20 +136,22 @@ belle_sip_header_t* belle_sip_header_get_next(const belle_sip_header_t* header)
}
const char *belle_sip_header_get_unparsed_value(belle_sip_header_t* obj){
char *tmp=belle_sip_object_to_string(obj);
char *ret;
char *end;
if (obj->unparsed_value){
belle_sip_free(obj->unparsed_value);
obj->unparsed_value=NULL;
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(obj,belle_sip_header_extension_t)) {
return belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(obj));
} else {
char *tmp=belle_sip_object_to_string(obj);
char *ret;
char *end;
if (obj->unparsed_value){
belle_sip_free(obj->unparsed_value);
obj->unparsed_value=NULL;
}
obj->unparsed_value=tmp;
ret=tmp;
ret+=strlen(obj->name)+1; /* name + semicolon*/
for(;*ret==' ';ret++){};/*skip spaces*/
return ret;
}
obj->unparsed_value=tmp;
ret=tmp;
ret+=strlen(obj->name)+1; /* name + semicolon*/
for(;*ret==' ';ret++){};/*skip spaces*/
end=strchr(ret,'\r');
if (end) *end='\0'; /*remove \r\n*/
return ret;
}
belle_sip_error_code belle_sip_header_marshal(belle_sip_header_t* header, char* buff, size_t buff_size, size_t *offset) {
......@@ -96,6 +167,8 @@ BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_header_t);
BELLE_SIP_INSTANCIATE_VPTR(belle_sip_header_t,belle_sip_object_t,belle_sip_header_destroy,belle_sip_header_clone,belle_sip_header_marshal,TRUE);
BELLE_SIP_PARSE(header)
/************************
* header_address
......@@ -928,31 +1001,7 @@ belle_sip_header_extension_t* belle_sip_header_extension_create (const char* nam
return ext;
}
/**
* special case for this header. I don't know why
*/
belle_sip_header_extension_t* belle_sip_header_extension_parse (const char* value) {
pANTLR3_INPUT_STREAM input;
pbelle_sip_messageLexer lex;
pANTLR3_COMMON_TOKEN_STREAM tokens;
pbelle_sip_messageParser parser;
/*belle_sip_message_sip_header_extension_return*/ belle_sip_messageParser_header_extension_return l_parsed_object;
input = ANTLR_STREAM_NEW("header_extension",value,strlen(value));
lex = belle_sip_messageLexerNew (input);
tokens = antlr3CommonTokenStreamSourceNew (1025, lex->pLexer->rec->state->tokSource);
parser = belle_sip_messageParserNew (tokens);
l_parsed_object = parser->header_extension(parser,FALSE,FALSE);
parser ->free(parser);
tokens ->free(tokens);
lex ->free(lex);
input ->close(input);
if (l_parsed_object.ret == NULL) {\
belle_sip_error("Parser error for [%s]",value);\
return NULL;\
} else \
return BELLE_SIP_HEADER_EXTENSION(l_parsed_object.ret);
}
GET_SET_STRING(belle_sip_header_extension,value);
/**************************
*Authorization header object inherent from parameters
......
......@@ -958,4 +958,19 @@ belle_sip_error_code belle_sip_headers_marshal(belle_sip_message_t *message, cha
#include "parserutils.h"
/******************************
*
* private Extension header inherit from header
*
******************************/
typedef struct _belle_sip_header_extension belle_sip_header_extension_t;
belle_sip_header_extension_t* belle_sip_header_extension_new();
belle_sip_header_extension_t* belle_sip_header_extension_parse (const char* extension) ;
belle_sip_header_extension_t* belle_sip_header_extension_create (const char* name,const char* value);
const char* belle_sip_header_extension_get_value(const belle_sip_header_extension_t* extension);
void belle_sip_header_extension_set_value(belle_sip_header_extension_t* extension,const char* value);
#define BELLE_SIP_HEADER_EXTENSION(t) BELLE_SIP_CAST(t,belle_sip_header_extension_t)
#endif
......@@ -45,8 +45,9 @@ options {
#pragma GCC diagnostic ignored "-Wparentheses"
#pragma GCC diagnostic ignored "-Wunused"
#pragma GCC diagnostic ignored "-Wtautological-compare"
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wunused-variable"
#endif
}
@parser::header {
/*
......@@ -69,9 +70,11 @@ options {
#pragma GCC diagnostic ignored "-Wparentheses"
#pragma GCC diagnostic ignored "-Wunused"
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
}
@rulecatch
{
......
This diff is collapsed.
This diff is collapsed.
......@@ -138,7 +138,7 @@ static void https_digest_get(void){
one_get("https://pauline:pouet@smtp.linphone.org/restricted",&counters);
CU_ASSERT_EQUAL(counters.three_hundred,1);
}
#if 0
static void https_client_cert_connection(void){
belle_tls_verify_policy_t *policy=belle_tls_verify_policy_new();
http_counters_t counters={0};
......@@ -149,13 +149,13 @@ static void https_client_cert_connection(void){
belle_tls_verify_policy_set_exceptions(policy,0);
belle_sip_object_unref(policy);
}
#endif
test_t http_tests[] = {
{ "One http GET", one_http_get },
{ "One https GET", one_https_get },
{ "https GET with long body", https_get_long_body },
{ "https digest GET", https_digest_get },
{ "https with client certificate", https_client_cert_connection },
{ "https digest GET", https_digest_get }/*, FIXME, nee a server for testing
{ "https with client certificate", https_client_cert_connection }*/
};
test_suite_t http_test_suite = {
......
......@@ -373,30 +373,33 @@ static void test_content_length_header(void) {
CU_ASSERT_PTR_NULL(belle_sip_header_content_length_parse("nimportequoi"));
}
static void test_header_extension(const char* name,const char* value) {
belle_sip_header_extension_t* L_tmp;
static belle_sip_header_t* test_header_extension(const char* name,const char* value) {
belle_sip_header_t* L_tmp;
char header[256];
char* l_raw_header=NULL;
snprintf(header,sizeof(header),"%s:%s",name,value);
belle_sip_header_extension_t* L_extension;
L_extension = belle_sip_header_extension_parse(header);
belle_sip_header_t* L_extension;
L_extension = belle_sip_header_parse(header);
l_raw_header = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_extension));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_extension));
L_tmp = belle_sip_header_extension_parse(l_raw_header);
L_extension = BELLE_SIP_HEADER_EXTENSION(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
L_tmp = belle_sip_header_parse(l_raw_header);
L_extension = BELLE_SIP_HEADER(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
belle_sip_free(l_raw_header);
CU_ASSERT_STRING_EQUAL(belle_sip_header_extension_get_value(L_extension), value);
belle_sip_object_unref(BELLE_SIP_OBJECT(L_extension));
CU_ASSERT_STRING_EQUAL(belle_sip_header_get_unparsed_value(L_extension), value);
/*FIXME jehan check why missing colon does not lead an exception
CU_ASSERT_PTR_NULL(belle_sip_header_extension_parse("nimportequoi"));*/
return L_extension;
}
static void test_header_extension_1() {
return test_header_extension("toto","titi");
belle_sip_object_unref(test_header_extension("toto","titi"));
}
static void test_header_extension_2() {
return test_header_extension("From","blion");
belle_sip_header_t* header = test_header_extension("From","sip:localhost");
CU_ASSERT_TRUE(BELLE_SIP_OBJECT_IS_INSTANCE_OF(header,belle_sip_header_from_t));
belle_sip_object_unref(header);
}
static void test_authorization_header(void) {
......@@ -795,6 +798,7 @@ static void test_privacy_header() {
test_privacy("Privacy: user; critical",value1,2);
test_privacy("Privacy: id",value2,1);
}
test_t headers_tests[] = {
{ "Address", test_address_header },
{ "Header address (very long)", test_very_long_address_header },
......
......@@ -151,7 +151,7 @@ void belle_sip_tester_uninit(void) {
}
}
int belle_sip_tester_run_tests(const char *suite_name, const char *test_name) {
int i;
int i,ret;
belle_sip_object_pool_t *pool;
/* initialize the CUnit test registry */
......@@ -199,9 +199,9 @@ int belle_sip_tester_run_tests(const char *suite_name, const char *test_name) {
}
belle_sip_object_unref(pool);
ret=CU_get_number_of_tests_failed()!=0;
CU_cleanup_registry();
return CU_get_error();
return ret;
}
......
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