mirror of https://github.com/ipxe/ipxe.git
[params] Allow for arbitrary HTTP request headers to be specified
Extend the request parameter mechanism to allow for arbitrary HTTP headers to be specified via e.g.: params param --header Referer http://www.example.com imgfetch http://192.168.0.1/script.ipxe##params Signed-off-by: Michael Brown <mcb30@ipxe.org>efivars
parent
33cb56cf1b
commit
96bb6ba441
|
@ -123,10 +123,12 @@ struct parameters * create_parameters ( const char *name ) {
|
||||||
* @v params Parameter list
|
* @v params Parameter list
|
||||||
* @v key Parameter key
|
* @v key Parameter key
|
||||||
* @v value Parameter value
|
* @v value Parameter value
|
||||||
|
* @v flags Parameter flags
|
||||||
* @ret param Parameter, or NULL on failure
|
* @ret param Parameter, or NULL on failure
|
||||||
*/
|
*/
|
||||||
struct parameter * add_parameter ( struct parameters *params,
|
struct parameter * add_parameter ( struct parameters *params,
|
||||||
const char *key, const char *value ) {
|
const char *key, const char *value,
|
||||||
|
unsigned int flags ) {
|
||||||
struct parameter *param;
|
struct parameter *param;
|
||||||
size_t key_len;
|
size_t key_len;
|
||||||
size_t value_len;
|
size_t value_len;
|
||||||
|
@ -147,11 +149,14 @@ struct parameter * add_parameter ( struct parameters *params,
|
||||||
param->key = key_copy;
|
param->key = key_copy;
|
||||||
strcpy ( value_copy, value );
|
strcpy ( value_copy, value );
|
||||||
param->value = value_copy;
|
param->value = value_copy;
|
||||||
|
param->flags = flags;
|
||||||
|
|
||||||
/* Add to list of parameters */
|
/* Add to list of parameters */
|
||||||
list_add_tail ( ¶m->list, ¶ms->entries );
|
list_add_tail ( ¶m->list, ¶ms->entries );
|
||||||
|
|
||||||
DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"\n",
|
DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"%s%s\n",
|
||||||
params->name, param->key, param->value );
|
params->name, param->key, param->value,
|
||||||
|
( ( param->flags & PARAMETER_FORM ) ? " (form)" : "" ),
|
||||||
|
( ( param->flags & PARAMETER_HEADER ) ? " (header)" : "" ) );
|
||||||
return param;
|
return param;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,12 +90,16 @@ static int params_exec ( int argc, char **argv ) {
|
||||||
struct param_options {
|
struct param_options {
|
||||||
/** Parameter list name */
|
/** Parameter list name */
|
||||||
char *params;
|
char *params;
|
||||||
|
/** Parameter is a header */
|
||||||
|
int header;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** "param" option list */
|
/** "param" option list */
|
||||||
static struct option_descriptor param_opts[] = {
|
static struct option_descriptor param_opts[] = {
|
||||||
OPTION_DESC ( "params", 'p', required_argument,
|
OPTION_DESC ( "params", 'p', required_argument,
|
||||||
struct param_options, params, parse_string ),
|
struct param_options, params, parse_string ),
|
||||||
|
OPTION_DESC ( "header", 'H', no_argument,
|
||||||
|
struct param_options, header, parse_flag ),
|
||||||
};
|
};
|
||||||
|
|
||||||
/** "param" command descriptor */
|
/** "param" command descriptor */
|
||||||
|
@ -114,6 +118,7 @@ static int param_exec ( int argc, char **argv ) {
|
||||||
struct param_options opts;
|
struct param_options opts;
|
||||||
char *key;
|
char *key;
|
||||||
char *value;
|
char *value;
|
||||||
|
unsigned int flags;
|
||||||
struct parameters *params;
|
struct parameters *params;
|
||||||
struct parameter *param;
|
struct parameter *param;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -132,12 +137,15 @@ static int param_exec ( int argc, char **argv ) {
|
||||||
goto err_parse_value;
|
goto err_parse_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Construct flags */
|
||||||
|
flags = ( opts.header ? PARAMETER_HEADER : PARAMETER_FORM );
|
||||||
|
|
||||||
/* Identify parameter list */
|
/* Identify parameter list */
|
||||||
if ( ( rc = parse_parameters ( opts.params, ¶ms ) ) != 0 )
|
if ( ( rc = parse_parameters ( opts.params, ¶ms ) ) != 0 )
|
||||||
goto err_parse_parameters;
|
goto err_parse_parameters;
|
||||||
|
|
||||||
/* Add parameter */
|
/* Add parameter */
|
||||||
param = add_parameter ( params, key, value );
|
param = add_parameter ( params, key, value, flags );
|
||||||
if ( ! param ) {
|
if ( ! param ) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto err_add_parameter;
|
goto err_add_parameter;
|
||||||
|
|
|
@ -32,8 +32,16 @@ struct parameter {
|
||||||
const char *key;
|
const char *key;
|
||||||
/** Value */
|
/** Value */
|
||||||
const char *value;
|
const char *value;
|
||||||
|
/** Flags */
|
||||||
|
unsigned int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Request parameter is a form parameter */
|
||||||
|
#define PARAMETER_FORM 0x0001
|
||||||
|
|
||||||
|
/** Request parameter is a header parameter */
|
||||||
|
#define PARAMETER_HEADER 0x0002
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increment request parameter list reference count
|
* Increment request parameter list reference count
|
||||||
*
|
*
|
||||||
|
@ -78,6 +86,7 @@ claim_parameters ( struct parameters *params ) {
|
||||||
extern struct parameters * find_parameters ( const char *name );
|
extern struct parameters * find_parameters ( const char *name );
|
||||||
extern struct parameters * create_parameters ( const char *name );
|
extern struct parameters * create_parameters ( const char *name );
|
||||||
extern struct parameter * add_parameter ( struct parameters *params,
|
extern struct parameter * add_parameter ( struct parameters *params,
|
||||||
const char *key, const char *value );
|
const char *key, const char *value,
|
||||||
|
unsigned int flags );
|
||||||
|
|
||||||
#endif /* _IPXE_PARAMS_H */
|
#endif /* _IPXE_PARAMS_H */
|
||||||
|
|
|
@ -830,7 +830,9 @@ static int http_transfer_complete ( struct http_transaction *http ) {
|
||||||
*/
|
*/
|
||||||
static int http_format_headers ( struct http_transaction *http, char *buf,
|
static int http_format_headers ( struct http_transaction *http, char *buf,
|
||||||
size_t len ) {
|
size_t len ) {
|
||||||
|
struct parameters *params = http->uri->params;
|
||||||
struct http_request_header *header;
|
struct http_request_header *header;
|
||||||
|
struct parameter *param;
|
||||||
size_t used;
|
size_t used;
|
||||||
size_t remaining;
|
size_t remaining;
|
||||||
char *line;
|
char *line;
|
||||||
|
@ -844,7 +846,7 @@ static int http_format_headers ( struct http_transaction *http, char *buf,
|
||||||
DBGC2 ( http, "HTTP %p TX %s\n", http, buf );
|
DBGC2 ( http, "HTTP %p TX %s\n", http, buf );
|
||||||
used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
|
used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
|
||||||
|
|
||||||
/* Construct all headers */
|
/* Construct all fixed headers */
|
||||||
for_each_table_entry ( header, HTTP_REQUEST_HEADERS ) {
|
for_each_table_entry ( header, HTTP_REQUEST_HEADERS ) {
|
||||||
|
|
||||||
/* Determine header value length */
|
/* Determine header value length */
|
||||||
|
@ -869,6 +871,23 @@ static int http_format_headers ( struct http_transaction *http, char *buf,
|
||||||
used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
|
used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Construct parameter headers, if any */
|
||||||
|
if ( params ) {
|
||||||
|
|
||||||
|
/* Construct all parameter headers */
|
||||||
|
for_each_param ( param, params ) {
|
||||||
|
|
||||||
|
/* Skip non-header parameters */
|
||||||
|
if ( ! ( param->flags & PARAMETER_HEADER ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Add parameter */
|
||||||
|
used += ssnprintf ( ( buf + used ), ( len - used ),
|
||||||
|
"%s: %s\r\n", param->key,
|
||||||
|
param->value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Construct terminating newline */
|
/* Construct terminating newline */
|
||||||
used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
|
used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
|
||||||
|
|
||||||
|
@ -1851,14 +1870,15 @@ static struct http_state http_trailers = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct HTTP parameter list
|
* Construct HTTP form parameter list
|
||||||
*
|
*
|
||||||
* @v params Parameter list
|
* @v params Parameter list
|
||||||
* @v buf Buffer to contain HTTP POST parameters
|
* @v buf Buffer to contain HTTP POST parameters
|
||||||
* @v len Length of buffer
|
* @v len Length of buffer
|
||||||
* @ret len Length of parameter list (excluding terminating NUL)
|
* @ret len Length of parameter list (excluding terminating NUL)
|
||||||
*/
|
*/
|
||||||
static size_t http_params ( struct parameters *params, char *buf, size_t len ) {
|
static size_t http_form_params ( struct parameters *params, char *buf,
|
||||||
|
size_t len ) {
|
||||||
struct parameter *param;
|
struct parameter *param;
|
||||||
ssize_t remaining = len;
|
ssize_t remaining = len;
|
||||||
size_t frag_len;
|
size_t frag_len;
|
||||||
|
@ -1867,6 +1887,10 @@ static size_t http_params ( struct parameters *params, char *buf, size_t len ) {
|
||||||
len = 0;
|
len = 0;
|
||||||
for_each_param ( param, params ) {
|
for_each_param ( param, params ) {
|
||||||
|
|
||||||
|
/* Skip non-form parameters */
|
||||||
|
if ( ! ( param->flags & PARAMETER_FORM ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Add the "&", if applicable */
|
/* Add the "&", if applicable */
|
||||||
if ( len ) {
|
if ( len ) {
|
||||||
if ( remaining > 0 )
|
if ( remaining > 0 )
|
||||||
|
@ -1920,25 +1944,26 @@ int http_open_uri ( struct interface *xfer, struct uri *uri ) {
|
||||||
size_t check_len;
|
size_t check_len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Calculate length of parameter list, if any */
|
/* Calculate length of form parameter list, if any */
|
||||||
len = ( params ? http_params ( params, NULL, 0 ) : 0 );
|
len = ( params ? http_form_params ( params, NULL, 0 ) : 0 );
|
||||||
|
|
||||||
/* Use POST if and only if there are parameters */
|
/* Use POST if and only if there are form parameters */
|
||||||
if ( len ) {
|
if ( len ) {
|
||||||
|
|
||||||
/* Use POST */
|
/* Use POST */
|
||||||
method = &http_post;
|
method = &http_post;
|
||||||
type = "application/x-www-form-urlencoded";
|
type = "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
/* Allocate temporary parameter list */
|
/* Allocate temporary form parameter list */
|
||||||
data = zalloc ( len + 1 /* NUL */ );
|
data = zalloc ( len + 1 /* NUL */ );
|
||||||
if ( ! data ) {
|
if ( ! data ) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto err_alloc;
|
goto err_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct temporary parameter list */
|
/* Construct temporary form parameter list */
|
||||||
check_len = http_params ( params, data, ( len + 1 /* NUL */ ) );
|
check_len = http_form_params ( params, data,
|
||||||
|
( len + 1 /* NUL */ ) );
|
||||||
assert ( check_len == len );
|
assert ( check_len == len );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -98,6 +98,8 @@ struct uri_params_test_list {
|
||||||
const char *key;
|
const char *key;
|
||||||
/** Value */
|
/** Value */
|
||||||
const char *value;
|
const char *value;
|
||||||
|
/** Flags */
|
||||||
|
unsigned int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A request parameter URI test */
|
/** A request parameter URI test */
|
||||||
|
@ -428,6 +430,7 @@ static void uri_params_list_okx ( struct uri_params_test *test,
|
||||||
file, line );
|
file, line );
|
||||||
okx ( strcmp ( param->value, list->value ) == 0,
|
okx ( strcmp ( param->value, list->value ) == 0,
|
||||||
file, line );
|
file, line );
|
||||||
|
okx ( param->flags == list->flags, file, line );
|
||||||
list++;
|
list++;
|
||||||
}
|
}
|
||||||
okx ( list->key == NULL, file, line );
|
okx ( list->key == NULL, file, line );
|
||||||
|
@ -456,7 +459,8 @@ static void uri_params_okx ( struct uri_params_test *test, const char *file,
|
||||||
okx ( params != NULL, file, line );
|
okx ( params != NULL, file, line );
|
||||||
if ( params ) {
|
if ( params ) {
|
||||||
for ( list = test->list ; list->key ; list++ ) {
|
for ( list = test->list ; list->key ; list++ ) {
|
||||||
param = add_parameter ( params, list->key, list->value);
|
param = add_parameter ( params, list->key, list->value,
|
||||||
|
list->flags );
|
||||||
okx ( param != NULL, file, line );
|
okx ( param != NULL, file, line );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -884,18 +888,22 @@ static struct uri_params_test_list uri_params_list[] = {
|
||||||
{
|
{
|
||||||
"vendor",
|
"vendor",
|
||||||
"10ec",
|
"10ec",
|
||||||
|
PARAMETER_FORM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"device",
|
"device",
|
||||||
"8139",
|
"8139",
|
||||||
|
PARAMETER_FORM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"uuid",
|
"uuid",
|
||||||
"f59fac00-758f-498f-9fe5-87d790045d94",
|
"f59fac00-758f-498f-9fe5-87d790045d94",
|
||||||
|
PARAMETER_HEADER,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
0,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -917,14 +925,17 @@ static struct uri_params_test_list uri_named_params_list[] = {
|
||||||
{
|
{
|
||||||
"mac",
|
"mac",
|
||||||
"00:1e:65:80:d3:b6",
|
"00:1e:65:80:d3:b6",
|
||||||
|
PARAMETER_FORM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"serial",
|
"serial",
|
||||||
"LXTQ20Z1139322762F2000",
|
"LXTQ20Z1139322762F2000",
|
||||||
|
PARAMETER_FORM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
0,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue