contact_ops.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. /*
  2. * $Id$
  3. *
  4. * mangler module
  5. *
  6. * Copyright (C) 2001-2003 FhG Fokus
  7. *
  8. * This file is part of SIP-router, a free SIP server.
  9. *
  10. * SIP-router is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version
  14. *
  15. * SIP-router is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * History:
  25. * --------
  26. * 2003-04-07 first version.
  27. */
  28. /*!
  29. * \file
  30. * \brief SIP-utils :: Mangler module
  31. * \ingroup siputils
  32. * - Module; \ref siputils
  33. */
  34. #define STRICT_CHECK 1
  35. #include "contact_ops.h"
  36. #include "utils.h"
  37. #include "../../mem/mem.h"
  38. #include "../../data_lump.h"
  39. #include "../../parser/hf.h"
  40. #include "../../parser/parse_uri.h"
  41. #include "../../parser/contact/parse_contact.h"
  42. #include "../../ut.h"
  43. #include <stdio.h>
  44. #include <string.h>
  45. //#define DEBUG
  46. int
  47. encode_contact (struct sip_msg *msg, char *encoding_prefix,char *public_ip)
  48. {
  49. contact_body_t *cb;
  50. contact_t *c;
  51. str uri;
  52. str newUri;
  53. int res;
  54. char separator;
  55. /*
  56. * I have a list of contacts in contact->parsed which is of type contact_body_t
  57. * inside i have a contact->parsed->contact which is the head of the list of contacts
  58. * inside it is a
  59. * str uri;
  60. * struct contact *next;
  61. * I just have to visit each uri and encode each uri according to a scheme
  62. */
  63. if ((msg->contact == NULL)&&((parse_headers(msg,HDR_CONTACT_F,0) == -1) ||
  64. (msg->contact == NULL) ))
  65. {
  66. LM_ERR("no Contact header present\n");
  67. return -1;
  68. }
  69. separator = DEFAULT_SEPARATOR[0];
  70. if (contact_flds_separator != NULL)
  71. if (strlen(contact_flds_separator)>=1)
  72. separator = contact_flds_separator[0];
  73. if (msg->contact->parsed == NULL) parse_contact (msg->contact);
  74. if (msg->contact->parsed != NULL)
  75. {
  76. cb = (contact_body_t *) msg->contact->parsed;
  77. c = cb->contacts;
  78. /* we visit each contact */
  79. if (c != NULL)
  80. {
  81. uri = c->uri;
  82. res = encode_uri (uri, encoding_prefix, public_ip,separator, &newUri);
  83. if (res != 0)
  84. {
  85. LM_ERR("failed encoding contact.Code %d\n", res);
  86. #ifdef STRICT_CHECK
  87. return res;
  88. #endif
  89. }
  90. else
  91. if (patch (msg, uri.s, uri.len, newUri.s, newUri.len) < 0)
  92. {
  93. LM_ERR("lumping failed in mangling port \n");
  94. return -2;
  95. }
  96. /* encoding next contacts too?*/
  97. #ifdef ENCODE_ALL_CONTACTS
  98. while (c->next != NULL)
  99. {
  100. c = c->next;
  101. uri = c->uri;
  102. res = encode_uri (uri, encoding_prefix,public_ip,separator,&newUri);
  103. if (res != 0)
  104. {
  105. LM_ERR("failed encode_uri.Code %d\n",res);
  106. #ifdef STRICT_CHECK
  107. return res;
  108. #endif
  109. }
  110. else
  111. if (patch (msg, uri.s, uri.len, newUri.s, newUri.len)< 0)
  112. {
  113. LM_ERR("lumping failed in mangling port \n");
  114. return -3;
  115. }
  116. } /* while */
  117. #endif /* ENCODE_ALL_CONTACTS */
  118. } /* if c != NULL */
  119. } /* end if */
  120. else /* after parsing still NULL */
  121. {
  122. LM_ERR("unable to parse Contact header\n");
  123. return -4;
  124. }
  125. return 1;
  126. }
  127. int
  128. decode_contact (struct sip_msg *msg,char *unused1,char *unused2)
  129. {
  130. str uri;
  131. str newUri;
  132. char separator;
  133. int res;
  134. uri.s = 0;
  135. uri.len = 0;
  136. #ifdef DEBUG
  137. fprintf (stdout,"---START--------DECODE CONTACT-----------------\n");
  138. fprintf (stdout,"%.*s\n",50,msg->buf);
  139. fprintf (stdout, "INITIAL.s=[%.*s]\n", uri.len, uri.s);
  140. #endif
  141. separator = DEFAULT_SEPARATOR[0];
  142. if (contact_flds_separator != NULL)
  143. if (strlen(contact_flds_separator)>=1)
  144. separator = contact_flds_separator[0];
  145. if ((msg->new_uri.s == NULL) || (msg->new_uri.len == 0))
  146. {
  147. uri = msg->first_line.u.request.uri;
  148. if (uri.s == NULL)
  149. return -1;
  150. }
  151. else
  152. {
  153. uri = msg->new_uri;
  154. }
  155. res = decode_uri (uri, separator, &newUri);
  156. #ifdef DEBUG
  157. if (res == 0)
  158. fprintf (stdout, "newuri.s=[%.*s]\n", newUri.len, newUri.s);
  159. #endif
  160. if (res != 0)
  161. {
  162. LM_ERR("failed decoding contact.Code %d\n", res);
  163. #ifdef STRICT_CHECK
  164. return res;
  165. #endif
  166. }
  167. else
  168. {
  169. /* we do not modify the original first line */
  170. if ((msg->new_uri.s == NULL) || (msg->new_uri.len == 0))
  171. msg->new_uri = newUri;
  172. else
  173. {
  174. pkg_free(msg->new_uri.s);
  175. msg->new_uri = newUri;
  176. }
  177. }
  178. return 1;
  179. }
  180. int
  181. decode_contact_header (struct sip_msg *msg,char *unused1,char *unused2)
  182. {
  183. contact_body_t *cb;
  184. contact_t *c;
  185. str uri;
  186. str newUri;
  187. char separator;
  188. int res;
  189. #ifdef DEBUG
  190. str* ruri;
  191. fprintf (stdout,"---START--------DECODE CONTACT HEADER-----------------\n");
  192. #endif
  193. if ((msg->contact == NULL)&&((parse_headers(msg,HDR_CONTACT_F,0) == -1) ||
  194. (msg->contact== NULL) ))
  195. {
  196. LM_ERR("no Contact header present\n");
  197. return -1;
  198. }
  199. separator = DEFAULT_SEPARATOR[0];
  200. if (contact_flds_separator != NULL)
  201. if (strlen(contact_flds_separator)>=1)
  202. separator = contact_flds_separator[0];
  203. #ifdef DEBUG
  204. fprintf (stdout,"Using separator %c\n",separator);
  205. ruri = GET_RURI(msg);
  206. fprintf (stdout,"[len = %d]New uri is->%.*s\n",
  207. ruri->len,ruri->len,ruri->s);
  208. ruri = &msg->first_line.u.request.uri;
  209. fprintf (stdout, "INITIAL.s=[%.*s]\n", ruri->len, ruri->s);
  210. #endif
  211. if (msg->contact->parsed == NULL) parse_contact (msg->contact);
  212. if (msg->contact->parsed != NULL)
  213. {
  214. cb = (contact_body_t *) msg->contact->parsed;
  215. c = cb->contacts;
  216. // we visit each contact
  217. if (c != NULL)
  218. {
  219. uri = c->uri;
  220. res = decode_uri (uri, separator, &newUri);
  221. #ifdef DEBUG
  222. fprintf (stdout, "newuri.s=[%.*s]\n", newUri.len, newUri.s);
  223. #endif
  224. if (res != 0)
  225. {
  226. LM_ERR("failed decoding contact.Code %d\n", res);
  227. #ifdef STRICT_CHECK
  228. return res;
  229. #endif
  230. }
  231. else
  232. if (patch (msg, uri.s, uri.len, newUri.s, newUri.len) < 0)
  233. {
  234. LM_ERR("lumping failed in mangling port \n");
  235. return -2;
  236. }
  237. #ifdef DECODE_ALL_CONTACTS
  238. while (c->next != NULL)
  239. {
  240. c = c->next;
  241. uri = c->uri;
  242. res = decode_uri (uri, separator, &newUri);
  243. if (res != 0)
  244. {
  245. LM_ERR("failed decoding contact.Code %d\n",res);
  246. #ifdef STRICT_CHECK
  247. return res;
  248. #endif
  249. }
  250. else
  251. if (patch (msg, uri.s, uri.len, newUri.s, newUri.len) < 0)
  252. {
  253. LM_ERR("lumping failed in mangling port \n");
  254. return -3;
  255. }
  256. } // end while
  257. #endif
  258. } // if c!= NULL
  259. } // end if
  260. else // after parsing still NULL
  261. {
  262. LM_ERR("unable to parse Contact header\n");
  263. return -4;
  264. }
  265. #ifdef DEBUG
  266. fprintf (stdout,"---END--------DECODE CONTACT HEADER-----------------\n");fflush(stdout);
  267. #endif
  268. return 1;
  269. }
  270. int
  271. encode2format (str uri, struct uri_format *format)
  272. {
  273. int foo;
  274. char *string, *pos, *start, *end;
  275. struct sip_uri sipUri;
  276. if (uri.s == NULL)
  277. return -1;
  278. string = uri.s;
  279. pos = memchr (string, '<', uri.len);
  280. if (pos != NULL) /* we are only interested of chars inside <> */
  281. {
  282. /* KD: I think this can be removed as the parsed contact removed <> already */
  283. start = memchr (string, ':', uri.len);
  284. if (start == NULL) return -2;
  285. if (start - pos < 4) return -3;
  286. start = start - 3;
  287. end = strchr (start, '>');
  288. if (end == NULL)
  289. return -4; /* must be a match to < */
  290. }
  291. else /* we do not have <> */
  292. {
  293. start = memchr (string, ':', uri.len);
  294. if (start == NULL)
  295. return -5;
  296. if (start - string < 3)
  297. return -6;
  298. /* KD: FIXME: Looks like this code can not handle 'sips' URIs and discards all other URI parameters! */
  299. start = start - 3;
  300. end = string + uri.len;
  301. }
  302. memset(format,0,sizeof(struct uri_format));
  303. format->first = start - string + 4; /*sip: */
  304. format->second = end - string;
  305. /* --------------------------testing ------------------------------- */
  306. /* sip:gva@[email protected];;transport=udp>;expires=2 INCORECT BEHAVIOR OF parse_uri,myfunction works good */
  307. foo = parse_uri (start, end - start, &sipUri);
  308. if (foo != 0)
  309. {
  310. LM_ERR("parse_uri failed on [%.*s].Code %d \n",uri.len,uri.s,foo);
  311. #ifdef DEBUG
  312. fprintf (stdout, "PARSING uri with parse uri not ok %d\n", foo);
  313. #endif
  314. return foo-10;
  315. }
  316. format->username = sipUri.user;
  317. format->password = sipUri.passwd;
  318. format->ip = sipUri.host;
  319. format->port = sipUri.port;
  320. format->protocol = sipUri.transport_val;
  321. #ifdef DEBUG
  322. fprintf (stdout, "transport=[%.*s] transportval=[%.*s]\n", sipUri.transport.len,sipUri.transport.s,sipUri.transport_val.len,sipUri.transport_val.s);
  323. fprintf(stdout,"First %d,second %d\n",format->first,format->second);
  324. #endif
  325. return 0;
  326. }
  327. int
  328. encode_uri (str uri, char *encoding_prefix, char *public_ip,char separator, str * result)
  329. {
  330. struct uri_format format;
  331. char *pos;
  332. int foo,res;
  333. result->s = NULL;
  334. result->len = 0;
  335. if (uri.len <= 1)
  336. return -1; /* no contact or an invalid one */
  337. if (public_ip == NULL)
  338. {
  339. LM_ERR("invalid NULL value for public_ip parameter\n");
  340. return -2;
  341. }
  342. #ifdef DEBUG
  343. fprintf (stdout, "Primit cerere de encodare a [%.*s] cu %s-%s\n", uri.len,uri.s, encoding_prefix, public_ip);
  344. #endif
  345. fflush (stdout);
  346. foo = encode2format (uri, &format);
  347. if (foo < 0)
  348. {
  349. LM_ERR("unable to encode Contact URI [%.*s].Return code %d\n",uri.len,uri.s,foo);
  350. return foo - 20;
  351. }
  352. #ifdef DEBUG
  353. fprintf(stdout,"user=%.*s ip=%.*s port=%.*s protocol=%.*s\n",format.username.len,format.username.s,format.ip.len,format.ip.s,
  354. format.port.len,format.port.s,format.protocol.len,format.protocol.s);
  355. #endif
  356. /* a complete uri would be sip:username@ip:port;transport=protocol goes to
  357. * sip:enc_pref*username*ip*port*protocol@public_ip
  358. */
  359. foo = 1; /*strlen(separator); */
  360. result->len = format.first + uri.len - format.second + //ar trebui sa sterg 1
  361. strlen (encoding_prefix) + foo +
  362. format.username.len + foo +
  363. format.password.len + foo +
  364. format.ip.len + foo + format.port.len + foo +
  365. format.protocol.len + 1 + strlen (public_ip);
  366. /* adding one comes from @ */
  367. result->s = pkg_malloc (result->len);
  368. pos = result->s;
  369. if (pos == NULL)
  370. {
  371. #ifdef DEBUG
  372. fprintf (stdout, "Unable to alloc result [%d] end=%d\n",result->len, format.second);
  373. #endif
  374. LM_ERR("unable to alloc pkg memory\n");
  375. return -3;
  376. }
  377. #ifdef DEBUG
  378. fprintf (stdout, "[pass=%d][Allocated %d bytes][first=%d][lengthsec=%d]\nAdding [%d] ->%.*s\n",format.password.len,result->len,format.first,uri.len-format.second,format.first, format.first,uri.s);fflush (stdout);
  379. #endif
  380. res = snprintf(pos,result->len,"%.*s%s%c%.*s%c%.*s%c%.*s%c%.*s%c%.*s@",format.first,uri.s,encoding_prefix,separator,
  381. format.username.len,format.username.s,separator,format.password.len,format.password.s,
  382. separator,format.ip.len,format.ip.s,separator,format.port.len,format.port.s,separator,format.protocol.len,format.protocol.s);
  383. if ((res < 0 )||(res>result->len))
  384. {
  385. LM_ERR("unable to construct new uri.\n");
  386. if (result->s != NULL) pkg_free(result->s);
  387. return -4;
  388. }
  389. #ifdef DEBUG
  390. fprintf(stdout,"res= %d\npos=%s\n",res,pos);
  391. #endif
  392. pos = pos + res ;/* overwriting the \0 from snprintf */
  393. memcpy (pos, public_ip, strlen (public_ip));
  394. pos = pos + strlen (public_ip);
  395. memcpy (pos, uri.s + format.second, uri.len - format.second);
  396. #ifdef DEBUG
  397. fprintf (stdout, "Adding2 [%d] ->%.*s\n", uri.len - format.second,uri.len - format.second, uri.s + format.second);
  398. fprintf (stdout, "NEW NEW uri is->[%.*s]\n", result->len, result->s);
  399. #endif
  400. /* Because called parse_uri format contains pointers to the inside of msg,must not deallocate */
  401. return 0;
  402. }
  403. int
  404. decode2format (str uri, char separator, struct uri_format *format)
  405. {
  406. char *start, *end, *pos,*lastpos;
  407. str tmp;
  408. enum {EX_PREFIX=0,EX_USER,EX_PASS,EX_IP,EX_PORT,EX_PROT,EX_FINAL} state;
  409. //memset (format, 0, sizeof ((struct uri_format)));
  410. if (uri.s == NULL)
  411. {
  412. LM_ERR("invalid parameter uri.It is NULL\n");
  413. return -1;
  414. }
  415. /* sip:enc_pref*username*password*ip*port*protocol@public_ip */
  416. start = memchr (uri.s, ':', uri.len);
  417. if (start == NULL)
  418. {
  419. LM_ERR("invalid SIP uri.Missing :\n");
  420. return -2;
  421. } /* invalid uri */
  422. start = start + 1; /* jumping over sip: ATENTIE LA BUFFER OVERFLOW DACA E DOAR sip: */
  423. format->first = start - uri.s;
  424. /* start */
  425. end = memchr(start,'@',uri.len-(start-uri.s));
  426. if (end == NULL)
  427. {
  428. LM_ERR("invalid SIP uri.Missing @\n");
  429. return -3;/* no host address found */
  430. }
  431. #ifdef DEBUG
  432. fprintf (stdout, "Decoding %.*s\n", (int)(long)(end-start), start);
  433. #endif
  434. state = EX_PREFIX;
  435. lastpos = start;
  436. for (pos = start;pos<end;pos++)
  437. {
  438. if (*pos == separator)
  439. {
  440. /* we copy between lastpos and pos */
  441. tmp.len = pos - lastpos;
  442. if (tmp.len>0) tmp.s = lastpos;
  443. else tmp.s = NULL;
  444. switch (state)
  445. {
  446. case EX_PREFIX: state = EX_USER;break;
  447. case EX_USER:format->username = tmp;state = EX_PASS;break;
  448. case EX_PASS:format->password = tmp;state = EX_IP;break;
  449. case EX_IP:format->ip = tmp;state = EX_PORT;break;
  450. case EX_PORT:format->port = tmp;state = EX_PROT;break;
  451. default:
  452. {
  453. /* this should not happen, we should find @ not separator */
  454. return -4;
  455. break;
  456. }
  457. }
  458. lastpos = pos+1;
  459. }
  460. }
  461. /* we must be in state EX_PROT and protocol is between lastpos and end@ */
  462. if (state != EX_PROT) return -6;
  463. format->protocol.len = end - lastpos;
  464. if (format->protocol.len>0) format->protocol.s = lastpos;
  465. else format->protocol.s = NULL;
  466. /* I should check perhaps that after @ there is something */
  467. #ifdef DEBUG
  468. fprintf (stdout, "username=%.*s\n", format->username.len,format->username.s);
  469. fprintf (stdout, "password=%.*s\n", format->password.len,format->password.s);
  470. fprintf (stdout, "ip=%.*s\n", format->ip.len, format->ip.s);
  471. fprintf (stdout, "port=%.*s\n", format->port.len,format->port.s);
  472. fprintf (stdout, "protocol=%.*s\n", format->protocol.len,format->protocol.s);
  473. #endif
  474. /* looking for the end of public ip */
  475. start = end;/*we are now at @ */
  476. for(pos = start;pos<uri.s+uri.len;pos++)
  477. {
  478. if ((*pos == ';')||(*pos == '>'))
  479. {
  480. /* found end */
  481. format->second = pos - uri.s;
  482. return 0;
  483. }
  484. }
  485. /* if we are here we did not find > or ; */
  486. format->second = uri.len;
  487. return 0;
  488. }
  489. int
  490. decode_uri (str uri, char separator, str * result)
  491. {
  492. char *pos;
  493. struct uri_format format;
  494. int foo;
  495. result->s = NULL;
  496. result->len = 0;
  497. if ((uri.len <= 0) || (uri.s == NULL))
  498. {
  499. LM_ERR("invalid value for uri\n");
  500. return -1;
  501. }
  502. foo = decode2format (uri, separator, &format);
  503. if (foo < 0)
  504. {
  505. LM_ERR("failed to decode Contact uri .Error code %d\n",foo);
  506. return foo - 20;
  507. }
  508. /* sanity check */
  509. if (format.ip.len <= 0)
  510. {
  511. LM_ERR("unable to decode host address \n");
  512. return -2;/* should I quit or ignore ? */
  513. }
  514. if ((format.password.len > 0) && (format.username.len <= 0))
  515. {
  516. LM_ERR("password decoded but no username available\n");
  517. return -3;
  518. }
  519. /* a complete uri would be sip:username:password@ip:port;transport=protocol goes to
  520. * sip:enc_pref#username#password#ip#port#protocol@public_ip
  521. */
  522. result->len = format.first + (uri.len - format.second); /* not NULL terminated */
  523. if (format.username.len > 0) result->len += format.username.len + 1; //: or @
  524. if (format.password.len > 0) result->len += format.password.len + 1; //@
  525. /* if (format.ip.len > 0) */ result->len += format.ip.len;
  526. if (format.port.len > 0) result->len += 1 + format.port.len; //:
  527. if (format.protocol.len > 0) result->len += 1 + 10 + format.protocol.len; //;transport=
  528. #ifdef DEBUG
  529. fprintf (stdout, "Result size is %d.Original Uri size is %d\n",result->len, uri.len);
  530. #endif
  531. /* adding one comes from * */
  532. result->s = pkg_malloc (result->len);
  533. if (result->s == NULL)
  534. {
  535. LM_ERR("unable to allocate pkg memory\n");
  536. return -4;
  537. }
  538. pos = result->s;
  539. #ifdef DEBUG
  540. fprintf (stdout, "Adding [%d] ->%.*s\n", format.first, format.first,uri.s);fflush (stdout);
  541. #endif
  542. memcpy (pos, uri.s, format.first); /* till sip: */
  543. pos = pos + format.first;
  544. if (format.username.len > 0)
  545. {
  546. memcpy (pos, format.username.s, format.username.len);
  547. pos = pos + format.username.len;
  548. if (format.password.len > 0)
  549. memcpy (pos, ":", 1);
  550. else
  551. memcpy (pos, "@", 1);
  552. pos = pos + 1;
  553. }
  554. if (format.password.len > 0)
  555. {
  556. memcpy (pos, format.password.s, format.password.len);
  557. pos = pos + format.password.len;
  558. memcpy (pos, "@", 1);
  559. pos = pos + 1;
  560. }
  561. /* if (format.ip.len > 0) */
  562. memcpy (pos, format.ip.s, format.ip.len);
  563. pos = pos + format.ip.len;
  564. if (format.port.len > 0)
  565. {
  566. memcpy (pos, ":", 1);
  567. pos = pos + 1;
  568. memcpy (pos, format.port.s, format.port.len);
  569. pos = pos + format.port.len;
  570. }
  571. if (format.protocol.len > 0)
  572. {
  573. memcpy (pos, ";transport=", 11);
  574. pos = pos + 11;
  575. memcpy (pos, format.protocol.s, format.protocol.len);
  576. pos = pos + format.protocol.len;
  577. }
  578. #ifdef DEBUG
  579. fprintf (stdout, "Adding2 [%d] ->%.*s\n", uri.len - format.second,uri.len - format.second, uri.s + format.second);fflush (stdout);
  580. #endif
  581. memcpy (pos, uri.s + format.second, uri.len - format.second); /* till end: */
  582. #ifdef DEBUG
  583. fprintf (stdout, "New decoded uri is->[%.*s]\n", result->len,result->s);
  584. #endif
  585. return 0;
  586. }