summaryrefslogtreecommitdiffstats
path: root/src/net/tcp
diff options
context:
space:
mode:
authorMichael Brown2016-01-09 14:20:55 +0100
committerMichael Brown2016-01-09 14:20:55 +0100
commit74c812a68cb272971708fff16f2ad1d8dadfcb5c (patch)
treeb86bfaac2bde75807dbfdcf3242e0859cac1e416 /src/net/tcp
parent[usb] Add support for numeric keypad on USB keyboards (diff)
downloadipxe-74c812a68cb272971708fff16f2ad1d8dadfcb5c.tar.gz
ipxe-74c812a68cb272971708fff16f2ad1d8dadfcb5c.tar.xz
ipxe-74c812a68cb272971708fff16f2ad1d8dadfcb5c.zip
[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.c53
1 files changed, 46 insertions, 7 deletions
diff --git a/src/net/tcp/httpcore.c b/src/net/tcp/httpcore.c
index f3685de0..d40633aa 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;
}