iPXE
Data Structures | Macros | Enumerations | Functions | Variables
uri.h File Reference

Uniform Resource Identifiers. More...

#include <stddef.h>
#include <stdlib.h>
#include <ipxe/refcnt.h>
#include <ipxe/in.h>

Go to the source code of this file.

Data Structures

struct  uri
 A Uniform Resource Identifier. More...
 

Macros

#define uri_field(uri, field)   (&uri->scheme)[field]
 Access URI field. More...
 
#define URI_FIELD(name)
 Calculate index of a URI field. More...
 

Enumerations

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_EPATH = URI_FIELD ( epath ),
  URI_EQUERY = URI_FIELD ( equery ), URI_EFRAGMENT = URI_FIELD ( efragment ), URI_FIELDS
}
 URI fields. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static int uri_is_absolute (const struct uri *uri)
 URI is an absolute URI. More...
 
static int uri_has_opaque (const struct uri *uri)
 URI has an opaque part. More...
 
static int uri_has_path (const struct uri *uri)
 URI has a path. More...
 
static int uri_has_absolute_path (const struct uri *uri)
 URI has an absolute path. More...
 
static int uri_has_relative_path (const struct uri *uri)
 URI has a relative path. More...
 
static struct uriuri_get (struct uri *uri)
 Increment URI reference count. More...
 
static void uri_put (struct uri *uri)
 Decrement URI reference count. More...
 
size_t uri_decode (const char *encoded, void *buf, size_t len)
 Decode URI field. More...
 
size_t uri_encode (unsigned int field, const void *raw, size_t raw_len, char *buf, ssize_t len)
 Encode URI field. More...
 
size_t uri_encode_string (unsigned int field, const char *string, char *buf, ssize_t len)
 Encode URI field string. More...
 
struct uriparse_uri (const char *uri_string)
 Parse URI. More...
 
size_t format_uri (const struct uri *uri, char *buf, size_t len)
 Format URI. More...
 
char * format_uri_alloc (const struct uri *uri)
 Format URI. More...
 
unsigned int uri_port (const struct uri *uri, unsigned int default_port)
 Get port from URI. More...
 
struct uriuri_dup (const struct uri *uri)
 Duplicate URI. More...
 
char * resolve_path (const char *base_path, const char *relative_path)
 Resolve base+relative path. More...
 
struct uriresolve_uri (const struct uri *base_uri, struct uri *relative_uri)
 Resolve base+relative URI. More...
 
struct uripxe_uri (struct sockaddr *sa_server, const char *filename)
 Construct URI from server address and filename. More...
 
void churi (struct uri *uri)
 Change working URI. More...
 

Variables

struct uricwuri
 Current working URI. More...
 

Detailed Description

Uniform Resource Identifiers.

Definition in file uri.h.

Macro Definition Documentation

◆ uri_field

#define uri_field (   uri,
  field 
)    (&uri->scheme)[field]

Access URI field.

Parameters
uriURI
fieldURI field index
Return values
fieldURI field (as an lvalue)

Definition at line 98 of file uri.h.

◆ URI_FIELD

#define URI_FIELD (   name)
Value:
( ( offsetof ( struct uri, name ) - \
offsetof ( struct uri, scheme ) ) / sizeof ( void * ) )
const char * name
Definition: ath9k_hw.c:1984
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
A Uniform Resource Identifier.
Definition: uri.h:64

Calculate index of a URI field.

Parameters
nameURI field name
Return values
fieldURI field index

Definition at line 106 of file uri.h.

Enumeration Type Documentation

◆ uri_fields

enum uri_fields

URI fields.

Enumerator
URI_SCHEME 
URI_OPAQUE 
URI_USER 
URI_PASSWORD 
URI_HOST 
URI_PORT 
URI_PATH 
URI_EPATH 
URI_EQUERY 
URI_EFRAGMENT 
URI_FIELDS 

Definition at line 111 of file uri.h.

111  {
112  URI_SCHEME = URI_FIELD ( scheme ),
113  URI_OPAQUE = URI_FIELD ( opaque ),
114  URI_USER = URI_FIELD ( user ),
115  URI_PASSWORD = URI_FIELD ( password ),
116  URI_HOST = URI_FIELD ( host ),
117  URI_PORT = URI_FIELD ( port ),
118  URI_PATH = URI_FIELD ( path ),
119  URI_EPATH = URI_FIELD ( epath ),
120  URI_EQUERY = URI_FIELD ( equery ),
121  URI_EFRAGMENT = URI_FIELD ( efragment ),
122  URI_FIELDS
123 };
Definition: uri.h:116
#define URI_FIELD(name)
Calculate index of a URI field.
Definition: uri.h:106
Definition: uri.h:117
Definition: uri.h:118
u8 port
Port number.
Definition: CIB_PRM.h:31
struct ntlm_data user
User name.
Definition: ntlm.h:20
Definition: uri.h:114
Definition: uri.h:119

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ uri_is_absolute()

