示例#1
0
文件: uri.c 项目: Prutkov-Alex/gpxe
/**
 * Unparse URI
 *
 * @v buf		Buffer to fill with URI string
 * @v size		Size of buffer
 * @v uri		URI to write into buffer, or NULL
 * @v fields		Bitmask of fields to include in URI string, or URI_ALL
 * @ret len		Length of URI string
 */
int unparse_uri ( char *buf, size_t size, struct uri *uri,
		  unsigned int fields ) {
	/* List of characters that typically go before certain fields */
	static char separators[] = { /* scheme */ 0, /* opaque */ ':',
				     /* user */ 0, /* password */ ':',
				     /* host */ '@', /* port */ ':',
				     /* path */ 0, /* query */ '?',
				     /* fragment */ '#' };
	int used = 0;
	int i;

	DBG ( "URI unparsing" );
	dump_uri ( uri );
	DBG ( "\n" );

	/* Ensure buffer is NUL-terminated */
	if ( size )
		buf[0] = '\0';

	/* Special-case NULL URI */
	if ( ! uri )
		return 0;

	/* Iterate through requested fields */
	for ( i = URI_FIRST_FIELD; i <= URI_LAST_FIELD; i++ ) {
		const char *field = uri_get_field ( uri, i );
		char sep = separators[i];

		/* Ensure `fields' only contains bits for fields that exist */
		if ( ! field )
			fields &= ~( 1 << i );

		/* Store this field if we were asked to */
		if ( fields & ( 1 << i ) ) {
			/* Print :// if we're non-opaque and had a scheme */
			if ( ( fields & URI_SCHEME_BIT ) &&
			     ( i > URI_OPAQUE ) ) {
				used += ssnprintf ( buf + used, size - used,
						    "://" );
				/* Only print :// once */
				fields &= ~URI_SCHEME_BIT;
			}

			/* Only print separator if an earlier field exists */
			if ( sep && ( fields & ( ( 1 << i ) - 1 ) ) )
				used += ssnprintf ( buf + used, size - used,
						    "%c", sep );

			/* Print contents of field, possibly encoded */
			if ( URI_ENCODED & ( 1 << i ) )
				used += uri_encode ( field, buf + used,
						     size - used, i );
			else
				used += ssnprintf ( buf + used, size - used,
						    "%s", field );
		}
	}

	return used;
}
示例#2
0
void
test_main (int argc, char **argv)
{
	const char *url;
	E2kUri *euri;

	if (argc != 2) {
		fprintf (stderr, "Usage: %s url \n", argv[0]);
		exit (1);
	}

	url = argv[1];
	euri = e2k_uri_new (url);
	dump_uri (euri);
	test_quit ();
}
示例#3
0
/** Test parsing and rebuilding a URI.
 *
 * \param uri Pre-created URI structure.
 * \param original The original URI string.
 * \param expected The expected, re-built string, or NULL if original is expected.
 * \return 1 on error, 0 on success. */
static int test_parsing_uri(VC_URI_PARTS_T *uri, const char *original, const char *expected)
{
   bool parsed;

   LOG_INFO(NULL, "URI: <%s>", original);

   parsed = vc_uri_parse( uri, original );
   if (!parsed)
   {
      LOG_ERROR(NULL, "*** Expected <%s> to parse, but it didn't", original);
      return 1;
   }

   dump_uri(uri);

   return check_uri(uri, expected ? expected : original);
}
示例#4
0
/**
 * Parse URI
 *
 * @v uri_string	URI as a string
 * @ret uri		URI
 *
 * Splits a URI into its component parts.  The return URI structure is
 * dynamically allocated and must eventually be freed by calling
 * uri_put().
 */
struct uri * parse_uri ( const char *uri_string ) {
	struct uri *uri;
	char *raw;
	char *tmp;
	char *path = NULL;
	char *authority = NULL;
	size_t raw_len;

	/* Allocate space for URI struct and a copy of the string */
	raw_len = ( strlen ( uri_string ) + 1 /* NUL */ );
	uri = zalloc ( sizeof ( *uri ) + raw_len );
	if ( ! uri )
		return NULL;
	raw = ( ( ( char * ) uri ) + sizeof ( *uri ) );

	/* Zero URI struct and copy in the raw string */
	memcpy ( raw, uri_string, raw_len );

	/* Start by chopping off the fragment, if it exists */
	if ( ( tmp = strchr ( raw, '#' ) ) ) {
		*(tmp++) = '\0';
		uri->fragment = tmp;
	}

	/* Identify absolute/relative URI.  We ignore schemes that are
	 * apparently only a single character long, since otherwise we
	 * misinterpret a DOS-style path name ("C:\path\to\file") as a
	 * URI with scheme="C",opaque="\path\to\file".
	 */
	if ( ( tmp = strchr ( raw, ':' ) ) && ( tmp > ( raw + 1 ) ) ) {
		/* Absolute URI: identify hierarchical/opaque */
		uri->scheme = raw;
		*(tmp++) = '\0';
		if ( *tmp == '/' ) {
			/* Absolute URI with hierarchical part */
			path = tmp;
		} else {
			/* Absolute URI with opaque part */
			uri->opaque = tmp;
		}
	} else {
		/* Relative URI */
		path = raw;
	}

	/* If we don't have a path (i.e. we have an absolute URI with
	 * an opaque portion, we're already finished processing
	 */
	if ( ! path )
		goto done;

	/* Chop off the query, if it exists */
	if ( ( tmp = strchr ( path, '?' ) ) ) {
		*(tmp++) = '\0';
		uri->query = tmp;
	}

