Browse Source

[downloader] Update image URI in response to a redirection

Update the image's recorded URI when a download redirection occurs.
This ensures that URIs relative to a redirected download are resolved
correctly.

In particular, this allows for the use of relative URIs in scripts
that are themselves downloaded via a redirection, such as the HTTP 301
redirection used to fix up URIs pointing to directories but omitting
the trailing slash (e.g. "http://boot.ipxe.org/demo", which will be
redirected to "http://boot.ipxe.org/demo/").

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
a8bef53908
1 changed files with 41 additions and 6 deletions
  1. 41
    6
      src/core/downloader.c

+ 41
- 6
src/core/downloader.c View File

136
  * @v meta		Data transfer metadata
136
  * @v meta		Data transfer metadata
137
  * @ret rc		Return status code
137
  * @ret rc		Return status code
138
  */
138
  */
139
-static int downloader_xfer_deliver ( struct downloader *downloader,
140
-				     struct io_buffer *iobuf,
141
-				     struct xfer_metadata *meta ) {
139
+static int downloader_deliver ( struct downloader *downloader,
140
+				struct io_buffer *iobuf,
141
+				struct xfer_metadata *meta ) {
142
 	int rc;
142
 	int rc;
143
 
143
 
144
 	/* Add data to buffer */
144
 	/* Add data to buffer */
160
  * @ret xferbuf		Data transfer buffer, or NULL on error
160
  * @ret xferbuf		Data transfer buffer, or NULL on error
161
  */
161
  */
162
 static struct xfer_buffer *
162
 static struct xfer_buffer *
163
-downloader_xfer_buffer ( struct downloader *downloader ) {
163
+downloader_buffer ( struct downloader *downloader ) {
164
 
164
 
165
 	/* Provide direct access to underlying data transfer buffer */
165
 	/* Provide direct access to underlying data transfer buffer */
166
 	return &downloader->buffer;
166
 	return &downloader->buffer;
167
 }
167
 }
168
 
168
 
169
+/**
170
+ * Redirect data transfer interface
171
+ *
172
+ * @v downloader	Downloader
173
+ * @v type		New location type
174
+ * @v args		Remaining arguments depend upon location type
175
+ * @ret rc		Return status code
176
+ */
177
+static int downloader_vredirect ( struct downloader *downloader, int type,
178
+				  va_list args ) {
179
+	va_list tmp;
180
+	struct uri *uri;
181
+	int rc;
182
+
183
+	/* Intercept redirects to a LOCATION_URI and update the image URI */
184
+	if ( type == LOCATION_URI ) {
185
+
186
+		/* Extract URI argument */
187
+		va_copy ( tmp, args );
188
+		uri = va_arg ( tmp, struct uri * );
189
+		va_end ( tmp );
190
+
191
+		/* Set image URI */
192
+		if ( ( rc = image_set_uri ( downloader->image, uri ) ) != 0 )
193
+			return rc;
194
+	}
195
+
196
+	/* Redirect to new location */
197
+	if ( ( rc = xfer_vreopen ( &downloader->xfer, type, args ) ) != 0 )
198
+		return rc;
199
+
200
+	return 0;
201
+}
202
+
169
 /** Downloader data transfer interface operations */
203
 /** Downloader data transfer interface operations */
170
 static struct interface_operation downloader_xfer_operations[] = {
204
 static struct interface_operation downloader_xfer_operations[] = {
171
-	INTF_OP ( xfer_deliver, struct downloader *, downloader_xfer_deliver ),
172
-	INTF_OP ( xfer_buffer, struct downloader *, downloader_xfer_buffer ),
205
+	INTF_OP ( xfer_deliver, struct downloader *, downloader_deliver ),
206
+	INTF_OP ( xfer_buffer, struct downloader *, downloader_buffer ),
207
+	INTF_OP ( xfer_vredirect, struct downloader *, downloader_vredirect ),
173
 	INTF_OP ( intf_close, struct downloader *, downloader_finished ),
208
 	INTF_OP ( intf_close, struct downloader *, downloader_finished ),
174
 };
209
 };
175
 
210
 

Loading…
Cancel
Save