static int uri_is_absolute ( const struct uri uri)
inlinestatic

URI is an absolute URI.

Parameters
uriURI
Return values
is_absoluteURI is absolute

An absolute URI begins with a scheme, e.g. "http:" or "mailto:". Note that this is a separate concept from a URI with an absolute path.

Definition at line 135 of file uri.h.

135  {
136  return ( uri->scheme != NULL );
137 }
const char * scheme
Scheme.
Definition: uri.h:68
A Uniform Resource Identifier.
Definition: uri.h:64
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References NULL, and uri::scheme.

Referenced by netboot(), pxe_uri(), and resolve_uri().

◆ uri_has_opaque()

static int uri_has_opaque ( const struct uri uri)
inlinestatic

URI has an opaque part.

Parameters
uriURI
Return values
has_opaqueURI has an opaque part

Definition at line 145 of file uri.h.

145  {
146  return ( uri->opaque && ( uri->opaque[0] != '\0' ) );
147 }
const char * opaque
Opaque part.
Definition: uri.h:70
A Uniform Resource Identifier.
Definition: uri.h:64

References uri::opaque.

◆ uri_has_path()

static int uri_has_path ( const struct uri uri)
inlinestatic

URI has a path.

Parameters
uriURI
Return values
has_pathURI has a path

Definition at line 155 of file uri.h.

155  {
156  return ( uri->path && ( uri->path[0] != '\0' ) );
157 }
const char * path
Path (after URI decoding)
Definition: uri.h:80
A Uniform Resource Identifier.
Definition: uri.h:64

References uri::path.

◆ uri_has_absolute_path()

static int uri_has_absolute_path ( const struct uri uri)
inlinestatic

URI has an absolute path.

Parameters
uriURI
Return values
has_absolute_pathURI has an absolute path

An absolute path begins with a '/'. Note that this is a separate concept from an absolute URI. Note also that a URI may not have a path at all.

Definition at line 169 of file uri.h.

169  {
170  return ( uri->path && ( uri->path[0] == '/' ) );
171 }
const char * path
Path (after URI decoding)
Definition: uri.h:80
A Uniform Resource Identifier.
Definition: uri.h:64

References uri::path.

◆ uri_has_relative_path()

static int uri_has_relative_path ( const struct uri uri)
inlinestatic

URI has a relative path.

Parameters
uriURI
Return values
has_relative_pathURI has a relative path

A relative path begins with something other than a '/'. Note that this is a separate concept from a relative URI. Note also that a URI may not have a path at all.

Definition at line 183 of file uri.h.

183  {
184  return ( uri->path && ( uri->path[0] != '/' ) );
185 }
const char * path
Path (after URI decoding)
Definition: uri.h:80
A Uniform Resource Identifier.
Definition: uri.h:64

References uri::path.

◆ uri_get()

static struct uri* uri_get ( struct uri uri)
inlinestatic

Increment URI reference count.

Parameters
uriURI, or NULL
Return values
uriURI as passed in

Definition at line 194 of file uri.h.

194  {
195  ref_get ( &uri->refcnt );
196  return uri;
197 }
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:92
struct refcnt refcnt
Reference count.
Definition: uri.h:66
A Uniform Resource Identifier.
Definition: uri.h:64

References ref_get, and uri::refcnt.

Referenced by alloc_sandev(), ftp_open(), http_connect(), http_open(), image_exec(), image_set_uri(), peerblk_open(), peermux_filter(), resolve_uri(), tftp_core_open(), and uri_churi_okx().

◆ uri_put()

static void uri_put ( struct uri uri)
inlinestatic

Decrement URI reference count.

Parameters
uriURI, or NULL

Definition at line 205 of file uri.h.

205  {
206  ref_put ( &uri->refcnt );
207 }
struct refcnt refcnt
Reference count.
Definition: uri.h:66
A Uniform Resource Identifier.
Definition: uri.h:64
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References ref_put, and uri::refcnt.

Referenced by churi(), efi_pxe_tftp_open(), free_image(), ftp_free(), http_conn_free(), http_free(), http_redirect(), image_exec(), image_set_uri(), imgdownload(), imgdownload_string(), netboot(), peerblk_free(), peerblk_retrieval_open(), peermux_free(), pxe_menu_boot(), pxe_uri(), sanboot_core_exec(), sandev_free(), tftp_apply_settings(), tftp_free(), uri_churi_okx(), uri_dup_okx(), uri_params_okx(), uri_parse_okx(), uri_port_okx(), uri_pxe_okx(), uri_resolve_okx(), xfer_open_uri(), and xfer_open_uri_string().

◆ uri_decode()