	/* Identify net/absolute/relative path */
	if ( strncmp ( path, "//", 2 ) == 0 ) {
		/* Net path.  If this is terminated by the first '/'
		 * of an absolute path, then we have no space for a
		 * terminator after the authority field, so shuffle
		 * the authority down by one byte, overwriting one of
		 * the two slashes.
		 */
		authority = ( path + 2 );
		if ( ( tmp = strchr ( authority, '/' ) ) ) {
			/* Shuffle down */
			uri->path = tmp;
			memmove ( ( authority - 1 ), authority,
				  ( tmp - authority ) );
			authority--;
			*(--tmp) = '\0';
		}
	} else {
		/* Absolute/relative path */
		uri->path = path;
	}

	/* Split authority into user[:password] and host[:port] portions */
	if ( ( tmp = strchr ( authority, '@' ) ) ) {
		/* Has user[:password] */
		*(tmp++) = '\0';
		uri->host = tmp;
		uri->user = authority;
		if ( ( tmp = strchr ( authority, ':' ) ) ) {
			/* Has password */
			*(tmp++) = '\0';
			uri->password = tmp;
		}
	} else {
		/* No user:password */
		uri->host = authority;
	}

	/* Split host into host[:port] */
	if ( ( tmp = strchr ( uri->host, ':' ) ) ) {
		*(tmp++) = '\0';
		uri->port = tmp;
	}

 done:
	DBG ( "URI \"%s\" split into", uri_string );
	dump_uri ( uri );
	DBG ( "\n" );

	return uri;
}
示例#5
0
/**
 * Unparse URI
 *
 * @v buf		Buffer to fill with URI string
 * @v size		Size of buffer
 * @v uri		URI to write into buffer, or NULL
 * @ret len		Length of URI string
 */
int unparse_uri ( char *buf, size_t size, struct uri *uri ) {
	int used = 0;

	DBG ( "URI unparsing" );
	dump_uri ( uri );
	DBG ( "\n" );

	/* Special-case NULL URI */
	if ( ! uri ) {
		if ( size )
			buf[0] = '\0';
		return 0;
	}

	/* Special-case opaque URIs */
	if ( uri->opaque ) {
		return ssnprintf ( ( buf + used ), ( size - used ),
				   "%s:%s", uri->scheme, uri->opaque );
	}

	/* scheme:// */
	if ( uri->scheme ) {
		used += ssnprintf ( ( buf + used ), ( size - used ),
				    "%s://", uri->scheme );
	}

	/* [user[:password]@]host[:port] */
	if ( uri->host ) {
		if ( uri->user ) {
			used += ssnprintf ( ( buf + used ), ( size - used ),
					    "%s", uri->user );
			if ( uri->password ) {
				used += ssnprintf ( ( buf + used ),
						    ( size - used ),
						    ":%s", uri->password );
			}
			used += ssnprintf ( ( buf + used ), ( size - used ),
					    "@" );
		}
		used += ssnprintf ( ( buf + used ), ( size - used ), "%s",
				    uri->host );
		if ( uri->port ) {
			used += ssnprintf ( ( buf + used ), ( size - used ),
					    ":%s", uri->port );
		}
	}

	/* /path */
	if ( uri->path ) {
		used += ssnprintf ( ( buf + used ), ( size - used ),
				    "%s", uri->path );
	}

	/* ?query */
	if ( uri->query ) {
		used += ssnprintf ( ( buf + used ), ( size - used ),
				    "?%s", uri->query );
	}

	/* #fragment */
	if ( uri->fragment ) {
		used += ssnprintf ( ( buf + used ), ( size - used ),
				    "#%s", uri->fragment );
	}

	return used;
}
示例#6
0
/** Test building a URI from component parts.
 *
 * \param uri Pre-created URI structure.
 * \param uri_data The data for building the URI and the expected output.
 * \return 1 on error, 0 on success. */
static int test_building_uri(VC_URI_PARTS_T *uri, BUILD_URI_T *uri_data)
{
   const char **p_str;
   const char *name, *value;

   LOG_INFO(NULL, "Building URI <%s>", uri_data->expected_uri);

   vc_uri_clear(uri);

   if (!vc_uri_set_scheme(uri, uri_data->scheme))
   {
      LOG_ERROR(NULL, "*** Failed to set scheme");
      return 1;
   }

   if (!vc_uri_set_userinfo(uri, uri_data->userinfo))
   {
      LOG_ERROR(NULL, "*** Failed to set userinfo");
      return 1;
   }

   if (!vc_uri_set_host(uri, uri_data->host))
   {
      LOG_ERROR(NULL, "*** Failed to set host");
      return 1;
   }

   if (!vc_uri_set_port(uri, uri_data->port))
   {
      LOG_ERROR(NULL, "*** Failed to set port");
      return 1;
   }

   if (!vc_uri_set_path(uri, uri_data->path))
   {
      LOG_ERROR(NULL, "*** Failed to set path");
      return 1;
   }

   if (!vc_uri_set_fragment(uri, uri_data->fragment))
   {
      LOG_ERROR(NULL, "*** Failed to set fragment");
      return 1;
   }

   p_str = uri_data->queries;
   name = *p_str++;

   while (name)
   {
      value = *p_str++;
      if (!vc_uri_add_query(uri, name, value))
      {
         LOG_ERROR(NULL, "*** Failed to add query");
         return 1;
      }
      name = *p_str++;
   }

   dump_uri(uri);

   return check_uri(uri, uri_data->expected_uri);
}