Home | History | Annotate | Download | only in gpxe
      1 #ifndef _GPXE_URI_H
      2 #define _GPXE_URI_H
      3 
      4 /** @file
      5  *
      6  * Uniform Resource Identifiers
      7  *
      8  */
      9 
     10 FILE_LICENCE ( GPL2_OR_LATER );
     11 
     12 #include <stddef.h>
     13 #include <stdlib.h>
     14 #include <gpxe/refcnt.h>
     15 
     16 /** A Uniform Resource Identifier
     17  *
     18  * Terminology for this data structure is as per uri(7), except that
     19  * "path" is defined to include the leading '/' for an absolute path.
     20  *
     21  * Note that all fields within a URI are optional and may be NULL.
     22  *
     23  * The pointers to the various fields are packed together so they can
     24  * be accessed in array fashion in some places in uri.c where doing so
     25  * saves significant code size.
     26  *
     27  * Some examples are probably helpful:
     28  *
     29  *   http://www.etherboot.org/wiki :
     30  *
     31  *   scheme = "http", host = "www.etherboot.org", path = "/wiki"
     32  *
     33  *   /var/lib/tftpboot :
     34  *
     35  *   path = "/var/lib/tftpboot"
     36  *
     37  *   mailto:bob (at) nowhere.com :
     38  *
     39  *   scheme = "mailto", opaque = "bob (at) nowhere.com"
     40  *
     41  *   ftp://joe:secret@insecure.org:8081/hidden/path/to?what=is#this
     42  *
     43  *   scheme = "ftp", user = "joe", password = "secret",
     44  *   host = "insecure.org", port = "8081", path = "/hidden/path/to",
     45  *   query = "what=is", fragment = "this"
     46  */
     47 struct uri {
     48 	/** Reference count */
     49 	struct refcnt refcnt;
     50 	/** Scheme */
     51 	const char *scheme;
     52 	/** Opaque part */
     53 	const char *opaque;
     54 	/** User name */
     55 	const char *user;
     56 	/** Password */
     57 	const char *password;
     58 	/** Host name */
     59 	const char *host;
     60 	/** Port number */
     61 	const char *port;
     62 	/** Path */
     63 	const char *path;
     64 	/** Query */
     65 	const char *query;
     66 	/** Fragment */
     67 	const char *fragment;
     68 } __attribute__ (( packed ));
     69 
     70 /** A field in a URI
     71  *
     72  * The order of the indices in this enumeration must match the order
     73  * of the fields in the URI structure.
     74  */
     75 enum {
     76 	URI_SCHEME = 0,		URI_SCHEME_BIT = ( 1 << URI_SCHEME ),
     77 	URI_OPAQUE = 1,		URI_OPAQUE_BIT = ( 1 << URI_OPAQUE ),
     78 	URI_USER = 2,		URI_USER_BIT = ( 1 << URI_USER ),
     79 	URI_PASSWORD = 3,	URI_PASSWORD_BIT = ( 1 << URI_PASSWORD ),
     80 	URI_HOST = 4,		URI_HOST_BIT = ( 1 << URI_HOST ),
     81 	URI_PORT = 5,		URI_PORT_BIT = ( 1 << URI_PORT ),
     82 	URI_PATH = 6,		URI_PATH_BIT = ( 1 << URI_PATH ),
     83 	URI_QUERY = 7,		URI_QUERY_BIT = ( 1 << URI_QUERY ),
     84 	URI_FRAGMENT = 8,	URI_FRAGMENT_BIT = ( 1 << URI_FRAGMENT ),
     85 
     86 	URI_FIRST_FIELD = URI_SCHEME,
     87 	URI_LAST_FIELD = URI_FRAGMENT,
     88 };
     89 
     90 /** Extract field from URI */
     91 #define uri_get_field( uri, field )	(&uri->scheme)[field]
     92 
     93 /** All URI fields */
     94 #define URI_ALL		( URI_SCHEME_BIT | URI_OPAQUE_BIT | URI_USER_BIT | \
     95 			  URI_PASSWORD_BIT | URI_HOST_BIT | URI_PORT_BIT | \
     96 			  URI_PATH_BIT | URI_QUERY_BIT | URI_FRAGMENT_BIT )
     97 
     98 /** URI fields that should be decoded on storage */
     99 #define URI_ENCODED	( URI_USER_BIT | URI_PASSWORD_BIT | URI_HOST_BIT | \
    100 			  URI_PATH_BIT | URI_QUERY_BIT | URI_FRAGMENT_BIT )
    101 
    102 /**
    103  * URI is an absolute URI
    104  *
    105  * @v uri			URI
    106  * @ret is_absolute		URI is absolute
    107  *
    108  * An absolute URI begins with a scheme, e.g. "http:" or "mailto:".
    109  * Note that this is a separate concept from a URI with an absolute
    110  * path.
    111  */
    112 static inline int uri_is_absolute ( struct uri *uri ) {
    113 	return ( uri->scheme != NULL );
    114 }
    115 
    116 /**
    117  * URI has an absolute path
    118  *
    119  * @v uri			URI
    120  * @ret has_absolute_path	URI has an absolute path
    121  *
    122  * An absolute path begins with a '/'.  Note that this is a separate
    123  * concept from an absolute URI.  Note also that a URI may not have a
    124  * path at all.
    125  */
    126 static inline int uri_has_absolute_path ( struct uri *uri ) {
    127 	return ( uri->path && ( uri->path[0] == '/' ) );
    128 }
    129 
    130 /**
    131  * URI has a relative path
    132  *
    133  * @v uri			URI
    134  * @ret has_relative_path	URI has a relative path
    135  *
    136  * A relative path begins with something other than a '/'.  Note that
    137  * this is a separate concept from a relative URI.  Note also that a
    138  * URI may not have a path at all.
    139  */
    140 static inline int uri_has_relative_path ( struct uri *uri ) {
    141 	return ( uri->path && ( uri->path[0] != '/' ) );
    142 }
    143 
    144 /**
    145  * Increment URI reference count
    146  *
    147  * @v uri		URI, or NULL
    148  * @ret uri		URI as passed in
    149  */
    150 static inline __attribute__ (( always_inline )) struct uri *
    151 uri_get ( struct uri *uri ) {
    152 	ref_get ( &uri->refcnt );
    153 	return uri;
    154 }
    155 
    156 /**
    157  * Decrement URI reference count
    158  *
    159  * @v uri		URI, or NULL
    160  */
    161 static inline __attribute__ (( always_inline )) void
    162 uri_put ( struct uri *uri ) {
    163 	ref_put ( &uri->refcnt );
    164 }
    165 
    166 extern struct uri *cwuri;
    167 
    168 extern struct uri * parse_uri ( const char *uri_string );
    169 extern unsigned int uri_port ( struct uri *uri, unsigned int default_port );
    170 extern int unparse_uri ( char *buf, size_t size, struct uri *uri,
    171 			 unsigned int fields );
    172 extern struct uri * uri_dup ( struct uri *uri );
    173 extern char * resolve_path ( const char *base_path,
    174 			     const char *relative_path );
    175 extern struct uri * resolve_uri ( struct uri *base_uri,
    176 				  struct uri *relative_uri );
    177 extern void churi ( struct uri *uri );
    178 extern size_t uri_encode ( const char *raw_string, char *buf, ssize_t len,
    179 			   int field );
    180 extern size_t uri_decode ( const char *encoded_string, char *buf, ssize_t len );
    181 
    182 #endif /* _GPXE_URI_H */
    183