size_t uri_decode ( const char *  encoded,
void *  buf,
size_t  len 
)

Decode URI field.

Parameters
encodedEncoded field
bufData buffer
lenLength
Return values
lenLength of data

URI decoding can never increase the length of a string; we can therefore safely decode in place.

Definition at line 53 of file uri.c.

53  {
54  uint8_t *out = buf;
55  unsigned int count = 0;
56  char hexbuf[3];
57  char *hexbuf_end;
58  char c;
59  char decoded;
60  unsigned int skip;
61 
62  /* Copy string, decoding escaped characters as necessary */
63  while ( ( c = *(encoded++) ) ) {
64  if ( c == '%' ) {
65  snprintf ( hexbuf, sizeof ( hexbuf ), "%s", encoded );
66  decoded = strtoul ( hexbuf, &hexbuf_end, 16 );
67  skip = ( hexbuf_end - hexbuf );
68  encoded += skip;
69  if ( skip )
70  c = decoded;
71  }
72  if ( count < len )
73  out[count] = c;
74  count++;
75  }
76  return count;
77 }
uint32_t c
Definition: md4.c:30
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:471
__be32 out[4]
Definition: CIB_PRM.h:36
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
uint16_t count
Number of entries.
Definition: ena.h:22
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382

References c, count, len, out, snprintf(), and strtoul().

Referenced by parse_uristring_setting(), and uri_decode_inplace().

◆ uri_encode()

size_t uri_encode ( unsigned int  field,
const void *  raw,
size_t  raw_len,
char *  buf,
ssize_t  len 
)

Encode URI field.

Parameters
fieldURI field index
rawRaw data
raw_lenLength of raw data
bufBuffer
lenLength of buffer
Return values
lenLength of encoded string (excluding NUL)

Definition at line 200 of file uri.c.

201  {
202  const uint8_t *raw_bytes = ( ( const uint8_t * ) raw );
203  ssize_t remaining = len;
204  size_t used;
205  char c;
206 
207  /* Ensure encoded string is NUL-terminated even if empty */
208  if ( len > 0 )
209  buf[0] = '\0';
210 
211  /* Copy string, escaping as necessary */
212  while ( raw_len-- ) {
213  c = *(raw_bytes++);
214  if ( uri_character_escaped ( c, field ) ) {
215  used = ssnprintf ( buf, remaining, "%%%02X", c );
216  } else {
217  used = ssnprintf ( buf, remaining, "%c", c );
218  }
219  buf += used;
220  remaining -= used;
221  }
222 
223  return ( len - remaining );
224 }
uint32_t c
Definition: md4.c:30
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
Definition: vsprintf.c:420
static size_t raw_len
Definition: base16.h:50
static int uri_character_escaped(char c, unsigned int field)
Check if character should be escaped within a URI field.
Definition: uri.c:106
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
__be32 raw[7]
Definition: CIB_PRM.h:28
signed long ssize_t
Definition: stdint.h:7

References c, len, raw, raw_len, ssnprintf(), and uri_character_escaped().

Referenced by format_uristring_setting(), ocsp_uri_string(), and uri_encode_string().

◆ uri_encode_string()

size_t uri_encode_string ( unsigned int  field,
const char *  string,
char *  buf,
ssize_t  len 
)

Encode URI field string.

Parameters
fieldURI field index
stringString
bufBuffer
lenLength of buffer
Return values
lenLength of encoded string (excluding NUL)

Definition at line 235 of file uri.c.

236  {
237 
238  return uri_encode ( field, string, strlen ( string ), buf, len );
239 }
size_t uri_encode(unsigned int field, const void *raw, size_t raw_len, char *buf, ssize_t len)
Encode URI field.
Definition: uri.c:200
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
uint32_t len
Length.
Definition: ena.h:14

References len, strlen(), and uri_encode().

Referenced by format_uri(), and http_params().

◆ parse_uri()

struct uri* parse_uri ( const char *  uri_string)

Parse URI.

Parameters
uri_stringURI as a string
Return values
uriURI

Splits a URI into its component parts. The return URI structure is dynamically allocated and must eventually be freed by calling uri_put().

Definition at line 296 of file uri.c.

