Commits

Julian Brost committed 05e947c

Proper handling of static files.

Comments (0)

Files changed (4)

theme/_static/style.css

+@import url(http://fonts.googleapis.com/css?family=Raleway:100|Open+Sans+Condensed:700|Open+Sans);
+
+body {
+	margin: 0;
+	padding: 0;
+	background-image:         linear-gradient(left, #eee 0%, #fff 20%, #fff 80%, #eee 100%);
+	background-image:      -o-linear-gradient(left, #eee 0%, #fff 20%, #fff 80%, #eee 100%);
+	background-image:    -moz-linear-gradient(left, #eee 0%, #fff 20%, #fff 80%, #eee 100%);
+	background-image: -webkit-linear-gradient(left, #eee 0%, #fff 20%, #fff 80%, #eee 100%);
+	background-image:     -ms-linear-gradient(left, #eee 0%, #fff 20%, #fff 80%, #eee 100%);
+	font-family: "Open Sans", "Helvetica", "Arial", sans-serif;
+	font-size: 0.8em;
+}
+
+header, nav, #articles, footer {
+	margin: auto;
+	width: 60em;
+}
+
+header {
+	margin-top: 24px;
+}
+
+header h1 {
+	margin: 0;
+	padding: 0;
+	font-family: "Raleway";
+	font-weight: 100;
+	text-align: center;
+	font-size: 6em;
+}
+
+nav {
+	padding: 0 2em;
+	background-color: #135;
+	margin-top: 16px;
+	margin-bottom: 20px;
+	text-align: center;
+}
+
+nav a {
+	display: inline-block;
+	color: #eee;
+	text-decoration: none;
+	font-size: 14px;
+	padding: 8px 16px;
+}
+
+nav a:hover {
+	background-color: #26a;
+}
+
+article h2 {
+	color: #135;
+	font-family: "Open Sans Condensed";
+	font-weight: 700;
+}
+
+article h2 a {
+	text-decoration: none;
+	color: inherit;
+}
+
+article p.meta {
+	margin-top: -1em;
+	color: #888;
+	font-size: 0.9em;
+}
+
+footer {
+	margin: 2em auto;
+	padding: 1em 8em;
+	border-top: 1px solid #bbb;
+	text-align: center;
+	color: #666;
+	font-size: 0.9em;
+}
 <html>
 	<head>
 		<title><!--goblog:TITLE--></title>
-		<link rel="stylesheet" href="<!--goblog:REL_LINK-->style.css">
+		<link rel="stylesheet" href="<!--goblog:REL_LINK-->_static/theme/style.css">
 	</head>
 	<body>
 		<header>

theme/style.css

-@import url(http://fonts.googleapis.com/css?family=Raleway:100|Open+Sans+Condensed:700|Open+Sans);
-
-body {
-	margin: 0;
-	padding: 0;
-	background-image:         linear-gradient(left, #eee 0%, #fff 20%, #fff 80%, #eee 100%);
-	background-image:      -o-linear-gradient(left, #eee 0%, #fff 20%, #fff 80%, #eee 100%);
-	background-image:    -moz-linear-gradient(left, #eee 0%, #fff 20%, #fff 80%, #eee 100%);
-	background-image: -webkit-linear-gradient(left, #eee 0%, #fff 20%, #fff 80%, #eee 100%);
-	background-image:     -ms-linear-gradient(left, #eee 0%, #fff 20%, #fff 80%, #eee 100%);
-	font-family: "Open Sans", "Helvetica", "Arial", sans-serif;
-	font-size: 0.8em;
-}
-
-header, nav, #articles, footer {
-	margin: auto;
-	width: 60em;
-}
-
-header {
-	margin-top: 24px;
-}
-
-header h1 {
-	margin: 0;
-	padding: 0;
-	font-family: "Raleway";
-	font-weight: 100;
-	text-align: center;
-	font-size: 6em;
-}
-
-nav {
-	padding: 0 2em;
-	background-color: #135;
-	margin-top: 16px;
-	margin-bottom: 20px;
-	text-align: center;
-}
-
-nav a {
-	display: inline-block;
-	color: #eee;
-	text-decoration: none;
-	font-size: 14px;
-	padding: 8px 16px;
-}
-
-nav a:hover {
-	background-color: #26a;
-}
-
-article h2 {
-	color: #135;
-	font-family: "Open Sans Condensed";
-	font-weight: 700;
-}
-
-article h2 a {
-	text-decoration: none;
-	color: inherit;
-}
-
-article p.meta {
-	margin-top: -1em;
-	color: #888;
-	font-size: 0.9em;
-}
-
-footer {
-	margin: 2em auto;
-	padding: 1em 8em;
-	border-top: 1px solid #bbb;
-	text-align: center;
-	color: #666;
-	font-size: 0.9em;
-}
 	"fmt"
 	"net/http"
 	"os"
+	"path"
+	"path/filepath"
+	"strings"
 )
 
 func handle(w http.ResponseWriter, r *http.Request) {
 		handlePostList(app, w, r)
 	} else if r.URL.Path == "/feed" {
 		handleFeed(w, r)
-	} else if r.URL.Path == "/style.css" {
-		http.ServeFile(w, r, app.JoinEnv("theme", "style.css"))
 	} else if postRegex.MatchString(r.URL.Path) {
 		handlePost(app, w, r)
 	} else {
 	}
 }
 
-func viewStatic(app *App, w http.ResponseWriter, r *http.Request) {}
+func viewStatic(app *App, w http.ResponseWriter, r *http.Request) {
+	pathElements := strings.Split(path.Clean(r.URL.Path), "/")
+	if len(pathElements) < 3 {
+		// TODO: 404
+		return
+	}
+	staticType := pathElements[2]
+	staticFile := pathElements[3:]
+	// TODO: make this more dynamic
+	switch staticType {
+	case "theme":
+		serveDir(w, r, app.JoinEnv("theme", "_static"), staticFile)
+	}
+}
+
+func serveDir(w http.ResponseWriter, r *http.Request, dir string, path []string) {
+	p := filepath.Join(dir, filepath.Join(path...))
+	p = filepath.Clean(p)
+	if !filepath.HasPrefix(p, dir) {
+		// directory traversal attack?
+		// TODO: 404
+		return
+	}
+	http.ServeFile(w, r, p)
+}
 
 func viewDebug(app *App, w http.ResponseWriter, r *http.Request) {
 	fmt.Fprintln(w, "Application:")