Add uri_base setting for getting the host:port portion of a URI.

This is useful for fetching relative URLs based on the DHCP server
provided file URI.
pull/114/head
planier 2020-05-28 11:43:18 -04:00
parent ebff21a515
commit 4e0bbc6640
3 changed files with 60 additions and 0 deletions

View File

@ -697,6 +697,10 @@ int fetch_setting ( struct settings *settings, const struct setting *setting,
if ( ( ret = settings->op->fetch ( settings, &tmp,
data, len ) ) >= 0 ) {
/* If incoming setting has a type, copy it over in
* case it was overridden. */
if ( setting->type )
tmp.type = setting->type;
/* Default to string type, if not yet specified */
if ( ! tmp.type )
tmp.type = &setting_type_string;
@ -1714,6 +1718,48 @@ const struct setting_type setting_type_uristring __setting_type = {
.format = format_uristring_setting,
};
/**
* Format a URI without the path, query, and fragment portions.
*
* @v type Setting type
* @v raw Raw setting value
* @v raw_len Length of raw setting value
* @v buf Buffer to contain formatted value
* @v len Length of buffer
* @ret len Length of formatted value, or negative error
*/
static int format_uribase_setting ( const struct setting_type *type __unused,
const void *raw, size_t raw_len,
char *buf, size_t len ) {
char *raw_str;
struct uri *base_uri;
size_t ret;
raw_str = strndup((const char*)raw, raw_len);
if (!raw_str) {
return -ENOMEM;
}
base_uri = parse_uri(raw_str);
if (!base_uri) {
ret = -ENOMEM;
goto err_uri_parse;
}
base_uri->path = NULL;
base_uri->query = NULL;
base_uri->fragment = NULL;
ret = format_uri(base_uri, buf, len);
uri_put(base_uri);
err_uri_parse:
free(raw_str);
return ret;
}
/** A setting to strip path, query, and fragment from a URI */
const struct setting_type setting_type_uribase __setting_type = {
.name = "uribase",
.format = format_uribase_setting,
};
/**
* Parse IPv4 address setting value (when IPv4 support is not present)
*

View File

@ -413,6 +413,7 @@ extern char * expand_settings ( const char *string );
extern const struct setting_type setting_type_string __setting_type;
extern const struct setting_type setting_type_uristring __setting_type;
extern const struct setting_type setting_type_uribase __setting_type;
extern const struct setting_type setting_type_ipv4 __setting_type;
extern const struct setting_type setting_type_ipv6 __setting_type;
extern const struct setting_type setting_type_int8 __setting_type;

View File

@ -172,6 +172,12 @@ static struct setting test_uristring_setting = {
.type = &setting_type_uristring,
};
/** Test URI base setting */
static struct setting test_uribase_setting = {
.name = "test_uribase",
.type = &setting_type_uribase,
};
/** Test IPv4 address setting type */
static struct setting test_ipv4_setting = {
.name = "test_ipv4",
@ -281,6 +287,13 @@ static void settings_test_exec ( void ) {
RAW ( 0, ' ', '%', '/', '#', ':', '@', '?', '=', '&' ),
"%00%20%25%2F%23%3A%40%3F%3D%26" );
/* "uribase" setting type (no store capability) */
fetchf_ok ( &test_settings, &test_uribase_setting,
RAW ( 'h', 't', 't', 'p', ':', '/', '/', 's', 'o', 'm', 'e',
'.', 's', 'e', 'r', 'v', 'e', 'r', ':', '1', '2', '3',
'4', '/', 'p', 'a', 't', 'h', '?', 'q', '#', 'f'),
"http://some.server:1234" );
/* "ipv4" setting type */
storef_ok ( &test_settings, &test_ipv4_setting, "192.168.0.1",
RAW ( 192, 168, 0, 1 ) );