summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2023-02-28 18:46:13 +0100
committerMichael Brown2023-03-01 13:20:02 +0100
commit96bb6ba441653a30729ade38dc6c23bc9e2d2339 (patch)
tree9a1023d23aabdb096ac7a3d0df5554fbf40d73f7
parent[params] Rename "form parameter" to "request parameter" (diff)
downloadipxe-96bb6ba441653a30729ade38dc6c23bc9e2d2339.tar.gz
ipxe-96bb6ba441653a30729ade38dc6c23bc9e2d2339.tar.xz
ipxe-96bb6ba441653a30729ade38dc6c23bc9e2d2339.zip
[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>
-rw-r--r--src/core/params.c11
-rw-r--r--src/hci/commands/param_cmd.c10
-rw-r--r--src/include/ipxe/params.h11
-rw-r--r--src/net/tcp/httpcore.c43
-rw-r--r--src/tests/uri_test.c13
5 files changed, 73 insertions, 15 deletions
diff --git a/src/core/params.c b/src/core/params.c
index 23206bef..58c829f6 100644
--- a/src/core/params.c
+++ b/src/core/params.c
@@ -123,10 +123,12 @@ struct parameters * create_parameters ( const char *name ) {
* @v params Parameter list
* @v key Parameter key
* @v value Parameter value
+ * @v flags Parameter flags
* @ret param Parameter, or NULL on failure
*/
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;
size_t key_len;
size_t value_len;
@@ -147,11 +149,14 @@ struct parameter * add_parameter ( struct parameters *params,
param->key = key_copy;
strcpy ( value_copy, value );
param->value = value_copy;
+ param->flags = flags;
/* Add to list of parameters */
list_add_tail ( &param->list, &params->entries );
- DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"\n",
- params->name, param->key, param->value );
+ DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"%s%s\n",
+ params->name, param->key, param->value,
+ ( ( param->flags & PARAMETER_FORM ) ? " (form)" : "" ),
+ ( ( param->flags & PARAMETER_HEADER ) ? " (header)" : "" ) );
return param;
}
diff --git a/src/hci/commands/param_cmd.c b/src/hci/commands/param_cmd.c
index 9e3260de..dad99f84 100644
--- a/src/hci/commands/param_cmd.c
+++ b/src/hci/commands/param_cmd.c
@@ -90,12 +90,16 @@ static int params_exec ( int argc, char **argv ) {
struct param_options {
/** Parameter list name */
char *params;
+ /** Parameter is a header */
+ int header;
};
/** "param" option list */
static struct option_descriptor param_opts[] = {
OPTION_DESC ( "params", 'p', required_argument,
struct param_options, params, parse_string ),
+ OPTION_DESC ( "header", 'H', no_argument,
+ struct param_options, header, parse_flag ),
};
/** "param" command descriptor */
@@ -114,6 +118,7 @@ static int param_exec ( int argc, char **argv ) {
struct param_options opts;
char *key;
char *value;
+ unsigned int flags;
struct parameters *params;
struct parameter *param;
int rc;
@@ -132,12 +137,15 @@ static int param_exec ( int argc, char **argv ) {
goto err_parse_value;
}
+ /* Construct flags */
+ flags = ( opts.header ? PARAMETER_HEADER : PARAMETER_FORM );
+
/* Identify parameter list */
if ( ( rc = parse_parameters ( opts.params, &params ) ) != 0 )
goto err_parse_parameters;
/* Add parameter */
- param = add_parameter ( params, key, value );
+ param = add_parameter ( params, key, value, flags );
if ( ! param ) {
rc = -ENOMEM;
goto err_add_parameter;
diff --git a/src/include/ipxe/params.h b/src/include/ipxe/params.h
index 955f57ac..61e46e02 100644
--- a/src/include/ipxe/params.h
+++ b/src/include/ipxe/params.h
@@ -32,8 +32,16 @@ struct parameter {
const char *key;
/** 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
*
@@ -78,6 +86,7 @@ claim_parameters ( struct parameters *params ) {
extern struct parameters * find_parameters ( const char *name );
extern struct parameters * create_parameters ( const char *name );
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 */
diff --git a/src/net/tcp/httpcore.c b/src/net/tcp/httpcore.c
index c970d54b..9ad39656 100644
--- a/src/net/tcp/httpcore.c
+++ b/src/net/tcp/httpcore.c
@@ -830,7 +830,9 @@ static int http_transfer_complete ( struct http_transaction *http ) {
*/
static int http_format_headers ( struct http_transaction *http, char *buf,
size_t len ) {
+ struct parameters *params = http->uri->params;
struct http_request_header *header;
+ struct parameter *param;
size_t used;
size_t remaining;
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 );
used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
- /* Construct all headers */
+ /* Construct all fixed headers */
for_each_table_entry ( header, HTTP_REQUEST_HEADERS ) {
/* 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" );
}
+ /* 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 */
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 buf Buffer to contain HTTP POST parameters
* @v len Length of buffer
* @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;
ssize_t remaining = len;
size_t frag_len;
@@ -1867,6 +1887,10 @@ static size_t http_params ( struct parameters *params, char *buf, size_t len ) {
len = 0;
for_each_param ( param, params ) {
+ /* Skip non-form parameters */
+ if ( ! ( param->flags & PARAMETER_FORM ) )
+ continue;
+
/* Add the "&", if applicable */
if ( len ) {
if ( remaining > 0 )
@@ -1920,25 +1944,26 @@ int http_open_uri ( struct interface *xfer, struct uri *uri ) {
size_t check_len;
int rc;
- /* Calculate length of parameter list, if any */
- len = ( params ? http_params ( params, NULL, 0 ) : 0 );
+ /* Calculate length of form parameter list, if any */
+ 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 ) {
/* Use POST */
method = &http_post;
type = "application/x-www-form-urlencoded";
- /* Allocate temporary parameter list */
+ /* Allocate temporary form parameter list */
data = zalloc ( len + 1 /* NUL */ );
if ( ! data ) {
rc = -ENOMEM;
goto err_alloc;
}
- /* Construct temporary parameter list */
- check_len = http_params ( params, data, ( len + 1 /* NUL */ ) );
+ /* Construct temporary form parameter list */
+ check_len = http_form_params ( params, data,
+ ( len + 1 /* NUL */ ) );
assert ( check_len == len );
} else {
diff --git a/src/tests/uri_test.c b/src/tests/uri_test.c
index 5e706032..9d2f6dba 100644
--- a/src/tests/uri_test.c
+++ b/src/tests/uri_test.c
@@ -98,6 +98,8 @@ struct uri_params_test_list {
const char *key;
/** Value */
const char *value;
+ /** Flags */
+ unsigned int flags;
};
/** A request parameter URI test */
@@ -428,6 +430,7 @@ static void uri_params_list_okx ( struct uri_params_test *test,
file, line );
okx ( strcmp ( param->value, list->value ) == 0,
file, line );
+ okx ( param->flags == list->flags, file, line );
list++;
}
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 );
if ( params ) {
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 );
}
}
@@ -884,18 +888,22 @@ static struct uri_params_test_list uri_params_list[] = {
{
"vendor",
"10ec",
+ PARAMETER_FORM,
},
{
"device",
"8139",
+ PARAMETER_FORM,
},
{
"uuid",
"f59fac00-758f-498f-9fe5-87d790045d94",
+ PARAMETER_HEADER,
},
{
NULL,
NULL,
+ 0,
}
};
@@ -917,14 +925,17 @@ static struct uri_params_test_list uri_named_params_list[] = {
{
"mac",
"00:1e:65:80:d3:b6",
+ PARAMETER_FORM,
},
{
"serial",
"LXTQ20Z1139322762F2000",
+ PARAMETER_FORM,
},
{
NULL,
NULL,
+ 0,
}
};