296  {
297  struct uri *uri;
298  struct parameters *params;
299  char *raw;
300  char *tmp;
301  char *path;
302  char *epath;
303  char *authority;
304  size_t raw_len;
305  unsigned int field;
306 
307  /* Allocate space for URI struct and two copies of the string */
308  raw_len = ( strlen ( uri_string ) + 1 /* NUL */ );
309  uri = zalloc ( sizeof ( *uri ) + ( 2 * raw_len ) );
310  if ( ! uri )
311  return NULL;
312  ref_init ( &uri->refcnt, uri_free );
313  raw = ( ( ( void * ) uri ) + sizeof ( *uri ) );
314  path = ( raw + raw_len );
315 
316  /* Copy in the raw string */
317  memcpy ( raw, uri_string, raw_len );
318 
319  /* Identify the parameter list, if present */
320  if ( ( tmp = strstr ( raw, "##params" ) ) ) {
321  *tmp = '\0';
322  tmp += 8 /* "##params" */;
323  params = find_parameters ( *tmp ? ( tmp + 1 ) : NULL );
324  if ( params ) {
325  uri->params = claim_parameters ( params );
326  } else {
327  /* Ignore non-existent submission blocks */
328  }
329  }
330 
331  /* Chop off the fragment, if it exists */
332  if ( ( tmp = strchr ( raw, '#' ) ) ) {
333  *(tmp++) = '\0';
334  uri->efragment = tmp;
335  }
336 
337  /* Identify absolute URIs */
338  epath = raw;
339  for ( tmp = raw ; ; tmp++ ) {
340  /* Possible scheme character (for our URI schemes) */
341  if ( isalpha ( *tmp ) || ( *tmp == '-' ) || ( *tmp == '_' ) )
342  continue;
343  /* Invalid scheme character or NUL: is a relative URI */
344  if ( *tmp != ':' )
345  break;
346  /* Absolute URI: identify hierarchical/opaque */
347  uri->scheme = raw;
348  *(tmp++) = '\0';
349  if ( *tmp == '/' ) {
350  /* Absolute URI with hierarchical part */
351  epath = tmp;
352  } else {
353  /* Absolute URI with opaque part */
354  uri->opaque = tmp;
355  epath = NULL;
356  }
357  break;
358  }
359 
360  /* If we don't have a path (i.e. we have an absolute URI with
361  * an opaque portion, we're already finished processing
362  */
363  if ( ! epath )
364  goto done;
365 
366  /* Chop off the query, if it exists */
367  if ( ( tmp = strchr ( epath, '?' ) ) ) {
368  *(tmp++) = '\0';
369  uri->equery = tmp;
370  }
371 
372  /* If we have no path remaining, then we're already finished
373  * processing.
374  */
375  if ( ! epath[0] )
376  goto done;
377 
378  /* Identify net/absolute/relative path */
379  if ( uri->scheme && ( strncmp ( epath, "//", 2 ) == 0 ) ) {
380  /* Net path. If this is terminated by the first '/'
381  * of an absolute path, then we have no space for a
382  * terminator after the authority field, so shuffle
383  * the authority down by one byte, overwriting one of
384  * the two slashes.
385  */
386  authority = ( epath + 2 );
387  if ( ( tmp = strchr ( authority, '/' ) ) ) {
388  /* Shuffle down */
389  uri->epath = tmp;
390  memmove ( ( authority - 1 ), authority,
391  ( tmp - authority ) );
392  authority--;
393  *(--tmp) = '\0';
394  }
395  } else {
396  /* Absolute/relative path */
397  uri->epath = epath;
398  authority = NULL;
399  }
400 
401  /* Create copy of path for decoding */
402  if ( uri->epath ) {
403  strcpy ( path, uri->epath );
404  uri->path = path;
405  }
406 
407  /* If we don't have an authority (i.e. we have a non-net
408  * path), we're already finished processing
409  */
410  if ( ! authority )
411  goto done;
412 
413  /* Split authority into user[:password] and host[:port] portions */
414  if ( ( tmp = strchr ( authority, '@' ) ) ) {
415  /* Has user[:password] */
416  *(tmp++) = '\0';
417  uri->host = tmp;
418  uri->user = authority;
419  if ( ( tmp = strchr ( authority, ':' ) ) ) {
420  /* Has password */
421  *(tmp++) = '\0';
422  uri->password = tmp;
423  }
424  } else {
425  /* No user:password */
426  uri->host = authority;
427  }
428 
429  /* Split host into host[:port] */
430  if ( ( tmp = strrchr ( uri->host, ':' ) ) &&
431  ( uri->host[ strlen ( uri->host ) - 1 ] != ']' ) ) {
432  *(tmp++) = '\0';
433  uri->port = tmp;
434  }
435 
436  done:
437  /* Decode fields in-place */
438  for ( field = 0 ; field < URI_EPATH ; field++ )
439  uri_decode_inplace ( ( char * ) uri_field ( uri, field ) );
440 
441  DBGC ( uri, "URI parsed \"%s\" to", uri_string );
442  uri_dump ( uri );
443  DBGC ( uri, "\n" );
444 
445  return uri;
446 }
const char * equery
Query (with original URI encoding)
Definition: uri.h:84
static void uri_dump(const struct uri *uri)
Dump URI for debugging.
Definition: uri.c:246
char * strrchr(const char *src, int character)
Find rightmost character within a string.
Definition: string.c:289
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
A form parameter list.
Definition: params.h:16
#define DBGC(...)
Definition: compiler.h:505
static int isalpha(int character)
Check if character is alphabetic.
Definition: ctype.h:64
struct parameters * find_parameters(const char *name)
Find form parameter list by name.
Definition: params.c:68
int strncmp(const char *first, const char *second, size_t max)
Compare strings.
Definition: string.c:186
const char * port
Port number.
Definition: uri.h:78
char * strstr(const char *haystack, const char *needle)
Find substring.
Definition: string.c:309
const char * scheme
Scheme.
Definition: uri.h:68
void * memcpy(void *dest, const void *src, size_t len) __nonnull
const char * path
Path (after URI decoding)
Definition: uri.h:80
char * strcpy(char *dest, const char *src)
Copy string.
Definition: string.c:326
struct parameters * params
Form parameters.
Definition: uri.h:88
static void uri_decode_inplace(char *encoded)
Decode URI field in-place.
Definition: uri.c:84
static size_t raw_len
Definition: base16.h:50
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
char * strchr(const char *src, int character)
Find character within a string.
Definition: string.c:271
uint8_t * tmp
Definition: entropy.h:156
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
const char * host
Host name.
Definition: uri.h:76
void * memmove(void *dest, const void *src, size_t len) __nonnull
Definition: uri.h:119
const char * efragment
Fragment (with original URI encoding)
Definition: uri.h:86
#define uri_field(uri, field)
Access URI field.
Definition: uri.h:98
const char * opaque
Opaque part.
Definition: uri.h:70
struct refcnt refcnt
Reference count.
Definition: uri.h:66
static void uri_free(struct refcnt *refcnt)
Free URI.
Definition: uri.c:279
const char * password
Password.
Definition: uri.h:74
const char * epath
Path (with original URI encoding)
Definition: uri.h:82
__be32 raw[7]
Definition: CIB_PRM.h:28
const char * user
User name.
Definition: uri.h:72
A Uniform Resource Identifier.
Definition: uri.h:64
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct bofm_section_header done
Definition: bofm_test.c:46

