├── testdata
├── i18n
│ ├── messages
│ │ ├── invalid_message_file_name.txt
│ │ ├── english_messages2.en
│ │ ├── dutch_messages.nl
│ │ └── english_messages.en
│ └── config
│ │ └── test_app.conf
├── conf
│ ├── mime-types.conf
│ ├── routes
│ └── app.conf
├── views
│ ├── i18n.html
│ ├── i18n_ctx.html
│ ├── footer.html
│ ├── hotels
│ │ └── show.html
│ └── header.html
└── public
│ └── js
│ └── sessvars.js
├── templates
└── errors
│ ├── 404.xml
│ ├── 403.txt
│ ├── 403.xml
│ ├── 404.txt
│ ├── 405.txt
│ ├── 405.xml
│ ├── 403.json
│ ├── 404.json
│ ├── 405.json
│ ├── 500.json
│ ├── 500.xml
│ ├── 403.html
│ ├── 405.html
│ ├── 500.txt
│ ├── 500.html
│ ├── 404.html
│ ├── 404-dev.html
│ └── 500-dev.html
├── .gitignore
├── docs
├── faq.md
├── code-generation.md
├── getting-started.md
├── testing.md
├── index.md
└── migration.md
├── examples
└── servethis
│ └── main.go
├── mkdocs.yml
├── watchfilter.go
├── sanitize.go
├── sign_fuzz_test.go
├── go.mod
├── cookie.go
├── reflection.go
├── panic.go
├── cmd
└── mars-gen
│ ├── filesorting.go
│ ├── main.go
│ └── main_test.go
├── cert_test.go
├── mime_test.go
├── reflection_test.go
├── session_fuzz_test.go
├── go.sum
├── sanitize_test.go
├── internal
├── pathtree
│ ├── LICENSE
│ └── tree_test.go
└── watcher
│ ├── watcher_test.go
│ └── watcher.go
├── LICENSE
├── .github
└── workflows
│ ├── build-and-test.yml
│ └── codeql-analysis.yml
├── filter.go
├── invoker.go
├── testing
├── equal.go
└── equal_test.go
├── results_test.go
├── sign.go
├── compress_test.go
├── panic_test.go
├── field.go
├── session_test.go
├── cert.go
├── sign_test.go
├── flash.go
├── hooks.go
├── validation_test.go
├── fakeapp_test.go
├── errors.go
├── intercept_test.go
├── server_test.go
├── templates_test.go
├── config.go
├── invoker_test.go
├── filterconfig_test.go
├── params.go
├── static.go
├── README.md
├── csrf.go
├── validators.go
├── server.go
├── http.go
├── params_test.go
├── compress.go
├── session.go
├── intercept.go
├── CHANGELOG.md
├── filterconfig.go
├── validation.go
├── i18n.go
└── validators_test.go
/testdata/i18n/messages/invalid_message_file_name.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/testdata/conf/mime-types.conf:
--------------------------------------------------------------------------------
1 | bkng=application/x-booking
--------------------------------------------------------------------------------
/testdata/views/i18n.html:
--------------------------------------------------------------------------------
1 | {{msg $ `arguments.html` .input}}
--------------------------------------------------------------------------------
/testdata/views/i18n_ctx.html:
--------------------------------------------------------------------------------
1 | {{t `arguments.html` .input}}
--------------------------------------------------------------------------------
/testdata/i18n/messages/english_messages2.en:
--------------------------------------------------------------------------------
1 | greeting2=Yo!
2 |
--------------------------------------------------------------------------------
/testdata/public/js/sessvars.js:
--------------------------------------------------------------------------------
1 | console.log('Test file');
2 |
--------------------------------------------------------------------------------
/templates/errors/404.xml:
--------------------------------------------------------------------------------
1 |
12 | {{.Description}} 13 |
14 | {{end}} 15 | 16 | 17 | -------------------------------------------------------------------------------- /templates/errors/405.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |12 | {{.Description}} 13 |
14 | {{end}} 15 | 16 | 17 | -------------------------------------------------------------------------------- /sanitize.go: -------------------------------------------------------------------------------- 1 | package mars 2 | 3 | import "regexp" 4 | 5 | var lineBreakPattern = regexp.MustCompile(`[\r\n]+`) 6 | 7 | func removeLineBreaks(s string) string { 8 | return lineBreakPattern.ReplaceAllString(s, " ") 9 | } 10 | 11 | func removeAllWhitespace(s string) string { 12 | return whiteSpacePattern.ReplaceAllString(s, "") 13 | } 14 | -------------------------------------------------------------------------------- /templates/errors/500.txt: -------------------------------------------------------------------------------- 1 | {{.Error.Title}} 2 | {{.Error.Description}} 3 | 4 | {{if eq .RunMode "dev"}} 5 | {{with .Error}} 6 | {{if .Path}} 7 | ---------- 8 | In {{.Path}} {{if .Line}}(around line {{.Line}}){{end}} 9 | 10 | {{range .ContextSource}} 11 | {{if .IsError}}>{{else}} {{end}} {{.Line}}: {{.Source}}{{end}} 12 | 13 | {{end}} 14 | {{end}} 15 | {{end}} 16 | -------------------------------------------------------------------------------- /sign_fuzz_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.18 2 | // +build go1.18 3 | 4 | package mars 5 | 6 | import ( 7 | "testing" 8 | ) 9 | 10 | func FuzzSignatureVerification(f *testing.F) { 11 | secretKey = generateRandomSecretKey() 12 | f.Add("4UcW-3rLvaGGxmA2KUPQgS30MVK7ESKKEPhs4Gir_-E") 13 | f.Fuzz(func(t *testing.T, sig string) { 14 | Verify("Untouchable", sig) 15 | }) 16 | } 17 | -------------------------------------------------------------------------------- /templates/errors/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |13 | {{.Error.Description}} 14 |
15 | {{end}} 16 | 17 | 18 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/roblillack/mars 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.24.2 6 | 7 | require ( 8 | github.com/agtorre/gocolorize v1.0.0 9 | github.com/codegangsta/cli v1.20.0 10 | github.com/fsnotify/fsnotify v1.7.0 11 | github.com/robfig/config v0.0.0-20141207224736-0f78529c8c7e 12 | golang.org/x/net v0.38.0 13 | ) 14 | 15 | require golang.org/x/sys v0.31.0 // indirect 16 | -------------------------------------------------------------------------------- /templates/errors/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |19 | {{.Description}} 20 |
21 | {{end}} 22 | 23 | {{end}} 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /cookie.go: -------------------------------------------------------------------------------- 1 | package mars 2 | 3 | import ( 4 | "net/url" 5 | "regexp" 6 | ) 7 | 8 | var ( 9 | cookieKeyValueParser = regexp.MustCompile("\x00([^:]*):([^\x00]*)\x00") 10 | ) 11 | 12 | // parseKeyValueCookie takes the raw (escaped) cookie value and parses out key values. 13 | func parseKeyValueCookie(val string, cb func(key, val string)) { 14 | val, _ = url.QueryUnescape(val) 15 | if matches := cookieKeyValueParser.FindAllStringSubmatch(val, -1); matches != nil { 16 | for _, match := range matches { 17 | cb(match[1], match[2]) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /testdata/views/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 |