[syslinux:lwip] pxe: move redirect processing to the URL-parsing level

syslinux-bot for H. Peter Anvin hpa at zytor.com
Sun Apr 24 21:03:23 PDT 2011


Commit-ID:  17e4fda81778ca19aae85a630c302230b3802b43
Gitweb:     http://syslinux.zytor.com/commit/17e4fda81778ca19aae85a630c302230b3802b43
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Sun, 24 Apr 2011 13:59:18 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Sun, 24 Apr 2011 13:59:18 -0700

pxe: move redirect processing to the URL-parsing level

Move redirect processing out of the HTTP code and into the top
URL-processing level.  This both makes the code simpler and also deals
with absurdities like HTTP redirecting to an FTP URL (which is legal.)

Signed-off-by: H. Peter Anvin <hpa at zytor.com>


---
 core/fs/pxe/ftp.c  |    3 ++-
 core/fs/pxe/http.c |   21 +++++----------------
 core/fs/pxe/pxe.c  |   41 +++++++++++++++++++++++++----------------
 core/fs/pxe/pxe.h  |    6 +++---
 core/fs/pxe/tftp.c |    4 +++-
 5 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/core/fs/pxe/ftp.c b/core/fs/pxe/ftp.c
index 0c03355..ca4b3d6 100644
--- a/core/fs/pxe/ftp.c
+++ b/core/fs/pxe/ftp.c
@@ -169,7 +169,7 @@ static void ftp_close_file(struct inode *inode)
     ftp_free(inode);
 }
 
-void ftp_open(struct url_info *url, struct inode *inode)
+void ftp_open(struct url_info *url, struct inode *inode, const char **redir)
 {
     struct pxe_pvt_inode *socket = PVT(inode);
     struct pxe_pvt_inode *ctlsock;
@@ -179,6 +179,7 @@ void ftp_open(struct url_info *url, struct inode *inode)
     int resp;
     err_t err;
 
+    (void)redir;		/* FTP does not redirect */
     inode->size = 0;
 
     if (!url->port)
diff --git a/core/fs/pxe/http.c b/core/fs/pxe/http.c
index 8d19755..f46cd4c 100644
--- a/core/fs/pxe/http.c
+++ b/core/fs/pxe/http.c
@@ -45,7 +45,7 @@ static bool append_ch(char *str, size_t size, size_t *pos, int ch)
     return success;
 }
 
-void http_open(struct url_info *url, struct inode *inode)
+void http_open(struct url_info *url, struct inode *inode, const char **redir)
 {
     struct pxe_pvt_inode *socket = PVT(inode);
     char header_buf[4096];
@@ -67,18 +67,15 @@ void http_open(struct url_info *url, struct inode *inode)
 	st_eoh,
     } state;
     struct ip_addr addr;
-    char location[1024], new_url[1024];
+    static char location[FILENAME_MAX];
     uint32_t content_length; /* same as inode->size */
     size_t response_size;
     int status;
     int pos;
-    int redirect_count;
 
     socket->fill_buffer = tcp_fill_buffer;
     socket->close = tcp_close_file;
-    redirect_count = 0;
 
-restart:
     /* Reset all of the variables */
     inode->size = content_length = -1;
 
@@ -193,7 +190,7 @@ restart:
 		    /* Skip leading whitespace */
 		    while (isspace(*next))
 			next++;
-		    strcpy(location, next);
+		    strlcpy(location, next, sizeof location);
 		}
 		/* Start the field name and field value afress */
 		field_name_len = 1;
@@ -275,16 +272,8 @@ restart:
 	/* A redirect */
 	if (!location[0])
 	    goto fail;