References DBGC, done, uri::efragment, uri::epath, uri::equery, find_parameters(), uri::host, isalpha(), memcpy(), memmove(), NULL, uri::opaque, uri::params, uri::password, uri::path, uri::port, raw, raw_len, ref_init, uri::refcnt, uri::scheme, strchr(), strcpy(), strlen(), strncmp(), strrchr(), strstr(), tmp, uri_decode_inplace(), uri_dump(), URI_EPATH, uri_field, uri_free(), uri::user, and zalloc().

Referenced by fetch_root_path(), http_redirect(), imgdownload_string(), peerblk_retrieval_uri(), pxe_uri(), sanboot_core_exec(), tftp_apply_settings(), uri_churi_okx(), uri_params_okx(), uri_parse_okx(), uri_port_okx(), uri_resolve_okx(), and xfer_open_uri_string().

◆ format_uri()

size_t format_uri ( const struct uri uri,
char *  buf,
size_t  len 
)

Format URI.

Parameters
uriURI
bufBuffer to fill with URI string
sizeSize of buffer
Return values
lenLength of URI string

Definition at line 471 of file uri.c.

471  {
472  static const char prefixes[URI_FIELDS] = {
473  [URI_PASSWORD] = ':',
474  [URI_PORT] = ':',
475  [URI_EQUERY] = '?',
476  [URI_EFRAGMENT] = '#',
477  };
478  char prefix;
479  size_t used = 0;
480  unsigned int field;
481 
482  /* Ensure buffer is NUL-terminated */
483  if ( len )
484  buf[0] = '\0';
485 
486  /* Special-case NULL URI */
487  if ( ! uri )
488  return 0;
489 
490  /* Generate fields */
491  for ( field = 0 ; field < URI_FIELDS ; field++ ) {
492 
493  /* Skip non-existent fields */
494  if ( ! uri_field ( uri, field ) )
495  continue;
496 
497  /* Skip path field if encoded path is present */
498  if ( ( field == URI_PATH ) && uri->epath )
499  continue;
500 
501  /* Prefix this field, if applicable */
502  prefix = prefixes[field];
503  if ( ( field == URI_HOST ) && ( uri->user != NULL ) )
504  prefix = '@';
505  if ( prefix ) {
506  used += ssnprintf ( ( buf + used ), ( len - used ),
507  "%c", prefix );
508  }
509 
510  /* Encode this field */
511  used += uri_encode_string ( field, uri_field ( uri, field ),
512  ( buf + used ), ( len - used ) );
513 
514  /* Suffix this field, if applicable */
515  if ( field == URI_SCHEME ) {
516  used += ssnprintf ( ( buf + used ), ( len - used ),
517  ":%s", ( uri->host ? "//" : "" ) );
518  }
519  }
520 
521  if ( len ) {
522  DBGC ( uri, "URI formatted" );
523  uri_dump ( uri );
524  DBGC ( uri, " to \"%s%s\"\n", buf,
525  ( ( used > len ) ? "<TRUNCATED>" : "" ) );
526  }
527 
528  return used;
529 }
Definition: uri.h:116
size_t uri_encode_string(unsigned int field, const char *string, char *buf, ssize_t len)
Encode URI field string.
Definition: uri.c:235
static void uri_dump(const struct uri *uri)
Dump URI for debugging.
Definition: uri.c:246
#define DBGC(...)
Definition: compiler.h:505
char prefix[4]
Definition: vmconsole.c:53
Definition: uri.h:117
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
Definition: vsprintf.c:420
Definition: uri.h:118
const char * host
Host name.
Definition: uri.h:76
uint32_t len
Length.
Definition: ena.h:14
#define uri_field(uri, field)
Access URI field.
Definition: uri.h:98
const char * epath
Path (with original URI encoding)
Definition: uri.h:82
const char * user
User name.
Definition: uri.h:72
A Uniform Resource Identifier.
Definition: uri.h:64
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References DBGC, uri::epath, uri::host, len, NULL, prefix, ssnprintf(), uri_dump(), URI_EFRAGMENT, uri_encode_string(), URI_EQUERY, uri_field, URI_FIELDS, URI_HOST, URI_PASSWORD, URI_PATH, URI_PORT, URI_SCHEME, and uri::user.

