mirror of
git://git.savannah.gnu.org/osip.git
synced 2026-01-12 00:19:45 +08:00
escaping sequence in uri
git-svn-id: svn://svn.savannah.nongnu.org/osip/trunk/osip@74 a617929b-4c5a-41d8-b177-2eda7db2ca6c
This commit is contained in:
25
BUGS
25
BUGS
@@ -1,27 +1,4 @@
|
||||
|
||||
FIXED:
|
||||
BUG2 : 06022002 0.8.1
|
||||
With the new fsm, some messages must be handled without giving
|
||||
them to the state machines. This is the case when receiving more
|
||||
than one 2xx responses. In the case where a 2xx has been received,
|
||||
the rfc says that it's up to the "transaction user" to deal with
|
||||
the message without the use of the transaction layer. This is needed
|
||||
because behavior is different in this case for UA and proxy. (and the
|
||||
state machines are usable by both UA and proxy since 0.8.1!)
|
||||
|
||||
By now, instead of refusing the 2xx messages, and leave it to the
|
||||
"transaction user" layer, the fsm will discard the event without
|
||||
telling the upper layer. This behavior will be fixed to leave
|
||||
the choice of deleting the message up to the user.
|
||||
|
||||
An other important modification in the latest draft of SIP (which
|
||||
has result in a modification of the fsm library) is the handling of
|
||||
ACK. For any response superior to 299, the ACK is completely
|
||||
handled by the fsm. You don't have to build it and send it as it's
|
||||
automated. (both proxy and UA handles those ACK following the same
|
||||
procedures in the latest draft of SIP! That's why...). Nevertheless,
|
||||
you'll have handle 2XX (for INVITE) in the "transaction user" alone:
|
||||
Proxy will forward the 2xx and UA will sends special ACK within the
|
||||
dialog.
|
||||
Yes, some bugs exists... :!
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
libosip (0.8.8)
|
||||
* urls.c: built-in support of escaped sequences in sip-uri!
|
||||
* vxworks minor patches.
|
||||
* nict.c and ict.c: fix a bug with the setting of the port.
|
||||
* fsm/dialog.c: if 1xx answer does not contain the route set, update
|
||||
|
||||
47
INSTALL
47
INSTALL
@@ -1,3 +1,46 @@
|
||||
see README file for installation.
|
||||
|
||||
For Windows, see README file in the ./windows directory.
|
||||
Note that osip is developped on a i386 linux and other architecture
|
||||
might be broken. Reports if one appears broken.
|
||||
|
||||
|
||||
Install process for UNIX. (latest tested 0.8.8)
|
||||
_________________________
|
||||
|
||||
$> tar -xvzf libosip-x.x.x.tar.gz
|
||||
$> mkdir bld-linux
|
||||
$> CFLAGS="-I/usr/local/include/" ../configure
|
||||
$> make
|
||||
$> make install (as root...)
|
||||
|
||||
Install process for Windows. (latest tested 0.8.8)
|
||||
____________________________
|
||||
|
||||
For Windows, see README file in the ./windows directory.
|
||||
Workspace files for VC++ are provided.
|
||||
|
||||
Install process for Cris architecture. (latest tested 0.8.7)
|
||||
______________________________________
|
||||
|
||||
mkdir bld-osip
|
||||
cd bld-osip
|
||||
CC="gcc_cris -mlinux -isystem /ldata/axis/cris-source/axis/devboard_lx/os/linux/include -I/ldata/axis/cris-source/axis/devboard_lx/apps/osip" CPP=
|
||||
"gcc_cris -E -mlinux -isystem /ldata/axis/cris-source/axis/devboard_lx/os/linux/include" LD="ld-cris -mcrisaout" AR="ar-cris" RANLIB="ranlib-cris"
|
||||
NM="nm-cris" ../osip/configure --prefix=/ldata/axis/cris-source/axis/devboard_lx/target/cris-axis-linux-gnu/usr/local
|
||||
make
|
||||
|
||||
see www.axis.com for more info on the ETRAX 100LX module.
|
||||
|
||||
Install process for VxWorks. (latest tested 0.8.8)
|
||||
____________________________
|
||||
|
||||
From a tornado user:
|
||||
|
||||
I built them in tornado GUI, and just test them in the simulate.
|
||||
1. Create a bootable vxworks image project.
|
||||
2. Add all files in the new project.
|
||||
3. Include the networks componets.
|
||||
4. Add the compiler parameter as follows:
|
||||
-D__VXWORKS_OS__ -DTHREAD_PTHREAD -D_REENTRANT -DOSIP_MT
|
||||
-DHAVE_SIGNAL_H -DENABLE_DEBUG -DENABLE_TRACE -DSHOW_MESSAGE
|
||||
|
||||
and play!
|
||||
@@ -86,5 +86,22 @@ sip:j.doe@big.com;to[to?r+s=foo:&.bar;qsdr$/def
|
||||
sip:j.d;oe:secret?@big.com;to[to?r+s=foo:&.bar;qsdr$/def
|
||||
#
|
||||
# this url lacks a value for its header_param!!
|
||||
#
|
||||
sip:j.+d$=o\?;e:secr&=+$,@big.com;to[to?r+s=foo:&.bar;qsdr$/def
|
||||
#
|
||||
#
|
||||
# test allowed values in the userinfo part of url.
|
||||
#
|
||||
sip:abcdefghijklmnopqurstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.!~*'()&=+$,;?/reserved%3A%40@big.com;
|
||||
|
||||
#
|
||||
# test allowed values in the password part of url.
|
||||
#
|
||||
sip:ab:jack%3B%3F%2F-_.!~*'()[]/:&+$;/?:@&=+$@big.com;
|
||||
#
|
||||
# test allowed values in the uri-parameter part of url.
|
||||
#
|
||||
sip:ab@big.com;ab-_.!~*'()[]/:&+$-_.!~*'()=ab-_.!~*'()[]/:&+$-_.!~*'(); cd-_.!~*'()[]/:&+$-_.!~*'()=cd-_.!~*'()[]/:&+$-_.!~*'()
|
||||
#
|
||||
# test allowed values in the header-parameter part of url.
|
||||
#
|
||||
sip:ab@big.com?ab-_.!~*'()[]/?:+$=-_.!~*'()[]/?:+$&-_.!~*'()[]/?:+$%26%3D%2C%3B?/= -_.!~*'()[]/?:+$%26%3D+$%2C%3B?/
|
||||
|
||||
@@ -419,6 +419,14 @@ char* url_getport(url_t *url);
|
||||
#ifndef DOXYGEN
|
||||
/* internal method */
|
||||
char *next_separator(char *ch, int separator_to_find, int before_separator);
|
||||
|
||||
char *url_escape_nonascii_and_nondef(const char *string, const char *def);
|
||||
char *url_escape_userinfo(const char *string);
|
||||
char *url_escape_password(const char *string);
|
||||
char *url_escape_uri_param(char *string);
|
||||
char *url_escape_header_param(char *string);
|
||||
void url_unescape(char *string);
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
157
parser/urls.c
157
parser/urls.c
@@ -167,10 +167,14 @@ url_parse(url_t *url, char *buf)
|
||||
if (host-password<2) return -1;
|
||||
url->password = (char *) smalloc(host-password);
|
||||
sstrncpy(url->password, password+1, host-password-1);
|
||||
url_unescape(url->password);
|
||||
}
|
||||
if (password-username<2) return -1;
|
||||
url->username = (char *) smalloc(password-username);
|
||||
sstrncpy(url->username, username+1, password-username-1);
|
||||
{
|
||||
url->username = (char *) smalloc(password-username);
|
||||
sstrncpy(url->username, username+1, password-username-1);
|
||||
url_unescape(url->username);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -322,18 +326,21 @@ url_parse_headers (url_t *url, char *headers)
|
||||
|
||||
hname = (char *) smalloc(equal-headers);
|
||||
sstrncpy(hname, headers+1, equal-headers-1);
|
||||
url_unescape(hname);
|
||||
|
||||
if (and!=NULL)
|
||||
{
|
||||
if (and-equal<2) { sfree(hname); return -1; }
|
||||
hvalue = (char *) smalloc(and-equal);
|
||||
sstrncpy(hvalue, equal+1, and-equal-1);
|
||||
url_unescape(hvalue);
|
||||
}
|
||||
else
|
||||
{ /* this is for the last header (no and...) */
|
||||
if (headers+strlen(headers)-equal+1 <2) { sfree(hname);return -1; }
|
||||
hvalue = (char *) smalloc(headers + strlen(headers)-equal +1);
|
||||
sstrncpy(hvalue, equal+1, headers + strlen(headers)-equal);
|
||||
url_unescape(hvalue);
|
||||
}
|
||||
|
||||
url_uheader_add (url, hname, hvalue);
|
||||
@@ -378,11 +385,13 @@ url_parse_params (url_t *url, char *params)
|
||||
if (comma-equal<2) return -1;
|
||||
pvalue = (char *) smalloc(comma-equal);
|
||||
sstrncpy(pvalue, equal+1, comma-equal-1);
|
||||
url_unescape(pvalue);
|
||||
}
|
||||
|
||||
if (equal-params<2) { sfree(pvalue); return -1; }
|
||||
pname = (char *) smalloc(equal-params);
|
||||
sstrncpy(pname, params+1, equal-params-1);
|
||||
url_unescape(pname);
|
||||
|
||||
url_uparam_add (url, pname, pvalue);
|
||||
|
||||
@@ -441,12 +450,16 @@ url_2char(url_t *url, char **dest) {
|
||||
|
||||
if (url->username!=NULL)
|
||||
{
|
||||
sprintf(buf,"%s",url->username);
|
||||
char *tmp = url_escape_userinfo(url->username);
|
||||
sprintf(buf,"%s",tmp);
|
||||
sfree(tmp);
|
||||
buf = buf + strlen(buf);
|
||||
}
|
||||
if ((url->password!=NULL)&&(url->username!=NULL))
|
||||
{ /* be sure that when a password is given, a username is also given */
|
||||
sprintf(buf,":%s",url->password);
|
||||
char *tmp = url_escape_password(url->password);
|
||||
sprintf(buf,":%s",tmp);
|
||||
sfree(tmp);
|
||||
buf = buf + strlen(buf);
|
||||
}
|
||||
if (url->username!=NULL)
|
||||
@@ -475,11 +488,18 @@ url_2char(url_t *url, char **dest) {
|
||||
url_param_t *u_param;
|
||||
while (!list_eol(url->url_params,pos))
|
||||
{
|
||||
char *tmp;
|
||||
u_param = (url_param_t *)list_get(url->url_params,pos);
|
||||
tmp = url_escape_uri_param(u_param->gname);
|
||||
if (u_param->gvalue!=NULL)
|
||||
sprintf(buf,";%s=%s",u_param->gname,u_param->gvalue);
|
||||
{
|
||||
char *tmp2 = url_escape_uri_param(u_param->gvalue);
|
||||
sprintf(buf,";%s=%s", tmp, tmp2);
|
||||
sfree(tmp2);
|
||||
}
|
||||
else
|
||||
sprintf(buf,";%s",u_param->gname);
|
||||
sprintf(buf,";%s",tmp);
|
||||
sfree(tmp);
|
||||
buf = buf + strlen(buf);
|
||||
pos++;
|
||||
}
|
||||
@@ -490,11 +510,19 @@ url_2char(url_t *url, char **dest) {
|
||||
url_header_t *u_header;
|
||||
while (!list_eol(url->url_headers,pos))
|
||||
{
|
||||
char *tmp;
|
||||
char *tmp2;
|
||||
u_header = (url_header_t *)list_get(url->url_headers,pos);
|
||||
tmp = url_escape_header_param(u_header->gname);
|
||||
tmp2 = url_escape_header_param(u_header->gvalue);
|
||||
if (pos==0)
|
||||
sprintf(buf,"?%s=%s",u_header->gname,u_header->gvalue);
|
||||
{
|
||||
sprintf(buf,"?%s=%s",u_header->gname,u_header->gvalue);
|
||||
}
|
||||
else
|
||||
sprintf(buf,"&%s=%s",u_header->gname,u_header->gvalue);
|
||||
sfree(tmp);
|
||||
sfree(tmp2);
|
||||
buf = buf + strlen(buf);
|
||||
pos++;
|
||||
}
|
||||
@@ -705,3 +733,118 @@ url_param_clone(url_param_t *uparam, url_param_t **dest)
|
||||
*dest = up;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define _ALPHANUM_ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890\0"
|
||||
#define _RESERVED_ ";/?:@&=+$\0"
|
||||
#define _MARK_ "-_.!~*'()\0"
|
||||
|
||||
#define _MARK__USER_UNRESERVED_ "-_.!~*'()&=+$,;?/\0"
|
||||
#define _MARK__PWORD_UNRESERVED_ "-_.!~*'()&=+$,\0"
|
||||
#define _MARK__URI_PARAM_UNRESERVED_ "-_.!~*'()[]/:&+$\0"
|
||||
#define _MARK__HEADER_PARAM_UNRESERVED_ "-_.!~*'()[]/?:+$\0"
|
||||
|
||||
#define osip_is_alphanum(in) ( \
|
||||
(in >= 'a' && in <= 'z') || \
|
||||
(in >= 'A' && in <= 'Z') || \
|
||||
(in >= '0' && in <= '9'))
|
||||
|
||||
char *url_escape_nonascii_and_nondef(const char *string, const char *def)
|
||||
{
|
||||
int alloc = strlen(string)+1;
|
||||
int length;
|
||||
char *ns = smalloc(alloc);
|
||||
unsigned char in;
|
||||
int newlen = alloc;
|
||||
int index=0;
|
||||
const char *tmp;
|
||||
int i;
|
||||
|
||||
length = alloc-1;
|
||||
while(length--) {
|
||||
in = *string;
|
||||
|
||||
i = 0;
|
||||
tmp = NULL;
|
||||
if (osip_is_alphanum(in))
|
||||
tmp = string;
|
||||
else
|
||||
{
|
||||
for (; def[i]!='\0' && def[i]!=in ; i++)
|
||||
{ }
|
||||
if(def[i]!='\0')
|
||||
tmp = string;
|
||||
}
|
||||
if(tmp==NULL) {
|
||||
/* encode it */
|
||||
newlen += 2; /* the size grows with two, since this'll become a %XX */
|
||||
if(newlen > alloc) {
|
||||
alloc *= 2;
|
||||
ns = realloc(ns, alloc);
|
||||
if(!ns)
|
||||
return NULL;
|
||||
}
|
||||
sprintf(&ns[index], "%%%02X", in);
|
||||
index+=3;
|
||||
}
|
||||
else {
|
||||
/* just copy this */
|
||||
ns[index++]=in;
|
||||
}
|
||||
string++;
|
||||
}
|
||||
ns[index]=0; /* terminate it */
|
||||
return ns;
|
||||
}
|
||||
|
||||
/* user = *( unreserved / escaped / user-unreserved ) */
|
||||
const char *userinfo_def = /* implied _ALPHANUM_ */ _MARK__USER_UNRESERVED_ ;
|
||||
char *url_escape_userinfo(const char *string)
|
||||
{
|
||||
return url_escape_nonascii_and_nondef(string, userinfo_def);
|
||||
}
|
||||
|
||||
/* user = *( unreserved / escaped / user-unreserved ) */
|
||||
const char *password_def = _MARK__PWORD_UNRESERVED_ ;
|
||||
char *url_escape_password(const char *string)
|
||||
{
|
||||
return url_escape_nonascii_and_nondef(string, password_def);
|
||||
}
|
||||
|
||||
const char *uri_param_def = _MARK__URI_PARAM_UNRESERVED_;
|
||||
char *url_escape_uri_param(char *string)
|
||||
{
|
||||
return url_escape_nonascii_and_nondef(string, uri_param_def);
|
||||
}
|
||||
|
||||
const char *header_param_def = _MARK__HEADER_PARAM_UNRESERVED_;
|
||||
char *url_escape_header_param(char *string)
|
||||
{
|
||||
return url_escape_nonascii_and_nondef(string, header_param_def);
|
||||
}
|
||||
|
||||
void url_unescape(char *string)
|
||||
{
|
||||
int alloc = strlen(string)+1;
|
||||
unsigned char in;
|
||||
int index=0;
|
||||
unsigned int hex;
|
||||
char *ptr;
|
||||
|
||||
ptr = string;
|
||||
while(--alloc > 0) {
|
||||
in = *ptr;
|
||||
if('%' == in) {
|
||||
/* encoded part */
|
||||
if(sscanf(ptr+1, "%02X", &hex)) {
|
||||
in = hex;
|
||||
ptr+=2;
|
||||
alloc-=2;
|
||||
}
|
||||
}
|
||||
|
||||
string[index++] = in;
|
||||
ptr++;
|
||||
}
|
||||
string[index]=0; /* terminate it */
|
||||
}
|
||||
|
||||
@@ -95,7 +95,11 @@ url_test_accessor_api(url_t *url)
|
||||
return 0;
|
||||
}
|
||||
if (url->username!=NULL)
|
||||
fprintf(stdout,"%s|",url->username);
|
||||
{
|
||||
char *tmp;
|
||||
fprintf(stdout,"%s|",url->username);
|
||||
}
|
||||
|
||||
if ((url->password!=NULL)&&(url->username!=NULL))
|
||||
fprintf(stdout,":%s|",url->password);
|
||||
if (url->username!=NULL)
|
||||
|
||||
Reference in New Issue
Block a user