[Etherboot-developers] xfer_* API questions
Brought to you by:
marty_connor,
stefanhajnoczi
From: Kevin L. <cra...@gm...> - 2009-02-23 16:02:33
|
Hello list I'm working on implementing HTTP redirects into gPXE to support the greater good of booting from services such as Amazon S3, Nirvanix Storage Cloud, Coral FreeCDN, and like services. My only hurdle in doing this is understanding the xfer_* API and the mechanics. Using mcb30's suggestions, I've hooked into http_header_handler struct in net/tcp/http.c for looking for Location: headers. In trying to understand xfer_redirect() it seems that it uses the xfer_interface_operations struct passed to xfer_init() during the initial connection. So, I'm guessing the http_xfer_operations->vredirect is a pointer to the function I really want to impliment for handling HTTP redirect requests? In which case whatever vredirect handling I implement will need to close the current xfer handle, then re-init on in it's place since the redirected URI may not even be relative to the current connection? The patch below is for RFC even though I know the http_rx_location() mechanics are a little off. Like, should I even return for http_rx_location() since I know the connection isn't valid anymore? Anywho, I couldn't find anything on the wiki about these mechanics so this is my plea for help :-) Thanks in advance, -- Kevin Landreth >From 44d27a18025558840c1b3dafbe22e71b2f350240 Mon Sep 17 00:00:00 2001 From: Kevin Landreth <cra...@gm...> Date: Mon, 23 Feb 2009 09:01:03 -0600 Subject: [PATCH] Added handlers for status codes and for Location: --- src/net/tcp/http.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 42 insertions(+), 0 deletions(-) diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c index 0191750..9d0fb02 100644 --- a/src/net/tcp/http.c +++ b/src/net/tcp/http.c @@ -138,6 +138,10 @@ static void http_done ( struct http_request *http, int rc ) { static int http_response_to_rc ( unsigned int response ) { switch ( response ) { case 200: + case 301: + case 302: + case 303: + case 307: return 0; case 404: return -ENOENT; @@ -205,6 +209,40 @@ static int http_rx_content_length ( struct http_request *http, return 0; } +/** + * Handle HTTP Redirection + * + * @v http HTTP request + * @v value HTTP header value + * @ret rc Return status code + */ +static int http_rx_location ( struct http_request *http, + const char *value ) { + /** Recursion detection */ + static int depth = 0; + depth++; + if ( depth > HTTP_MAX_DEPTH ) + return -EIO; + + /** Blindly resolve uri, + * let xfer_redirect deal with the fault */ + http->uri = resolve_uri(http->uri, + parse_uri(value)); + if ( ! http->uri ) + return -ENOMEM; + + /** Set the cwuri to the newly resolve one */ + uri_put(http->uri); + + int rc = -ENOTSUP; + /** Attempt a redirect hook */ + if ( (rc = xfer_redirect(&http->xfer, LOCATION_URI, + &http->uri, HTTP_PORT, NULL) ) == 0) + depth = 0; + + return rc; +} + /** An HTTP header handler */ struct http_header_handler { /** Name (e.g. "Content-Length") */ @@ -226,6 +264,10 @@ static struct http_header_handler http_header_handlers[] = { .header = "Content-Length", .rx = http_rx_content_length, }, + { + .header = "Location", + .rx = http_rx_location, + }, { NULL, NULL } }; -- 1.6.0.6 |