diff options
author | Michael Brown <mcb30@ipxe.org> | 2023-03-01 11:06:46 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2023-03-01 11:12:44 +0000 |
commit | 60531ff6e25d363f36f843cae29a95031aac2147 (patch) | |
tree | 215d4b18ea30335599665c2a69966e5b942f692b | |
parent | 04e60a278abcda47301f6be2c23755e5e1004661 (diff) | |
download | ipxe-60531ff6e25d363f36f843cae29a95031aac2147.zip ipxe-60531ff6e25d363f36f843cae29a95031aac2147.tar.gz ipxe-60531ff6e25d363f36f843cae29a95031aac2147.tar.bz2 |
[http] Use POST method only if the form parameter list is non-empty
An attempt to use an existent but empty form parameter list will
currently result in an invalid POST request since the Content-Length
header will be missing.
Fix by using GET instead of POST if the form parameter list is empty.
This is a non-breaking change (since the current behaviour produces an
invalid request), and simplifies the imminent generalisation of the
parameter list concept to handle both header and form parameters.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/net/tcp/httpcore.c | 76 |
1 files changed, 32 insertions, 44 deletions
diff --git a/src/net/tcp/httpcore.c b/src/net/tcp/httpcore.c index fd94b5f..c970d54 100644 --- a/src/net/tcp/httpcore.c +++ b/src/net/tcp/httpcore.c @@ -1904,53 +1904,58 @@ static size_t http_params ( struct parameters *params, char *buf, size_t len ) { } /** - * Open HTTP transaction for simple GET URI - * - * @v xfer Data transfer interface - * @v uri Request URI - * @ret rc Return status code - */ -static int http_open_get_uri ( struct interface *xfer, struct uri *uri ) { - - return http_open ( xfer, &http_get, uri, NULL, NULL ); -} - -/** - * Open HTTP transaction for simple POST URI + * Open HTTP transaction for simple URI * * @v xfer Data transfer interface * @v uri Request URI * @ret rc Return status code */ -static int http_open_post_uri ( struct interface *xfer, struct uri *uri ) { +int http_open_uri ( struct interface *xfer, struct uri *uri ) { struct parameters *params = uri->params; struct http_request_content content; + struct http_method *method; + const char *type; void *data; size_t len; size_t check_len; int rc; - /* Calculate length of parameter list */ - len = http_params ( params, NULL, 0 ); + /* Calculate length of parameter list, if any */ + len = ( params ? http_params ( params, NULL, 0 ) : 0 ); - /* Allocate temporary parameter list */ - data = zalloc ( len + 1 /* NUL */ ); - if ( ! data ) { - rc = -ENOMEM; - goto err_alloc; - } + /* Use POST if and only if there are parameters */ + if ( len ) { - /* Construct temporary parameter list */ - check_len = http_params ( params, data, ( len + 1 /* NUL */ ) ); - assert ( check_len == len ); + /* Use POST */ + method = &http_post; + type = "application/x-www-form-urlencoded"; + + /* Allocate temporary 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 */ ) ); + assert ( check_len == len ); + + } else { + + /* Use GET */ + method = &http_get; + type = NULL; + data = NULL; + } /* Construct request content */ - content.type = "application/x-www-form-urlencoded"; + content.type = type; content.data = data; content.len = len; /* Open HTTP transaction */ - if ( ( rc = http_open ( xfer, &http_post, uri, NULL, &content ) ) != 0 ) + if ( ( rc = http_open ( xfer, method, uri, NULL, &content ) ) != 0 ) goto err_open; err_open: @@ -1959,23 +1964,6 @@ static int http_open_post_uri ( struct interface *xfer, struct uri *uri ) { return rc; } -/** - * Open HTTP transaction for simple URI - * - * @v xfer Data transfer interface - * @v uri Request URI - * @ret rc Return status code - */ -int http_open_uri ( struct interface *xfer, struct uri *uri ) { - - /* Open GET/POST URI as applicable */ - if ( uri->params ) { - return http_open_post_uri ( xfer, uri ); - } else { - return http_open_get_uri ( xfer, uri ); - } -} - /* Drag in HTTP extensions */ REQUIRING_SYMBOL ( http_open ); REQUIRE_OBJECT ( config_http ); |