[ipxe-devel] [PATCH] Include port in HTTP Host header as needed

Malte Starostik lists at malte.homeip.net
Fri Jul 15 13:30:10 UTC 2011


According to sec. 14.23 or RFC2616, a HTTP Host header without port
implies the default port is used.  Thus, when fetching from anywhere but
port 80 for HTTP or 443 for HTTPS, the port ought to be explicitly given
in that header.  Otherwise, some servers might fail to associate the
request with the correct virtual host or generate incorrect
self-referencing URLs.

As an example, this mod_perl snippet was used to include a URL to itself
in a dynamically generated boot script:
    my $base = $r->construct_url($r->parsed_uri->rpath);

Without this patch, the resulting URL lacks the port number which breaks
unless running on port 80.  Using the actual socket address isn't really
an option as this might have been fiddled with by some port redirection.
---
 src/net/tcp/http.c |   18 +++++++++++++++---
 1 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c
index 012b226..c1f23fc 100644
--- a/src/net/tcp/http.c
+++ b/src/net/tcp/http.c
@@ -61,6 +61,8 @@ enum http_flags {
 	HTTP_HEAD_ONLY = 0x0002,
 	/** Keep connection alive */
 	HTTP_KEEPALIVE = 0x0004,
+	/** Request is to a non-default port */
+	HTTP_NON_DEFAULT_PORT = 0x0008,
 };
 
 /** HTTP receive state */
@@ -662,13 +664,17 @@ static void http_step ( struct http_request *http ) {
 	if ( ( rc = xfer_printf ( &http->socket,
 				  "%s %s%s HTTP/1.1\r\n"
 				  "User-Agent: iPXE/" VERSION "\r\n"
-				  "Host: %s\r\n"
+				  "Host: %s%s%s\r\n"
 				  "%s%s%s%s%s%s%s"
 				  "\r\n",
 				  ( ( http->flags & HTTP_HEAD_ONLY ) ?
 				    "HEAD" : "GET" ),
 				  ( http->uri->path ? "" : "/" ),
 				  request, host,
+				  ( ( http->flags & HTTP_NON_DEFAULT_PORT ) ?
+				    ":" : "" ),
+				  ( ( http->flags & HTTP_NON_DEFAULT_PORT ) ?
+				    http->uri->port : "" ),
 				  ( ( http->flags & HTTP_KEEPALIVE ) ?
 				    "Connection: Keep-Alive\r\n" : "" ),
 				  ( partial ? "Range: bytes=" : "" ),
@@ -720,7 +726,8 @@ static int http_partial_read ( struct http_request *http,
 
 	/* Schedule request */
 	http->rx_state = HTTP_RX_RESPONSE;
-	http->flags = ( HTTP_TX_PENDING | HTTP_KEEPALIVE );
+	http->flags |= ( HTTP_TX_PENDING | HTTP_KEEPALIVE );
+	http->flags &= ~HTTP_HEAD_ONLY;
 	if ( ! len )
 		http->flags |= HTTP_HEAD_ONLY;
 	process_add ( &http->process );
@@ -841,6 +848,7 @@ int http_open_filter ( struct interface *xfer, struct uri *uri,
 	struct sockaddr_tcpip server;
 	struct interface *socket;
 	int rc;
+	unsigned int port;
 
 	/* Sanity checks */
 	if ( ! uri->host )
@@ -858,9 +866,13 @@ int http_open_filter ( struct interface *xfer, struct uri *uri,
 	process_init ( &http->process, &http_process_desc, &http->refcnt );
 	http->flags = HTTP_TX_PENDING;
 
+
 	/* Open socket */
 	memset ( &server, 0, sizeof ( server ) );
-	server.st_port = htons ( uri_port ( http->uri, default_port ) );
+	port = uri_port ( http->uri, default_port );
+	if ( port != default_port )
+	    http->flags |= HTTP_NON_DEFAULT_PORT;
+	server.st_port = htons ( port );
 	socket = &http->socket;
 	if ( filter ) {
 		if ( ( rc = filter ( socket, &socket ) ) != 0 )
-- 
1.7.3.4




More information about the ipxe-devel mailing list