Referenced by efi_uri_path(), format_uri_alloc(), http_open(), multiboot_add_cmdline(), uri_format_okx(), and uri_pxe_okx().

◆ format_uri_alloc()

char* format_uri_alloc ( const struct uri uri)

Format URI.

Parameters
uriURI
Return values
stringURI string, or NULL on failure

The caller is responsible for eventually freeing the allocated memory.

Definition at line 540 of file uri.c.

540  {
541  size_t len;
542  char *string;
543 
544  len = ( format_uri ( uri, NULL, 0 ) + 1 /* NUL */ );
545  string = malloc ( len );
546  if ( string )
547  format_uri ( uri, string, len );
548  return string;
549 }
uint32_t string
Definition: multiboot.h:14
size_t format_uri(const struct uri *uri, char *buf, size_t len)
Format URI.
Definition: uri.c:471
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint32_t len
Length.
Definition: ena.h:14
A Uniform Resource Identifier.
Definition: uri.h:64
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References format_uri(), len, malloc(), NULL, and string.

Referenced by imgdownload(), uri_churi_okx(), uri_format_okx(), and uri_resolve_okx().

◆ uri_port()

unsigned int uri_port ( const struct uri uri,
unsigned int  default_port 
)

Get port from URI.

Parameters
uriURI, or NULL
default_portDefault port to use if none specified in URI
Return values
portPort

Definition at line 455 of file uri.c.

455  {
456 
457  if ( ( ! uri ) || ( ! uri->port ) )
458  return default_port;
459 
460  return ( strtoul ( uri->port, NULL, 0 ) );
461 }
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:471
const char * port
Port number.
Definition: uri.h:78
A Uniform Resource Identifier.
Definition: uri.h:64
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References NULL, uri::port, and strtoul().

Referenced by ftp_open(), http_connect(), slam_open(), tcp_open_uri(), tftp_core_open(), udp_open_uri(), and uri_port_okx().

◆ uri_dup()

struct uri* uri_dup ( const struct uri uri)

Duplicate URI.

Parameters
uriURI
Return values
uriDuplicate URI

Creates a modifiable copy of a URI.

Definition at line 594 of file uri.c.

594  {
595  struct uri *dup;
596  size_t len;
597 
598  /* Allocate new URI */
599  len = uri_copy_fields ( uri, NULL );
600  dup = zalloc ( len );
601  if ( ! dup )
602  return NULL;
603  ref_init ( &dup->refcnt, uri_free );
604 
605  /* Copy fields */
606  uri_copy_fields ( uri, dup );
607 
608  /* Copy parameters */
609  dup->params = params_get ( uri->params );
610 
611  DBGC ( uri, "URI duplicated" );
612  uri_dump ( uri );
613  DBGC ( uri, "\n" );
614 
615  return dup;
616 }
static void uri_dump(const struct uri *uri)
Dump URI for debugging.
Definition: uri.c:246
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
#define DBGC(...)
Definition: compiler.h:505
static size_t uri_copy_fields(const struct uri *src, struct uri *dest)
Copy URI fields.
Definition: uri.c:558
struct parameters * params
Form parameters.
Definition: uri.h:88
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
uint32_t len
Length.
Definition: ena.h:14
struct refcnt refcnt
Reference count.
Definition: uri.h:66
static void uri_free(struct refcnt *refcnt)
Free URI.
Definition: uri.c:279
A Uniform Resource Identifier.
Definition: uri.h:64
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References DBGC, len, NULL, uri::params, ref_init, uri::refcnt, uri_copy_fields(), uri_dump(), uri_free(), and zalloc().

