summaryrefslogtreecommitdiff
path: root/core/fs
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-04-25 21:46:55 -0700
committerH. Peter Anvin <hpa@zytor.com>2011-04-25 21:46:55 -0700
commit80a29a87118bd7539e8a310810dc0045d7a27279 (patch)
tree969e7b66a4f830d8e196240024a97100f9e77ced /core/fs
parent3953ca3532ca3281cc248f9985d9276c6f8486f0 (diff)
downloadsyslinux-80a29a87118bd7539e8a310810dc0045d7a27279.tar.gz
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@zytor.com>
Diffstat (limited to 'core/fs')
-rw-r--r--core/fs/pxe/http.c89
1 files changed, 87 insertions, 2 deletions
diff --git a/core/fs/pxe/http.c b/core/fs/pxe/http.c
index f46cd4cf..ae5e010c 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;