From 8865571f707388265e642dd4019cf8b735f4fb64 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 4 Oct 2026 16:56:51 +0100 Subject: [PATCH] [http] Include a zero request content length when applicable We currently send a Content-Length request header only when the content length is non-zero. This breaks some use cases for a PUT request, such as uploading a zero-length file to AWS S3. Fix by choosing whether or not to include a Content-Length request header based on the request method. Signed-off-by: Michael Brown --- src/include/ipxe/http.h | 5 +++++ src/net/tcp/httpcore.c | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/include/ipxe/http.h b/src/include/ipxe/http.h index e96c2c881..0b9ec62cd 100644 --- a/src/include/ipxe/http.h +++ b/src/include/ipxe/http.h @@ -100,8 +100,13 @@ struct http_connection { struct http_method { /** Method name (e.g. "GET" or "POST") */ const char *name; + /** Flags */ + unsigned int flags; }; +/** HTTP method has a request body */ +#define HTTP_FL_REQ_BODY 0x0001 + /** HTTP method table */ #define HTTP_METHODS __table ( struct http_method, "http_methods" ) diff --git a/src/net/tcp/httpcore.c b/src/net/tcp/httpcore.c index affb48265..80d91b78f 100644 --- a/src/net/tcp/httpcore.c +++ b/src/net/tcp/httpcore.c @@ -138,21 +138,25 @@ static struct http_transfer_encoding http_transfer_identity; /** HTTP HEAD method */ struct http_method http_head __http_method = { .name = "HEAD", + .flags = 0, }; /** HTTP GET method */ struct http_method http_get __http_method = { .name = "GET", + .flags = 0, }; /** HTTP POST method */ struct http_method http_post __http_method = { .name = "POST", + .flags = HTTP_FL_REQ_BODY, }; /** HTTP PUT method */ struct http_method http_put __http_method = { .name = "PUT", + .flags = HTTP_FL_REQ_BODY, }; /** @@ -1095,11 +1099,15 @@ static int http_format_content_length ( struct http_transaction *http, char *buf, size_t len ) { /* Construct content length, if applicable */ - if ( http->request.content.len ) { + if ( http->request.method->flags & HTTP_FL_REQ_BODY ) { return snprintf ( buf, len, "%zd", http->request.content.len ); - } else { + } else if ( http->request.content.len == 0 ) { return 0; } + + DBGC ( http, "HTTP %p cannot %s with a request body\n", + http, http->request.method->name ); + return -ENOTSUP; } /** HTTP "Content-Length" header */