Add httpd -v, fix ? in static URLs, and very start of CGI plumbing.
diff --git a/lib/lib.h b/lib/lib.h
index f7d723e..f27ed20 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -352,7 +352,7 @@
void xsendto(int sockfd, void *buf, size_t len, struct sockaddr *dest);
int xrecvwait(int fd, char *buf, int len, union socksaddr *sa, int timeout);
char *escape_url(char *str, char *and);
-void unescape_url(char *str);
+char *unescape_url(char *str);
// password.c
int get_salt(char *salt, char * algo);
diff --git a/lib/net.c b/lib/net.c
index 8d3a677..533df28 100644
--- a/lib/net.c
+++ b/lib/net.c
@@ -197,18 +197,23 @@
}
// Convert %XX escapes to character (in place)
-void unescape_url(char *str)
+char *unescape_url(char *str)
{
- char *to;
+ char *to, *cut = strchr(str, '?');
int i;
for (to = str;;) {
if (*str!='%' || !isxdigit(str[1]) || !isxdigit(str[2])) {
- if (!(*to++ = *str++)) break;
+ if (str==cut) {
+ *to++ = 0;
+ str++;
+ } else if (!(*to++ = *str++)) break;
} else {
sscanf(++str, "%2x", &i);
*to++ = i;
str += 2;
}
}
+
+ return cut;
}
diff --git a/toys/net/httpd.c b/toys/net/httpd.c
index f4dc464..2460dea 100644
--- a/toys/net/httpd.c
+++ b/toys/net/httpd.c
@@ -12,17 +12,22 @@
* -ifv -p [IP:]PORT -u [USER][:GRP] -c CFGFILE
* cgi: SERVER_PORT SERVER_NAME REMOTE_ADDR REMOTE_HOST REQUEST_METHOD
-USE_HTTPD(NEWTOY(httpd, ">1", TOYFLAG_USR|TOYFLAG_BIN))
+USE_HTTPD(NEWTOY(httpd, ">1v", TOYFLAG_USR|TOYFLAG_BIN))
config HTTPD
bool "httpd"
default y
help
- usage: httpd [DIR]
+ usage: httpd [-e STR] [DIR]
Serve contents of directory as static web pages.
+
+ -e Escape STR as URL, printing result and exiting.
+ -d Decode escaped STR, printing result and exiting.
+ -v Verbose
*/
+#define FOR_httpd
#include "toys.h"
char *rfc1123(char *buf, time_t t)
@@ -32,23 +37,6 @@
return buf;
}
-// Stop: header time.
-void header_time(int stat, char *str, char *more)
-{
- char buf[64];
-
- xprintf("HTTP/1.1 %d %s\r\nServer: toybox httpd/%s\r\nDate: %s\r\n%s"
- "Connection: close\r\n\r\n", stat, str, TOYBOX_VERSION,
- rfc1123(buf, time(0)), more ? : "");
-}
-
-void error_time(int stat, char *str)
-{
- header_time(stat, str, 0);
- xprintf("<html><head><title>%d %s</title></head>"
- "<body><h3>%d %s</h3></body></html>", stat, str, stat, str);
-}
-
// She never told me...
char *mime(char *file)
{
@@ -80,6 +68,25 @@
return toybuf;
}
+// Stop: header time.
+static void header_time(int stat, char *str, char *more)
+{
+ char buf[64];
+
+ if (!more) more = "";
+ if (FLAG(v)) dprintf(2, "REPLY: %d %s\n%s\n", stat, str, more);
+ xprintf("HTTP/1.1 %d %s\r\nServer: toybox httpd/%s\r\nDate: %s\r\n%s"
+ "Connection: close\r\n\r\n", stat, str, TOYBOX_VERSION,
+ rfc1123(buf, time(0)), more);
+}
+
+static void error_time(int stat, char *str)
+{
+ header_time(stat, str, 0);
+ xprintf("<html><head><title>%d %s</title></head>"
+ "<body><h3>%d %s</h3></body></html>", stat, str, stat, str);
+}
+
static int isunder(char *file, char *dir)
{
char *s1 = xabspath(dir, ABS_FILE), *s2 = xabspath(file, 0), *ss = s2;
@@ -95,8 +102,15 @@
void handle(int infd, int outfd)
{
FILE *fp = fdopen(infd, "r");
- char *s = xgetline(fp), *ss, *esc, *path, *word[3];
- int i, fd;
+ char *s = xgetline(fp), *cut, *ss, *esc, *path, *word[3];
+ int i = sizeof(toybuf), fd;
+
+ if (!s) return;
+
+ if (!getsockname(0, (void *)&toybuf, &i)) {
+ if (FLAG(v))
+ dprintf(2, "Hello %s\n%s\n", ntop((void *)toybuf), s);
+ }
// Split line into method/path/protocol
for (i = 0, ss = s;;) {
@@ -110,6 +124,7 @@
// Process additional http/1.1 lines
while ((ss = xgetline(fp))) {
i = *chomp(ss);
+ if (FLAG(v)) dprintf(2, "%s\n", ss);
// TODO: any of
//User-Agent: Wget/1.20.1 (linux-gnu) - do we want to log anything?
//Accept: */* - 406 Too Snobbish
@@ -123,10 +138,11 @@
if (!strcasecmp(word[0], "get")) {
struct stat st;
+
if (*(ss = word[1])!='/') error_time(400, "Bad Request");
while (*ss=='/') ss++;
if (!*ss) ss = "./";
- else unescape_url(ss);
+ else cut = unescape_url(ss);
// TODO domain.com:/path/to/blah domain2.com:/path/to/that
if (!isunder(ss, ".") || stat(ss, &st)) error_time(404, "Not Found");