|
@@ -136,9 +136,9 @@ static int downloader_progress ( struct downloader *downloader,
|
136
|
136
|
* @v meta Data transfer metadata
|
137
|
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
|
142
|
int rc;
|
143
|
143
|
|
144
|
144
|
/* Add data to buffer */
|
|
@@ -160,16 +160,51 @@ static int downloader_xfer_deliver ( struct downloader *downloader,
|
160
|
160
|
* @ret xferbuf Data transfer buffer, or NULL on error
|
161
|
161
|
*/
|
162
|
162
|
static struct xfer_buffer *
|
163
|
|
-downloader_xfer_buffer ( struct downloader *downloader ) {
|
|
163
|
+downloader_buffer ( struct downloader *downloader ) {
|
164
|
164
|
|
165
|
165
|
/* Provide direct access to underlying data transfer buffer */
|
166
|
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
|
203
|
/** Downloader data transfer interface operations */
|
170
|
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
|
208
|
INTF_OP ( intf_close, struct downloader *, downloader_finished ),
|
174
|
209
|
};
|
175
|
210
|
|