📄 urls.c
字号:
/* The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) Copyright (C) 2001,2002,2003 Aymeric MOIZARD jack@atosc.org This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include <osip/port.h>#include <osip/smsg.h>#include <stdlib.h>#include <stdio.h>/* allocate a new url structure *//* OUTPUT: url_t *url | structure to save results. *//* OUTPUT: err_t *err | structure to store error. *//* return -1 on error */inturl_init (url_t ** url){ *url = (url_t *) smalloc (sizeof (url_t)); if (*url == NULL) return -1; (*url)->scheme = NULL; (*url)->username = NULL; (*url)->password = NULL; (*url)->host = NULL; (*url)->port = NULL; (*url)->url_params = (list_t *) smalloc (sizeof (list_t)); if ((*url)->url_params == NULL) { sfree (*url); *url = NULL; return -1; } list_init ((*url)->url_params); (*url)->url_headers = (list_t *) smalloc (sizeof (list_t)); if ((*url)->url_headers == NULL) { sfree ((*url)->url_params); sfree (*url); *url = NULL; return -1; } list_init ((*url)->url_headers); (*url)->string = NULL; return 0;}/* examples: sip:j.doe@big.com;maddr=239.255.255.1;ttl=15 sip:j.doe@big.com sip:j.doe:secret@big.com;transport=tcp sip:j.doe@big.com?subject=project sip:+1-212-555-1212:1234@gateway.com;user=phone sip:1212@gateway.com sip:alice@10.1.2.3 sip:alice@example.com sip:alice@registrar.com;method=REGISTER NOT EQUIVALENT: SIP:JUSER@ExAmPlE.CoM;Transport=udp sip:juser@ExAmPlE.CoM;Transport=UDP*//* this method search for the separator and *//* return it only if it is located before the *//* second separator. */char *next_separator (char *ch, int separator_to_find, int before_separator){ char *ind; char *tmp; ind = strchr (ch, separator_to_find); if (ind == NULL) return NULL; tmp = NULL; if (before_separator != 0) tmp = strchr (ch, before_separator); if (tmp != NULL) { if (ind < tmp) return ind; } else return ind; return NULL;}/* parse the sip url. *//* INPUT : char *buf | url to be parsed.*//* OUTPUT: url_t *url | structure to save results. *//* OUTPUT: err_t *err | structure to store error. *//* return -1 on error */inturl_parse (url_t * url, char *buf){ char *username; char *password; char *host; char *port; char *params; char *headers; char *tmp; /* basic tests */ if (buf == NULL) return -1; tmp = strchr (buf, ':'); if (tmp == NULL) return -1; if (tmp - buf < 2) return -1; url->scheme = (char *) smalloc (tmp - buf + 1); if (url->scheme == NULL) return -1; sstrncpy (url->scheme, buf, tmp - buf);#if (!defined WIN32 && !defined _WIN32_WCE) if (strlen (url->scheme) < 3 || (0 != strncasecmp (url->scheme, "sip", 3) && 0 != strncasecmp (url->scheme, "sips", 4))) { /* Is not a sipurl ! */ int i = strlen (tmp + 1); if (i < 2) return -1; url->string = (char *) smalloc (i + 1); if (url->string == NULL) return -1; sstrncpy (url->string, tmp + 1, i); return 0; }#else if (strlen (url->scheme) < 3 || (0 != _strnicmp (url->scheme, "sip", 3) && 0 != _strnicmp (url->scheme, "sips", 4))) { /* Is not a sipurl ! */ int i = strlen (tmp + 1); if (i < 2) return -1; url->string = (char *) smalloc (i + 1); if (url->string == NULL) return -1; sstrncpy (url->string, tmp + 1, i); return 0; }#endif /* law number 1: if ('?' exists && is_located_after '@') or if ('?' exists && '@' is not there -no username-) =====> HEADER_PARAM EXIST =====> start at index(?) =====> end at the end of url */ /* find the beginning of host */ username = strchr (buf, ':'); /* if ':' does not exist, the url is not valid */ if (username == NULL) return -1; host = strchr (buf, '@'); if (host == NULL) host = username; else /* username exists */ { password = next_separator (username + 1, ':', '@'); if (password == NULL) password = host; else /* password exists */ { if (host - password < 2) return -1; url->password = (char *) smalloc (host - password); if (url->password == NULL) return -1; sstrncpy (url->password, password + 1, host - password - 1); url_unescape (url->password); } if (password - username < 2) return -1; { url->username = (char *) smalloc (password - username); if (url->username == NULL) return -1; sstrncpy (url->username, username + 1, password - username - 1); url_unescape (url->username); } } /* search for header after host */ headers = strchr (host, '?'); if (headers == NULL) headers = buf + strlen (buf); else /* headers exist */ url_parse_headers (url, headers); /* search for params after host */ params = strchr (host, ';'); /* search for params after host */ if (params == NULL) params = headers; else /* params exist */ { if (headers - params + 1 < 2) return -1; tmp = smalloc (headers - params + 1); if (tmp == NULL) return -1; tmp = sstrncpy (tmp, params, headers - params); url_parse_params (url, tmp); sfree (tmp); } port = params - 1; while (port > host && *port != ']' && *port != ':') port--; if (*port == ':') { if (host == port) port = params; else { if ((params - port < 2) || (params - port > 8)) return -1; /* error cases */ url->port = (char *) smalloc (params - port); if (url->port == NULL) return -1; sstrncpy (url->port, port + 1, params - port - 1); sclrspace (url->port); } } else port = params; /* adjust port for ipv6 address */ tmp = port; while (tmp > host && *tmp != ']') tmp--; if (*tmp == ']') { port = tmp; while (host < port && *host != '[') host++; if (host >= port) return -1; } if (port - host < 2) return -1; url->host = (char *) smalloc (port - host); if (url->host == NULL) return -1; sstrncpy (url->host, host + 1, port - host - 1); sclrspace (url->host); return 0;}voidurl_setscheme (url_t * url, char *scheme){ url->scheme = scheme;}char *url_getscheme (url_t * url){ if (url == NULL) return NULL; return url->scheme;}voidurl_setusername (url_t * url, char *username){ url->username = username;}char *url_getusername (url_t * url){ if (url == NULL) return NULL; return url->username;}voidurl_setpassword (url_t * url, char *password){ url->password = password;}char *url_getpassword (url_t * url){ if (url == NULL) return NULL; return url->password;}voidurl_sethost (url_t * url, char *host){ url->host = host;}char *url_gethost (url_t * url){ if (url == NULL) return NULL; return url->host;}voidurl_setport (url_t * url, char *port){ url->port = port;}char *url_getport (url_t * url){ if (url == NULL) return NULL; return url->port;}inturl_parse_headers (url_t * url, char *headers){ char *and; char *equal; /* find '=' wich is the separator for one header */ /* find ';' wich is the separator for multiple headers */ equal = strchr (headers, '='); and = strchr (headers + 1, '&'); if (equal == NULL) /* each header MUST have a value */ return -1; do { char *hname; char *hvalue; hname = (char *) smalloc (equal - headers); if (hname == NULL) return -1; 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); if (hvalue == NULL) { sfree (hname); return -1; } 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); if (hvalue == NULL) { sfree (hname); return -1; } sstrncpy (hvalue, equal + 1, headers + strlen (headers) - equal); url_unescape (hvalue); } url_uheader_add (url, hname, hvalue); if (and == NULL) /* we just set the last header */ equal = NULL; else /* continue on next header */ { headers = and; equal = strchr (headers, '='); and = strchr (headers + 1, '&'); if (equal == NULL) /* each header MUST have a value */ return -1; } } while (equal != NULL); return 0;}inturl_parse_params (url_t * url, char *params){ char *pname; char *pvalue; char *comma; char *equal; /* find '=' wich is the separator for one param */ /* find ';' wich is the separator for multiple params */ equal = next_separator (params + 1, '=', ';'); comma = strchr (params + 1, ';'); while (comma != NULL) { if (equal == NULL) { equal = comma; pvalue = NULL; } else { if (comma - equal < 2) return -1; pvalue = (char *) smalloc (comma - equal); if (pvalue == NULL) return -1; sstrncpy (pvalue, equal + 1, comma - equal - 1); url_unescape (pvalue); } if (equal - params < 2) { sfree (pvalue); return -1; } pname = (char *) smalloc (equal - params); if (pname == NULL) { sfree (pvalue); return -1; } sstrncpy (pname, params + 1, equal - params - 1); url_unescape (pname); url_uparam_add (url, pname, pvalue); params = comma; equal = next_separator (params + 1, '=', ';'); comma = strchr (params + 1, ';'); } /* this is the last header (comma==NULL) */ comma = params + strlen (params); if (equal == NULL) { equal = comma; /* at the end */ pvalue = NULL; } else { if (comma - equal < 2) return -1; pvalue = (char *) smalloc (comma - equal); if (pvalue == NULL) return -1; sstrncpy (pvalue, equal + 1, comma - equal - 1); } if (equal - params < 2) { sfree (pvalue); return -1; } pname = (char *) smalloc (equal - params); if (pname == NULL) { sfree (pvalue); return -1; } sstrncpy (pname, params + 1, equal - params - 1); url_uparam_add (url, pname, pvalue); return 0;}inturl_2char (url_t * url, char **dest){ char *buf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -