Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

uri.c 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. /** @file
  19. *
  20. * Uniform Resource Identifiers
  21. *
  22. */
  23. #include <stdint.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <gpxe/uri.h>
  27. /**
  28. * Parse URI
  29. *
  30. * @v uri_string URI as a string
  31. * @ret uri URI
  32. *
  33. * Splits a URI into its component parts. The return URI structure is
  34. * dynamically allocated and must eventually be freed by calling
  35. * free_uri().
  36. */
  37. struct uri * parse_uri ( const char *uri_string ) {
  38. struct uri *uri;
  39. char *raw;
  40. char *tmp;
  41. char *path = NULL;
  42. char *authority = NULL;
  43. size_t raw_len;
  44. /* Allocate space for URI struct and a copy of the string */
  45. raw_len = ( strlen ( uri_string ) + 1 /* NUL */ );
  46. uri = malloc ( sizeof ( *uri ) + raw_len );
  47. if ( ! uri )
  48. return NULL;
  49. raw = ( ( ( char * ) uri ) + sizeof ( *uri ) );
  50. /* Zero URI struct and copy in the raw string */
  51. memset ( uri, 0, sizeof ( *uri ) );
  52. memcpy ( raw, uri_string, raw_len );
  53. /* Start by chopping off the fragment, if it exists */
  54. if ( ( tmp = strchr ( raw, '#' ) ) ) {
  55. *(tmp++) = '\0';
  56. uri->fragment = tmp;
  57. }
  58. /* Identify absolute/relative URI */
  59. if ( ( tmp = strchr ( raw, ':' ) ) ) {
  60. /* Absolute URI: identify hierarchical/opaque */
  61. uri->scheme = raw;
  62. *(tmp++) = '\0';
  63. if ( *tmp == '/' ) {
  64. /* Absolute URI with hierarchical part */
  65. path = tmp;
  66. } else {
  67. /* Absolute URI with opaque part */
  68. uri->opaque = tmp;
  69. }
  70. } else {
  71. /* Relative URI */
  72. path = raw;
  73. }
  74. /* If we don't have a path (i.e. we have an absolute URI with
  75. * an opaque portion, we're already finished processing
  76. */
  77. if ( ! path )
  78. goto done;
  79. /* Chop off the query, if it exists */
  80. if ( ( tmp = strchr ( path, '?' ) ) ) {
  81. *(tmp++) = '\0';
  82. uri->query = tmp;
  83. }
  84. /* Identify net/absolute/relative path */
  85. if ( strncmp ( path, "//", 2 ) == 0 ) {
  86. /* Net path. If this is terminated by the first '/'
  87. * of an absolute path, then we have no space for a
  88. * terminator after the authority field, so shuffle
  89. * the authority down by one byte, overwriting one of
  90. * the two slashes.
  91. */
  92. authority = ( path + 2 );
  93. if ( ( tmp = strchr ( authority, '/' ) ) ) {
  94. /* Shuffle down */
  95. uri->path = tmp;
  96. memmove ( ( authority - 1 ), authority,
  97. ( tmp - authority ) );
  98. authority--;
  99. *(--tmp) = '\0';
  100. }
  101. } else {
  102. /* Absolute/relative path */
  103. uri->path = path;
  104. }
  105. /* Split authority into user[:password] and host[:port] portions */
  106. if ( ( tmp = strchr ( authority, '@' ) ) ) {
  107. /* Has user[:password] */
  108. *(tmp++) = '\0';
  109. uri->host = tmp;
  110. uri->user = authority;
  111. if ( ( tmp = strchr ( authority, ':' ) ) ) {
  112. /* Has password */
  113. *(tmp++) = '\0';
  114. uri->password = tmp;
  115. }
  116. } else {
  117. /* No user:password */
  118. uri->host = authority;
  119. }
  120. /* Split host into host[:port] */
  121. if ( ( tmp = strchr ( uri->host, ':' ) ) ) {
  122. *(tmp++) = '\0';
  123. uri->port = tmp;
  124. }
  125. done:
  126. DBG ( "URI \"%s\" split into", raw );
  127. if ( uri->scheme )
  128. DBG ( " scheme \"%s\"", uri->scheme );
  129. if ( uri->opaque )
  130. DBG ( " opaque \"%s\"", uri->opaque );
  131. if ( uri->user )
  132. DBG ( " user \"%s\"", uri->user );
  133. if ( uri->password )
  134. DBG ( " password \"%s\"", uri->password );
  135. if ( uri->host )
  136. DBG ( " host \"%s\"", uri->host );
  137. if ( uri->port )
  138. DBG ( " port \"%s\"", uri->port );
  139. if ( uri->path )
  140. DBG ( " path \"%s\"", uri->path );
  141. if ( uri->query )
  142. DBG ( " query \"%s\"", uri->query );
  143. if ( uri->fragment )
  144. DBG ( " fragment \"%s\"", uri->fragment );
  145. DBG ( "\n" );
  146. return uri;
  147. }
  148. /**
  149. * Get port from URI
  150. *
  151. * @v uri URI
  152. * @v default_port Default port to use if none specified in URI
  153. * @ret port Port
  154. */
  155. unsigned int uri_port ( struct uri *uri, unsigned int default_port ) {
  156. return ( uri->port ? strtoul ( uri->port, NULL, 0 ) : default_port );
  157. }