[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