david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[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>
This commit is contained in:
Michael Brown 2016-01-09 13:20:55 +00:00
parent 2f861d736f
commit 74c812a68c
1 changed files with 46 additions and 7 deletions

View File

@ -684,6 +684,51 @@ int http_open ( struct interface *xfer, struct http_method *method,
return rc;
}
/**
* 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
*
@ -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;
}