Browse Source

[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>
tags/v1.20.1
Michael Brown 8 years ago
parent
commit
74c812a68c
1 changed files with 46 additions and 7 deletions
  1. 46
    7
      src/net/tcp/httpcore.c

+ 46
- 7
src/net/tcp/httpcore.c View File

@@ -684,6 +684,51 @@ int http_open ( struct interface *xfer, struct http_method *method,
684 684
 	return rc;
685 685
 }
686 686
 
687
+/**
688
+ * Redirect HTTP transaction
689
+ *
690
+ * @v http		HTTP transaction
691
+ * @v location		New location
692
+ * @ret rc		Return status code
693
+ */
694
+static int http_redirect ( struct http_transaction *http,
695
+			   const char *location ) {
696
+	struct uri *location_uri;
697
+	struct uri *resolved_uri;
698
+	int rc;
699
+
700
+	DBGC2 ( http, "HTTP %p redirecting to \"%s\"\n", http, location );
701
+
702
+	/* Parse location URI */
703
+	location_uri = parse_uri ( location );
704
+	if ( ! location_uri ) {
705
+		rc = -ENOMEM;
706
+		goto err_parse_uri;
707
+	}
708
+
709
+	/* Resolve as relative to original URI */
710
+	resolved_uri = resolve_uri ( http->uri, location_uri );
711
+	if ( ! resolved_uri ) {
712
+		rc = -ENOMEM;
713
+		goto err_resolve_uri;
714
+	}
715
+
716
+	/* Redirect to new URI */
717
+	if ( ( rc = xfer_redirect ( &http->xfer, LOCATION_URI,
718
+				    resolved_uri ) ) != 0 ) {
719
+		DBGC ( http, "HTTP %p could not redirect: %s\n",
720
+		       http, strerror ( rc ) );
721
+		goto err_redirect;
722
+	}
723
+
724
+ err_redirect:
725
+	uri_put ( resolved_uri );
726
+ err_resolve_uri:
727
+	uri_put ( location_uri );
728
+ err_parse_uri:
729
+	return rc;
730
+}
731
+
687 732
 /**
688 733
  * Handle successful transfer completion
689 734
  *
@@ -717,14 +762,8 @@ static int http_transfer_complete ( struct http_transaction *http ) {
717 762
 
718 763
 	/* Perform redirection, if applicable */
719 764
 	if ( ( location = http->response.location ) ) {
720
-		DBGC2 ( http, "HTTP %p redirecting to \"%s\"\n",
721
-			http, location );
722
-		if ( ( rc = xfer_redirect ( &http->xfer, LOCATION_URI_STRING,
723
-					    location ) ) != 0 ) {
724
-			DBGC ( http, "HTTP %p could not redirect: %s\n",
725
-			       http, strerror ( rc ) );
765
+		if ( ( rc = http_redirect ( http, location ) ) != 0 )
726 766
 			return rc;
727
-		}
728 767
 		http_close ( http, 0 );
729 768
 		return 0;
730 769
 	}

Loading…
Cancel
Save