aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-03-01 11:06:46 +0000
committerMichael Brown <mcb30@ipxe.org>2023-03-01 11:12:44 +0000
commit60531ff6e25d363f36f843cae29a95031aac2147 (patch)
tree215d4b18ea30335599665c2a69966e5b942f692b
parent04e60a278abcda47301f6be2c23755e5e1004661 (diff)
downloadipxe-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.c76
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 );