diff options
author | Michael Brown <mcb30@ipxe.org> | 2016-01-09 13:20:55 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2016-01-09 13:20:55 +0000 |
commit | 74c812a68cb272971708fff16f2ad1d8dadfcb5c (patch) | |
tree | b86bfaac2bde75807dbfdcf3242e0859cac1e416 /src/net/tcp | |
parent | 2f861d736f8b156aa87de3f0e250380ca292f767 (diff) | |
download | ipxe-74c812a68cb272971708fff16f2ad1d8dadfcb5c.tar.gz |
[http] Handle relative redirection URIs
Resolve redirection URIs as being relative to the original HTTP
request URI, rather than treating them as being implicitly relative to
the current working URI.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/tcp')
-rw-r--r-- | src/net/tcp/httpcore.c | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/src/net/tcp/httpcore.c b/src/net/tcp/httpcore.c index f3685de04..d40633aaf 100644 --- a/src/net/tcp/httpcore.c +++ b/src/net/tcp/httpcore.c @@ -685,6 +685,51 @@ int http_open ( struct interface *xfer, struct http_method *method, } /** + * Redirect HTTP transaction + * + * @v http HTTP transaction + * @v location New location + * @ret rc Return status code + */ +static int http_redirect ( struct http_transaction *http, + const char *location ) { + struct uri *location_uri; + struct uri *resolved_uri; + int rc; + + DBGC2 ( http, "HTTP %p redirecting to \"%s\"\n", http, location ); + + /* Parse location URI */ + location_uri = parse_uri ( location ); + if ( ! location_uri ) { + rc = -ENOMEM; + goto err_parse_uri; + } + + /* Resolve as relative to original URI */ + resolved_uri = resolve_uri ( http->uri, location_uri ); + if ( ! resolved_uri ) { + rc = -ENOMEM; + goto err_resolve_uri; + } + + /* Redirect to new URI */ + if ( ( rc = xfer_redirect ( &http->xfer, LOCATION_URI, + resolved_uri ) ) != 0 ) { + DBGC ( http, "HTTP %p could not redirect: %s\n", + http, strerror ( rc ) ); + goto err_redirect; + } + + err_redirect: + uri_put ( resolved_uri ); + err_resolve_uri: + uri_put ( location_uri ); + err_parse_uri: + return rc; +} + +/** * Handle successful transfer completion * * @v http HTTP transaction @@ -717,14 +762,8 @@ static int http_transfer_complete ( struct http_transaction *http ) { /* Perform redirection, if applicable */ if ( ( location = http->response.location ) ) { - DBGC2 ( http, "HTTP %p redirecting to \"%s\"\n", - http, location ); - if ( ( rc = xfer_redirect ( &http->xfer, LOCATION_URI_STRING, - location ) ) != 0 ) { - DBGC ( http, "HTTP %p could not redirect: %s\n", - http, strerror ( rc ) ); + if ( ( rc = http_redirect ( http, location ) ) != 0 ) return rc; - } http_close ( http, 0 ); return 0; } |