iPXE
uri.h
Go to the documentation of this file.
00001 #ifndef _IPXE_URI_H
00002 #define _IPXE_URI_H
00003 
00004 /** @file
00005  *
00006  * Uniform Resource Identifiers
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <stddef.h>
00013 #include <stdlib.h>
00014 #include <ipxe/refcnt.h>
00015 #include <ipxe/in.h>
00016 
00017 struct parameters;
00018 
00019 /** A Uniform Resource Identifier
00020  *
00021  * Terminology for this data structure is as per uri(7), except that
00022  * "path" is defined to include the leading '/' for an absolute path.
00023  *
00024  * Note that all fields within a URI are optional and may be NULL.
00025  *
00026  * The pointers to the various fields are packed together so they can
00027  * be accessed in array fashion in some places in uri.c where doing so
00028  * saves significant code size.
00029  *
00030  * Some examples are probably helpful:
00031  *
00032  *   http://www.ipxe.org/wiki :
00033  *
00034  *   scheme = "http", host = "www.ipxe.org", path = "/wiki"
00035  *
00036  *   /var/lib/tftpboot :
00037  *
00038  *   path = "/var/lib/tftpboot"
00039  *
00040  *   mailto:bob@nowhere.com :
00041  *
00042  *   scheme = "mailto", opaque = "bob@nowhere.com"
00043  *
00044  *   ftp://joe:secret@insecure.org:8081/hidden/path/to?what=is#this
00045  *
00046  *   scheme = "ftp", user = "joe", password = "secret",
00047  *   host = "insecure.org", port = "8081", path = "/hidden/path/to",
00048  *   query = "what=is", fragment = "this"
00049  */
00050 struct uri {
00051         /** Reference count */
00052         struct refcnt refcnt;
00053         /** Scheme */
00054         const char *scheme;
00055         /** Opaque part */
00056         const char *opaque;
00057         /** User name */
00058         const char *user;
00059         /** Password */
00060         const char *password;
00061         /** Host name */
00062         const char *host;
00063         /** Port number */
00064         const char *port;
00065         /** Path */
00066         const char *path;
00067         /** Query */
00068         const char *query;
00069         /** Fragment */
00070         const char *fragment;
00071         /** Form parameters */
00072         struct parameters *params;
00073 } __attribute__ (( packed ));
00074 
00075 /**
00076  * Access URI field
00077  *
00078  * @v uri               URI
00079  * @v field             URI field index
00080  * @ret field           URI field (as an lvalue)
00081  */
00082 #define uri_field( uri, field ) (&uri->scheme)[field]
00083 
00084 /**
00085  * Calculate index of a URI field
00086  *
00087  * @v name              URI field name
00088  * @ret field           URI field index
00089  */
00090 #define URI_FIELD( name )                                               \
00091         ( ( offsetof ( struct uri, name ) -                             \
00092             offsetof ( struct uri, scheme ) ) / sizeof ( void * ) )
00093 
00094 /** URI fields */
00095 enum uri_fields {
00096         URI_SCHEME = URI_FIELD ( scheme ),
00097         URI_OPAQUE = URI_FIELD ( opaque ),
00098         URI_USER = URI_FIELD ( user ),
00099         URI_PASSWORD = URI_FIELD ( password ),
00100         URI_HOST = URI_FIELD ( host ),
00101         URI_PORT = URI_FIELD ( port ),
00102         URI_PATH = URI_FIELD ( path ),
00103         URI_QUERY = URI_FIELD ( query ),
00104         URI_FRAGMENT = URI_FIELD ( fragment ),
00105         URI_FIELDS
00106 };
00107 
00108 /**
00109  * URI is an absolute URI
00110  *
00111  * @v uri                       URI
00112  * @ret is_absolute             URI is absolute
00113  *
00114  * An absolute URI begins with a scheme, e.g. "http:" or "mailto:".
00115  * Note that this is a separate concept from a URI with an absolute
00116  * path.
00117  */
00118 static inline int uri_is_absolute ( const struct uri *uri ) {
00119         return ( uri->scheme != NULL );
00120 }
00121 
00122 /**
00123  * URI has an opaque part
00124  *
00125  * @v uri                       URI
00126  * @ret has_opaque              URI has an opaque part
00127  */
00128 static inline int uri_has_opaque ( const struct uri *uri ) {
00129         return ( uri->opaque && ( uri->opaque[0] != '\0' ) );
00130 }
00131 
00132 /**
00133  * URI has a path
00134  *
00135  * @v uri                       URI
00136  * @ret has_path                URI has a path
00137  */
00138 static inline int uri_has_path ( const struct uri *uri ) {
00139         return ( uri->path && ( uri->path[0] != '\0' ) );
00140 }
00141 
00142 /**
00143  * URI has an absolute path
00144  *
00145  * @v uri                       URI
00146  * @ret has_absolute_path       URI has an absolute path
00147  *
00148  * An absolute path begins with a '/'.  Note that this is a separate
00149  * concept from an absolute URI.  Note also that a URI may not have a
00150  * path at all.
00151  */
00152 static inline int uri_has_absolute_path ( const struct uri *uri ) {
00153         return ( uri->path && ( uri->path[0] == '/' ) );
00154 }
00155 
00156 /**
00157  * URI has a relative path
00158  *
00159  * @v uri                       URI
00160  * @ret has_relative_path       URI has a relative path
00161  *
00162  * A relative path begins with something other than a '/'.  Note that
00163  * this is a separate concept from a relative URI.  Note also that a
00164  * URI may not have a path at all.
00165  */
00166 static inline int uri_has_relative_path ( const struct uri *uri ) {
00167         return ( uri->path && ( uri->path[0] != '/' ) );
00168 }
00169 
00170 /**
00171  * Increment URI reference count
00172  *
00173  * @v uri               URI, or NULL
00174  * @ret uri             URI as passed in
00175  */
00176 static inline __attribute__ (( always_inline )) struct uri *
00177 uri_get ( struct uri *uri ) {
00178         ref_get ( &uri->refcnt );
00179         return uri;
00180 }
00181 
00182 /**
00183  * Decrement URI reference count
00184  *
00185  * @v uri               URI, or NULL
00186  */
00187 static inline __attribute__ (( always_inline )) void
00188 uri_put ( struct uri *uri ) {
00189         ref_put ( &uri->refcnt );
00190 }
00191 
00192 extern struct uri *cwuri;
00193 
00194 extern size_t uri_decode ( const char *encoded, void *buf, size_t len );
00195 extern size_t uri_encode ( unsigned int field, const void *raw, size_t raw_len,
00196                            char *buf, ssize_t len );
00197 extern size_t uri_encode_string ( unsigned int field, const char *string,
00198                                   char *buf, ssize_t len );
00199 extern struct uri * parse_uri ( const char *uri_string );
00200 extern size_t format_uri ( const struct uri *uri, char *buf, size_t len );
00201 extern char * format_uri_alloc ( const struct uri *uri );
00202 extern unsigned int uri_port ( const struct uri *uri,
00203                                unsigned int default_port );
00204 extern struct uri * uri_dup ( const struct uri *uri );
00205 extern char * resolve_path ( const char *base_path,
00206                              const char *relative_path );
00207 extern struct uri * resolve_uri ( const struct uri *base_uri,
00208                                   struct uri *relative_uri );
00209 extern struct uri * pxe_uri ( struct sockaddr *sa_server,
00210                               const char *filename );
00211 extern void churi ( struct uri *uri );
00212 
00213 #endif /* _IPXE_URI_H */