From d5f3bbbcc1635424e893aecb338834c77ca3f1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnar=20Gu=C3=B0var=C3=B0arson?= Date: Mon, 20 Jan 2025 14:09:58 +0000 Subject: [PATCH 1/9] Upgrade go libraries and mod --- go.mod | 9 +++++---- go.sum | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 5f325de..9ea1eb4 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,10 @@ module github.com/advania/pass -go 1.12 +go 1.22 require ( - github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 - github.com/google/go-cmp v0.3.0 // indirect - github.com/lib/pq v1.1.1 + github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f + github.com/lib/pq v1.10.9 ) + +require github.com/google/go-cmp v0.3.0 // indirect diff --git a/go.sum b/go.sum index 0216795..7ad5fe0 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,54 @@ -github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 h1:KRMr9A3qfbVM7iV/WcLY/rL5LICqwMHLhwRXKu99fXw= -github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= +cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.3-0.20170329110642-4da3e2cfbabc/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/garyburd/redigo v1.1.1-0.20170914051019-70e1b1943d4f/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f h1:16RtHeWGkJMc80Etb8RPCcKevXGldr57+LOyZt8zOlg= +github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f/go.mod h1:ijRvpgDJDI262hYq/IQVYgf8hd8IHUs93Ol0kvMBAx4= +github.com/golang/lint v0.0.0-20170918230701-e5d664eb928e/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.1.1-0.20171103154506-982329095285/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4= -github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/gregjones/httpcache v0.0.0-20170920190843-316c5e0ff04e/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/magiconair/properties v1.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mitchellh/mapstructure v0.0.0-20170523030023-d0303fe80992/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/pelletier/go-toml v1.0.1-0.20170904195809-1d6b12b7cb29/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spf13/afero v0.0.0-20170901052352-ee1bd8ee15a1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.1.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/jwalterweatherman v0.0.0-20170901151539-12bd96e66386/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.1-0.20170901120850-7aff26db30c1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/api v0.0.0-20170921000349-586095a6e407/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20170918111702-1e559d0a00ee/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 9a8c0bd084480901a483799ddb46c84ed16862c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnar=20Gu=C3=B0var=C3=B0arson?= Date: Mon, 20 Jan 2025 14:10:42 +0000 Subject: [PATCH 2/9] Add example config json --- pass.json.template | 62 ++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/pass.json.template b/pass.json.template index 29b78b9..19fefa1 100644 --- a/pass.json.template +++ b/pass.json.template @@ -1,32 +1,34 @@ { - "Certificate": { - "File": "your.crt", - "Key": "your.key" - }, - "HSTS": { - "MaxAge": 63072000, - "IncludeSubDomains": false, - "Preload": false - }, - "Hostname": "pass.example.com", - "ListenAddress": "[::1]:4443", - "PDOString": "host=pass.example.com. port=5432 dbname=passwords user=password_frontend", - "Secret": "a good 64+ character site secret", - "PasswordLength": { - "Min": 6, - "Max": 10000 - }, - "TemplatePath": "templates", - "Title": "Advania Pass", - "TrustedProxies": [], - "TrustedProxyIPHeader": "", - "Addons": { - "email": { - "Server": "relay.example.com:smtp", - "Sender": { - "Address": "test@example.com", - "Name": "Example" - } - } - } + "Addons": { + "email": { + "Sender": { + "Address": "todo@example.com", + "Name": "Pass" + }, + "Server": "todo.example.com" + } + }, + "Certificate": { + "File": "cert.crt", + "Key": "cert.key" + }, + "HSTS": { + "MaxAge": 9000001, + "IncludeSubdomains": false, + "Preload": false + }, + "Hostname": "pass.example.com", + "ListenAddress": "[::]:4443", + "PDOString": "postgres://password_frontend@localhost/passwords?sslmode=disable", + "Secret": "example: dd if=/dev/random bs=128 count=1 | base64 -w0 ; echo", + "PasswordLength": { + "Min": 20, + "Max": 1024 + }, + "MinEntryLength": 2048, + "SecretDays": 7, + "Title": "Pass", + "TemplatePath": "templates", + "TrustedProxies": [], + "TrustedProxyIPHeader": "" } From cb1dabeb77b6c49680581003bb21f16f415da9bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnar=20Gu=C3=B0var=C3=B0arson?= Date: Mon, 20 Jan 2025 14:09:24 +0000 Subject: [PATCH 3/9] Explain site secret error more clearly --- pass.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pass.go b/pass.go index 94f73b1..4764353 100644 --- a/pass.go +++ b/pass.go @@ -652,7 +652,7 @@ func loadConfig(configFileName string) (cfg passConfiguration, err error) { } if len(cfg.Secret) < 64 { - return cfg, fmt.Errorf("Site secret shorter than 64 characters, please make it at least 64 characters") + return cfg, fmt.Errorf("%s 'Secret' shorter than 64 characters, please make it at least 64 characters", configFileName) } return cfg, nil From d3681b9ad6155c8c7dfebaa81611d62a7f80a768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnar=20Gu=C3=B0var=C3=B0arson?= Date: Mon, 20 Jan 2025 13:54:52 +0000 Subject: [PATCH 4/9] Add comment to create database before running migrate.sh --- db/migrate.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/db/migrate.sh b/db/migrate.sh index b8c4529..483f643 100755 --- a/db/migrate.sh +++ b/db/migrate.sh @@ -1,9 +1,11 @@ -#!/bin/bash +#!/bin/bash -x +# Create database and roles before running this script, see README for how. +# # Before Use: Set the neccessary database credentials in ~/.pgpass on your # management user, not on the user running this application. # -# database.example.com:5432:*:username:password +# database.example.com:5432:pass:password_owner_role:password # # Export the following environment variables (e.g. in ~/.bash_profile): # From 0ec3c8446a6e93a9054c83216bc2814d3f7df99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnar=20Gu=C3=B0var=C3=B0arson?= Date: Mon, 20 Jan 2025 13:55:41 +0000 Subject: [PATCH 5/9] Add target="_blank" to keepass link Accidentally clicking the link made me navigate to it, clicking back is not possible so i lost a password that way... --- pass.go | 2 +- templates/get/post.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pass.go b/pass.go index 4764353..7299ab5 100644 --- a/pass.go +++ b/pass.go @@ -84,7 +84,7 @@ var contentSecurityPolicyHTML = strings.Join([]string{ "form-action 'self';", "frame-ancestors 'none';", "block-all-mixed-content;", - "sandbox allow-scripts allow-forms allow-same-origin;", + "sandbox allow-scripts allow-forms allow-popups allow-same-origin;", "require-sri-for script style;", "base-uri 'none';", }, " ") diff --git a/templates/get/post.html b/templates/get/post.html index c7a5445..58efdb1 100644 --- a/templates/get/post.html +++ b/templates/get/post.html @@ -10,7 +10,7 @@

Password

I have the password, now what?

- Add it to your password manager! + Add it to your password manager! Or memorize it... because once you leave this page, you will not be able to retrieve the password from here again!

From 330d8fe0163fe9d5163741777b755033ede26723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnar=20Gu=C3=B0var=C3=B0arson?= Date: Wed, 12 Feb 2025 11:36:22 +0000 Subject: [PATCH 6/9] Remove Feature-Policy header This header seems to be stuck in feature hell, and developers refuse to add a default-for-all kind of flag, so you need to define every scope you want to disable. See https://www.permissionspolicy.com/ to see just how lengthy the header becomes. Bug: https://github.com/w3c/webappsec-permissions-policy/issues/189 --- pass.go | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/pass.go b/pass.go index 7299ab5..58fd12b 100644 --- a/pass.go +++ b/pass.go @@ -98,27 +98,6 @@ var contentSecurityPolicyJSON = strings.Join([]string{ "base-uri 'none';", }, " ") -var featurePolicy = strings.Join([]string{ - "accelerometer 'none';", - "ambient-light-sensor 'none';", - "autoplay 'none';", - "camera 'none';", - "encrypted-media 'none';", - "fullscreen 'none';", - "geolocation 'none';", - "gyroscope 'none';", - "magnetometer 'none';", - "microphone 'none';", - "midi 'none';", - "payment 'none';", - "picture-in-picture 'none';", - "speaker 'none';", - "sync-xhr 'none';", - "sync-script 'none';", - "usb 'none';", - "vr 'none';", -}, " ") - // generateSecurityHeaders generates the http securityHeaders to be outputted // as http headers before every request func (p *Pass) generateSecurityHeaders() { @@ -133,7 +112,6 @@ func (p *Pass) generateSecurityHeaders() { } p.sv.securityHeaders["Access-Control-Allow-Origin"] = p.GetURL() - p.sv.securityHeaders["Feature-Policy"] = featurePolicy p.sv.securityHeaders["Referrer-Policy"] = "no-referrer" p.sv.securityHeaders["X-Content-Type-Options"] = "nosniff" p.sv.securityHeaders["X-Frame-Options"] = "deny" From 07593345d65502d7d68cde95981756984d5306ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnar=20Gu=C3=B0var=C3=B0arson?= Date: Wed, 19 Feb 2025 20:19:32 +0000 Subject: [PATCH 7/9] Add ContentSecurityPolicyOverride --- pass.go | 18 ++++++++++++++---- pass.json.template | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/pass.go b/pass.go index 58fd12b..9f1ef90 100644 --- a/pass.go +++ b/pass.go @@ -30,6 +30,7 @@ type passConfiguration struct { File string Key string } + ContentSecurityPolicyOverride string HSTS struct { MaxAge int IncludeSubDomains bool @@ -351,11 +352,16 @@ func (p *Pass) OutputHeaders(rw http.ResponseWriter, r *http.Request) { rw.Header().Set(key, value) } - // More restrictive CSP for json requests - if helpers.HTTPAcceptCheck("application/json", r.Header) { - rw.Header().Set("Content-Security-Policy", contentSecurityPolicyJSON) + if p.sv.cfg.ContentSecurityPolicyOverride == "" { + // More restrictive CSP for json requests + if helpers.HTTPAcceptCheck("application/json", r.Header) { + rw.Header().Set("Content-Security-Policy", contentSecurityPolicyJSON) + } else { + rw.Header().Set("Content-Security-Policy", contentSecurityPolicyHTML) + } } else { - rw.Header().Set("Content-Security-Policy", contentSecurityPolicyHTML) + // Allow config to override the CSP + rw.Header().Set("Content-Security-Policy", p.sv.cfg.ContentSecurityPolicyOverride) } } @@ -762,6 +768,10 @@ func Main(pass *Pass) { fmt.Printf("Main program: %s\n", mainApp) fmt.Printf("Wrapped by: %s\n", wrapper) + if sv.cfg.ContentSecurityPolicyOverride != "" { + fmt.Printf("NOTE: Content-Security-Policy override applied for all requests: %s\n", sv.cfg.ContentSecurityPolicyOverride) + } + // goroutine that runs forever checking the state of the database connection // This can not run in the normal process flow because of a bug in the pq // module, it is not possible to cancel a query with a timeout diff --git a/pass.json.template b/pass.json.template index 19fefa1..45e13ab 100644 --- a/pass.json.template +++ b/pass.json.template @@ -8,6 +8,7 @@ "Server": "todo.example.com" } }, + "ContentSecurityPolicyOverride": "", "Certificate": { "File": "cert.crt", "Key": "cert.key" From 35222de5cb91378ca7dc6ed1f2e2b5abaf5e450a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnar=20Gu=C3=B0var=C3=B0arson?= <358099+Gunni@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:40:59 +0000 Subject: [PATCH 8/9] Change module path --- go.mod | 2 +- pass.go | 2 +- pass/main.go | 4 ++-- senders/sender_email.go | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 9ea1eb4..eb0d00c 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/advania/pass +module github.com/Gunni/pass go 1.22 diff --git a/pass.go b/pass.go index 9f1ef90..8816f3b 100644 --- a/pass.go +++ b/pass.go @@ -19,7 +19,7 @@ import ( "strings" "time" - "github.com/advania/pass/helpers" + "github.com/Gunni/pass/helpers" "github.com/lib/pq" ) diff --git a/pass/main.go b/pass/main.go index 10aaea7..0056ccb 100644 --- a/pass/main.go +++ b/pass/main.go @@ -5,8 +5,8 @@ import ( "net/http" textTemplate "text/template" - "github.com/advania/pass" - "github.com/advania/pass/senders" + "github.com/Gunni/pass" + "github.com/Gunni/pass/senders" ) func main() { diff --git a/senders/sender_email.go b/senders/sender_email.go index 8ebba56..60fe13d 100644 --- a/senders/sender_email.go +++ b/senders/sender_email.go @@ -11,8 +11,8 @@ import ( textTemplate "text/template" "time" - "github.com/advania/pass" - "github.com/advania/pass/helpers" + "github.com/Gunni/pass" + "github.com/Gunni/pass/helpers" ) // EmailConfig contains the config required for SendEmail From 1f5837c36aced5a3a8b293de356abc25d62c3f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnar=20Gu=C3=B0var=C3=B0arson?= Date: Mon, 3 Mar 2025 10:46:44 +0000 Subject: [PATCH 9/9] Fix bug in handling static file paths /logo/asdf is not /logo --- pass.go | 57 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/pass.go b/pass.go index 8816f3b..d586f2f 100644 --- a/pass.go +++ b/pass.go @@ -508,34 +508,37 @@ func onBeforeRequest(rv *requestVariables) { func handler(p *Pass, rv *requestVariables) { if rv.r.Method == http.MethodGet { - switch rv.path[0] { - case "favicon.ico": - p.serveStatic(rv, "static/favicon.ico", "image/x-icon") - return - case "css": - p.serveStatic(rv, "static/css.css", "text/css") - return - case "js": - p.serveStatic(rv, "static/js.js", "application/javascript") - return - case "logo": - p.serveStatic(rv, "static/logo_header.png", "image/png") - return - case "robots.txt": - rv.w.Header().Set("Content-Type", "text/plain") - rv.w.Header().Set("Cache-Control", "max-age=2592000") // 30 days - rv.w.Write([]byte("User-agent: *\nDisallow: /")) - return - case "ping": - rv.w.Header().Set("Cache-Control", "max-age=0") - // Takes ~42 seconds if db is unresponsive, use it to check for it using client side js - // https://github.com/lib/pq/issues/620 - // returns HTTP 500 if server can be instantly detected as being down - if err := rv.sv.db.ping(); err != nil { - log.Printf("db.Ping() returned %v\n", err) - rv.w.WriteHeader(http.StatusInternalServerError) + if len(rv.path) == 1 { + // All the below paths are length 1, prevent handling /logo/asdf as if /logo was used + switch rv.path[0] { + case "favicon.ico": + p.serveStatic(rv, "static/favicon.ico", "image/x-icon") + return + case "css": + p.serveStatic(rv, "static/css.css", "text/css") + return + case "js": + p.serveStatic(rv, "static/js.js", "application/javascript") + return + case "logo": + p.serveStatic(rv, "static/logo_header.png", "image/png") + return + case "robots.txt": + rv.w.Header().Set("Content-Type", "text/plain") + rv.w.Header().Set("Cache-Control", "max-age=2592000") // 30 days + rv.w.Write([]byte("User-agent: *\nDisallow: /")) + return + case "ping": + rv.w.Header().Set("Cache-Control", "max-age=0") + // Takes ~42 seconds if db is unresponsive, use it to check for it using client side js + // https://github.com/lib/pq/issues/620 + // returns HTTP 500 if server can be instantly detected as being down + if err := rv.sv.db.ping(); err != nil { + log.Printf("db.Ping() returned %v\n", err) + rv.w.WriteHeader(http.StatusInternalServerError) + } + return } - return } }