[http] Eliminate polling while waiting for window to open
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
parent
5c9c39e299
commit
3ad1a1a60a
|
@ -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,17 +506,20 @@ 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;
|
||||||
|
|
||||||
|
/* Do nothing until socket is ready */
|
||||||
|
if ( ! xfer_window ( &http->socket ) )
|
||||||
|
return;
|
||||||
|
|
||||||
/* Construct path?query request */
|
/* Construct path?query request */
|
||||||
unparse_uri ( request, sizeof ( request ), http->uri,
|
unparse_uri ( request, sizeof ( request ), http->uri,
|
||||||
URI_PATH_BIT | URI_QUERY_BIT );
|
URI_PATH_BIT | URI_QUERY_BIT );
|
||||||
|
|
||||||
/* We want to execute only once */
|
|
||||||
process_del ( &http->process );
|
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
@ -519,6 +530,9 @@ static void http_step ( struct http_request *http ) {
|
||||||
base64_encode ( user_pw, user_pw_len, user_pw_base64 );
|
base64_encode ( user_pw, user_pw_len, user_pw_base64 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark request as transmitted */
|
||||||
|
http->tx_state = HTTP_TX_DONE;
|
||||||
|
|
||||||
/* Send GET request */
|
/* Send GET request */
|
||||||
if ( ( rc = xfer_printf ( &http->socket,
|
if ( ( rc = xfer_printf ( &http->socket,
|
||||||
"GET %s%s HTTP/1.1\r\n"
|
"GET %s%s HTTP/1.1\r\n"
|
||||||
|
@ -536,11 +550,11 @@ static void http_step ( struct http_request *http ) {
|
||||||
http_done ( http, rc );
|
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
|
||||||
|
|
Reference in New Issue