david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[http] Eliminate polling while waiting for window to open

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2011-06-24 17:59:43 +01:00
parent 5c9c39e299
commit 3ad1a1a60a
1 changed files with 46 additions and 32 deletions

View File

@ -48,6 +48,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
FEATURE ( FEATURE_PROTOCOL, "HTTP", DHCP_EB_FEATURE_HTTP, 1 ); 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 */ /** HTTP receive state */
enum http_rx_state { enum http_rx_state {
HTTP_RX_RESPONSE = 0, HTTP_RX_RESPONSE = 0,
@ -75,6 +81,8 @@ struct http_request {
/** TX process */ /** TX process */
struct process process; struct process process;
/** TX state */
enum http_tx_state tx_state;
/** HTTP response code */ /** HTTP response code */
unsigned int response; unsigned int response;
@ -498,49 +506,55 @@ static void http_step ( struct http_request *http ) {
int rc; int rc;
int request_len = unparse_uri ( NULL, 0, http->uri, int request_len = unparse_uri ( NULL, 0, http->uri,
URI_PATH_BIT | URI_QUERY_BIT ); URI_PATH_BIT | URI_QUERY_BIT );
char request[ request_len + 1 /* NUL */ ];
if ( xfer_window ( &http->socket ) ) { /* Do nothing if we have already transmitted the request */
char request[request_len + 1]; if ( http->tx_state != HTTP_TX_REQUEST )
return;
/* Construct path?query request */ /* Do nothing until socket is ready */
unparse_uri ( request, sizeof ( request ), http->uri, if ( ! xfer_window ( &http->socket ) )
URI_PATH_BIT | URI_QUERY_BIT ); return;
/* We want to execute only once */ /* Construct path?query request */
process_del ( &http->process ); unparse_uri ( request, sizeof ( request ), http->uri,
URI_PATH_BIT | URI_QUERY_BIT );
/* Construct authorisation, if applicable */ /* Construct authorisation, if applicable */
if ( user ) { if ( user ) {
/* Make "user:password" string from decoded fields */ /* Make "user:password" string from decoded fields */
snprintf ( ( ( char * ) user_pw ), sizeof ( user_pw ), snprintf ( ( ( char * ) user_pw ), sizeof ( user_pw ),
"%s:%s", user, password ); "%s:%s", user, password );
/* Base64-encode the "user:password" string */ /* Base64-encode the "user:password" string */
base64_encode ( user_pw, user_pw_len, user_pw_base64 ); base64_encode ( user_pw, user_pw_len, user_pw_base64 );
} }
/* Send GET request */ /* Mark request as transmitted */
if ( ( rc = xfer_printf ( &http->socket, http->tx_state = HTTP_TX_DONE;
"GET %s%s HTTP/1.1\r\n"
"User-Agent: iPXE/" VERSION "\r\n" /* Send GET request */
"%s%s%s" if ( ( rc = xfer_printf ( &http->socket,
"Host: %s\r\n" "GET %s%s HTTP/1.1\r\n"
"\r\n", "User-Agent: iPXE/" VERSION "\r\n"
http->uri->path ? "" : "/", "%s%s%s"
request, "Host: %s\r\n"
( user ? "\r\n",
"Authorization: Basic " : "" ), http->uri->path ? "" : "/",
( user ? user_pw_base64 : "" ), request,
( user ? "\r\n" : "" ), ( user ?
host ) ) != 0 ) { "Authorization: Basic " : "" ),
http_done ( http, rc ); ( user ? user_pw_base64 : "" ),
} ( user ? "\r\n" : "" ),
host ) ) != 0 ) {
http_done ( http, rc );
} }
} }
/** HTTP socket interface operations */ /** HTTP socket interface operations */
static struct interface_operation http_socket_operations[] = { static struct interface_operation http_socket_operations[] = {
INTF_OP ( xfer_deliver, struct http_request *, http_socket_deliver ), 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 ), INTF_OP ( intf_close, struct http_request *, http_done ),
}; };
@ -561,7 +575,7 @@ static struct interface_descriptor http_xfer_desc =
/** HTTP process descriptor */ /** HTTP process descriptor */
static struct process_descriptor http_process_desc = 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 * Initiate an HTTP connection, with optional filter