Replace the --base code with relative paths.
authorMalte S. Stretz <mss@apache.org>
Wed, 1 Jun 2011 11:30:13 +0000 (13:30 +0200)
committerEmil Mikulic <emikulic@gmail.com>
Sat, 4 Jun 2011 14:00:31 +0000 (00:00 +1000)
Most of the functionality turned out to be overkill since
relative paths work fine, too.  The only broken thing is
lighttpd 1.4 which doesn't support proxying of stuff like
  /darkstat/ -> http://localhost:667/
But this will be fixed properly in mod_proxy_core in 1.5
once (if ever) it is released.

contrib/darkproxy.php [new file with mode: 0644]
darkstat.8.in
darkstat.c
graph_db.c
hosts_db.c
html.c
html.h
http.c
http.h

diff --git a/contrib/darkproxy.php b/contrib/darkproxy.php
new file mode 100644 (file)
index 0000000..de0d3f2
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+# copyright (c) 2011 Malte S. Stretz
+#
+# This is a simple proxy script to test the proper implementation of
+# relative hrefs in combination with eg. lighttpd 1.4 which doesn't
+# support the features of mod_proxy_core yet.
+
+$darkstat = "http://localhost:667";
+
+if ($_SERVER['PATH_INFO'] == '') {
+  header("Status: 303 Move!", true);
+  header("Location: " . $_SERVER['PHP_SELF'] . "/", true);
+  exit;
+}
+
+function header_cb($proxy, $h) {
+  header($h);
+  return strlen($h);
+}
+
+$proxy = curl_init();
+curl_setopt($proxy, CURLOPT_URL, $darkstat . $_SERVER['PATH_INFO']);
+curl_setopt($proxy, CURLOPT_HEADERFUNCTION, 'header_cb'); 
+curl_exec($proxy);
+curl_close($proxy);
index 477f198..73e2318 100644 (file)
@@ -38,8 +38,6 @@ darkstat \- network statistics gatherer
 ] [
 .BI \-b " bindaddr"
 ] [
-.BI \-\-base " path"
-] [
 .BI \-f " filter"
 ] [
 .BI \-l " network/netmask"
@@ -169,25 +167,6 @@ Bind the web interface to the specified address.
 The default is to listen on all interfaces.
 .\"
 .TP
-.BI \-\-base " path"
-.RS
-Specify the path of the base URL.
-This can be useful if \fIdarkstat\fR is accessed via a reverse proxy.
-
-For example, if you use Apache's \fImod_proxy\fR and want to avoid a
-complicated setup with \fImod_proxy_html\fR (and \fImod_header\fR to unset
-the \fIAccept-Encoding\fR header), just set the base path to something like
-\fIstats\fR and use a config similar to the following snippet:
-
-.IP
- ProxyPass /stats/ http://localhost:667/stats/
- ProxyPassReverse /stats/ http://localhost:667/stats/
-.PP
-
-The default is \fI/\fR (ie. the root).
-.RE
-.\"
-.TP
 .BI \-f " filter"
 Use the specified filter expression when capturing traffic.
 The filter syntax is beyond the scope of this manual page;
index 217d0e2..b4dd39b 100644 (file)
@@ -139,9 +139,6 @@ static void cb_local(const char *arg) { acct_init_localnet(arg); }
 const char *opt_chroot_dir = NULL;
 static void cb_chroot(const char *arg) { opt_chroot_dir = arg; }
 
-const char *opt_base = NULL;
-static void cb_base(const char *arg) { opt_base = arg; }
-
 const char *opt_privdrop_user = NULL;
 static void cb_user(const char *arg) { opt_privdrop_user = arg; }
 
@@ -234,7 +231,6 @@ static struct cmdline_arg cmdline_args[] = {
    {"--no-lastseen",  NULL,              cb_no_lastseen,  0},
    {"-p",             "port",            cb_port,         0},
    {"-b",             "bindaddr",        cb_bindaddr,     0},
-   {"--base",         "path",            cb_base,         0},
    {"-f",             "filter",          cb_filter,       0},
    {"-l",             "network/netmask", cb_local,        0},
    {"--chroot",       "dir",             cb_chroot,       0},
@@ -421,7 +417,7 @@ main(int argc, char **argv)
    /* do this first as it forks - minimize memory use */
    if (opt_want_dns) dns_init(opt_privdrop_user);
    cap_init(opt_interface, opt_filter, opt_want_promisc); /* needs root */
-   http_init(opt_base, opt_bindaddr, opt_bindport, /*maxconn=*/-1);
+   http_init(opt_bindaddr, opt_bindport, /*maxconn=*/-1);
    ncache_init(); /* must do before chroot() */
 
    privdrop(opt_chroot_dir, opt_privdrop_user);
index 002084f..aef6d8e 100644 (file)
@@ -17,7 +17,6 @@
 #include "err.h"
 #include "str.h"
 #include "html.h"
-#include "http.h"
 #include "graph_db.h"
 #include "now.h"
 #include "opt.h"
@@ -312,7 +311,7 @@ html_front_page(void)
    char start_when[100];
 
    buf = str_make();
-   html_open(buf, "Graphs", /*want_graph_js=*/1);
+   html_open(buf, "Graphs", /*path_depth=*/0, /*want_graph_js=*/1);
 
    str_append(buf, "<p>\n");
    str_append(buf, "<b>Running for</b> <span id=\"rf\">");
index 2845f56..e31605f 100644 (file)
@@ -15,7 +15,6 @@
 #include "hosts_db.h"
 #include "db.h"
 #include "html.h"
-#include "http.h" /* for http_base_url */
 #include "ncache.h"
 #include "now.h"
 #include "opt.h"
@@ -316,10 +315,10 @@ format_row_host(struct str *buf, const struct bucket *b,
 
    str_appendf(buf,
       "<tr class=\"%s\">\n"
-      " <td><a href=\"%shosts/%s/\">%s</a></td>\n"
+      " <td><a href=\"%s/\">%s</a></td>\n"
       " <td>%s</td>\n",
       css_class,
-      http_base_url, ip, ip,
+      ip, ip,
       (b->u.host.dns == NULL) ? "" : b->u.host.dns);
 
    if (hosts_db_show_macs)
@@ -974,7 +973,7 @@ html_hosts_main(const char *qs)
 #define NEXT "next page &gt;&gt;&gt;"
 #define FULL "full table"
 
-   html_open(buf, "Hosts", /*want_graph_js=*/0);
+   html_open(buf, "Hosts", /*path_depth=*/1, /*want_graph_js=*/0);
    format_table(buf, hosts_db, start, sort, full);
 
    /* <prev | full | stats | next> */
@@ -1033,7 +1032,7 @@ html_hosts_detail(const char *ip)
 
    /* Overview. */
    buf = str_make();
-   html_open(buf, ip, /*want_graph_js=*/0);
+   html_open(buf, ip, /*path_depth=*/2, /*want_graph_js=*/0);
    if (strcmp(ip, canonical) != 0)
       str_appendf(buf, "(canonically <b>%s</b>)\n", canonical);
    str_appendf(buf,
diff --git a/html.c b/html.c
index 6e98aaa..0bdd384 100644 (file)
--- a/html.c
+++ b/html.c
 #include "config.h"
 #include "str.h"
 #include "html.h"
-#include "http.h" /* for http_base_url */
 #include "opt.h"
 
-void html_open(struct str *buf, const char *title,
+#include <assert.h>
+
+static const char *relpaths[] = {
+    ".",
+    "..",
+    "../.."
+};
+
+void html_open(struct str *buf, const char *title, const int path_depth,
     const int want_graph_js)
 {
+    assert(path_depth < (sizeof(relpaths)/sizeof(char *)));
+    const char *root = relpaths[path_depth];
+
     str_appendf(buf,
         "<!DOCTYPE html>\n"
         "<html>\n"
@@ -25,13 +35,13 @@ void html_open(struct str *buf, const char *title,
          "<title>%s (darkstat3 %s)</title>\n"
          "<meta name=\"generator\" content=\"" PACKAGE_STRING "\">\n"
          "<meta name=\"robots\" content=\"noindex, noarchive\">\n"
-         "<link rel=\"stylesheet\" href=\"%sstyle.css\" type=\"text/css\">\n"
-        , title, opt_interface, http_base_url);
+         "<link rel=\"stylesheet\" href=\"%s/style.css\" type=\"text/css\">\n"
+        , title, opt_interface, root);
 
     if (want_graph_js)
         str_appendf(buf,
-            "<script src=\"%sgraph.js\" type=\"text/javascript\"></script>\n"
-            , http_base_url);
+            "<script src=\"%s/graph.js\" type=\"text/javascript\"></script>\n"
+            , root);
 
     str_appendf(buf,
         "</head>\n"
@@ -39,14 +49,14 @@ void html_open(struct str *buf, const char *title,
         "<div class=\"menu\">\n"
         "<ul class=\"menu\">" /* no whitespace (newlines) in list */
          "<li class=\"label\">" PACKAGE_STRING "</li>"
-         "<li><a href=\"%s\">graphs</a></li>"
-         "<li><a href=\"%shosts/\">hosts</a></li>"
+         "<li><a href=\"%s/\">graphs</a></li>"
+         "<li><a href=\"%s/hosts/\">hosts</a></li>"
          "<li><a href=\"" PACKAGE_URL "\">homepage</a></li>"
         "</ul>\n"
         "</div>\n"
         "<div class=\"content\">\n"
          "<h2 class=\"pageheader\">%s</h2>\n"
-        , http_base_url, http_base_url, title);
+        , root, root, title);
 }
 
 void html_close(struct str *buf)
diff --git a/html.h b/html.h
index bfe86b4..e89a857 100644 (file)
--- a/html.h
+++ b/html.h
@@ -7,7 +7,7 @@
 #ifndef __DARKSTAT_HTML_H
 #define __DARKSTAT_HTML_H
 
-void html_open(struct str *buf, const char *title,
+void html_open(struct str *buf, const char *title, const int path_depth,
     const int want_graph_js);
 void html_close(struct str *buf);
 
diff --git a/http.c b/http.c
index 10d0769..585d96e 100644 (file)
--- a/http.c
+++ b/http.c
@@ -36,8 +36,6 @@
 #include <unistd.h>
 #include <zlib.h>
 
-char *http_base_url = NULL;
-
 static const char mime_type_xml[] = "text/xml";
 static const char mime_type_html[] = "text/html; charset=us-ascii";
 static const char mime_type_css[] = "text/css";
@@ -619,17 +617,6 @@ static void process_get(struct connection *conn)
         return;
     }
 
-    /* make relative (or fail) */
-    decoded_url = safe_url;
-    if (!str_starts_with(decoded_url, http_base_url))
-    {
-        default_reply(conn, 404, "Not Found",
-            "The page you requested could not be found.");
-        free(decoded_url);
-        return;
-    }
-    safe_url = decoded_url + strlen(http_base_url) - 1;
-
     if (strcmp(safe_url, "/") == 0) {
         struct str *buf = html_front_page();
         str_extract(buf, &(conn->reply_length), &(conn->reply));
@@ -641,7 +628,7 @@ static void process_get(struct connection *conn)
         if (buf == NULL) {
             default_reply(conn, 404, "Not Found",
                 "The page you requested could not be found.");
-            free(decoded_url);
+            free(safe_url);
             return;
         }
         str_extract(buf, &(conn->reply_length), &(conn->reply));
@@ -661,10 +648,10 @@ static void process_get(struct connection *conn)
     else {
         default_reply(conn, 404, "Not Found",
             "The page you requested could not be found.");
-        free(decoded_url);
+        free(safe_url);
         return;
     }
-    free(decoded_url);
+    free(safe_url);
 
     process_gzip(conn);
     assert(conn->mime_type != NULL);
@@ -879,41 +866,6 @@ static void poll_send_reply(struct connection *conn)
     if (conn->reply_sent == conn->reply_length) conn->state = DONE;
 }
 
-
-
-/* --------------------------------------------------------------------------
- * Initialize the base path.
- */
-static void http_init_base(const char *url)
-{
-    char *slashed_url, *safe_url;
-    size_t urllen;
-
-    if (url == NULL) {
-        http_base_url = strdup("/");
-        return;
-    }
-
-    /* make sure that the url has leading and trailing slashes */
-    urllen = strlen(url);
-    slashed_url = xmalloc(urllen+3);
-    slashed_url[0] = '/';
-    memcpy(slashed_url+1, url, urllen); /* don't copy NUL */
-    slashed_url[urllen+1] = '/';
-    slashed_url[urllen+2] = '\0';
-
-    /* clean the url */
-    safe_url = make_safe_uri(slashed_url);
-    free(slashed_url);
-    if (safe_url == NULL) {
-        verbosef("invalid base \"%s\", ignored", url);
-        http_base_url = strdup("/"); /* set to default */
-        return;
-    }
-    else
-        http_base_url = safe_url;
-}
-
 /* Use getaddrinfo to figure out what type of socket to create and
  * what to bind it to.  "bindaddr" can be NULL.  Remember to freeaddrinfo()
  * the result.
@@ -949,14 +901,13 @@ static struct addrinfo *get_bind_addr(
  * Initialize the sockin global.  This is the socket that we accept
  * connections from.  Pass -1 as max_conn for system limit.
  */
-void http_init(const char *base, const char *bindaddr,
-    const unsigned short bindport, const int max_conn)
+void http_init(const char *bindaddr, const unsigned short bindport,
+    const int max_conn)
 {
     struct addrinfo *ai;
     char ipaddr[INET6_ADDRSTRLEN];
     int sockopt, ret;
 
-    http_init_base(base);
     ai = get_bind_addr(bindaddr, bindport);
 
     /* create incoming socket */
@@ -986,11 +937,11 @@ void http_init(const char *base, const char *bindaddr,
     if (bind(sockin, ai->ai_addr, ai->ai_addrlen) == -1)
         err(1, "bind(\"%s\") failed", ipaddr);
 
-    verbosef("listening on http://%s%s%s:%u%s",
+    verbosef("listening on http://%s%s%s:%u/",
         (ai->ai_family == AF_INET6) ? "[" : "",
         ipaddr,
         (ai->ai_family == AF_INET6) ? "]" : "",
-        bindport, http_base_url);
+        bindport);
 
     freeaddrinfo(ai);
 
@@ -1112,7 +1063,6 @@ void http_poll(fd_set *recv_set, fd_set *send_set)
 }
 
 void http_stop(void) {
-    free(http_base_url);
     close(sockin);
 }
 
diff --git a/http.h b/http.h
index b57e101..7987b33 100644 (file)
--- a/http.h
+++ b/http.h
@@ -8,10 +8,8 @@
 #include <sys/select.h>
 #include <netinet/in.h>
 
-extern char *http_base_url;
-
-void http_init(const char *base, const char * bindaddr,
-   const unsigned short bindport, const int max_conn);
+void http_init(const char * bindaddr, const unsigned short bindport,
+   const int max_conn);
 void http_fd_set(fd_set *recv_set, fd_set *send_set, int *max_fd,
    struct timeval *timeout, int *need_timeout);
 void http_poll(fd_set *read_set, fd_set *write_set);