Browse Source
Merge pull request #36 from mutantmonkey/csp
Merge pull request #36 from mutantmonkey/csp
Add support for Content-Security-Policy and X-Frame-Optionspull/40/head
18 changed files with 277 additions and 99 deletions
-
40csp.go
-
38csp_test.go
-
2fileserve.go
-
16server.go
-
70static/css/linx.css
-
16static/js/bin.js
-
2static/js/bin_hljs.js
-
87static/js/upload.js
-
2templates/404.html
-
2templates/display/audio.html
-
30templates/display/bin.html
-
2templates/display/file.html
-
2templates/display/image.html
-
5templates/display/pdf.html
-
6templates/display/video.html
-
4templates/index.html
-
2templates/oops.html
-
4templates/paste.html
@ -0,0 +1,40 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"net/http" |
|||
) |
|||
|
|||
const ( |
|||
cspHeader = "Content-Security-Policy" |
|||
frameOptionsHeader = "X-Frame-Options" |
|||
) |
|||
|
|||
type csp struct { |
|||
h http.Handler |
|||
opts CSPOptions |
|||
} |
|||
|
|||
type CSPOptions struct { |
|||
policy string |
|||
frame string |
|||
} |
|||
|
|||
func (c csp) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
|||
// only add a CSP if one is not already set
|
|||
if existing := w.Header().Get(cspHeader); existing == "" { |
|||
w.Header().Add(cspHeader, c.opts.policy) |
|||
} |
|||
|
|||
w.Header().Set(frameOptionsHeader, c.opts.frame) |
|||
|
|||
c.h.ServeHTTP(w, r) |
|||
} |
|||
|
|||
func ContentSecurityPolicy(o CSPOptions) func(http.Handler) http.Handler { |
|||
fn := func(h http.Handler) http.Handler { |
|||
return csp{h, o} |
|||
} |
|||
return fn |
|||
} |
|||
|
|||
// vim:set ts=8 sw=8 noet:
|
@ -0,0 +1,38 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"net/http" |
|||
"net/http/httptest" |
|||
"testing" |
|||
|
|||
"github.com/zenazn/goji" |
|||
) |
|||
|
|||
var testCSPHeaders = map[string]string{ |
|||
"Content-Security-Policy": "default-src 'none'; style-src 'self';", |
|||
"X-Frame-Options": "SAMEORIGIN", |
|||
} |
|||
|
|||
func TestContentSecurityPolicy(t *testing.T) { |
|||
w := httptest.NewRecorder() |
|||
|
|||
req, err := http.NewRequest("GET", "/", nil) |
|||
if err != nil { |
|||
t.Fatal(err) |
|||
} |
|||
|
|||
goji.Use(ContentSecurityPolicy(CSPOptions{ |
|||
policy: testCSPHeaders["Content-Security-Policy"], |
|||
frame: testCSPHeaders["X-Frame-Options"], |
|||
})) |
|||
|
|||
goji.DefaultMux.ServeHTTP(w, req) |
|||
|
|||
for k, v := range testCSPHeaders { |
|||
if w.HeaderMap[k][0] != v { |
|||
t.Fatalf("%s header did not match expected value set by middleware", k) |
|||
} |
|||
} |
|||
} |
|||
|
|||
// vim:set ts=8 sw=8 noet:
|
@ -0,0 +1,2 @@ |
|||
hljs.tabReplace = ' '; |
|||
hljs.initHighlightingOnLoad(); |
@ -1,5 +1,5 @@ |
|||
{% extends "base.html" %} |
|||
|
|||
{% block content %} |
|||
<a href="/"><img style="border:0;" src='/static/images/404.jpg' width='400'></a> |
|||
<a href="/"><img src='/static/images/404.jpg'></a> |
|||
{% endblock %} |
@ -1,7 +1,7 @@ |
|||
{% extends "base.html" %} |
|||
|
|||
{% block main %} |
|||
<div class="normal" style="width: 500px;"> |
|||
<div class="normal display-file"> |
|||
<p class="center">You are requesting <a href="/selif/{{ filename }}">{{ filename }}</a>, <a href="/selif/{{ filename }}">click here</a> to download.</p> |
|||
</div> |
|||
{% endblock %} |
@ -1,10 +1,8 @@ |
|||
{% extends "base.html" %} |
|||
|
|||
{% block main %} |
|||
<div id='video'> |
|||
<video controls autoplay width="800"> |
|||
<video class="display-video" controls autoplay> |
|||
<source src="/selif/{{ filename }}"/> |
|||
<a href='/selif/{{ filename }}'>Download it instead</a> |
|||
</video> |
|||
</div> |
|||
|
|||
{% endblock %} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue