Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[http] Eliminate polling while waiting for window to open
Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Jun 28, 2011
1 parent 5c9c39e commit 3ad1a1a
Showing 1 changed file with 46 additions and 32 deletions.
78 changes: 46 additions & 32 deletions src/net/tcp/http.c
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 ),
};

Expand All @@ -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
Expand Down

0 comments on commit 3ad1a1a

Please sign in to comment.