diff options
author | Benny Prijono <bennylp@teluu.com> | 2008-08-05 19:28:17 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2008-08-05 19:28:17 +0000 |
commit | c99d9cd5ab9be3bce89f84a54abbe87348529a2e (patch) | |
tree | 88dbefe829e108bc75b672b584d022959cb76081 /pjsip/src | |
parent | 0b4ecc3c596af2032c986107d7c9b8f671e277fa (diff) |
Implement ticket #551: Generic URI scheme handler (thanks Juri Glaß for the patch)
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2193 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src')
-rw-r--r-- | pjsip/src/pjsip/sip_parser.c | 41 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_uri.c | 93 |
2 files changed, 133 insertions, 1 deletions
diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c index e4d2c0d2..644ad843 100644 --- a/pjsip/src/pjsip/sip_parser.c +++ b/pjsip/src/pjsip/sip_parser.c @@ -48,6 +48,11 @@ #define HNV_UNRESERVED "[]/?:+$" #define HDR_CHAR HNV_UNRESERVED UNRESERVED ESCAPED +/* A generic URI can consist of (For a complete BNF see RFC 2396): + #?;:@&=+-_.!~*'()%$,/ + */ +#define GENERIC_URI_CHARS "#?;:@&=+-_.!~*'()%$,/" "%" + #define PJSIP_VERSION "SIP/2.0" #define UNREACHED(expr) @@ -152,6 +157,9 @@ static void* int_parse_sip_url( pj_scanner *scanner, static pjsip_name_addr * int_parse_name_addr( pj_scanner *scanner, pj_pool_t *pool ); +static void* int_parse_other_uri(pj_scanner *scanner, + pj_pool_t *pool, + pj_bool_t parse_params); static void parse_hdr_end( pj_scanner *scanner ); static pjsip_hdr* parse_hdr_accept( pjsip_parse_ctx *ctx ); @@ -376,6 +384,10 @@ static pj_status_t init_parser() pj_cis_add_str( &pconst.pjsip_DISPLAY_SPEC, ":\r\n<"); pj_cis_invert(&pconst.pjsip_DISPLAY_SPEC); + status = pj_cis_dup(&pconst.pjsip_OTHER_URI_CONTENT, &pconst.pjsip_ALNUM_SPEC); + PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); + pj_cis_add_str( &pconst.pjsip_OTHER_URI_CONTENT, GENERIC_URI_CHARS); + /* * Register URI parsers. */ @@ -690,7 +702,7 @@ static pjsip_parse_uri_func* find_uri_handler(const pj_str_t *scheme) if (parser_stricmp(uri_handler[i].scheme, (*scheme))==0) return uri_handler[i].parse; } - return NULL; + return &int_parse_other_uri; } /* Register URI parser. */ @@ -1463,6 +1475,33 @@ static pjsip_name_addr *int_parse_name_addr( pj_scanner *scanner, } +/* Parse other URI */ +static void* int_parse_other_uri(pj_scanner *scanner, + pj_pool_t *pool, + pj_bool_t parse_params) +{ + pjsip_other_uri *uri = 0; + const pjsip_parser_const_t *pc = pjsip_parser_const(); + int skip_ws = scanner->skip_ws; + + PJ_UNUSED_ARG(parse_params); + + scanner->skip_ws = 0; + + uri = pjsip_other_uri_create(pool); + + pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &uri->scheme); + if (pj_scan_get_char(scanner) != ':') { + PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); + } + + pj_scan_get(scanner, &pc->pjsip_OTHER_URI_CONTENT, &uri->content); + scanner->skip_ws = skip_ws; + + return uri; +} + + /* Parse SIP request line. */ static void int_parse_req_line( pj_scanner *scanner, pj_pool_t *pool, pjsip_request_line *req_line) diff --git a/pjsip/src/pjsip/sip_uri.c b/pjsip/src/pjsip/sip_uri.c index b066dc66..c5bb2c5d 100644 --- a/pjsip/src/pjsip/sip_uri.c +++ b/pjsip/src/pjsip/sip_uri.c @@ -617,3 +617,96 @@ static int pjsip_name_addr_compare( pjsip_uri_context_e context, return 0; } +/////////////////////////////////////////////////////////////////////////////// + +static const pj_str_t *other_uri_get_scheme( const pjsip_other_uri*); +static void *other_uri_get_uri( pjsip_other_uri*); +static pj_ssize_t other_uri_print( pjsip_uri_context_e context, + const pjsip_other_uri *url, + char *buf, pj_size_t size); +static int other_uri_cmp( pjsip_uri_context_e context, + const pjsip_other_uri *url1, + const pjsip_other_uri *url2); +static pjsip_other_uri* other_uri_clone( pj_pool_t *pool, + const pjsip_other_uri *rhs); + +static pjsip_uri_vptr other_uri_vptr = +{ + (P_GET_SCHEME) &other_uri_get_scheme, + (P_GET_URI) &other_uri_get_uri, + (P_PRINT_URI) &other_uri_print, + (P_CMP_URI) &other_uri_cmp, + (P_CLONE) &other_uri_clone +}; + + +PJ_DEF(pjsip_other_uri*) pjsip_other_uri_create(pj_pool_t *pool) +{ + pjsip_other_uri *uri = PJ_POOL_ZALLOC_T(pool, pjsip_other_uri); + uri->vptr = &other_uri_vptr; + return uri; +} + +static const pj_str_t *other_uri_get_scheme( const pjsip_other_uri *uri ) +{ + return &uri->scheme; +} + +static void *other_uri_get_uri( pjsip_other_uri *uri ) +{ + return uri; +} + +static pj_ssize_t other_uri_print(pjsip_uri_context_e context, + const pjsip_other_uri *uri, + char *buf, pj_size_t size) +{ + char *startbuf = buf; + char *endbuf = buf + size; + + PJ_UNUSED_ARG(context); + + if (uri->scheme.slen + uri->content.slen + 1 > (int)size) + return -1; + + /* Print scheme. */ + copy_advance(buf, uri->scheme); + *buf++ = ':'; + + /* Print content. */ + copy_advance(buf, uri->content); + + return (buf - startbuf); +} + +static int other_uri_cmp(pjsip_uri_context_e context, + const pjsip_other_uri *uri1, + const pjsip_other_uri *uri2) +{ + PJ_UNUSED_ARG(context); + + /* Scheme must match. */ + if (pj_stricmp(&uri1->scheme, &uri2->scheme) != 0) { + return PJSIP_ECMPSCHEME; + } + + /* Content must match. */ + if(pj_stricmp(&uri1->content, &uri2->content) != 0) { + return -1; + } + + /* Equal. */ + return 0; +} + +/* Clone *: URI */ +static pjsip_other_uri* other_uri_clone(pj_pool_t *pool, + const pjsip_other_uri *rhs) +{ + pjsip_other_uri *uri = pjsip_other_uri_create(pool); + pj_strdup(pool, &uri->scheme, &rhs->scheme); + pj_strdup(pool, &uri->content, &rhs->content); + + return uri; +} + |