diff options
| author | Michael Brown | 2009-03-30 14:24:56 +0200 |
|---|---|---|
| committer | Michael Brown | 2009-03-30 14:24:56 +0200 |
| commit | 323cdf8c4c510fc6da081b96994d0131c11a29dd (patch) | |
| tree | 268806d5d1de34a96a446356a065057b060c7282 /src/core | |
| parent | [bzimage] Support old (pre-2.00 bootloader) Linux kernel formats (diff) | |
| download | ipxe-323cdf8c4c510fc6da081b96994d0131c11a29dd.tar.gz ipxe-323cdf8c4c510fc6da081b96994d0131c11a29dd.tar.xz ipxe-323cdf8c4c510fc6da081b96994d0131c11a29dd.zip | |
[xfer] Implement xfer_vreopen() to properly handle redirections
When handling a redirection event, we need to close the existing
connection before opening the new connection.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/downloader.c | 2 | ||||
| -rw-r--r-- | src/core/open.c | 28 | ||||
| -rw-r--r-- | src/core/posix_io.c | 2 |
3 files changed, 30 insertions, 2 deletions
diff --git a/src/core/downloader.c b/src/core/downloader.c index 0a443db23..83027d388 100644 --- a/src/core/downloader.c +++ b/src/core/downloader.c @@ -205,7 +205,7 @@ static void downloader_xfer_close ( struct xfer_interface *xfer, int rc ) { /** Downloader data transfer interface operations */ static struct xfer_interface_operations downloader_xfer_operations = { .close = downloader_xfer_close, - .vredirect = xfer_vopen, + .vredirect = xfer_vreopen, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = downloader_xfer_deliver_iob, diff --git a/src/core/open.c b/src/core/open.c index 89a96d72e..beb67a037 100644 --- a/src/core/open.c +++ b/src/core/open.c @@ -53,6 +53,8 @@ int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { /* Find opener which supports this URI scheme */ for_each_table_entry ( opener, URI_OPENERS ) { if ( strcmp ( resolved_uri->scheme, opener->scheme ) == 0 ) { + DBGC ( xfer, "XFER %p opening %s URI\n", + xfer, opener->scheme ); rc = opener->open ( xfer, resolved_uri ); goto done; } @@ -170,3 +172,29 @@ int xfer_open ( struct xfer_interface *xfer, int type, ... ) { va_end ( args ); return rc; } + +/** + * Reopen location + * + * @v xfer Data transfer interface + * @v type Location type + * @v args Remaining arguments depend upon location type + * @ret rc Return status code + * + * This will close the existing connection and open a new connection + * using xfer_vopen(). It is intended to be used as a .vredirect + * method handler. + */ +int xfer_vreopen ( struct xfer_interface *xfer, int type, va_list args ) { + struct xfer_interface_operations *op = xfer->op; + + /* Close existing connection */ + xfer_nullify ( xfer ); + xfer_close ( xfer, 0 ); + + /* Restore to operational status */ + xfer->op = op; + + /* Open new location */ + return xfer_vopen ( xfer, type, args ); +} diff --git a/src/core/posix_io.c b/src/core/posix_io.c index e0459bdf1..6f6d815ac 100644 --- a/src/core/posix_io.c +++ b/src/core/posix_io.c @@ -137,7 +137,7 @@ posix_file_xfer_deliver_iob ( struct xfer_interface *xfer, /** POSIX file data transfer interface operations */ static struct xfer_interface_operations posix_file_xfer_operations = { .close = posix_file_xfer_close, - .vredirect = xfer_vopen, + .vredirect = xfer_vreopen, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = posix_file_xfer_deliver_iob, |
