diff options
author | Michael Brown <mcb30@ipxe.org> | 2014-02-27 13:32:53 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2014-02-27 13:32:53 +0000 |
commit | 76675365271291beb9ddaeec10da14f4faa55ecc (patch) | |
tree | 0143200258d478e381b9d492bead2bdda91fe865 /src/include/ipxe/uri.h | |
parent | c7b69ac793b7704c09560eb6850e4ec2bd66e575 (diff) | |
download | ipxe-76675365271291beb9ddaeec10da14f4faa55ecc.tar.gz |
[uri] Refactor URI parsing and formatting
Add support for parsing of URIs containing literal IPv6 addresses
(e.g. "http://[fe80::69ff:fe50:5845%25net0]/boot.ipxe").
Duplicate URIs by directly copying the relevant fields, rather than by
formatting and reparsing a URI string. This relaxes the requirements
on the URI formatting code and allows it to focus on generating
human-readable URIs (e.g. by not escaping ':' characters within
literal IPv6 addresses). As a side-effect, this allows relative URIs
containing parameter lists (e.g. "../boot.php##params") to function
as expected.
Add validity check for FTP paths to ensure that only printable
characters are accepted (since FTP is a human-readable line-based
protocol with no support for character escaping).
Construct TFTP next-server+filename URIs directly, rather than parsing
a constructed "tftp://..." string,
Add self-tests for URI functions.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include/ipxe/uri.h')
-rw-r--r-- | src/include/ipxe/uri.h | 78 |
1 files changed, 41 insertions, 37 deletions
diff --git a/src/include/ipxe/uri.h b/src/include/ipxe/uri.h index a9ec45550..7613d578d 100644 --- a/src/include/ipxe/uri.h +++ b/src/include/ipxe/uri.h @@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <stddef.h> #include <stdlib.h> #include <ipxe/refcnt.h> +#include <ipxe/in.h> struct parameters; @@ -71,37 +72,38 @@ struct uri { struct parameters *params; } __attribute__ (( packed )); -/** A field in a URI +/** + * Access URI field * - * The order of the indices in this enumeration must match the order - * of the fields in the URI structure. + * @v uri URI + * @v field URI field index + * @ret field URI field (as an lvalue) */ -enum { - URI_SCHEME = 0, URI_SCHEME_BIT = ( 1 << URI_SCHEME ), - URI_OPAQUE = 1, URI_OPAQUE_BIT = ( 1 << URI_OPAQUE ), - URI_USER = 2, URI_USER_BIT = ( 1 << URI_USER ), - URI_PASSWORD = 3, URI_PASSWORD_BIT = ( 1 << URI_PASSWORD ), - URI_HOST = 4, URI_HOST_BIT = ( 1 << URI_HOST ), - URI_PORT = 5, URI_PORT_BIT = ( 1 << URI_PORT ), - URI_PATH = 6, URI_PATH_BIT = ( 1 << URI_PATH ), - URI_QUERY = 7, URI_QUERY_BIT = ( 1 << URI_QUERY ), - URI_FRAGMENT = 8, URI_FRAGMENT_BIT = ( 1 << URI_FRAGMENT ), - - URI_FIRST_FIELD = URI_SCHEME, - URI_LAST_FIELD = URI_FRAGMENT, -}; - -/** Extract field from URI */ -#define uri_get_field( uri, field ) (&uri->scheme)[field] +#define uri_field( uri, field ) (&uri->scheme)[field] -/** All URI fields */ -#define URI_ALL ( URI_SCHEME_BIT | URI_OPAQUE_BIT | URI_USER_BIT | \ - URI_PASSWORD_BIT | URI_HOST_BIT | URI_PORT_BIT | \ - URI_PATH_BIT | URI_QUERY_BIT | URI_FRAGMENT_BIT ) - -/** URI fields that should be decoded on storage */ -#define URI_ENCODED ( URI_USER_BIT | URI_PASSWORD_BIT | URI_HOST_BIT | \ - URI_PATH_BIT | URI_QUERY_BIT | URI_FRAGMENT_BIT ) +/** + * Calculate index of a URI field + * + * @v name URI field name + * @ret field URI field index + */ +#define URI_FIELD( name ) \ + ( ( offsetof ( struct uri, name ) - \ + offsetof ( struct uri, scheme ) ) / sizeof ( void * ) ) + +/** URI fields */ +enum uri_fields { + URI_SCHEME = URI_FIELD ( scheme ), + URI_OPAQUE = URI_FIELD ( opaque ), + URI_USER = URI_FIELD ( user ), + URI_PASSWORD = URI_FIELD ( password ), + URI_HOST = URI_FIELD ( host ), + URI_PORT = URI_FIELD ( port ), + URI_PATH = URI_FIELD ( path ), + URI_QUERY = URI_FIELD ( query ), + URI_FRAGMENT = URI_FIELD ( fragment ), + URI_FIELDS +}; /** * URI is an absolute URI @@ -125,8 +127,8 @@ static inline int uri_is_absolute ( const struct uri *uri ) { */ static inline int uri_has_opaque ( const struct uri *uri ) { return ( uri->opaque && ( uri->opaque[0] != '\0' ) ); - } + /** * URI has a path * @@ -189,18 +191,20 @@ uri_put ( struct uri *uri ) { extern struct uri *cwuri; +extern size_t uri_encode ( const char *string, unsigned int field, + char *buf, ssize_t len ); extern struct uri * parse_uri ( const char *uri_string ); -extern unsigned int uri_port ( struct uri *uri, unsigned int default_port ); -extern int unparse_uri ( char *buf, size_t size, struct uri *uri, - unsigned int fields ); -extern struct uri * uri_dup ( struct uri *uri ); +extern size_t format_uri ( const struct uri *uri, char *buf, size_t len ); +extern char * format_uri_alloc ( const struct uri *uri ); +extern unsigned int uri_port ( const struct uri *uri, + unsigned int default_port ); +extern struct uri * uri_dup ( const struct uri *uri ); extern char * resolve_path ( const char *base_path, const char *relative_path ); -extern struct uri * resolve_uri ( struct uri *base_uri, +extern struct uri * resolve_uri ( const struct uri *base_uri, struct uri *relative_uri ); +extern struct uri * tftp_uri ( struct in_addr next_server, + const char *filename ); extern void churi ( struct uri *uri ); -extern size_t uri_encode ( const char *raw_string, char *buf, ssize_t len, - int field ); -extern size_t uri_decode ( const char *encoded_string, char *buf, ssize_t len ); #endif /* _IPXE_URI_H */ |