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