-	redirect_count++;
-	if (redirect_count > 5)
-	    goto fail;
-	strlcpy(new_url, location, sizeof new_url);
-	parse_url(url, new_url);
-	url_set_ip(url);
-	tcp_close_file(inode);
-	/* XXX: This needs to go all the way back to scheme selection */
-	goto restart;
-	break;
+	*redir = location;
+	goto fail;
     default:
 	goto fail;
 	break;
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index 71532d6..0f76804 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -37,7 +37,7 @@ __lowmem char packet_buf[PKTBUF_SIZE] __aligned(16);
 
 static struct url_scheme {
     const char *name;
-    void (*open)(struct url_info *url, struct inode *inode);
+    void (*open)(struct url_info *url, struct inode *inode, const char **redir);
 } url_schemes[] = {
     { "tftp", tftp_open },
     { "http", http_open },
@@ -382,27 +382,36 @@ static void __pxe_searchdir(const char *filename, struct file *file)
     char fullpath[2*FILENAME_MAX];
     struct url_info url;
     const struct url_scheme *us;
+    int redirect_count = 0;
 
     inode = file->inode = NULL;
 
-    strlcpy(fullpath, filename, sizeof fullpath);
-    parse_url(&url, fullpath);
-    if (url.type == URL_SUFFIX) {
-	snprintf(fullpath, sizeof fullpath, "%s%s", fs->cwd_name, filename);
-	parse_url(&url, fullpath);
-    }
-
-    inode = allocate_socket(fs);
-    if (!inode)
-	return;			/* Allocation failure */
+    while (filename) {
+	if (redirect_count++ > 5)
+	    break;
 
-    url_set_ip(&url);
+	strlcpy(fullpath, filename, sizeof fullpath);
+	parse_url(&url, fullpath);
+	if (url.type == URL_SUFFIX) {
+	    snprintf(fullpath, sizeof fullpath, "%s%s", fs->cwd_name, filename);
+	    parse_url(&url, fullpath);
+	}
 
-    for (us = url_schemes; us->name; us++) {
-	if (!strcmp(us->name, url.scheme)) {
-	    us->open(&url, inode);
-	    break;
+	inode = allocate_socket(fs);
+	if (!inode)
+	    return;			/* Allocation failure */
+	
+	url_set_ip(&url);
+	
+	filename = NULL;
+	for (us = url_schemes; us->name; us++) {
+	    if (!strcmp(us->name, url.scheme)) {
+		us->open(&url, inode, &filename);
+		break;
+	    }
 	}
+
+	/* filename here is set on a redirect */
     }
 
     if (inode->size)
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index 699cf65..b23f7a7 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -245,17 +245,17 @@ uint16_t get_port(void);
 void free_port(uint16_t port);
 
 /* tftp.c */
-void tftp_open(struct url_info *url, struct inode *inode);
+void tftp_open(struct url_info *url, struct inode *inode, const char **redir);
 
 /* gpxeurl.c */
 void gpxe_open(struct inode *inode, const char *url);
 #define GPXE 1
 
 /* http.c */
-void http_open(struct url_info *url, struct inode *inode);
+void http_open(struct url_info *url, struct inode *inode, const char **redir);
 
 /* ftp.c */
-void ftp_open(struct url_info *url, struct inode *inode);
+void ftp_open(struct url_info *url, struct inode *inode, const char **redir);
 
 /* tcp.c */
 void tcp_close_file(struct inode *inode);
diff --git a/core/fs/pxe/tftp.c b/core/fs/pxe/tftp.c
index 89b21ae..637f0e9 100644
--- a/core/fs/pxe/tftp.c
+++ b/core/fs/pxe/tftp.c
@@ -210,7 +210,7 @@ static void tftp_get_packet(struct inode *inode)
  * @out: the lenght of this file, stores in file->file_len
  *
  */
-void tftp_open(struct url_info *url, struct inode *inode)
+void tftp_open(struct url_info *url, struct inode *inode, const char **redir)
 {
     struct pxe_pvt_inode *socket = PVT(inode);
     char *buf;
@@ -234,6 +234,8 @@ void tftp_open(struct url_info *url, struct inode *inode)
     uint32_t opdata, *opdata_ptr;
     struct ip_addr addr;
 
+    (void)redir;		/* TFTP does not redirect */
+
     if (url->type != URL_OLD_TFTP) {
 	/*
 	 * The TFTP URL specification allows the TFTP to end with a



More information about the Syslinux-commits mailing list