Referenced by resolve_uri(), tftp_uri(), uri_dup_okx(), and uri_params_okx().

◆ resolve_path()

char* resolve_path ( const char *  base_path,
const char *  relative_path 
)

Resolve base+relative path.

Parameters
base_uriBase path
relative_uriRelative path
Return values
resolved_uriResolved path, or NULL on failure

Takes a base path (e.g. "/var/lib/tftpboot/vmlinuz" and a relative path (e.g. "initrd.gz") and produces a new path (e.g. "/var/lib/tftpboot/initrd.gz"). Note that any non-directory portion of the base path will automatically be stripped; this matches the semantics used when resolving the path component of URIs.

Definition at line 632 of file uri.c.

633  {
634  char *base_copy;
635  char *base_tmp;
636  char *resolved;
637 
638  /* If relative path is absolute, just re-use it */
639  if ( relative_path[0] == '/' )
640  return strdup ( relative_path );
641 
642  /* Create modifiable copy of path for dirname() */
643  base_copy = strdup ( base_path );
644  if ( ! base_copy )
645  return NULL;
646 
647  /* Strip filename portion of base path */
648  base_tmp = dirname ( base_copy );
649 
650  /* Process "./" and "../" elements */
651  while ( *relative_path == '.' ) {
652  relative_path++;
653  if ( *relative_path == 0 ) {
654  /* Do nothing */
655  } else if ( *relative_path == '/' ) {
656  relative_path++;
657  } else if ( *relative_path == '.' ) {
658  relative_path++;
659  if ( *relative_path == 0 ) {
660  base_tmp = dirname ( base_tmp );
661  } else if ( *relative_path == '/' ) {
662  base_tmp = dirname ( base_tmp );
663  relative_path++;
664  } else {
665  relative_path -= 2;
666  break;
667  }
668  } else {
669  relative_path--;
670  break;
671  }
672  }
673 
674  /* Create and return new path */
675  if ( asprintf ( &resolved, "%s%s%s", base_tmp,
676  ( ( base_tmp[ strlen ( base_tmp ) - 1 ] == '/' ) ?
677  "" : "/" ), relative_path ) < 0 )
678  resolved = NULL;
679  free ( base_copy );
680  return resolved;
681 }
char * dirname(char *path)
Return directory name from path.
Definition: basename.c:57
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition: asprintf.c:41
char * strdup(const char *src)
Duplicate string.
Definition: string.c:380
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References asprintf(), dirname(), free, NULL, strdup(), and strlen().

Referenced by efi_local_open_path(), resolve_uri(), and uri_resolve_path_okx().

◆ resolve_uri()

struct uri* resolve_uri ( const struct uri base_uri,
struct uri relative_uri 
)

Resolve base+relative URI.

Parameters
base_uriBase URI, or NULL
relative_uriRelative URI
Return values
resolved_uriResolved URI, or NULL on failure

Takes a base URI (e.g. "http://ipxe.org/kernels/vmlinuz" and a relative URI (e.g. "../initrds/initrd.gz") and produces a new URI (e.g. "http://ipxe.org/initrds/initrd.gz").

Definition at line 694 of file uri.c.

695  {
696  struct uri tmp_uri;
697  char *tmp_epath = NULL;
698  char *tmp_path = NULL;
699  struct uri *new_uri;
700 
701  /* If relative URI is absolute, just re-use it */
702  if ( uri_is_absolute ( relative_uri ) || ( ! base_uri ) )
703  return uri_get ( relative_uri );
704 
705  /* Mangle URI */
706  memcpy ( &tmp_uri, base_uri, sizeof ( tmp_uri ) );
707  if ( relative_uri->epath ) {
708  tmp_epath = resolve_path ( ( base_uri->epath ?
709  base_uri->epath : "/" ),
710  relative_uri->epath );
711  if ( ! tmp_epath )
712  goto err_epath;
713  tmp_path = strdup ( tmp_epath );
714  if ( ! tmp_path )
715  goto err_path;
716  uri_decode_inplace ( tmp_path );
717  tmp_uri.epath = tmp_epath;
718  tmp_uri.path = tmp_path;
719  tmp_uri.equery = relative_uri->equery;
720  tmp_uri.efragment = relative_uri->efragment;
721  tmp_uri.params = relative_uri->params;
722  } else if ( relative_uri->equery ) {
723  tmp_uri.equery = relative_uri->equery;
724  tmp_uri.efragment = relative_uri->efragment;
725  tmp_uri.params = relative_uri->params;
726  } else if ( relative_uri->efragment ) {
727  tmp_uri.efragment = relative_uri->efragment;
728  tmp_uri.params = relative_uri->params;
729  } else if ( relative_uri->params ) {
730  tmp_uri.params = relative_uri->params;
731  }
732 
733  /* Create demangled URI */
734  new_uri = uri_dup ( &tmp_uri );
735  free ( tmp_path );
736  free ( tmp_epath );
737  return new_uri;
738 
739  free ( tmp_path );
740  err_path:
741  free ( tmp_epath );
742  err_epath:
743  return NULL;
744 }
const char * equery
Query (with original URI encoding)
Definition: uri.h:84
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition: uri.h:194
static int uri_is_absolute(const struct uri *uri)
URI is an absolute URI.
Definition: uri.h:135
void * memcpy(void *dest, const void *src, size_t len) __nonnull
char * resolve_path(const char *base_path, const char *relative_path)
Resolve base+relative path.
Definition: uri.c:632
struct parameters * params
Form parameters.
Definition: uri.h:88
static void uri_decode_inplace(char *encoded)
Decode URI field in-place.
Definition: uri.c:84
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct uri * uri_dup(const struct uri *uri)
Duplicate URI.
Definition: uri.c:594
char * strdup(const char *src)
Duplicate string.
Definition: string.c:380
const char * efragment
Fragment (with original URI encoding)
Definition: uri.h:86
const char * epath
Path (with original URI encoding)
Definition: uri.h:82
A Uniform Resource Identifier.
Definition: uri.h:64
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References uri::efragment, uri::epath, uri::equery, free, memcpy(), NULL, uri::params, uri::path, resolve_path(), strdup(), uri_decode_inplace(), uri_dup(), uri_get(), and uri_is_absolute().

Referenced by churi(), http_redirect(), imgdownload(), uri_resolve_okx(), and xfer_open_uri().

◆ pxe_uri()

struct uri* pxe_uri ( struct sockaddr sa_server,
const char *  filename 
)

Construct URI from server address and filename.

Parameters
sa_serverServer address
filenameFilename
Return values
uriURI, or NULL on failure

PXE TFTP filenames specified via the DHCP next-server field often contain characters such as ':' or '#' which would confuse the generic URI parser. We provide a mechanism for directly constructing a TFTP URI from the next-server and filename.

Definition at line 808 of file uri.c.

808  {
809  struct uri *uri;
810 
811  /* Fail if filename is empty */
812  if ( ! ( filename && filename[0] ) )
813  return NULL;
814 
815  /* If filename is a hierarchical absolute URI, then use that
816  * URI. (We accept only hierarchical absolute URIs, since PXE
817  * filenames sometimes start with DOS drive letters such as
818  * "C:\", which get misinterpreted as opaque absolute URIs.)
819  */
820  uri = parse_uri ( filename );
821  if ( uri && uri_is_absolute ( uri ) && ( ! uri->opaque ) )
822  return uri;
823  uri_put ( uri );
824 
825  /* Otherwise, construct a TFTP URI directly */
826  return tftp_uri ( sa_server, filename );
827 }
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:205
static int uri_is_absolute(const struct uri *uri)
URI is an absolute URI.
Definition: uri.h:135
static struct uri * tftp_uri(struct sockaddr *sa_server, const char *filename)
Construct TFTP URI from server address and filename.
Definition: uri.c:753
const char * opaque
Opaque part.
Definition: uri.h:70
A Uniform Resource Identifier.
Definition: uri.h:64
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition: uri.c:296

References NULL, uri::opaque, parse_uri(), tftp_uri(), uri_is_absolute(), and uri_put().

Referenced by efi_pxe_tftp_open(), fetch_next_server_and_filename(), pxe_tftp_open(), and uri_pxe_okx().

◆ churi()

void churi ( struct uri uri)

Change working URI.

Parameters
uriNew working URI, or NULL

Definition at line 45 of file cwuri.c.

45  {
46  struct uri *new_uri = NULL;
47 
48  if ( uri )
49  new_uri = resolve_uri ( cwuri, uri );
50 
51  uri_put ( cwuri );
52  cwuri = new_uri;
53 }
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:205
A Uniform Resource Identifier.
Definition: uri.h:64
struct uri * resolve_uri(const struct uri *base_uri, struct uri *relative_uri)
Resolve base+relative URI.
Definition: uri.c:694
struct uri * cwuri
Current working URI.
Definition: cwuri.c:38
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References cwuri, NULL, resolve_uri(), and uri_put().

Referenced by image_exec(), tftp_apply_settings(), and uri_churi_okx().

Variable Documentation

◆ cwuri

struct uri* cwuri

Current working URI.

Definition at line 38 of file cwuri.c.

Referenced by churi(), image_exec(), imgdownload(), uri_churi_okx(), and xfer_open_uri().