[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>
efivars
Michael Brown 2023-03-01 11:06:46 +00:00
parent 04e60a278a
commit 60531ff6e2
1 changed files with 32 additions and 44 deletions

View File

@ -1904,53 +1904,58 @@ static size_t http_params ( struct parameters *params, char *buf, size_t len ) {
}
/**
* Open HTTP transaction for simple GET 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_get_uri ( struct interface *xfer, struct uri *uri ) {
return http_open ( xfer, &http_get, uri, NULL, NULL );
}
/**
* Open HTTP transaction for simple POST 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 ) {
/* 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 temporary parameter list */
check_len = http_params ( params, data, ( len + 1 /* NUL */ ) );
assert ( check_len == len );
/* 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 );