[syslinux:lwip] pxe, http: send the sysappend/ipappend strings as cookies

syslinux-bot for H. Peter Anvin hpa at zytor.com
Mon Apr 25 21:51:35 PDT 2011


Commit-ID:  80a29a87118bd7539e8a310810dc0045d7a27279
Gitweb:     http://syslinux.zytor.com/commit/80a29a87118bd7539e8a310810dc0045d7a27279
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Mon, 25 Apr 2011 21:46:55 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Mon, 25 Apr 2011 21:46:55 -0700

pxe, http: send the sysappend/ipappend strings as cookies

When using http, send the sysappend/ipappend strings as cookies
prefixed with _Syslinux_ ... the implementation of this may change.
This is using the "old" cookie format for compactness (single header,
for all cookies, and no $Version tag.)  PHP at least seems perfectly
happy to deal with it.

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


---
 core/fs/pxe/http.c |   89 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/core/fs/pxe/http.c b/core/fs/pxe/http.c
index f46cd4c..ae5e010 100644
--- a/core/fs/pxe/http.c
+++ b/core/fs/pxe/http.c
@@ -1,3 +1,4 @@
+#include <syslinux/sysappend.h>
 #include <ctype.h>
 #include <lwip/api.h>
 #include "pxe.h"
@@ -45,6 +46,83 @@ static bool append_ch(char *str, size_t size, size_t *pos, int ch)
     return success;
 }
 
+static size_t cookie_len;
+static char *cookie_buf;
+
+static size_t http_do_bake_cookies(char *q)
+{
+    static const char uchexchar[16] = "0123456789ABCDEF";
+    int i;
+    size_t len;
+    size_t n = 0;
+    const char *p;
+    char c;
+    size_t qlen = q ? -1UL : 0;
+    bool first = true;
+
+    for (i = 0; i < SYSAPPEND_MAX; i++) {
+	if ((p = sysappend_strings[i])) {
+	    len = snprintf(q, qlen, "%s_Syslinux_", first ? "Cookie: " : "");
+	    if (q)
+		q += len;
+	    n += len;
+	    first = false;
+	    /* Copy string up to and including '=' */
+	    do {
+		c = *p++;
+		if (q)
+		    *q++ = c;
+		n++;
+	    } while (c != '=');
+	    while ((c = *p++)) {
+		if (c == ' ') {
+		    if (q)
+			*q++ = '+';
+		    n++;
+		} else if (is_token(c)) {
+		    if (q)
+			*q++ = c;
+		    n++;
+		} else {
+		    if (q) {
+			*q++ = '%';
+			*q++ = uchexchar[c >> 4];
+			*q++ = uchexchar[c & 15];
+		    }
+		    n += 3;
+		}
+	    }
+	    if (q)
+		*q++ = ';';
+	    n++;
+	}
+    }
+    if (!first) {
+	if (q) {
+	    *q++ = '\r';
+	    *q++ = '\n';
+	}
+	n += 2;
+    }
+    if (q)
+	*q = '\0';
+    
+    return n;
+}
+
+void http_bake_cookies(void)
+{
+    if (cookie_buf)
+	free(cookie_buf);
+
+    cookie_len = http_do_bake_cookies(NULL);
+    cookie_buf = malloc(cookie_len+1);
+    if (!cookie_buf)
+	return;
+
+    http_do_bake_cookies(cookie_buf);
+}
+
 void http_open(struct url_info *url, struct inode *inode, const char **redir)
 {
     struct pxe_pvt_inode *socket = PVT(inode);
@@ -73,6 +151,10 @@ void http_open(struct url_info *url, struct inode *inode, const char **redir)
     int status;
     int pos;
 
+    /* XXX: make this an external call at the appropriate time instead */
+    if (!cookie_buf)
+	http_bake_cookies();
+
     socket->fill_buffer = tcp_fill_buffer;
     socket->close = tcp_close_file;
 
@@ -107,12 +189,15 @@ void http_open(struct url_info *url, struct inode *inode, const char **redir)
 			   "Host: %s\r\n"
 			   "User-Agent: PXELINUX/%s\r\n"
 			   "Connection: close\r\n"
+			   "%s"
 			   "\r\n",
-			   url->host, VERSION_STR);
+			   url->host, VERSION_STR,
+			   cookie_buf ? cookie_buf : "");
     if (header_len > sizeof header_buf)
 	goto fail;		/* Buffer overflow */
 
-    err = netconn_write(socket->conn, header_buf, header_len, NETCONN_NOCOPY);
+    err = netconn_write(socket->conn, header_buf,
+			header_len, NETCONN_NOCOPY);
     if (err) {
 	printf("netconn_write error %d\n", err);
 	goto fail;



More information about the Syslinux-commits mailing list