summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2011-06-24 18:59:43 +0200
committerMichael Brown2011-06-28 15:45:12 +0200
commit3ad1a1a60a01e28ae4c02bcd5dfd8f4bf83e7aea (patch)
treed3e5c22bd907b45854d9e9b84fe9ebddcfd6ab55 /src
parent[scsi] Eliminate polling while waiting for window to open (diff)
downloadipxe-3ad1a1a60a01e28ae4c02bcd5dfd8f4bf83e7aea.tar.gz
ipxe-3ad1a1a60a01e28ae4c02bcd5dfd8f4bf83e7aea.tar.xz
ipxe-3ad1a1a60a01e28ae4c02bcd5dfd8f4bf83e7aea.zip
[http] Eliminate polling while waiting for window to open
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r--src/net/tcp/http.c78
1 files changed, 46 insertions, 32 deletions
diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c
index 15f88b31..432e5cd9 100644
--- a/src/net/tcp/http.c
+++ b/src/net/tcp/http.c
@@ -48,6 +48,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
FEATURE ( FEATURE_PROTOCOL, "HTTP", DHCP_EB_FEATURE_HTTP, 1 );
+/** HTTP transmission state */
+enum http_tx_state {
+ HTTP_TX_REQUEST = 0,
+ HTTP_TX_DONE,
+};
+
/** HTTP receive state */
enum http_rx_state {
HTTP_RX_RESPONSE = 0,
@@ -75,6 +81,8 @@ struct http_request {
/** TX process */
struct process process;
+ /** TX state */
+ enum http_tx_state tx_state;
/** HTTP response code */
unsigned int response;
@@ -498,49 +506,55 @@ static void http_step ( struct http_request *http ) {
int rc;
int request_len = unparse_uri ( NULL, 0, http->uri,
URI_PATH_BIT | URI_QUERY_BIT );
+ char request[ request_len + 1 /* NUL */ ];
- if ( xfer_window ( &http->socket ) ) {
- char request[request_len + 1];
+ /* Do nothing if we have already transmitted the request */
+ if ( http->tx_state != HTTP_TX_REQUEST )
+ return;
- /* Construct path?query request */
- unparse_uri ( request, sizeof ( request ), http->uri,
- URI_PATH_BIT | URI_QUERY_BIT );
+ /* Do nothing until socket is ready */
+ if ( ! xfer_window ( &http->socket ) )
+ return;
- /* We want to execute only once */
- process_del ( &http->process );
+ /* Construct path?query request */
+ unparse_uri ( request, sizeof ( request ), http->uri,
+ URI_PATH_BIT | URI_QUERY_BIT );
- /* Construct authorisation, if applicable */
- if ( user ) {
- /* Make "user:password" string from decoded fields */
- snprintf ( ( ( char * ) user_pw ), sizeof ( user_pw ),
- "%s:%s", user, password );
+ /* Construct authorisation, if applicable */
+ if ( user ) {
+ /* Make "user:password" string from decoded fields */
+ snprintf ( ( ( char * ) user_pw ), sizeof ( user_pw ),
+ "%s:%s", user, password );
- /* Base64-encode the "user:password" string */
- base64_encode ( user_pw, user_pw_len, user_pw_base64 );
- }
+ /* Base64-encode the "user:password" string */
+ base64_encode ( user_pw, user_pw_len, user_pw_base64 );
+ }
- /* Send GET request */
- if ( ( rc = xfer_printf ( &http->socket,
- "GET %s%s HTTP/1.1\r\n"
- "User-Agent: iPXE/" VERSION "\r\n"
- "%s%s%s"
- "Host: %s\r\n"
- "\r\n",
- http->uri->path ? "" : "/",
- request,
- ( user ?
- "Authorization: Basic " : "" ),
- ( user ? user_pw_base64 : "" ),
- ( user ? "\r\n" : "" ),
- host ) ) != 0 ) {
- http_done ( http, rc );
- }
+ /* Mark request as transmitted */
+ http->tx_state = HTTP_TX_DONE;
+
+ /* Send GET request */
+ if ( ( rc = xfer_printf ( &http->socket,
+ "GET %s%s HTTP/1.1\r\n"
+ "User-Agent: iPXE/" VERSION "\r\n"
+ "%s%s%s"
+ "Host: %s\r\n"
+ "\r\n",
+ http->uri->path ? "" : "/",
+ request,
+ ( user ?
+ "Authorization: Basic " : "" ),
+ ( user ? user_pw_base64 : "" ),
+ ( user ? "\r\n" : "" ),
+ host ) ) != 0 ) {
+ http_done ( http, rc );
}
}
/** HTTP socket interface operations */
static struct interface_operation http_socket_operations[] = {
INTF_OP ( xfer_deliver, struct http_request *, http_socket_deliver ),
+ INTF_OP ( xfer_window_changed, struct http_request *, http_step ),
INTF_OP ( intf_close, struct http_request *, http_done ),
};
@@ -561,7 +575,7 @@ static struct interface_descriptor http_xfer_desc =
/** HTTP process descriptor */
static struct process_descriptor http_process_desc =
- PROC_DESC ( struct http_request, process, http_step );
+ PROC_DESC_ONCE ( struct http_request, process, http_step );
/**
* Initiate an HTTP connection, with optional filter