GRUB's HTTP module declares support for HTTP/1.1, which defaults to Connection:keepalive. At the end of the content, the server holds the TCP connection open waiting for the next request.
It seems that grub_net_poll_cards() is watching for the HTTP module to set net->stall, and otherwise waits the full 400ms GRUB_NET_INTERVAL to return to processing. However, HTTP module only sets that flag in specific conditions:
This patch sets Connection:close, which will tell the server to close the connection as soon as it has finished sending the file. GRUB closes any connections that are left open (in http_seek), so it does not change performance. When the server disconnects, I think it triggers http_err and then quits out of grub_net_poll_cards early.
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index 5aa4ad3..a5d64f6 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -318,6 +318,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
+ grub_strlen (data->filename)
+ sizeof (" HTTP/1.1\r\nHost: ") - 1
+ grub_strlen (file->device->net->server)
+ + sizeof ("\r\nConnection: close") - 1
+ sizeof ("\r\nUser-Agent: " PACKAGE_STRING
"\r\n") - 1
+ sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX"
@@ -366,6 +367,17 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
grub_strlen (file->device->net->server));
ptr = nb->tail;
+ err = grub_netbuff_put (nb,
+ sizeof ("\r\nConnection: close")
+ - 1);
+ if (err)
+ {
+ grub_netbuff_free (nb);
+ return err;
+ }
+ grub_memcpy (ptr, "\r\nConnection: close",
+ sizeof ("\r\nConnection: close") - 1);
+ ptr = nb->tail;
err = grub_netbuff_put (nb,
sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n")
- 1);