|
@@ -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
|
}
|