diff options
author | Joshua Oreman <oremanj@rwcr.net> | 2009-12-29 22:36:04 -0500 |
---|---|---|
committer | Marty Connor <mdc@etherboot.org> | 2010-01-20 18:14:28 -0500 |
commit | 3d9dd93a1452e28c728483b03e352691238491ed (patch) | |
tree | 73a41396fd514d12dbd7bd69ebfc49810bf73c7c /src/net/tcp/http.c | |
parent | ef9d1a32c6dc83d1086141c18d2be19a05ab8e49 (diff) | |
download | ipxe-3d9dd93a1452e28c728483b03e352691238491ed.tar.gz |
[uri] Decode/encode URIs when parsing/unparsing
Currently, handling of URI escapes is ad-hoc; escaped strings are
stored as-is in the URI structure, and it is up to the individual
protocol to unescape as necessary. This is error-prone and expensive
in terms of code size. Modify this behavior by unescaping in
parse_uri() and escaping in unparse_uri() those fields that typically
handle URI escapes (hostname, user, password, path, query, fragment),
and allowing unparse_uri() to accept a subset of fields to print so
it can be easily used to generate e.g. the escaped HTTP path?query
request.
Signed-off-by: Joshua Oreman <oremanj@rwcr.net>
Signed-off-by: Marty Connor <mdc@etherboot.org>
Diffstat (limited to 'src/net/tcp/http.c')
-rw-r--r-- | src/net/tcp/http.c | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c index a02408a90..807a0c3e1 100644 --- a/src/net/tcp/http.c +++ b/src/net/tcp/http.c @@ -417,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 : "" ); @@ -429,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 ); @@ -457,14 +452,12 @@ 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 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 : "" ), + request, ( user ? "Authorization: Basic " : "" ), ( user ? user_pw_base64 : "" ), |