uri.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. /*******************************************************************************
  2. *
  3. * Copyright (c) 2000-2003 Intel Corporation
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * - Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * - Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. * - Neither name of Intel Corporation nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
  22. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  23. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  25. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  26. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  27. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. ******************************************************************************/
  31. #ifndef GENLIB_NET_URI_H
  32. #define GENLIB_NET_URI_H
  33. /*!
  34. * \file
  35. */
  36. #if !defined(WIN32)
  37. #include <sys/param.h>
  38. #endif
  39. #include "UpnpGlobal.h" /* for */
  40. #include "UpnpInet.h"
  41. #include <ctype.h>
  42. #include <errno.h>
  43. #include <fcntl.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <sys/types.h>
  47. #include <time.h>
  48. #ifdef WIN32
  49. #ifndef UPNP_USE_MSVCPP
  50. /* VC Winsocks2 includes these functions */
  51. #include "inet_pton.h"
  52. #endif
  53. #else
  54. #include <netdb.h> /* for struct addrinfo */
  55. #endif
  56. #ifdef WIN32
  57. #define strncasecmp strnicmp
  58. #else
  59. /* Other systems have strncasecmp */
  60. #endif
  61. #ifdef __cplusplus
  62. extern "C" {
  63. #endif
  64. /*! length for HTTP DATE: "DATE: Sun, 01 Jul 2000 08:15:23 GMT<cr><lf>" */
  65. #define HTTP_DATE_LENGTH 37
  66. #define SEPARATORS "()<>@,;:\\\"/[]?={} \t"
  67. #define MARK "-_.!~*'()"
  68. /*! added {} for compatibility */
  69. #define RESERVED ";/?:@&=+$,{}"
  70. #define HTTP_SUCCESS 1
  71. #define FALSE 0
  72. #define TAB 9
  73. #define CR 13
  74. #define LF 10
  75. #define SOCKET_BUFFER_SIZE 5000
  76. enum hostType {
  77. HOSTNAME,
  78. IPv4address
  79. };
  80. enum pathType {
  81. ABS_PATH,
  82. REL_PATH,
  83. OPAQUE_PART
  84. };
  85. #ifdef WIN32
  86. /* there is a conflict in windows with other symbols. */
  87. enum uriType {
  88. absolute,
  89. relative
  90. };
  91. #else
  92. enum uriType {
  93. ABSOLUTE,
  94. RELATIVE
  95. };
  96. #endif
  97. /*!
  98. * \brief Buffer used in parsinghttp messages, urls, etc. generally this simply
  99. * holds a pointer into a larger array.
  100. */
  101. typedef struct TOKEN {
  102. const char *buff;
  103. size_t size;
  104. } token;
  105. /*!
  106. * \brief Represents a host port: e.g. "127.127.0.1:80" text is a token
  107. * pointing to the full string representation.
  108. */
  109. typedef struct HOSTPORT {
  110. /*! Full host port. */
  111. token text;
  112. /* Network Byte Order */
  113. struct sockaddr_storage IPaddress;
  114. } hostport_type;
  115. /*!
  116. * \brief Represents a URI used in parse_uri and elsewhere
  117. */
  118. typedef struct URI{
  119. enum uriType type;
  120. token scheme;
  121. enum pathType path_type;
  122. token pathquery;
  123. token fragment;
  124. hostport_type hostport;
  125. } uri_type;
  126. /*!
  127. * \brief Represents a list of URLs as in the "callback" header of SUBSCRIBE
  128. * message in GENA. "char *" URLs holds dynamic memory.
  129. */
  130. typedef struct URL_LIST {
  131. /*! */
  132. size_t size;
  133. /*! All the urls, delimited by <> */
  134. char *URLs;
  135. /*! */
  136. uri_type *parsedURLs;
  137. } URL_list;
  138. /*!
  139. * \brief Replaces an escaped sequence with its unescaped version as in
  140. * http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)
  141. *
  142. * Size of array is NOT checked (MUST be checked by caller)
  143. *
  144. * \note This function modifies the string. If the sequence is an escaped
  145. * sequence it is replaced, the other characters in the string are shifted
  146. * over, and NULL characters are placed at the end of the string.
  147. *
  148. * \return
  149. */
  150. int replace_escaped(
  151. /*! [in,out] String of characters. */
  152. char *in,
  153. /*! [in] Index at which to start checking the characters. */
  154. size_t index,
  155. /*! [out] . */
  156. size_t *max);
  157. /*!
  158. * \brief Copies one URL_list into another.
  159. *
  160. * This includes dynamically allocating the out->URLs field (the full string),
  161. * and the structures used to hold the parsedURLs. This memory MUST be freed
  162. * by the caller through: free_URL_list(&out).
  163. *
  164. * \return
  165. * \li HTTP_SUCCESS - On Success.
  166. * \li UPNP_E_OUTOF_MEMORY - On Failure to allocate memory.
  167. */
  168. int copy_URL_list(
  169. /*! [in] Source URL list. */
  170. URL_list *in,
  171. /*! [out] Destination URL list. */
  172. URL_list *out);
  173. /*!
  174. * \brief Frees the memory associated with a URL_list.
  175. *
  176. * Frees the dynamically allocated members of of list. Does NOT free the
  177. * pointer to the list itself ( i.e. does NOT free(list)).
  178. */
  179. void free_URL_list(
  180. /*! [in] URL list object. */
  181. URL_list *list);
  182. /*!
  183. * \brief Function useful in debugging for printing a parsed uri.
  184. */
  185. #ifdef DEBUG
  186. void print_uri(
  187. /*! [in] URI object to print. */
  188. uri_type *in);
  189. #else
  190. static UPNP_INLINE void print_uri(uri_type *in)
  191. {
  192. return;
  193. in = in;
  194. }
  195. #endif
  196. /*!
  197. * \brief Function useful in debugging for printing a token.
  198. */
  199. #ifdef DEBUG
  200. void print_token(
  201. /*! [in] Token object to print. */
  202. token *in);
  203. #else
  204. static UPNP_INLINE void print_token(
  205. /*! [in] Token object to print. */
  206. token *in)
  207. {
  208. return;
  209. in = in;
  210. }
  211. #endif
  212. /*!
  213. * \brief Compares buffer in the token object with the buffer in in2.
  214. *
  215. * \return
  216. * \li < 0, if string1 is less than string2.
  217. * \li == 0, if string1 is identical to string2 .
  218. * \li > 0, if string1 is greater than string2.
  219. */
  220. int token_string_casecmp(
  221. /*! [in] Token object whose buffer is to be compared. */
  222. token *in1,
  223. /*! [in] String of characters to compare with. */
  224. const char *in2);
  225. /*!
  226. * \brief Compares a null terminated string to a token (exact).
  227. *
  228. * \return
  229. * \li < 0, if string1 is less than string2.
  230. * \li == 0, if string1 is identical to string2 .
  231. * \li > 0, if string1 is greater than string2.
  232. */
  233. int token_string_cmp(
  234. /*! [in] Token object whose buffer is to be compared. */
  235. token *in1,
  236. /*! [in] String of characters to compare with. */
  237. char *in2);
  238. /*!
  239. * \brief Compares two tokens.
  240. *
  241. * \return
  242. * \li < 0, if string1 is less than string2.
  243. * \li == 0, if string1 is identical to string2 .
  244. * \li > 0, if string1 is greater than string2.
  245. */
  246. int token_cmp(
  247. /*! [in] First token object whose buffer is to be compared. */
  248. token *in1,
  249. /*! [in] Second token object used for the comparison. */
  250. token *in2);
  251. /*!
  252. * \brief Removes http escaped characters such as: "%20" and replaces them with
  253. * their character representation. i.e. "hello%20foo" -> "hello foo".
  254. *
  255. * The input IS MODIFIED in place (shortened). Extra characters are replaced
  256. * with \b NULL.
  257. *
  258. * \return UPNP_E_SUCCESS.
  259. */
  260. int remove_escaped_chars(
  261. /*! [in,out] String of characters to be modified. */
  262. char *in,
  263. /*! [in,out] Size limit for the number of characters. */
  264. size_t *size);
  265. /*!
  266. * \brief Removes ".", and ".." from a path.
  267. *
  268. * If a ".." can not be resolved (i.e. the .. would go past the root of the
  269. * path) an error is returned.
  270. *
  271. * The input IS modified in place.)
  272. *
  273. * \note Examples
  274. * char path[30]="/../hello";
  275. * remove_dots(path, strlen(path)) -> UPNP_E_INVALID_URL
  276. * char path[30]="/./hello";
  277. * remove_dots(path, strlen(path)) -> UPNP_E_SUCCESS,
  278. * in = "/hello"
  279. * char path[30]="/./hello/foo/../goodbye" ->
  280. * UPNP_E_SUCCESS, in = "/hello/goodbye"
  281. *
  282. * \return
  283. * \li UPNP_E_SUCCESS - On Success.
  284. * \li UPNP_E_OUTOF_MEMORY - On failure to allocate memory.
  285. * \li UPNP_E_INVALID_URL - Failure to resolve URL.
  286. */
  287. int remove_dots(
  288. /*! [in] String of characters from which "dots" have to be removed. */
  289. char *in,
  290. /*! [in] Size limit for the number of characters. */
  291. size_t size);
  292. /*!
  293. * \brief resolves a relative url with a base url returning a NEW (dynamically
  294. * allocated with malloc) full url.
  295. *
  296. * If the base_url is \b NULL, then a copy of the rel_url is passed back if
  297. * the rel_url is absolute then a copy of the rel_url is passed back if neither
  298. * the base nor the rel_url are Absolute then NULL is returned. Otherwise it
  299. * tries and resolves the relative url with the base as described in
  300. * http://www.ietf.org/rfc/rfc2396.txt (RFCs explaining URIs).
  301. *
  302. * The resolution of '..' is NOT implemented, but '.' is resolved.
  303. *
  304. * \return
  305. */
  306. char *resolve_rel_url(
  307. /*! [in] Base URL. */
  308. char *base_url,
  309. /*! [in] Relative URL. */
  310. char *rel_url);
  311. /*!
  312. * \brief Parses a uri as defined in http://www.ietf.org/rfc/rfc2396.txt
  313. * (RFC explaining URIs).
  314. *
  315. * Handles absolute, relative, and opaque uris. Parses into the following
  316. * pieces: scheme, hostport, pathquery, fragment (path and query are treated
  317. * as one token)
  318. *
  319. * Caller should check for the pieces they require.
  320. *
  321. * \return
  322. */
  323. int parse_uri(
  324. /*! [in] Character string containing uri information to be parsed. */
  325. const char *in,
  326. /*! [in] Maximum limit on the number of characters. */
  327. size_t max,
  328. /*! [out] Output parameter which will have the parsed uri information. */
  329. uri_type *out);
  330. /*!
  331. * \brief Same as parse_uri(), except that all strings are unescaped
  332. * (%XX replaced by chars).
  333. *
  334. * \note This modifies 'pathquery' and 'fragment' parts of the input.
  335. *
  336. * \return
  337. */
  338. int parse_uri_and_unescape(
  339. /*! [in] Character string containing uri information to be parsed. */
  340. char *in,
  341. /*! [in] Maximum limit on the number of characters. */
  342. size_t max,
  343. /*! [out] Output parameter which will have the parsed uri information. */
  344. uri_type *out);
  345. /*!
  346. * \brief
  347. *
  348. * \return
  349. */
  350. int parse_token(
  351. /*! [in] . */
  352. char *in,
  353. /*! [out] . */
  354. token *out,
  355. /*! [in] . */
  356. int max_size);
  357. /* Commented #defines, functions and typdefs */
  358. #if 0
  359. #define HTTP_E_BAD_URL UPNP_E_INVALID_URL
  360. #define HTTP_E_READ_SOCKET UPNP_E_SOCKET_READ
  361. #define HTTP_E_BIND_SOCKET UPNP_E_SOCKET_BIND
  362. #define HTTP_E_WRITE_SOCKET UPNP_E_SOCKET_WRITE
  363. #define HTTP_E_CONNECT_SOCKET UPNP_E_SOCKET_CONNECT
  364. #define HTTP_E_SOCKET UPNP_E_OUTOF_SOCKET
  365. #define HTTP_E_BAD_RESPONSE UPNP_E_BAD_RESPONSE
  366. #define HTTP_E_BAD_REQUEST UPNP_E_BAD_REQUEST
  367. #define HTTP_E_BAD_IP_ADDRESS UPNP_E_INVALID_URL
  368. #define RESPONSE_TIMEOUT 30
  369. #endif
  370. #if 0
  371. /*!
  372. * Buffer used to store data read from a socket during an http transfer in
  373. * function read_bytes.
  374. */
  375. typedef struct SOCKET_BUFFER{
  376. char buff[SOCKET_BUFFER_SIZE];
  377. int size;
  378. struct SOCKET_BUFFER *next;
  379. } socket_buffer;
  380. typedef struct HTTP_HEADER {
  381. token header;
  382. token value;
  383. struct HTTP_HEADER * next;
  384. } http_header;
  385. typedef struct HTTP_STATUS_LINE{
  386. token http_version;
  387. token status_code;
  388. token reason_phrase;
  389. } http_status;
  390. typedef struct HTTP_REQUEST_LINE {
  391. token http_version;
  392. uri_type request_uri;
  393. token method;
  394. } http_request;
  395. /*!
  396. * Represents a parsed HTTP_MESSAGE head_list is dynamically allocated
  397. */
  398. typedef struct HTTP_MESSAGE {
  399. http_status status;
  400. http_request request;
  401. http_header * header_list;
  402. token content;
  403. } http_message;
  404. #endif
  405. #if 0
  406. int transferHTTP(
  407. char *request,
  408. char *toSend,
  409. int toSendSize,
  410. char **out,
  411. char *Url);
  412. int transferHTTPRaw(
  413. char *toSend,
  414. int toSendSize,
  415. char **out,
  416. char *URL);
  417. /*!
  418. * \brief helper function.
  419. */
  420. int transferHTTPparsedURL(
  421. char *request,
  422. char *toSend,
  423. int toSendSize,
  424. char **out,
  425. uri_type *URL);
  426. /*!
  427. * \brief assumes that char * out has enough space ( 38 characters)
  428. * outputs the current time in the following null terminated string:
  429. * "DATE: Sun, Jul 06 2000 08:53:01 GMT\r\n"
  430. */
  431. void currentTmToHttpDate(
  432. char *out);
  433. int parse_http_response(
  434. char *in,
  435. http_message *out,
  436. int max_len);
  437. int parse_http_request(
  438. char *in,
  439. http_message *out,
  440. int max_len);
  441. void print_http_message(
  442. http_message *message);
  443. int search_for_header(
  444. http_message *in,
  445. char *header,
  446. token *out_value);
  447. void print_status_line(
  448. http_status *in);
  449. void print_request_line(
  450. http_request *in);
  451. int parse_http_line(
  452. char *in,
  453. int max_size);
  454. int parse_not_LWS(
  455. char *in,
  456. token *out,
  457. int max_size);
  458. int parse_LWS(
  459. char *in,
  460. int max_size);
  461. size_t write_bytes(
  462. int fd,
  463. char *bytes,
  464. size_t n,
  465. int timeout);
  466. void free_http_message(
  467. http_message *message);
  468. #endif
  469. #ifdef __cplusplus
  470. }
  471. #endif
  472. #endif /* GENLIB_NET_URI_H */