diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-02-03 16:06:41 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-03 16:06:41 -0800 |
commit | addaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa (patch) | |
tree | 2ffea726dc494e87ecc9f506bc6a2bc9242730e3 /gpxe/src/net/tcp/http.c | |
parent | 5c0f48e49f8d7d084810ecf0b98a76aaebb44835 (diff) | |
parent | e7a5f95432132c8fc8f8ede39fda1d368002ddd8 (diff) | |
download | syslinux.git-addaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa.tar.gz syslinux.git-addaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa.tar.xz syslinux.git-addaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa.zip |
Merge branch 'master' into i915res
Diffstat (limited to 'gpxe/src/net/tcp/http.c')
-rw-r--r-- | gpxe/src/net/tcp/http.c | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/gpxe/src/net/tcp/http.c b/gpxe/src/net/tcp/http.c index 93ccfd3b..a365b2a4 100644 --- a/gpxe/src/net/tcp/http.c +++ b/gpxe/src/net/tcp/http.c @@ -16,6 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +FILE_LICENCE ( GPL2_OR_LATER ); + /** * @file * @@ -138,6 +140,8 @@ static void http_done ( struct http_request *http, int rc ) { static int http_response_to_rc ( unsigned int response ) { switch ( response ) { case 200: + case 301: + case 302: return 0; case 404: return -ENOENT; @@ -181,6 +185,28 @@ static int http_rx_response ( struct http_request *http, char *response ) { } /** + * Handle HTTP Location header + * + * @v http HTTP request + * @v value HTTP header value + * @ret rc Return status code + */ +static int http_rx_location ( struct http_request *http, const char *value ) { + int rc; + + /* Redirect to new location */ + DBGC ( http, "HTTP %p redirecting to %s\n", http, value ); + if ( ( rc = xfer_redirect ( &http->xfer, LOCATION_URI_STRING, + value ) ) != 0 ) { + DBGC ( http, "HTTP %p could not redirect: %s\n", + http, strerror ( rc ) ); + return rc; + } + + return 0; +} + +/** * Handle HTTP Content-Length header * * @v http HTTP request @@ -223,6 +249,10 @@ struct http_header_handler { /** List of HTTP header handlers */ static struct http_header_handler http_header_handlers[] = { { + .header = "Location", + .rx = http_rx_location, + }, + { .header = "Content-Length", .rx = http_rx_content_length, }, @@ -387,9 +417,7 @@ static int http_socket_deliver_iob ( struct xfer_interface *socket, static void http_step ( struct process *process ) { struct http_request *http = container_of ( process, struct http_request, process ); - const char *path = http->uri->path; const char *host = http->uri->host; - const char *query = http->uri->query; const char *user = http->uri->user; const char *password = ( http->uri->password ? http->uri->password : "" ); @@ -399,27 +427,24 @@ static void http_step ( struct process *process ) { char user_pw[ user_pw_len + 1 /* NUL */ ]; char user_pw_base64[ user_pw_base64_len + 1 /* NUL */ ]; int rc; + int request_len = unparse_uri ( NULL, 0, http->uri, + URI_PATH_BIT | URI_QUERY_BIT ); if ( xfer_window ( &http->socket ) ) { + char request[request_len + 1]; + + /* Construct path?query request */ + unparse_uri ( request, sizeof ( request ), http->uri, + URI_PATH_BIT | URI_QUERY_BIT ); /* We want to execute only once */ process_del ( &http->process ); /* Construct authorisation, if applicable */ if ( user ) { - char *buf = user_pw; - ssize_t remaining = sizeof ( user_pw ); - size_t len; - - /* URI-decode the username and password */ - len = uri_decode ( user, buf, remaining ); - buf += len; - remaining -= len; - *(remaining--, buf++) = ':'; - len = uri_decode ( password, buf, remaining ); - buf += len; - remaining -= len; - assert ( remaining >= 0 ); + /* Make "user:password" string from decoded fields */ + snprintf ( user_pw, sizeof ( user_pw ), "%s:%s", + user, password ); /* Base64-encode the "user:password" string */ base64_encode ( user_pw, user_pw_base64 ); @@ -427,14 +452,13 @@ static void http_step ( struct process *process ) { /* Send GET request */ if ( ( rc = xfer_printf ( &http->socket, - "GET %s%s%s HTTP/1.0\r\n" + "GET %s%s HTTP/1.0\r\n" "User-Agent: gPXE/" VERSION "\r\n" "%s%s%s" "Host: %s\r\n" "\r\n", - ( path ? path : "/" ), - ( query ? "?" : "" ), - ( query ? query : "" ), + http->uri->path ? "" : "/", + request, ( user ? "Authorization: Basic " : "" ), ( user ? user_pw_base64 : "" ), @@ -464,7 +488,7 @@ static void http_socket_close ( struct xfer_interface *socket, int rc ) { /** HTTP socket operations */ static struct xfer_interface_operations http_socket_operations = { .close = http_socket_close, - .vredirect = xfer_vopen, + .vredirect = xfer_vreopen, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = http_socket_deliver_iob, |