├── Procfile ├── vendor └── github.com │ ├── cactus │ ├── mlog │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── CHANGELOG.md │ │ ├── flagset_test.go │ │ ├── formatwriter_plain_test.go │ │ ├── LICENSE.md │ │ ├── formatwriter_structured_test.go │ │ ├── formatwriter_json_test.go │ │ ├── time.go │ │ ├── logmap_test.go │ │ ├── doc.go │ │ ├── time_test.go │ │ ├── flagset.go │ │ ├── formatwriter_json_bench_test.go │ │ ├── formatwriter_plain.go │ │ ├── formatwriter_plain_bench_test.go │ │ ├── formatwriter_structured.go │ │ ├── formatwriter_structured_bench_test.go │ │ ├── logger_bench_test.go │ │ ├── slicebuffer.go │ │ ├── default_logger.go │ │ ├── logmap.go │ │ └── formatwriter_json.go │ └── tai64 │ │ ├── .travis.yml │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── offsets.go │ │ ├── time_test.go │ │ └── time.go │ ├── pelletier │ └── go-toml │ │ ├── .gitignore │ │ ├── fuzz.sh │ │ ├── position_test.go │ │ ├── fuzz.go │ │ ├── .travis.yml │ │ ├── example.toml │ │ ├── example-crlf.toml │ │ ├── marshal_test.toml │ │ ├── position.go │ │ ├── doc.go │ │ ├── benchmark.sh │ │ ├── LICENSE │ │ ├── token_test.go │ │ ├── query │ │ └── tokens.go │ │ ├── keysparsing_test.go │ │ ├── keysparsing.go │ │ ├── benchmark.yml │ │ ├── toml_test.go │ │ ├── doc_test.go │ │ ├── token.go │ │ ├── test.sh │ │ ├── tomltree_create_test.go │ │ ├── benchmark_test.go │ │ ├── README.md │ │ └── benchmark.json │ ├── pmezard │ └── go-difflib │ │ ├── .travis.yml │ │ ├── README.md │ │ └── LICENSE │ ├── jessevdk │ └── go-flags │ │ ├── termsize_linux.go │ │ ├── termsize_unix.go │ │ ├── termsize_other.go │ │ ├── termsize_nosysioctl.go │ │ ├── check_crosscompile.sh │ │ ├── termsize.go │ │ ├── arg.go │ │ ├── options_test.go │ │ ├── tag_test.go │ │ ├── closest.go │ │ ├── unknown_test.go │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── optstyle_other.go │ │ ├── long_test.go │ │ ├── marshal_test.go │ │ ├── multitag.go │ │ ├── convert_test.go │ │ ├── optstyle_windows.go │ │ ├── example_test.go │ │ ├── error.go │ │ ├── pointer_test.go │ │ └── assert_test.go │ ├── stretchr │ └── testify │ │ ├── .travis.gofmt.sh │ │ ├── assert │ │ ├── assertion_format.go.tmpl │ │ ├── assertion_forward.go.tmpl │ │ ├── errors.go │ │ ├── forward_assertions.go │ │ └── doc.go │ │ ├── .travis.govet.sh │ │ ├── package_test.go │ │ ├── .travis.yml │ │ ├── .travis.gogenerate.sh │ │ ├── Gopkg.toml │ │ ├── .gitignore │ │ ├── Gopkg.lock │ │ ├── doc.go │ │ └── LICENSE │ └── davecgh │ └── go-spew │ ├── .gitignore │ ├── .travis.yml │ ├── cov_report.sh │ ├── LICENSE │ └── spew │ ├── dumpnocgo_test.go │ ├── bypasssafe.go │ ├── internal_test.go │ ├── internalunsafe_test.go │ └── dumpcgo_test.go ├── .travis.yml ├── signify.pub ├── .gitignore ├── .circleci └── config.yml ├── .github ├── pull_request_template.md └── issue_template.md ├── examples ├── go-camo.service ├── ruby-hex.rb ├── ruby-base64.rb ├── python-hex.py ├── python-base64.py ├── go-hex.go └── go-base64.go ├── pkg ├── camo │ ├── example_proxymetrics_test.go │ ├── misc.go │ ├── vars.go │ └── encoding │ │ └── url.go ├── stats │ ├── stats_test.go │ └── stats.go └── router │ ├── httpdate.go │ ├── httpdate_test.go │ └── router.go ├── cmd ├── go-camo │ └── main_vers_gen.go └── url-tool │ └── main.go ├── LICENSE.md ├── Gopkg.toml ├── Gopkg.lock ├── man └── url-tool.1.mdoc └── tools └── genversion.go /Procfile: -------------------------------------------------------------------------------- 1 | web: go-camo --listen=0.0.0.0:$PORT -k $HMAC_KEY 2 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | /pkg 3 | /vendor/src 4 | *.py[co] 5 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/.gitignore: -------------------------------------------------------------------------------- 1 | test_program/test_program_bin 2 | fuzz/ 3 | -------------------------------------------------------------------------------- /vendor/github.com/pmezard/go-difflib/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.5 4 | - tip 5 | 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | script: make test 3 | sudo: false 4 | go: 5 | - "1.9.x" 6 | - "1.10.x" 7 | -------------------------------------------------------------------------------- /signify.pub: -------------------------------------------------------------------------------- 1 | untrusted comment: signify public key 2 | RWRq5QOIGZJNa8f1xHPoLi01qEgT85SL6U/DmBcxECpKg+lRvupunbKx 3 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | script: go test -v -cpu=1,2 ./... 4 | go: 5 | - 1.8 6 | - 1.9 7 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/tai64/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | script: go test -v -cpu=1,2 ./... 4 | go: 5 | - 1.8 6 | - 1.9 7 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/termsize_linux.go: -------------------------------------------------------------------------------- 1 | // +build linux 2 | 3 | package flags 4 | 5 | const ( 6 | tIOCGWINSZ = 0x5413 7 | ) 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /config.json 3 | /diagrams 4 | /prox.exe 5 | /server.pem 6 | /server.key 7 | /server.crt 8 | /server.csr 9 | *.py[co] 10 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | ## HEAD 5 | * add panic methods 6 | 7 | ## 1.0.0 2016-05-08 8 | * initial version tag 9 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/termsize_unix.go: -------------------------------------------------------------------------------- 1 | // +build darwin freebsd netbsd openbsd 2 | 3 | package flags 4 | 5 | const ( 6 | tIOCGWINSZ = 0x40087468 7 | ) 8 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/termsize_other.go: -------------------------------------------------------------------------------- 1 | // +build !darwin,!freebsd,!netbsd,!openbsd,!linux 2 | 3 | package flags 4 | 5 | const ( 6 | tIOCGWINSZ = 0 7 | ) 8 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/termsize_nosysioctl.go: -------------------------------------------------------------------------------- 1 | // +build windows plan9 solaris 2 | 3 | package flags 4 | 5 | func getTerminalColumns() int { 6 | return 80 7 | } 8 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/.travis.gofmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -n "$(gofmt -l .)" ]; then 4 | echo "Go code is not formatted:" 5 | gofmt -d . 6 | exit 1 7 | fi 8 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl: -------------------------------------------------------------------------------- 1 | {{.CommentFormat}} 2 | func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool { 3 | return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}}) 4 | } 5 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl: -------------------------------------------------------------------------------- 1 | {{.CommentWithoutT "a"}} 2 | func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool { 3 | return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}}) 4 | } 5 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/.travis.govet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname $0)" 4 | DIRS=". assert require mock _codegen" 5 | set -e 6 | for subdir in $DIRS; do 7 | pushd $subdir 8 | go vet 9 | popd 10 | done 11 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | working_directory: /go/src/github.com/cactus/go-camo 5 | docker: 6 | - image: circleci/golang:1 7 | steps: 8 | - checkout 9 | - run: make test 10 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/package_test.go: -------------------------------------------------------------------------------- 1 | package testify 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestImports(t *testing.T) { 9 | if assert.Equal(t, 1, 1) != true { 10 | t.Error("Something is wrong.") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### Description 2 | 3 | Please explain the changes you made here. 4 | 5 | ### Checklist 6 | 7 | - [ ] Code compiles correctly 8 | - [ ] Created tests (if appropriate) 9 | - [ ] All tests passing 10 | - [ ] Extended the README / documentation (if necessary) 11 | 12 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | sudo: false 4 | 5 | go: 6 | - 1.7 7 | - 1.8 8 | - 1.9 9 | - tip 10 | 11 | script: 12 | - ./.travis.gogenerate.sh 13 | - ./.travis.gofmt.sh 14 | - ./.travis.govet.sh 15 | - go test -v -race $(go list ./... | grep -v vendor) 16 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Specifications 2 | 3 | Please list the go-camo version, as well as the Operation System (and version) 4 | that go-camo is running on. The go-camo version can be found by `go-camo -V`. 5 | 6 | Version: 7 | Platform: 8 | 9 | ### Expected Behavior 10 | 11 | ### Actual Behavior 12 | 13 | ### Steps to reproduce 14 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/.travis.gogenerate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "$TRAVIS_GO_VERSION" =~ ^1\.[45](\..*)?$ ]]; then 4 | exit 0 5 | fi 6 | 7 | go get github.com/ernesto-jimenez/gogen/imports 8 | go generate ./... 9 | if [ -n "$(git diff)" ]; then 10 | echo "Go generate had not been run" 11 | git diff 12 | exit 1 13 | fi 14 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/fuzz.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | set -eu 3 | 4 | go get github.com/dvyukov/go-fuzz/go-fuzz 5 | go get github.com/dvyukov/go-fuzz/go-fuzz-build 6 | 7 | if [ ! -e toml-fuzz.zip ]; then 8 | go-fuzz-build github.com/pelletier/go-toml 9 | fi 10 | 11 | rm -fr fuzz 12 | mkdir -p fuzz/corpus 13 | cp *.toml fuzz/corpus 14 | 15 | go-fuzz -bin=toml-fuzz.zip -workdir=fuzz 16 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/Gopkg.toml: -------------------------------------------------------------------------------- 1 | [prune] 2 | unused-packages = true 3 | non-go = true 4 | go-tests = true 5 | 6 | [[constraint]] 7 | name = "github.com/davecgh/go-spew" 8 | version = "~1.1.0" 9 | 10 | [[constraint]] 11 | name = "github.com/pmezard/go-difflib" 12 | version = "~1.0.0" 13 | 14 | [[constraint]] 15 | name = "github.com/stretchr/objx" 16 | version = "~0.1.0" 17 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/errors.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | // AnError is an error instance useful for testing. If the code does not care 8 | // about error specifics, and only needs to return the error for example, this 9 | // error should be used to make the test code more readable. 10 | var AnError = errors.New("assert.AnError general error for testing") 11 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | 24 | .DS_Store 25 | -------------------------------------------------------------------------------- /examples/go-camo.service: -------------------------------------------------------------------------------- 1 | # go-camo systemd unit file 2 | 3 | [Unit] 4 | Description=Go-Camo 5 | After=network-online.target 6 | Wants=network-online.target 7 | 8 | [Service] 9 | Environment="GOCAMO_HMAC=replace-me!!" 10 | ExecStart=/usr/local/bin/go-camo 11 | Restart=on-failure 12 | RestartSec=10 13 | User=nobody 14 | Group=nobody 15 | WorkingDirectory=/var/empty/ 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/check_crosscompile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo '# linux arm7' 6 | GOARM=7 GOARCH=arm GOOS=linux go build 7 | echo '# linux arm5' 8 | GOARM=5 GOARCH=arm GOOS=linux go build 9 | echo '# windows 386' 10 | GOARCH=386 GOOS=windows go build 11 | echo '# windows amd64' 12 | GOARCH=amd64 GOOS=windows go build 13 | echo '# darwin' 14 | GOARCH=amd64 GOOS=darwin go build 15 | echo '# freebsd' 16 | GOARCH=amd64 GOOS=freebsd go build 17 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.5.4 4 | - 1.6.3 5 | - 1.7 6 | install: 7 | - go get -v golang.org/x/tools/cmd/cover 8 | script: 9 | - go test -v -tags=safe ./spew 10 | - go test -v -tags=testcgo ./spew -covermode=count -coverprofile=profile.cov 11 | after_success: 12 | - go get -v github.com/mattn/goveralls 13 | - export PATH=$PATH:$HOME/gopath/bin 14 | - goveralls -coverprofile=profile.cov -service=travis-ci 15 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/forward_assertions.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | // Assertions provides assertion methods around the 4 | // TestingT interface. 5 | type Assertions struct { 6 | t TestingT 7 | } 8 | 9 | // New makes a new Assertions object for the specified TestingT. 10 | func New(t TestingT) *Assertions { 11 | return &Assertions{ 12 | t: t, 13 | } 14 | } 15 | 16 | //go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs 17 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/termsize.go: -------------------------------------------------------------------------------- 1 | // +build !windows,!plan9,!solaris 2 | 3 | package flags 4 | 5 | import ( 6 | "syscall" 7 | "unsafe" 8 | ) 9 | 10 | type winsize struct { 11 | row, col uint16 12 | xpixel, ypixel uint16 13 | } 14 | 15 | func getTerminalColumns() int { 16 | ws := winsize{} 17 | 18 | if tIOCGWINSZ != 0 { 19 | syscall.Syscall(syscall.SYS_IOCTL, 20 | uintptr(0), 21 | uintptr(tIOCGWINSZ), 22 | uintptr(unsafe.Pointer(&ws))) 23 | 24 | return int(ws.col) 25 | } 26 | 27 | return 80 28 | } 29 | -------------------------------------------------------------------------------- /pkg/camo/example_proxymetrics_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2018 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package camo_test 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | 11 | "github.com/cactus/go-camo/pkg/camo" 12 | "github.com/cactus/go-camo/pkg/stats" 13 | ) 14 | 15 | func ExampleProxyMetrics() { 16 | config := camo.Config{} 17 | proxy, err := camo.New(config) 18 | if err != nil { 19 | fmt.Println("Error: ", err) 20 | os.Exit(1) 21 | } 22 | 23 | ps := &stats.ProxyStats{} 24 | proxy.SetMetricsCollector(ps) 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/position_test.go: -------------------------------------------------------------------------------- 1 | // Testing support for go-toml 2 | 3 | package toml 4 | 5 | import ( 6 | "testing" 7 | ) 8 | 9 | func TestPositionString(t *testing.T) { 10 | p := Position{123, 456} 11 | expected := "(123, 456)" 12 | value := p.String() 13 | 14 | if value != expected { 15 | t.Errorf("Expected %v, got %v instead", expected, value) 16 | } 17 | } 18 | 19 | func TestInvalid(t *testing.T) { 20 | for i, v := range []Position{ 21 | {0, 1234}, 22 | {1234, 0}, 23 | {0, 0}, 24 | } { 25 | if !v.Invalid() { 26 | t.Errorf("Position at %v is valid: %v", i, v) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/ruby-hex.rb: -------------------------------------------------------------------------------- 1 | require "openssl" 2 | 3 | CAMO_HOST = "https://img.example.com" 4 | 5 | def camo_url(hmac_key, image_url) 6 | if image_url.start_with?("https:") 7 | return image_url 8 | end 9 | hexdigest = OpenSSL::HMAC.hexdigest("sha1", hmac_key, image_url) 10 | hexurl = image_url.unpack("U*").collect{|x| x.to_s(16)}.join 11 | return "#{CAMO_HOST}/#{hexdigest}/#{hexurl}" 12 | end 13 | 14 | puts camo_url("test", "http://golang.org/doc/gopher/frontpage.png") 15 | # 'https://img.example.org/0f6def1cb147b0e84f39cbddc5ea10c80253a6f3/687474703a2f2f676f6c616e672e6f72672f646f632f676f706865722f66726f6e74706167652e706e67' 16 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/fuzz.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package toml 4 | 5 | func Fuzz(data []byte) int { 6 | tree, err := LoadBytes(data) 7 | if err != nil { 8 | if tree != nil { 9 | panic("tree must be nil if there is an error") 10 | } 11 | return 0 12 | } 13 | 14 | str, err := tree.ToTomlString() 15 | if err != nil { 16 | if str != "" { 17 | panic(`str must be "" if there is an error`) 18 | } 19 | panic(err) 20 | } 21 | 22 | tree, err = Load(str) 23 | if err != nil { 24 | if tree != nil { 25 | panic("tree must be nil if there is an error") 26 | } 27 | return 0 28 | } 29 | 30 | return 1 31 | } 32 | -------------------------------------------------------------------------------- /examples/ruby-base64.rb: -------------------------------------------------------------------------------- 1 | require "base64" 2 | require "openssl" 3 | 4 | CAMO_HOST = "https://img.example.com" 5 | 6 | def camo_url(hmac_key, image_url) 7 | if image_url.start_with?("https:") 8 | return image_url 9 | end 10 | b64digest = Base64.urlsafe_encode64(OpenSSL::HMAC.digest("sha1", hmac_key, image_url)).delete("=") 11 | b64url = Base64.urlsafe_encode64(image_url).delete("=") 12 | return "#{CAMO_HOST}/#{b64digest}/#{b64url}" 13 | end 14 | 15 | puts camo_url("test", "http://golang.org/doc/gopher/frontpage.png") 16 | # https://img.example.com/D23vHLFHsOhPOcvdxeoQyAJTpvM/aHR0cDovL2dvbGFuZy5vcmcvZG9jL2dvcGhlci9mcm9udHBhZ2UucG5n 17 | -------------------------------------------------------------------------------- /examples/python-hex.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import hmac 3 | 4 | 5 | CAMO_HOST = 'https://img.example.com' 6 | 7 | 8 | def camo_url(hmac_key, image_url): 9 | if image_url.startswith("https:"): 10 | return image_url 11 | hexdigest = hmac.new(hmac_key, image_url, hashlib.sha1).hexdigest() 12 | hexurl = image_url.encode('hex') 13 | requrl = '%s/%s/%s' % (CAMO_HOST, hexdigest, hexurl) 14 | return requrl 15 | 16 | 17 | print camo_url("test", "http://golang.org/doc/gopher/frontpage.png") 18 | # 'https://img.example.org/0f6def1cb147b0e84f39cbddc5ea10c80253a6f3/687474703a2f2f676f6c616e672e6f72672f646f632f676f706865722f66726f6e74706167652e706e67' 19 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/arg.go: -------------------------------------------------------------------------------- 1 | package flags 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | // Arg represents a positional argument on the command line. 8 | type Arg struct { 9 | // The name of the positional argument (used in the help) 10 | Name string 11 | 12 | // A description of the positional argument (used in the help) 13 | Description string 14 | 15 | // The minimal number of required positional arguments 16 | Required int 17 | 18 | // The maximum number of required positional arguments 19 | RequiredMaximum int 20 | 21 | value reflect.Value 22 | tag multiTag 23 | } 24 | 25 | func (a *Arg) isRemaining() bool { 26 | return a.value.Type().Kind() == reflect.Slice 27 | } 28 | -------------------------------------------------------------------------------- /examples/python-base64.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import hmac 3 | import base64 4 | 5 | 6 | CAMO_HOST = 'https://img.example.com' 7 | 8 | 9 | def camo_url(hmac_key, image_url): 10 | if image_url.startswith("https:"): 11 | return image_url 12 | b64digest = base64.urlsafe_b64encode( 13 | hmac.new(hmac_key, image_url, hashlib.sha1).digest()).strip('=') 14 | b64url = base64.urlsafe_b64encode(image_url).strip('=') 15 | requrl = '%s/%s/%s' % (CAMO_HOST, b64digest, b64url) 16 | return requrl 17 | 18 | 19 | print camo_url("test", "http://golang.org/doc/gopher/frontpage.png") 20 | # 'https://img.example.org/D23vHLFHsOhPOcvdxeoQyAJTpvM/aHR0cDovL2dvbGFuZy5vcmcvZG9jL2dvcGhlci9mcm9udHBhZ2UucG5n' 21 | 22 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | go: 4 | - 1.8.5 5 | - 1.9.2 6 | - tip 7 | matrix: 8 | allow_failures: 9 | - go: tip 10 | fast_finish: true 11 | script: 12 | - if [ -n "$(go fmt ./...)" ]; then exit 1; fi 13 | - ./test.sh 14 | - ./benchmark.sh $TRAVIS_BRANCH https://github.com/$TRAVIS_REPO_SLUG.git 15 | before_install: 16 | - go get github.com/axw/gocov/gocov 17 | - go get github.com/mattn/goveralls 18 | - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi 19 | branches: 20 | only: [master] 21 | after_success: 22 | - $HOME/gopath/bin/goveralls -service=travis-ci -coverprofile=coverage.out -repotoken $COVERALLS_TOKEN 23 | -------------------------------------------------------------------------------- /cmd/go-camo/main_vers_gen.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2018 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // THIS FILE IS AUTOGENERATED. DO NOT EDIT! 6 | 7 | package main 8 | 9 | const licenseText = ` 10 | This software is available under the MIT License at: 11 | https://github.com/cactus/go-camo 12 | 13 | Portions of this software utilize third party libraries: 14 | * Runtime dependencies: 15 | ├── github.com/cactus/mlog (MIT license) 16 | └── github.com/jessevdk/go-flags (BSD license) 17 | 18 | * Test/Build only dependencies: 19 | ├── github.com/stretchr/testify (MIT license) 20 | └── github.com/pelletier/go-toml (MIT license) 21 | 22 | ` -------------------------------------------------------------------------------- /examples/go-hex.go: -------------------------------------------------------------------------------- 1 | // +build ignore 2 | 3 | package main 4 | 5 | import ( 6 | "crypto/hmac" 7 | "crypto/sha1" 8 | "encoding/hex" 9 | "fmt" 10 | "strings" 11 | ) 12 | 13 | var CAMO_HOST = "https://img.example.com" 14 | 15 | func GenCamoUrl(hmacKey []byte, srcUrl string) string { 16 | if strings.HasPrefix(srcUrl, "https:") { 17 | return srcUrl 18 | } 19 | oBytes := []byte(srcUrl) 20 | mac := hmac.New(sha1.New, hmacKey) 21 | mac.Write(oBytes) 22 | macSum := hex.EncodeToString(mac.Sum(nil)) 23 | encodedUrl := hex.EncodeToString(oBytes) 24 | hexurl := CAMO_HOST + "/" + macSum + "/" + encodedUrl 25 | return hexurl 26 | } 27 | 28 | func main() { 29 | fmt.Println(GenCamoUrl([]byte("test"), "http://golang.org/doc/gopher/frontpage.png")) 30 | } 31 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/example.toml: -------------------------------------------------------------------------------- 1 | # This is a TOML document. Boom. 2 | 3 | title = "TOML Example" 4 | 5 | [owner] 6 | name = "Tom Preston-Werner" 7 | organization = "GitHub" 8 | bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." 9 | dob = 1979-05-27T07:32:00Z # First class dates? Why not? 10 | 11 | [database] 12 | server = "192.168.1.1" 13 | ports = [ 8001, 8001, 8002 ] 14 | connection_max = 5000 15 | enabled = true 16 | 17 | [servers] 18 | 19 | # You can indent as you please. Tabs or spaces. TOML don't care. 20 | [servers.alpha] 21 | ip = "10.0.0.1" 22 | dc = "eqdc10" 23 | 24 | [servers.beta] 25 | ip = "10.0.0.2" 26 | dc = "eqdc10" 27 | 28 | [clients] 29 | data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it 30 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/cov_report.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This script uses gocov to generate a test coverage report. 4 | # The gocov tool my be obtained with the following command: 5 | # go get github.com/axw/gocov/gocov 6 | # 7 | # It will be installed to $GOPATH/bin, so ensure that location is in your $PATH. 8 | 9 | # Check for gocov. 10 | if ! type gocov >/dev/null 2>&1; then 11 | echo >&2 "This script requires the gocov tool." 12 | echo >&2 "You may obtain it with the following command:" 13 | echo >&2 "go get github.com/axw/gocov/gocov" 14 | exit 1 15 | fi 16 | 17 | # Only run the cgo tests if gcc is installed. 18 | if type gcc >/dev/null 2>&1; then 19 | (cd spew && gocov test -tags testcgo | gocov report) 20 | else 21 | (cd spew && gocov test | gocov report) 22 | fi 23 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/example-crlf.toml: -------------------------------------------------------------------------------- 1 | # This is a TOML document. Boom. 2 | 3 | title = "TOML Example" 4 | 5 | [owner] 6 | name = "Tom Preston-Werner" 7 | organization = "GitHub" 8 | bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." 9 | dob = 1979-05-27T07:32:00Z # First class dates? Why not? 10 | 11 | [database] 12 | server = "192.168.1.1" 13 | ports = [ 8001, 8001, 8002 ] 14 | connection_max = 5000 15 | enabled = true 16 | 17 | [servers] 18 | 19 | # You can indent as you please. Tabs or spaces. TOML don't care. 20 | [servers.alpha] 21 | ip = "10.0.0.1" 22 | dc = "eqdc10" 23 | 24 | [servers.beta] 25 | ip = "10.0.0.2" 26 | dc = "eqdc10" 27 | 28 | [clients] 29 | data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it 30 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/flagset_test.go: -------------------------------------------------------------------------------- 1 | package mlog 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "testing" 7 | ) 8 | 9 | func TestFlagSet(t *testing.T) { 10 | logger := New(ioutil.Discard, 0) 11 | 12 | expected := Ltimestamp | Ldebug 13 | logger.SetFlags(expected) 14 | flags := logger.Flags() 15 | fmt.Println(flags) 16 | if flags&(expected) == 0 { 17 | t.Errorf("flags did not match\n%12s %#v\n%12s %#v", 18 | "expected:", expected.GoString(), 19 | "actual:", flags.GoString()) 20 | } 21 | 22 | expected = Ltimestamp | Llongfile 23 | logger.SetFlags(expected) 24 | flags = logger.Flags() 25 | if flags&(expected) == 0 { 26 | t.Errorf("flags did not match\n%12s %#v\n%12s %#v", 27 | "expected:", expected.GoString(), 28 | "actual:", flags.GoString()) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/marshal_test.toml: -------------------------------------------------------------------------------- 1 | title = "TOML Marshal Testing" 2 | 3 | [basic] 4 | bool = true 5 | date = 1979-05-27T07:32:00Z 6 | float = 123.4 7 | int = 5000 8 | string = "Bite me" 9 | uint = 5001 10 | 11 | [basic_lists] 12 | bools = [true,false,true] 13 | dates = [1979-05-27T07:32:00Z,1980-05-27T07:32:00Z] 14 | floats = [12.3,45.6,78.9] 15 | ints = [8001,8001,8002] 16 | strings = ["One","Two","Three"] 17 | uints = [5002,5003] 18 | 19 | [basic_map] 20 | one = "one" 21 | two = "two" 22 | 23 | [subdoc] 24 | 25 | [subdoc.first] 26 | name = "First" 27 | 28 | [subdoc.second] 29 | name = "Second" 30 | 31 | [[subdoclist]] 32 | name = "List.First" 33 | 34 | [[subdoclist]] 35 | name = "List.Second" 36 | 37 | [[subdocptrs]] 38 | name = "Second" 39 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2012-2016 Dave Collins 4 | 5 | Permission to use, copy, modify, and distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /pkg/stats/stats_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2018 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package stats 6 | 7 | import ( 8 | "runtime" 9 | "sync" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | func TestConcurrentUpdate(t *testing.T) { 16 | t.Parallel() 17 | ps := &ProxyStats{} 18 | var wg sync.WaitGroup 19 | for i := 0; i < 100; i++ { 20 | wg.Add(1) 21 | go func() { 22 | defer wg.Done() 23 | for v := 0; v < 100000; v++ { 24 | ps.AddServed() 25 | ps.AddBytes(1024) 26 | runtime.Gosched() 27 | } 28 | }() 29 | } 30 | 31 | wg.Wait() 32 | c, b := ps.GetStats() 33 | assert.Equal(t, 10000000, int(c), "unexpected client count") 34 | assert.Equal(t, 10240000000, int(b), "unexpected bytes count") 35 | } 36 | -------------------------------------------------------------------------------- /examples/go-base64.go: -------------------------------------------------------------------------------- 1 | // +build ignore 2 | 3 | package main 4 | 5 | import ( 6 | "crypto/hmac" 7 | "crypto/sha1" 8 | "encoding/base64" 9 | "fmt" 10 | "strings" 11 | ) 12 | 13 | var CAMO_HOST = "https://img.example.com" 14 | 15 | func b64encode(data []byte) string { 16 | return strings.TrimRight(base64.URLEncoding.EncodeToString(data), "=") 17 | } 18 | 19 | func GenCamoUrl(hmacKey []byte, srcUrl string) string { 20 | if strings.HasPrefix(srcUrl, "https:") { 21 | return srcUrl 22 | } 23 | oBytes := []byte(srcUrl) 24 | mac := hmac.New(sha1.New, hmacKey) 25 | mac.Write(oBytes) 26 | macSum := b64encode(mac.Sum(nil)) 27 | encodedUrl := b64encode(oBytes) 28 | encurl := CAMO_HOST + "/" + macSum + "/" + encodedUrl 29 | return encurl 30 | } 31 | 32 | func main() { 33 | fmt.Println(GenCamoUrl([]byte("test"), "http://golang.org/doc/gopher/frontpage.png")) 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/Gopkg.lock: -------------------------------------------------------------------------------- 1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. 2 | 3 | 4 | [[projects]] 5 | name = "github.com/davecgh/go-spew" 6 | packages = ["spew"] 7 | revision = "346938d642f2ec3594ed81d874461961cd0faa76" 8 | version = "v1.1.0" 9 | 10 | [[projects]] 11 | name = "github.com/pmezard/go-difflib" 12 | packages = ["difflib"] 13 | revision = "792786c7400a136282c1664665ae0a8db921c6c2" 14 | version = "v1.0.0" 15 | 16 | [[projects]] 17 | name = "github.com/stretchr/objx" 18 | packages = ["."] 19 | revision = "facf9a85c22f48d2f52f2380e4efce1768749a89" 20 | version = "v0.1" 21 | 22 | [solve-meta] 23 | analyzer-name = "dep" 24 | analyzer-version = 1 25 | inputs-digest = "448ddae4702c6aded2555faafd390c537789bb1c483f70b0431e6634f73f2090" 26 | solver-name = "gps-cdcl" 27 | solver-version = 1 28 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/position.go: -------------------------------------------------------------------------------- 1 | // Position support for go-toml 2 | 3 | package toml 4 | 5 | import ( 6 | "fmt" 7 | ) 8 | 9 | // Position of a document element within a TOML document. 10 | // 11 | // Line and Col are both 1-indexed positions for the element's line number and 12 | // column number, respectively. Values of zero or less will cause Invalid(), 13 | // to return true. 14 | type Position struct { 15 | Line int // line within the document 16 | Col int // column within the line 17 | } 18 | 19 | // String representation of the position. 20 | // Displays 1-indexed line and column numbers. 21 | func (p Position) String() string { 22 | return fmt.Sprintf("(%d, %d)", p.Line, p.Col) 23 | } 24 | 25 | // Invalid returns whether or not the position is valid (i.e. with negative or 26 | // null values) 27 | func (p Position) Invalid() bool { 28 | return p.Line <= 0 || p.Col <= 0 29 | } 30 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/doc.go: -------------------------------------------------------------------------------- 1 | // Package toml is a TOML parser and manipulation library. 2 | // 3 | // This version supports the specification as described in 4 | // https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md 5 | // 6 | // Marshaling 7 | // 8 | // Go-toml can marshal and unmarshal TOML documents from and to data 9 | // structures. 10 | // 11 | // TOML document as a tree 12 | // 13 | // Go-toml can operate on a TOML document as a tree. Use one of the Load* 14 | // functions to parse TOML data and obtain a Tree instance, then one of its 15 | // methods to manipulate the tree. 16 | // 17 | // JSONPath-like queries 18 | // 19 | // The package github.com/pelletier/go-toml/query implements a system 20 | // similar to JSONPath to quickly retrieve elements of a TOML document using a 21 | // single expression. See the package documentation for more information. 22 | // 23 | package toml 24 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | reference_ref=${1:-master} 6 | reference_git=${2:-.} 7 | 8 | if ! `hash benchstat 2>/dev/null`; then 9 | echo "Installing benchstat" 10 | go get golang.org/x/perf/cmd/benchstat 11 | go install golang.org/x/perf/cmd/benchstat 12 | fi 13 | 14 | tempdir=`mktemp -d /tmp/go-toml-benchmark-XXXXXX` 15 | ref_tempdir="${tempdir}/ref" 16 | ref_benchmark="${ref_tempdir}/benchmark-`echo -n ${reference_ref}|tr -s '/' '-'`.txt" 17 | local_benchmark="`pwd`/benchmark-local.txt" 18 | 19 | echo "=== ${reference_ref} (${ref_tempdir})" 20 | git clone ${reference_git} ${ref_tempdir} >/dev/null 2>/dev/null 21 | pushd ${ref_tempdir} >/dev/null 22 | git checkout ${reference_ref} >/dev/null 2>/dev/null 23 | go test -bench=. -benchmem | tee ${ref_benchmark} 24 | popd >/dev/null 25 | 26 | echo "" 27 | echo "=== local" 28 | go test -bench=. -benchmem | tee ${local_benchmark} 29 | 30 | echo "" 31 | echo "=== diff" 32 | benchstat -delta-test=none ${ref_benchmark} ${local_benchmark} -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/options_test.go: -------------------------------------------------------------------------------- 1 | package flags 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestPassDoubleDash(t *testing.T) { 8 | var opts = struct { 9 | Value bool `short:"v"` 10 | }{} 11 | 12 | p := NewParser(&opts, PassDoubleDash) 13 | ret, err := p.ParseArgs([]string{"-v", "--", "-v", "-g"}) 14 | 15 | if err != nil { 16 | t.Fatalf("Unexpected error: %v", err) 17 | return 18 | } 19 | 20 | if !opts.Value { 21 | t.Errorf("Expected Value to be true") 22 | } 23 | 24 | assertStringArray(t, ret, []string{"-v", "-g"}) 25 | } 26 | 27 | func TestPassAfterNonOption(t *testing.T) { 28 | var opts = struct { 29 | Value bool `short:"v"` 30 | }{} 31 | 32 | p := NewParser(&opts, PassAfterNonOption) 33 | ret, err := p.ParseArgs([]string{"-v", "arg", "-v", "-g"}) 34 | 35 | if err != nil { 36 | t.Fatalf("Unexpected error: %v", err) 37 | return 38 | } 39 | 40 | if !opts.Value { 41 | t.Errorf("Expected Value to be true") 42 | } 43 | 44 | assertStringArray(t, ret, []string{"arg", "-v", "-g"}) 45 | } 46 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/doc.go: -------------------------------------------------------------------------------- 1 | // Package testify is a set of packages that provide many tools for testifying that your code will behave as you intend. 2 | // 3 | // testify contains the following packages: 4 | // 5 | // The assert package provides a comprehensive set of assertion functions that tie in to the Go testing system. 6 | // 7 | // The http package contains tools to make it easier to test http activity using the Go testing system. 8 | // 9 | // The mock package provides a system by which it is possible to mock your objects and verify calls are happening as expected. 10 | // 11 | // The suite package provides a basic structure for using structs as testing suites, and methods on those structs as tests. It includes setup/teardown functionality in the way of interfaces. 12 | package testify 13 | 14 | // blank imports help docs. 15 | import ( 16 | // assert package 17 | _ "github.com/stretchr/testify/assert" 18 | // http package 19 | _ "github.com/stretchr/testify/http" 20 | // mock package 21 | _ "github.com/stretchr/testify/mock" 22 | ) 23 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/tag_test.go: -------------------------------------------------------------------------------- 1 | package flags 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestTagMissingColon(t *testing.T) { 8 | var opts = struct { 9 | Value bool `short` 10 | }{} 11 | 12 | assertParseFail(t, ErrTag, "expected `:' after key name, but got end of tag (in `short`)", &opts, "") 13 | } 14 | 15 | func TestTagMissingValue(t *testing.T) { 16 | var opts = struct { 17 | Value bool `short:` 18 | }{} 19 | 20 | assertParseFail(t, ErrTag, "expected `\"' to start tag value at end of tag (in `short:`)", &opts, "") 21 | } 22 | 23 | func TestTagMissingQuote(t *testing.T) { 24 | var opts = struct { 25 | Value bool `short:"v` 26 | }{} 27 | 28 | assertParseFail(t, ErrTag, "expected end of tag value `\"' at end of tag (in `short:\"v`)", &opts, "") 29 | } 30 | 31 | func TestTagNewline(t *testing.T) { 32 | var opts = struct { 33 | Value bool `long:"verbose" description:"verbose 34 | something"` 35 | }{} 36 | 37 | assertParseFail(t, ErrTag, "unexpected newline in tag value `description' (in `long:\"verbose\" description:\"verbose\nsomething\"`)", &opts, "") 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2018 Eli Janssen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/formatwriter_plain_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mlog 6 | 7 | import ( 8 | "bytes" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestFormatWriterPlainEncodeString(t *testing.T) { 15 | var stringTests = map[string]struct { 16 | input string 17 | output string 18 | }{ 19 | "generic": {`test`, `test`}, 20 | "quote": {`"this"`, `"this"`}, 21 | "r&n": {"te\r\nst", `te\r\nst`}, 22 | "tab": {"\t what", `\t what`}, 23 | "weird chars": {"\u2028 \u2029", "\u2028 \u2029"}, 24 | "other weird chars": {`"\u003c\u0026\u003e"`, `"\u003c\u0026\u003e"`}, 25 | "invalid utf8": {"\xff\xff\xffhello", `\ufffd\ufffd\ufffdhello`}, 26 | } 27 | 28 | b := &bytes.Buffer{} 29 | for name, tt := range stringTests { 30 | b.Truncate(0) 31 | encodeStringPlain(b, tt.input) 32 | assert.Equal(t, []byte(tt.output), b.Bytes(), "%s: did not match expectation", name) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2016 Eli Janssen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/formatwriter_structured_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mlog 6 | 7 | import ( 8 | "bytes" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestFormatWriterStructuredEncodeString(t *testing.T) { 15 | var stringTests = map[string]struct { 16 | input string 17 | output string 18 | }{ 19 | "generic": {`test`, `test`}, 20 | "quote": {`"this"`, `\"this\"`}, 21 | "r&n": {"te\r\nst", `te\r\nst`}, 22 | "tab": {"\t what", `\t what`}, 23 | "weird chars": {"\u2028 \u2029", "\u2028 \u2029"}, 24 | "other weird chars": {`"\u003c\u0026\u003e"`, `\"\u003c\u0026\u003e\"`}, 25 | "invalid utf8": {"\xff\xff\xffhello", `\ufffd\ufffd\ufffdhello`}, 26 | } 27 | 28 | b := &bytes.Buffer{} 29 | for name, tt := range stringTests { 30 | b.Truncate(0) 31 | encodeStringStructured(b, tt.input) 32 | assert.Equal(t, []byte(tt.output), b.Bytes(), "%s: did not match expectation", name) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/tai64/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2016 Eli Janssen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 - 2017 Thomas Pelletier, Eric Anderton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /pkg/router/httpdate.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2018 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package router 6 | 7 | import ( 8 | "sync" 9 | "sync/atomic" 10 | "time" 11 | 12 | "github.com/cactus/mlog" 13 | ) 14 | 15 | const timeFormat = "Mon, 02 Jan 2006 15:04:05 GMT" 16 | 17 | // HTTPDate holds current date stamp formatting for HTTP date header 18 | type iHTTPDate struct { 19 | dateValue atomic.Value 20 | onceUpdater sync.Once 21 | } 22 | 23 | func (h *iHTTPDate) String() string { 24 | stamp := h.dateValue.Load() 25 | if stamp == nil { 26 | mlog.Print("got a nil datesamp. Trying to recover...") 27 | h.Update() 28 | return time.Now().UTC().Format(timeFormat) 29 | } 30 | return stamp.(string) 31 | } 32 | 33 | func (h *iHTTPDate) Update() { 34 | h.dateValue.Store(time.Now().UTC().Format(timeFormat)) 35 | } 36 | 37 | func newiHTTPDate() *iHTTPDate { 38 | d := &iHTTPDate{} 39 | d.Update() 40 | // spawn a single formattedDate updater 41 | d.onceUpdater.Do(func() { 42 | go func() { 43 | for range time.Tick(1 * time.Second) { 44 | d.Update() 45 | } 46 | }() 47 | }) 48 | return d 49 | } 50 | 51 | var formattedDate = newiHTTPDate() 52 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/formatwriter_json_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mlog 6 | 7 | import ( 8 | "bytes" 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | func testEncodeString(e byteSliceWriter, s string) { 16 | encoder := json.NewEncoder(e) 17 | encoder.Encode(s) 18 | } 19 | 20 | func TestFormatWriterJSONEncodeString(t *testing.T) { 21 | var jsonStringTests = map[string]string{ 22 | "generic": `test`, 23 | "quote": `"this"`, 24 | "r&n": "te\r\nst", 25 | "tab": "\t what", 26 | "weird chars": "\u2028 \u2029", 27 | "other weird chars": `"\u003c\u0026\u003e"`, 28 | "invalid utf8": "\xff\xff\xffhello", 29 | } 30 | 31 | b := &bytes.Buffer{} 32 | for name, s := range jsonStringTests { 33 | e, err := json.Marshal(s) 34 | assert.Nil(t, err, "%s: json marshal failed", name) 35 | 36 | b.Truncate(0) 37 | b.WriteByte('"') 38 | encodeStringJSON(b, s) 39 | b.WriteByte('"') 40 | assert.Equal(t, string(e), b.String(), "%s: did not match expectation", name) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/closest.go: -------------------------------------------------------------------------------- 1 | package flags 2 | 3 | func levenshtein(s string, t string) int { 4 | if len(s) == 0 { 5 | return len(t) 6 | } 7 | 8 | if len(t) == 0 { 9 | return len(s) 10 | } 11 | 12 | dists := make([][]int, len(s)+1) 13 | for i := range dists { 14 | dists[i] = make([]int, len(t)+1) 15 | dists[i][0] = i 16 | } 17 | 18 | for j := range t { 19 | dists[0][j] = j 20 | } 21 | 22 | for i, sc := range s { 23 | for j, tc := range t { 24 | if sc == tc { 25 | dists[i+1][j+1] = dists[i][j] 26 | } else { 27 | dists[i+1][j+1] = dists[i][j] + 1 28 | if dists[i+1][j] < dists[i+1][j+1] { 29 | dists[i+1][j+1] = dists[i+1][j] + 1 30 | } 31 | if dists[i][j+1] < dists[i+1][j+1] { 32 | dists[i+1][j+1] = dists[i][j+1] + 1 33 | } 34 | } 35 | } 36 | } 37 | 38 | return dists[len(s)][len(t)] 39 | } 40 | 41 | func closestChoice(cmd string, choices []string) (string, int) { 42 | if len(choices) == 0 { 43 | return "", 0 44 | } 45 | 46 | mincmd := -1 47 | mindist := -1 48 | 49 | for i, c := range choices { 50 | l := levenshtein(cmd, c) 51 | 52 | if mincmd < 0 || l < mindist { 53 | mindist = l 54 | mincmd = i 55 | } 56 | } 57 | 58 | return choices[mincmd], mindist 59 | } 60 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell 2 | 3 | Please consider promoting this project if you find it useful. 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without restriction, 8 | including without limitation the rights to use, copy, modify, merge, 9 | publish, distribute, sublicense, and/or sell copies of the Software, 10 | and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 21 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 22 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/time.go: -------------------------------------------------------------------------------- 1 | package mlog 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/cactus/tai64" 7 | ) 8 | 9 | func writeTime(sb intSliceWriter, t *time.Time, flags FlagSet) { 10 | year, month, day := t.Date() 11 | sb.AppendIntWidth(year, 4) 12 | sb.WriteByte('-') 13 | sb.AppendIntWidth(int(month), 2) 14 | sb.WriteByte('-') 15 | sb.AppendIntWidth(day, 2) 16 | 17 | sb.WriteByte('T') 18 | 19 | hour, min, sec := t.Clock() 20 | sb.AppendIntWidth(hour, 2) 21 | sb.WriteByte(':') 22 | sb.AppendIntWidth(min, 2) 23 | sb.WriteByte(':') 24 | sb.AppendIntWidth(sec, 2) 25 | 26 | sb.WriteByte('.') 27 | sb.AppendIntWidth(t.Nanosecond(), 9) 28 | 29 | _, offset := t.Zone() 30 | if offset == 0 { 31 | sb.WriteByte('Z') 32 | } else { 33 | if offset < 0 { 34 | sb.WriteByte('-') 35 | offset = -offset 36 | } else { 37 | sb.WriteByte('+') 38 | } 39 | sb.AppendIntWidth(offset/3600, 2) 40 | sb.WriteByte(':') 41 | sb.AppendIntWidth(offset%3600, 2) 42 | } 43 | } 44 | 45 | func writeTimeTAI64N(sb intSliceWriter, t *time.Time, flags FlagSet) { 46 | tu := t.UTC() 47 | tux := tu.Unix() 48 | offset := tai64.GetOffsetUnix(tux) 49 | sb.WriteString("@4") 50 | sb.AppendIntWidthHex(tux+offset, 15) 51 | sb.AppendIntWidthHex(int64(tu.Nanosecond()), 8) 52 | } 53 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/unknown_test.go: -------------------------------------------------------------------------------- 1 | package flags 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestUnknownFlags(t *testing.T) { 8 | var opts = struct { 9 | Verbose []bool `short:"v" long:"verbose" description:"Verbose output"` 10 | }{} 11 | 12 | args := []string{ 13 | "-f", 14 | } 15 | 16 | p := NewParser(&opts, 0) 17 | args, err := p.ParseArgs(args) 18 | 19 | if err == nil { 20 | t.Fatal("Expected error for unknown argument") 21 | } 22 | } 23 | 24 | func TestIgnoreUnknownFlags(t *testing.T) { 25 | var opts = struct { 26 | Verbose []bool `short:"v" long:"verbose" description:"Verbose output"` 27 | }{} 28 | 29 | args := []string{ 30 | "hello", 31 | "world", 32 | "-v", 33 | "--foo=bar", 34 | "--verbose", 35 | "-f", 36 | } 37 | 38 | p := NewParser(&opts, IgnoreUnknown) 39 | args, err := p.ParseArgs(args) 40 | 41 | if err != nil { 42 | t.Fatal(err) 43 | } 44 | 45 | exargs := []string{ 46 | "hello", 47 | "world", 48 | "--foo=bar", 49 | "-f", 50 | } 51 | 52 | issame := (len(args) == len(exargs)) 53 | 54 | if issame { 55 | for i := 0; i < len(args); i++ { 56 | if args[i] != exargs[i] { 57 | issame = false 58 | break 59 | } 60 | } 61 | } 62 | 63 | if !issame { 64 | t.Fatalf("Expected %v but got %v", exargs, args) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /pkg/router/httpdate_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2018 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package router 6 | 7 | import ( 8 | "testing" 9 | "time" 10 | 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestHTTPDateGoroutineUpdate(t *testing.T) { 15 | t.Parallel() 16 | d := newiHTTPDate() 17 | n := d.String() 18 | time.Sleep(2 * time.Second) 19 | l := d.String() 20 | assert.NotEqual(t, n, l, "Date did not update as expected: %s == %s", n, l) 21 | } 22 | 23 | func TestHTTPDateManualUpdate(t *testing.T) { 24 | t.Parallel() 25 | d := &iHTTPDate{} 26 | d.Update() 27 | n := d.String() 28 | time.Sleep(2 * time.Second) 29 | d.Update() 30 | l := d.String() 31 | assert.NotEqual(t, n, l, "Date did not update as expected: %s == %s", n, l) 32 | } 33 | 34 | func TestHTTPDateManualUpdateUninitialized(t *testing.T) { 35 | t.Parallel() 36 | d := &iHTTPDate{} 37 | 38 | n := d.String() 39 | time.Sleep(2 * time.Second) 40 | d.Update() 41 | l := d.String() 42 | assert.NotEqual(t, n, l, "Date did not update as expected: %s == %s", n, l) 43 | } 44 | 45 | func BenchmarkDataString(b *testing.B) { 46 | d := newiHTTPDate() 47 | b.ResetTimer() 48 | b.RunParallel(func(pb *testing.PB) { 49 | for pb.Next() { 50 | _ = d.String() 51 | } 52 | }) 53 | } 54 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/dumpnocgo_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when either cgo is not supported or "-tags testcgo" is not added to the go 17 | // test command line. This file intentionally does not setup any cgo tests in 18 | // this scenario. 19 | // +build !cgo !testcgo 20 | 21 | package spew_test 22 | 23 | func addCgoDumpTests() { 24 | // Don't add any tests for cgo since this file is only compiled when 25 | // there should not be any cgo tests. 26 | } 27 | -------------------------------------------------------------------------------- /vendor/github.com/pmezard/go-difflib/README.md: -------------------------------------------------------------------------------- 1 | go-difflib 2 | ========== 3 | 4 | [![Build Status](https://travis-ci.org/pmezard/go-difflib.png?branch=master)](https://travis-ci.org/pmezard/go-difflib) 5 | [![GoDoc](https://godoc.org/github.com/pmezard/go-difflib/difflib?status.svg)](https://godoc.org/github.com/pmezard/go-difflib/difflib) 6 | 7 | Go-difflib is a partial port of python 3 difflib package. Its main goal 8 | was to make unified and context diff available in pure Go, mostly for 9 | testing purposes. 10 | 11 | The following class and functions (and related tests) have be ported: 12 | 13 | * `SequenceMatcher` 14 | * `unified_diff()` 15 | * `context_diff()` 16 | 17 | ## Installation 18 | 19 | ```bash 20 | $ go get github.com/pmezard/go-difflib/difflib 21 | ``` 22 | 23 | ### Quick Start 24 | 25 | Diffs are configured with Unified (or ContextDiff) structures, and can 26 | be output to an io.Writer or returned as a string. 27 | 28 | ```Go 29 | diff := UnifiedDiff{ 30 | A: difflib.SplitLines("foo\nbar\n"), 31 | B: difflib.SplitLines("foo\nbaz\n"), 32 | FromFile: "Original", 33 | ToFile: "Current", 34 | Context: 3, 35 | } 36 | text, _ := GetUnifiedDiffString(diff) 37 | fmt.Printf(text) 38 | ``` 39 | 40 | would output: 41 | 42 | ``` 43 | --- Original 44 | +++ Current 45 | @@ -1,3 +1,3 @@ 46 | foo 47 | -bar 48 | +baz 49 | ``` 50 | 51 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.6.x 5 | - 1.7.x 6 | 7 | install: 8 | # go-flags 9 | - go get -d -v ./... 10 | - go build -v ./... 11 | 12 | # linting 13 | - go get github.com/golang/lint 14 | - go install github.com/golang/lint/golint 15 | 16 | # code coverage 17 | - go get golang.org/x/tools/cmd/cover 18 | - go get github.com/onsi/ginkgo/ginkgo 19 | - go get github.com/modocache/gover 20 | - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then go get github.com/mattn/goveralls; fi 21 | 22 | script: 23 | # go-flags 24 | - $(exit $(gofmt -l . | wc -l)) 25 | - go test -v ./... 26 | 27 | # linting 28 | - go tool vet -all=true -v=true . || true 29 | - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/golint ./... 30 | 31 | # code coverage 32 | - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/ginkgo -r -cover 33 | - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/gover 34 | - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/goveralls -coverprofile=gover.coverprofile -service=travis-ci -repotoken $COVERALLS_TOKEN; fi 35 | 36 | env: 37 | # coveralls.io 38 | secure: "RCYbiB4P0RjQRIoUx/vG/AjP3mmYCbzOmr86DCww1Z88yNcy3hYr3Cq8rpPtYU5v0g7wTpu4adaKIcqRE9xknYGbqj3YWZiCoBP1/n4Z+9sHW3Dsd9D/GRGeHUus0laJUGARjWoCTvoEtOgTdGQDoX7mH+pUUY0FBltNYUdOiiU=" 39 | -------------------------------------------------------------------------------- /pkg/stats/stats.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2018 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package stats 6 | 7 | import ( 8 | "fmt" 9 | "net/http" 10 | "sync/atomic" 11 | ) 12 | 13 | // ProxyStats is the counter container 14 | type ProxyStats struct { 15 | clients uint64 16 | bytes uint64 17 | } 18 | 19 | // AddServed increments the number of clients served counter 20 | func (ps *ProxyStats) AddServed() { 21 | atomic.AddUint64(&ps.clients, 1) 22 | } 23 | 24 | // AddBytes increments the number of bytes served counter 25 | func (ps *ProxyStats) AddBytes(bc int64) { 26 | if bc <= 0 { 27 | return 28 | } 29 | atomic.AddUint64(&ps.bytes, uint64(bc)) 30 | } 31 | 32 | // GetStats returns the stats: clients, bytes 33 | func (ps *ProxyStats) GetStats() (uint64, uint64) { 34 | psClients := atomic.LoadUint64(&ps.clients) 35 | psBytes := atomic.LoadUint64(&ps.bytes) 36 | return psClients, psBytes 37 | } 38 | 39 | // Handler returns an http.HandlerFunc that returns running totals and 40 | // stats about the server. 41 | func Handler(ps *ProxyStats) http.HandlerFunc { 42 | return func(w http.ResponseWriter, r *http.Request) { 43 | w.Header().Set("Content-Type", "text/plain; charset=utf-8") 44 | w.WriteHeader(200) 45 | c, b := ps.GetStats() 46 | fmt.Fprintf(w, "ClientsServed, BytesServed\n%d, %d\n", c, b) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Gopkg.toml: -------------------------------------------------------------------------------- 1 | # Gopkg.toml example 2 | # 3 | # Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md 4 | # for detailed Gopkg.toml documentation. 5 | # 6 | # required = ["github.com/user/thing/cmd/thing"] 7 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] 8 | # 9 | # [[constraint]] 10 | # name = "github.com/user/project" 11 | # version = "1.0.0" 12 | # 13 | # [[constraint]] 14 | # name = "github.com/user/project2" 15 | # branch = "dev" 16 | # source = "github.com/myfork/project2" 17 | # 18 | # [[override]] 19 | # name = "github.com/x/y" 20 | # version = "2.4.0" 21 | 22 | 23 | [metadata.heroku] 24 | root-package = "github.com/cactus/go-camo" 25 | install = ["./cmd/..."] 26 | ensure = "false" 27 | 28 | [prune] 29 | go-tests = true 30 | unused-packages = true 31 | 32 | [[constraint]] 33 | name = "github.com/cactus/mlog" 34 | version = "1.0.1" 35 | 36 | [constraint.metadata] 37 | license = "MIT" 38 | 39 | [[constraint]] 40 | name = "github.com/jessevdk/go-flags" 41 | version = "1.3.0" 42 | 43 | [constraint.metadata] 44 | license = "BSD" 45 | 46 | [[constraint]] 47 | name = "github.com/stretchr/testify" 48 | version = "1.2.1" 49 | 50 | [constraint.metadata] 51 | btest-only = true 52 | license = "MIT" 53 | 54 | [[constraint]] 55 | name = "github.com/pelletier/go-toml" 56 | version = "1.1.0" 57 | 58 | [constraint.metadata] 59 | btest-only = true 60 | license = "MIT" 61 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/logmap_test.go: -------------------------------------------------------------------------------- 1 | package mlog 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | type discardSliceWriter struct{} 10 | 11 | func (d *discardSliceWriter) WriteString(s string) (int, error) { return len(s), nil } 12 | func (d *discardSliceWriter) Write(b []byte) (int, error) { return len(b), nil } 13 | func (d *discardSliceWriter) WriteByte(c byte) error { return nil } 14 | func (d *discardSliceWriter) Truncate(i int) {} 15 | 16 | func BenchmarkLogMapUnsortedWriteBuf(b *testing.B) { 17 | buf := &discardSliceWriter{} 18 | m := Map{} 19 | for i := 1; i <= 100; i++ { 20 | m[randString(10, false)] = randString(25, true) 21 | } 22 | b.ResetTimer() 23 | for i := 0; i < b.N; i++ { 24 | m.unsortedWriteBuf(buf) 25 | buf.Truncate(0) 26 | } 27 | } 28 | 29 | func BenchmarkLogMapSortedWriteBuf(b *testing.B) { 30 | buf := &discardSliceWriter{} 31 | m := Map{} 32 | for i := 1; i <= 100; i++ { 33 | m[randString(10, false)] = randString(25, true) 34 | } 35 | b.ResetTimer() 36 | for i := 0; i < b.N; i++ { 37 | m.sortedWriteBuf(buf) 38 | buf.Truncate(0) 39 | } 40 | } 41 | 42 | func TestLogMapWriteTo(t *testing.T) { 43 | m := Map{"test": "this is \"a test\" of \t some \n a"} 44 | buf := &sliceBuffer{make([]byte, 0, 1024)} 45 | m.sortedWriteBuf(buf) 46 | n := `test="this is \"a test\" of \t some \n a"` 47 | l := buf.String() 48 | assert.Equal(t, n, l, "did not match") 49 | 50 | } 51 | -------------------------------------------------------------------------------- /vendor/github.com/pmezard/go-difflib/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Patrick Mezard 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | The names of its contributors may not be used to endorse or promote 14 | products derived from this software without specific prior written 15 | permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 18 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 20 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 23 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /pkg/camo/misc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2018 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package camo 6 | 7 | import ( 8 | "net" 9 | "os" 10 | "syscall" 11 | ) 12 | 13 | func isBrokenPipe(err error) bool { 14 | if opErr, ok := err.(*net.OpError); ok { 15 | // >= go1.6 16 | if syscallErr, ok := opErr.Err.(*os.SyscallError); ok { 17 | switch syscallErr.Err { 18 | case syscall.EPIPE, syscall.ECONNRESET: 19 | return true 20 | default: 21 | return false 22 | } 23 | } 24 | 25 | // older go 26 | switch opErr.Err { 27 | case syscall.EPIPE, syscall.ECONNRESET: 28 | return true 29 | default: 30 | return false 31 | } 32 | } 33 | return false 34 | } 35 | 36 | func mustParseNetmask(s string) *net.IPNet { 37 | _, ipnet, err := net.ParseCIDR(s) 38 | if err != nil { 39 | panic(`misc: mustParseNetmask(` + s + `): ` + err.Error()) 40 | } 41 | return ipnet 42 | } 43 | 44 | func mustParseNetmasks(networks []string) []*net.IPNet { 45 | nets := make([]*net.IPNet, 0) 46 | for _, s := range networks { 47 | ipnet := mustParseNetmask(s) 48 | nets = append(nets, ipnet) 49 | } 50 | return nets 51 | } 52 | 53 | func isRejectedIP(ip net.IP) bool { 54 | if !ip.IsGlobalUnicast() { 55 | return true 56 | } 57 | 58 | checker := rejectIPv4Networks 59 | if len(ip) < net.IPv6len { 60 | checker = rejectIPv6Networks 61 | } 62 | 63 | for _, ipnet := range checker { 64 | if ipnet.Contains(ip) { 65 | return true 66 | } 67 | } 68 | 69 | return false 70 | } 71 | -------------------------------------------------------------------------------- /Gopkg.lock: -------------------------------------------------------------------------------- 1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. 2 | 3 | 4 | [[projects]] 5 | name = "github.com/cactus/mlog" 6 | packages = ["."] 7 | revision = "b0f3ca06304d8079f8111461ffdac48dfb7802f4" 8 | version = "v1.0.1" 9 | 10 | [[projects]] 11 | name = "github.com/cactus/tai64" 12 | packages = ["."] 13 | revision = "9fff3ffed63c4047456ef9d5c5708f260584e9ee" 14 | version = "v1.0.0" 15 | 16 | [[projects]] 17 | name = "github.com/davecgh/go-spew" 18 | packages = ["spew"] 19 | revision = "346938d642f2ec3594ed81d874461961cd0faa76" 20 | version = "v1.1.0" 21 | 22 | [[projects]] 23 | name = "github.com/jessevdk/go-flags" 24 | packages = ["."] 25 | revision = "96dc06278ce32a0e9d957d590bb987c81ee66407" 26 | version = "v1.3.0" 27 | 28 | [[projects]] 29 | name = "github.com/pelletier/go-toml" 30 | packages = [ 31 | ".", 32 | "query" 33 | ] 34 | revision = "acdc4509485b587f5e675510c4f2c63e90ff68a8" 35 | version = "v1.1.0" 36 | 37 | [[projects]] 38 | name = "github.com/pmezard/go-difflib" 39 | packages = ["difflib"] 40 | revision = "792786c7400a136282c1664665ae0a8db921c6c2" 41 | version = "v1.0.0" 42 | 43 | [[projects]] 44 | name = "github.com/stretchr/testify" 45 | packages = ["assert"] 46 | revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" 47 | version = "v1.2.1" 48 | 49 | [solve-meta] 50 | analyzer-name = "dep" 51 | analyzer-version = 1 52 | inputs-digest = "912a8efe8ba9f3ecca88b5ddc2879fe9ffb78c550d22f3192aebb8a94e0f3e84" 53 | solver-name = "gps-cdcl" 54 | solver-version = 1 55 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/doc.go: -------------------------------------------------------------------------------- 1 | // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. 2 | // 3 | // Example Usage 4 | // 5 | // The following is a complete example using assert in a standard test function: 6 | // import ( 7 | // "testing" 8 | // "github.com/stretchr/testify/assert" 9 | // ) 10 | // 11 | // func TestSomething(t *testing.T) { 12 | // 13 | // var a string = "Hello" 14 | // var b string = "Hello" 15 | // 16 | // assert.Equal(t, a, b, "The two words should be the same.") 17 | // 18 | // } 19 | // 20 | // if you assert many times, use the format below: 21 | // 22 | // import ( 23 | // "testing" 24 | // "github.com/stretchr/testify/assert" 25 | // ) 26 | // 27 | // func TestSomething(t *testing.T) { 28 | // assert := assert.New(t) 29 | // 30 | // var a string = "Hello" 31 | // var b string = "Hello" 32 | // 33 | // assert.Equal(a, b, "The two words should be the same.") 34 | // } 35 | // 36 | // Assertions 37 | // 38 | // Assertions allow you to easily write test code, and are global funcs in the `assert` package. 39 | // All assertion functions take, as the first argument, the `*testing.T` object provided by the 40 | // testing framework. This allows the assertion funcs to write the failings and other details to 41 | // the correct place. 42 | // 43 | // Every assertion function also takes an optional string message as the final argument, 44 | // allowing custom error messages to be appended to the message the assertion method outputs. 45 | package assert 46 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Jesse van den Kieboom. All rights reserved. 2 | Redistribution and use in source and binary forms, with or without 3 | modification, are permitted provided that the following conditions are 4 | met: 5 | 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above 9 | copyright notice, this list of conditions and the following disclaimer 10 | in the documentation and/or other materials provided with the 11 | distribution. 12 | * Neither the name of Google Inc. nor the names of its 13 | contributors may be used to endorse or promote products derived from 14 | this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package mlog provides a purposefully basic logging library for Go. 7 | 8 | mlog only has 3 logging levels: debug, info, and fatal. 9 | 10 | Each logging level has 3 logging methods. As an example, the following methods 11 | log at the "info" level: Info, Infof, Infom. There are similar methods for 12 | the fatal and debug levels. 13 | 14 | Example usage: 15 | 16 | import ( 17 | "bytes" 18 | 19 | "github.com/cactus/mlog" 20 | ) 21 | 22 | func main() { 23 | mlog.Infom("this is a log", mlog.Map{ 24 | "interesting": "data", 25 | "something": 42, 26 | }) 27 | 28 | mlog.Debugm("this won't print") 29 | 30 | // set flags for the default logger 31 | // alternatively, you can create your own logger 32 | // and supply flags at creation time 33 | mlog.SetFlags(mlog.Ldebug) 34 | 35 | mlog.Debugm("this will print!") 36 | 37 | mlog.Debugm("can it print?", mlog.Map{ 38 | "how_fancy": []byte{'v', 'e', 'r', 'y', '!'}, 39 | "this_too": bytes.NewBuffer([]byte("if fmt.Print can print it!")), 40 | }) 41 | 42 | // you can use a more classical Printf type log method too. 43 | mlog.Debugf("a printf style debug log: %s", "here!") 44 | mlog.Infof("a printf style info log: %s", "here!") 45 | 46 | mlog.Fatalm("time for a nap", mlog.Map{"cleanup": false}) 47 | } 48 | */ 49 | package mlog 50 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/tai64/README.md: -------------------------------------------------------------------------------- 1 | tai64 2 | ===== 3 | 4 | [![Build Status](https://travis-ci.org/cactus/tai64.svg?branch=master)](https://travis-ci.org/cactus/tai64) 5 | [![GoDoc](https://godoc.org/github.com/cactus/tai64?status.png)](https://godoc.org/github.com/cactus/tai64) 6 | [![Go Report Card](https://goreportcard.com/badge/github.com/cactus/tai64)](https://goreportcard.com/report/github.com/cactus/tai64) 7 | [![License](https://img.shields.io/github/license/cactus/tai64.svg)](https://github.com/cactus/tai64/blob/master/LICENSE.md) 8 | 9 | ## About 10 | 11 | Formats and parses [TAI64 and TAI64N][1] timestamps. 12 | 13 | ## Usage 14 | 15 | ``` go 16 | package main 17 | 18 | import ( 19 | "fmt" 20 | "os" 21 | "time" 22 | 23 | "github.com/cactus/tai64" 24 | ) 25 | 26 | func main() { 27 | t := time.Now() 28 | fmt.Println(t) 29 | 30 | s := tai64.FormatNano(t) 31 | fmt.Println(s) 32 | 33 | p, err := tai64.Parse(s) 34 | if err != nil { 35 | fmt.Println("Failed to decode time") 36 | os.Exit(1) 37 | } 38 | 39 | // tai64 times are in UTC 40 | fmt.Println(p) 41 | 42 | // time.Equal properly compares times with different locations. 43 | if t.Equal(p) { 44 | fmt.Println("equal") 45 | } else { 46 | fmt.Println("not equal") 47 | } 48 | } 49 | ``` 50 | 51 | Output: 52 | 53 | ``` 54 | 2016-05-25 13:44:01.281160355 -0700 PDT 55 | @4000000057460eb510c22aa3 56 | 2016-05-25 20:44:01.281160355 +0000 UTC 57 | equal 58 | ``` 59 | 60 | ## License 61 | 62 | Released under the [MIT license][2]. See `LICENSE.md` file for details. 63 | 64 | 65 | [1]: http://www.tai64.com 66 | [2]: http://www.opensource.org/licenses/mit-license.php 67 | -------------------------------------------------------------------------------- /pkg/router/router.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2018 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package router 6 | 7 | import ( 8 | "io" 9 | "net/http" 10 | "strings" 11 | ) 12 | 13 | // DumbRouter is a basic, special purpose, http router 14 | type DumbRouter struct { 15 | ServerName string 16 | CamoHandler http.Handler 17 | StatsHandler http.HandlerFunc 18 | AddHeaders map[string]string 19 | } 20 | 21 | // SetHeaders sets the headers on the response 22 | func (dr *DumbRouter) SetHeaders(w http.ResponseWriter) { 23 | h := w.Header() 24 | for k, v := range dr.AddHeaders { 25 | h.Set(k, v) 26 | } 27 | h.Set("Date", formattedDate.String()) 28 | h.Set("Server", dr.ServerName) 29 | } 30 | 31 | // RootHandler is a simple http hander for / that returns "Go-Camo" 32 | func (dr *DumbRouter) RootHandler(w http.ResponseWriter, r *http.Request) { 33 | w.Header().Set("Content-Type", "text/plain; charset=utf-8") 34 | // Status 200 is the default. No need to set explicitly here. 35 | io.WriteString(w, dr.ServerName) 36 | } 37 | 38 | // ServeHTTP fulfills the http server interface 39 | func (dr *DumbRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) { 40 | // set some default headers 41 | dr.SetHeaders(w) 42 | 43 | if r.Method != "HEAD" && r.Method != "GET" { 44 | http.Error(w, "Method Not Allowed", 405) 45 | } 46 | 47 | components := strings.Split(r.URL.Path, "/") 48 | if len(components) == 3 { 49 | dr.CamoHandler.ServeHTTP(w, r) 50 | return 51 | } 52 | 53 | if dr.StatsHandler != nil && r.URL.Path == "/status" { 54 | dr.StatsHandler(w, r) 55 | return 56 | } 57 | 58 | if r.URL.Path == "/" { 59 | dr.RootHandler(w, r) 60 | return 61 | } 62 | 63 | http.Error(w, "404 Not Found", 404) 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/tai64/offsets.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // THIS FILE IS AUTOGENERATED. DO NOT EDIT! 6 | 7 | package tai64 8 | 9 | // http://maia.usno.navy.mil/ser7/tai-utc.dat 10 | // http://www.stjarnhimlen.se/comp/time.html 11 | var tia64nDifferences = []struct { 12 | utime int64 13 | offset int64 14 | }{ 15 | {63072000, 10}, // 1972-01-01T00:00:00Z 16 | {78796800, 11}, // 1972-07-01T00:00:00Z 17 | {94694400, 12}, // 1973-01-01T00:00:00Z 18 | {126230400, 13}, // 1974-01-01T00:00:00Z 19 | {157766400, 14}, // 1975-01-01T00:00:00Z 20 | {189302400, 15}, // 1976-01-01T00:00:00Z 21 | {220924800, 16}, // 1977-01-01T00:00:00Z 22 | {252460800, 17}, // 1978-01-01T00:00:00Z 23 | {283996800, 18}, // 1979-01-01T00:00:00Z 24 | {315532800, 19}, // 1980-01-01T00:00:00Z 25 | {362793600, 20}, // 1981-07-01T00:00:00Z 26 | {394329600, 21}, // 1982-07-01T00:00:00Z 27 | {425865600, 22}, // 1983-07-01T00:00:00Z 28 | {489024000, 23}, // 1985-07-01T00:00:00Z 29 | {567993600, 24}, // 1988-01-01T00:00:00Z 30 | {631152000, 25}, // 1990-01-01T00:00:00Z 31 | {662688000, 26}, // 1991-01-01T00:00:00Z 32 | {709948800, 27}, // 1992-07-01T00:00:00Z 33 | {741484800, 28}, // 1993-07-01T00:00:00Z 34 | {773020800, 29}, // 1994-07-01T00:00:00Z 35 | {820454400, 30}, // 1996-01-01T00:00:00Z 36 | {867715200, 31}, // 1997-07-01T00:00:00Z 37 | {915148800, 32}, // 1999-01-01T00:00:00Z 38 | {1136073600, 33}, // 2006-01-01T00:00:00Z 39 | {1230768000, 34}, // 2009-01-01T00:00:00Z 40 | {1341100800, 35}, // 2012-07-01T00:00:00Z 41 | {1435708800, 36}, // 2015-07-01T00:00:00Z 42 | {1483228800, 37}, // 2017-01-01T00:00:00Z 43 | } 44 | 45 | var tia64nSize = len(tia64nDifferences) 46 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/bypasssafe.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when the code is running on Google App Engine, compiled by GopherJS, or 17 | // "-tags safe" is added to the go build command line. The "disableunsafe" 18 | // tag is deprecated and thus should not be used. 19 | // +build js appengine safe disableunsafe 20 | 21 | package spew 22 | 23 | import "reflect" 24 | 25 | const ( 26 | // UnsafeDisabled is a build-time constant which specifies whether or 27 | // not access to the unsafe package is available. 28 | UnsafeDisabled = true 29 | ) 30 | 31 | // unsafeReflectValue typically converts the passed reflect.Value into a one 32 | // that bypasses the typical safety restrictions preventing access to 33 | // unaddressable and unexported data. However, doing this relies on access to 34 | // the unsafe package. This is a stub version which simply returns the passed 35 | // reflect.Value when the unsafe package is not available. 36 | func unsafeReflectValue(v reflect.Value) reflect.Value { 37 | return v 38 | } 39 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/token_test.go: -------------------------------------------------------------------------------- 1 | package toml 2 | 3 | import "testing" 4 | 5 | func TestTokenStringer(t *testing.T) { 6 | var tests = []struct { 7 | tt tokenType 8 | expect string 9 | }{ 10 | {tokenError, "Error"}, 11 | {tokenEOF, "EOF"}, 12 | {tokenComment, "Comment"}, 13 | {tokenKey, "Key"}, 14 | {tokenString, "String"}, 15 | {tokenInteger, "Integer"}, 16 | {tokenTrue, "True"}, 17 | {tokenFalse, "False"}, 18 | {tokenFloat, "Float"}, 19 | {tokenEqual, "="}, 20 | {tokenLeftBracket, "["}, 21 | {tokenRightBracket, "]"}, 22 | {tokenLeftCurlyBrace, "{"}, 23 | {tokenRightCurlyBrace, "}"}, 24 | {tokenLeftParen, "("}, 25 | {tokenRightParen, ")"}, 26 | {tokenDoubleLeftBracket, "]]"}, 27 | {tokenDoubleRightBracket, "[["}, 28 | {tokenDate, "Date"}, 29 | {tokenKeyGroup, "KeyGroup"}, 30 | {tokenKeyGroupArray, "KeyGroupArray"}, 31 | {tokenComma, ","}, 32 | {tokenColon, ":"}, 33 | {tokenDollar, "$"}, 34 | {tokenStar, "*"}, 35 | {tokenQuestion, "?"}, 36 | {tokenDot, "."}, 37 | {tokenDotDot, ".."}, 38 | {tokenEOL, "EOL"}, 39 | {tokenEOL + 1, "Unknown"}, 40 | } 41 | 42 | for i, test := range tests { 43 | got := test.tt.String() 44 | if got != test.expect { 45 | t.Errorf("[%d] invalid string of token type; got %q, expected %q", i, got, test.expect) 46 | } 47 | } 48 | } 49 | 50 | func TestTokenString(t *testing.T) { 51 | var tests = []struct { 52 | tok token 53 | expect string 54 | }{ 55 | {token{Position{1, 1}, tokenEOF, ""}, "EOF"}, 56 | {token{Position{1, 1}, tokenError, "Δt"}, "Δt"}, 57 | {token{Position{1, 1}, tokenString, "bar"}, `"bar"`}, 58 | {token{Position{1, 1}, tokenString, "123456789012345"}, `"123456789012345"`}, 59 | } 60 | 61 | for i, test := range tests { 62 | got := test.tok.String() 63 | if got != test.expect { 64 | t.Errorf("[%d] invalid of string token; got %q, expected %q", i, got, test.expect) 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/optstyle_other.go: -------------------------------------------------------------------------------- 1 | // +build !windows forceposix 2 | 3 | package flags 4 | 5 | import ( 6 | "strings" 7 | ) 8 | 9 | const ( 10 | defaultShortOptDelimiter = '-' 11 | defaultLongOptDelimiter = "--" 12 | defaultNameArgDelimiter = '=' 13 | ) 14 | 15 | func argumentStartsOption(arg string) bool { 16 | return len(arg) > 0 && arg[0] == '-' 17 | } 18 | 19 | func argumentIsOption(arg string) bool { 20 | if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' { 21 | return true 22 | } 23 | 24 | if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' { 25 | return true 26 | } 27 | 28 | return false 29 | } 30 | 31 | // stripOptionPrefix returns the option without the prefix and whether or 32 | // not the option is a long option or not. 33 | func stripOptionPrefix(optname string) (prefix string, name string, islong bool) { 34 | if strings.HasPrefix(optname, "--") { 35 | return "--", optname[2:], true 36 | } else if strings.HasPrefix(optname, "-") { 37 | return "-", optname[1:], false 38 | } 39 | 40 | return "", optname, false 41 | } 42 | 43 | // splitOption attempts to split the passed option into a name and an argument. 44 | // When there is no argument specified, nil will be returned for it. 45 | func splitOption(prefix string, option string, islong bool) (string, string, *string) { 46 | pos := strings.Index(option, "=") 47 | 48 | if (islong && pos >= 0) || (!islong && pos == 1) { 49 | rest := option[pos+1:] 50 | return option[:pos], "=", &rest 51 | } 52 | 53 | return option, "", nil 54 | } 55 | 56 | // addHelpGroup adds a new group that contains default help parameters. 57 | func (c *Command) addHelpGroup(showHelp func() error) *Group { 58 | var help struct { 59 | ShowHelp func() error `short:"h" long:"help" description:"Show this help message"` 60 | } 61 | 62 | help.ShowHelp = showHelp 63 | ret, _ := c.AddGroup("Help Options", "", &help) 64 | ret.isBuiltinHelp = true 65 | 66 | return ret 67 | } 68 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/query/tokens.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "fmt" 5 | "github.com/pelletier/go-toml" 6 | "strconv" 7 | "unicode" 8 | ) 9 | 10 | // Define tokens 11 | type tokenType int 12 | 13 | const ( 14 | eof = -(iota + 1) 15 | ) 16 | 17 | const ( 18 | tokenError tokenType = iota 19 | tokenEOF 20 | tokenKey 21 | tokenString 22 | tokenInteger 23 | tokenFloat 24 | tokenLeftBracket 25 | tokenRightBracket 26 | tokenLeftParen 27 | tokenRightParen 28 | tokenComma 29 | tokenColon 30 | tokenDollar 31 | tokenStar 32 | tokenQuestion 33 | tokenDot 34 | tokenDotDot 35 | ) 36 | 37 | var tokenTypeNames = []string{ 38 | "Error", 39 | "EOF", 40 | "Key", 41 | "String", 42 | "Integer", 43 | "Float", 44 | "[", 45 | "]", 46 | "(", 47 | ")", 48 | ",", 49 | ":", 50 | "$", 51 | "*", 52 | "?", 53 | ".", 54 | "..", 55 | } 56 | 57 | type token struct { 58 | toml.Position 59 | typ tokenType 60 | val string 61 | } 62 | 63 | func (tt tokenType) String() string { 64 | idx := int(tt) 65 | if idx < len(tokenTypeNames) { 66 | return tokenTypeNames[idx] 67 | } 68 | return "Unknown" 69 | } 70 | 71 | func (t token) Int() int { 72 | if result, err := strconv.Atoi(t.val); err != nil { 73 | panic(err) 74 | } else { 75 | return result 76 | } 77 | } 78 | 79 | func (t token) String() string { 80 | switch t.typ { 81 | case tokenEOF: 82 | return "EOF" 83 | case tokenError: 84 | return t.val 85 | } 86 | 87 | return fmt.Sprintf("%q", t.val) 88 | } 89 | 90 | func isSpace(r rune) bool { 91 | return r == ' ' || r == '\t' 92 | } 93 | 94 | func isAlphanumeric(r rune) bool { 95 | return unicode.IsLetter(r) || r == '_' 96 | } 97 | 98 | func isDigit(r rune) bool { 99 | return unicode.IsNumber(r) 100 | } 101 | 102 | func isHexDigit(r rune) bool { 103 | return isDigit(r) || 104 | (r >= 'a' && r <= 'f') || 105 | (r >= 'A' && r <= 'F') 106 | } 107 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/keysparsing_test.go: -------------------------------------------------------------------------------- 1 | package toml 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func testResult(t *testing.T, key string, expected []string) { 9 | parsed, err := parseKey(key) 10 | t.Logf("key=%s expected=%s parsed=%s", key, expected, parsed) 11 | if err != nil { 12 | t.Fatal("Unexpected error:", err) 13 | } 14 | if len(expected) != len(parsed) { 15 | t.Fatal("Expected length", len(expected), "but", len(parsed), "parsed") 16 | } 17 | for index, expectedKey := range expected { 18 | if expectedKey != parsed[index] { 19 | t.Fatal("Expected", expectedKey, "at index", index, "but found", parsed[index]) 20 | } 21 | } 22 | } 23 | 24 | func testError(t *testing.T, key string, expectedError string) { 25 | res, err := parseKey(key) 26 | if err == nil { 27 | t.Fatalf("Expected error, but succesfully parsed key %s", res) 28 | } 29 | if fmt.Sprintf("%s", err) != expectedError { 30 | t.Fatalf("Expected error \"%s\", but got \"%s\".", expectedError, err) 31 | } 32 | } 33 | 34 | func TestBareKeyBasic(t *testing.T) { 35 | testResult(t, "test", []string{"test"}) 36 | } 37 | 38 | func TestBareKeyDotted(t *testing.T) { 39 | testResult(t, "this.is.a.key", []string{"this", "is", "a", "key"}) 40 | } 41 | 42 | func TestDottedKeyBasic(t *testing.T) { 43 | testResult(t, "\"a.dotted.key\"", []string{"a.dotted.key"}) 44 | } 45 | 46 | func TestBaseKeyPound(t *testing.T) { 47 | testError(t, "hello#world", "invalid bare character: #") 48 | } 49 | 50 | func TestQuotedKeys(t *testing.T) { 51 | testResult(t, `hello."foo".bar`, []string{"hello", "foo", "bar"}) 52 | testResult(t, `"hello!"`, []string{"hello!"}) 53 | testResult(t, `foo."ba.r".baz`, []string{"foo", "ba.r", "baz"}) 54 | 55 | // escape sequences must not be converted 56 | testResult(t, `"hello\tworld"`, []string{`hello\tworld`}) 57 | } 58 | 59 | func TestEmptyKey(t *testing.T) { 60 | testError(t, "", "empty key") 61 | testError(t, " ", "empty key") 62 | testResult(t, `""`, []string{""}) 63 | } 64 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/time_test.go: -------------------------------------------------------------------------------- 1 | package mlog 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestTime(t *testing.T) { 11 | loc := time.FixedZone("PDT", -25200) 12 | cases := []struct { 13 | F FlagSet 14 | T time.Time 15 | R string 16 | }{ 17 | { 18 | Ltimestamp, 19 | time.Date(2016, time.November, 1, 2, 3, 4, 5, loc), 20 | `2016-11-01T02:03:04.000000005-07:00`, 21 | }, 22 | { 23 | Ltimestamp, 24 | time.Date(2016, time.January, 11, 12, 13, 14, 15, time.UTC), 25 | `2016-01-11T12:13:14.000000015Z`, 26 | }, 27 | { 28 | Ltimestamp, 29 | time.Date(2016, time.November, 1, 2, 3, 4, 5000, loc), 30 | `2016-11-01T02:03:04.000005000-07:00`, 31 | }, 32 | { 33 | Ltimestamp, 34 | time.Date(2016, time.January, 11, 12, 13, 14, 15000, time.UTC), 35 | `2016-01-11T12:13:14.000015000Z`, 36 | }, 37 | } 38 | 39 | b := &sliceBuffer{make([]byte, 0, 1024)} 40 | for _, tc := range cases { 41 | b.Truncate(0) 42 | writeTime(b, &(tc.T), tc.F) 43 | assert.Equal(t, tc.R, b.String(), "time written incorrectly") 44 | } 45 | } 46 | 47 | func TestTimeTAI64N(t *testing.T) { 48 | loc := time.FixedZone("PDT", -25200) 49 | cases := []struct { 50 | F FlagSet 51 | T time.Time 52 | R string 53 | }{ 54 | { 55 | Ltai64n, 56 | time.Date(1980, time.November, 1, 2, 3, 4, 5, loc), 57 | `@4000000014613edb00000005`, 58 | }, 59 | { 60 | Ltai64n, 61 | time.Date(1980, time.January, 11, 12, 13, 14, 15, time.UTC), 62 | `@4000000012dc80ed0000000f`, 63 | }, 64 | { 65 | Ltai64n, 66 | time.Date(2016, time.November, 1, 2, 3, 4, 5000, loc), 67 | `@4000000058185a6c00001388`, 68 | }, 69 | { 70 | Ltai64n, 71 | time.Date(2016, time.January, 11, 12, 13, 14, 15000, time.UTC), 72 | `@4000000056939c7e00003a98`, 73 | }, 74 | } 75 | 76 | b := &sliceBuffer{make([]byte, 0, 1024)} 77 | for _, tc := range cases { 78 | b.Truncate(0) 79 | writeTimeTAI64N(b, &(tc.T), tc.F) 80 | assert.Equal(t, tc.R, b.String(), "time written incorrectly") 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/keysparsing.go: -------------------------------------------------------------------------------- 1 | // Parsing keys handling both bare and quoted keys. 2 | 3 | package toml 4 | 5 | import ( 6 | "bytes" 7 | "errors" 8 | "fmt" 9 | "unicode" 10 | ) 11 | 12 | // Convert the bare key group string to an array. 13 | // The input supports double quotation to allow "." inside the key name, 14 | // but escape sequences are not supported. Lexers must unescape them beforehand. 15 | func parseKey(key string) ([]string, error) { 16 | groups := []string{} 17 | var buffer bytes.Buffer 18 | inQuotes := false 19 | wasInQuotes := false 20 | ignoreSpace := true 21 | expectDot := false 22 | 23 | for _, char := range key { 24 | if ignoreSpace { 25 | if char == ' ' { 26 | continue 27 | } 28 | ignoreSpace = false 29 | } 30 | switch char { 31 | case '"': 32 | if inQuotes { 33 | groups = append(groups, buffer.String()) 34 | buffer.Reset() 35 | wasInQuotes = true 36 | } 37 | inQuotes = !inQuotes 38 | expectDot = false 39 | case '.': 40 | if inQuotes { 41 | buffer.WriteRune(char) 42 | } else { 43 | if !wasInQuotes { 44 | if buffer.Len() == 0 { 45 | return nil, errors.New("empty table key") 46 | } 47 | groups = append(groups, buffer.String()) 48 | buffer.Reset() 49 | } 50 | ignoreSpace = true 51 | expectDot = false 52 | wasInQuotes = false 53 | } 54 | case ' ': 55 | if inQuotes { 56 | buffer.WriteRune(char) 57 | } else { 58 | expectDot = true 59 | } 60 | default: 61 | if !inQuotes && !isValidBareChar(char) { 62 | return nil, fmt.Errorf("invalid bare character: %c", char) 63 | } 64 | if !inQuotes && expectDot { 65 | return nil, errors.New("what?") 66 | } 67 | buffer.WriteRune(char) 68 | expectDot = false 69 | } 70 | } 71 | if inQuotes { 72 | return nil, errors.New("mismatched quotes") 73 | } 74 | if buffer.Len() > 0 { 75 | groups = append(groups, buffer.String()) 76 | } 77 | if len(groups) == 0 { 78 | return nil, errors.New("empty key") 79 | } 80 | return groups, nil 81 | } 82 | 83 | func isValidBareChar(r rune) bool { 84 | return isAlphanumeric(r) || r == '-' || unicode.IsNumber(r) 85 | } 86 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/long_test.go: -------------------------------------------------------------------------------- 1 | package flags 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestLong(t *testing.T) { 8 | var opts = struct { 9 | Value bool `long:"value"` 10 | }{} 11 | 12 | ret := assertParseSuccess(t, &opts, "--value") 13 | 14 | assertStringArray(t, ret, []string{}) 15 | 16 | if !opts.Value { 17 | t.Errorf("Expected Value to be true") 18 | } 19 | } 20 | 21 | func TestLongArg(t *testing.T) { 22 | var opts = struct { 23 | Value string `long:"value"` 24 | }{} 25 | 26 | ret := assertParseSuccess(t, &opts, "--value", "value") 27 | 28 | assertStringArray(t, ret, []string{}) 29 | assertString(t, opts.Value, "value") 30 | } 31 | 32 | func TestLongArgEqual(t *testing.T) { 33 | var opts = struct { 34 | Value string `long:"value"` 35 | }{} 36 | 37 | ret := assertParseSuccess(t, &opts, "--value=value") 38 | 39 | assertStringArray(t, ret, []string{}) 40 | assertString(t, opts.Value, "value") 41 | } 42 | 43 | func TestLongDefault(t *testing.T) { 44 | var opts = struct { 45 | Value string `long:"value" default:"value"` 46 | }{} 47 | 48 | ret := assertParseSuccess(t, &opts) 49 | 50 | assertStringArray(t, ret, []string{}) 51 | assertString(t, opts.Value, "value") 52 | } 53 | 54 | func TestLongOptional(t *testing.T) { 55 | var opts = struct { 56 | Value string `long:"value" optional:"yes" optional-value:"value"` 57 | }{} 58 | 59 | ret := assertParseSuccess(t, &opts, "--value") 60 | 61 | assertStringArray(t, ret, []string{}) 62 | assertString(t, opts.Value, "value") 63 | } 64 | 65 | func TestLongOptionalArg(t *testing.T) { 66 | var opts = struct { 67 | Value string `long:"value" optional:"yes" optional-value:"value"` 68 | }{} 69 | 70 | ret := assertParseSuccess(t, &opts, "--value", "no") 71 | 72 | assertStringArray(t, ret, []string{"no"}) 73 | assertString(t, opts.Value, "value") 74 | } 75 | 76 | func TestLongOptionalArgEqual(t *testing.T) { 77 | var opts = struct { 78 | Value string `long:"value" optional:"yes" optional-value:"value"` 79 | }{} 80 | 81 | ret := assertParseSuccess(t, &opts, "--value=value", "no") 82 | 83 | assertStringArray(t, ret, []string{"no"}) 84 | assertString(t, opts.Value, "value") 85 | } 86 | -------------------------------------------------------------------------------- /pkg/camo/vars.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2018 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package camo 6 | 7 | import ( 8 | "regexp" 9 | ) 10 | 11 | // ValidReqHeaders are http request headers that are acceptable to pass from 12 | // the client to the remote server. Only those present and true, are forwarded. 13 | // Empty implies no filtering. 14 | var ValidReqHeaders = map[string]bool{ 15 | "Accept": true, 16 | "Accept-Charset": true, 17 | // images (aside from xml/svg), don't generally benefit (generally) from 18 | // compression 19 | "Accept-Encoding": false, 20 | "Accept-Language": true, 21 | "Cache-Control": true, 22 | "If-None-Match": true, 23 | "If-Modified-Since": true, 24 | "X-Forwarded-For": true, 25 | } 26 | 27 | // ValidRespHeaders are http response headers that are acceptable to pass from 28 | // the remote server to the client. Only those present and true, are forwarded. 29 | // Empty implies no filtering. 30 | var ValidRespHeaders = map[string]bool{ 31 | // Do not offer to accept range requests 32 | "Accept-Ranges": false, 33 | "Cache-Control": true, 34 | "Content-Encoding": true, 35 | "Content-Type": true, 36 | "Etag": true, 37 | "Expires": true, 38 | "Last-Modified": true, 39 | // override in response with either nothing, or ServerNameVer 40 | "Server": false, 41 | "Transfer-Encoding": true, 42 | } 43 | 44 | // networks to reject 45 | var rejectIPv4Networks = mustParseNetmasks( 46 | []string{ 47 | // ipv4 loopback 48 | "127.0.0.0/8", 49 | // ipv4 link local 50 | "169.254.0.0/16", 51 | // ipv4 rfc1918 52 | "10.0.0.0/8", 53 | "172.16.0.0/12", 54 | "192.168.0.0/16", 55 | }, 56 | ) 57 | 58 | var rejectIPv6Networks = mustParseNetmasks( 59 | []string{ 60 | // ipv6 loopback 61 | "::1/128", 62 | // ipv6 link local 63 | "fe80::/10", 64 | // old ipv6 site local 65 | "fec0::/10", 66 | // ipv6 ULA 67 | "fc00::/7", 68 | // ipv4 mapped onto ipv6 69 | "::ffff:0:0/96", 70 | }, 71 | ) 72 | 73 | // match for localhost 74 | var localhostRegex = regexp.MustCompile(`^localhost\.?(localdomain)?\.?$`) 75 | -------------------------------------------------------------------------------- /man/url-tool.1.mdoc: -------------------------------------------------------------------------------- 1 | .Dd May 22, 2014 2 | .Dt URL-TOOL \&1 "GO-CAMO MANUAL" 3 | .Os GO-CAMO VERSION 4 | .Sh NAME 5 | .Nm url-tool 6 | .Nd provides a simple way to generate signed URLs from the command line 7 | .Sh SYNOPSIS 8 | .Nm url-tool 9 | .Oo 10 | .Em OPTIONS Ns 11 | .Oc 12 | .Oo 13 | .Em OPTION-ARGUMENTS Ns 14 | .Oc 15 | .Sh DESCRIPTION 16 | .Sy url-tool 17 | provides a simple way to generate signed URLs from the command line 18 | compatible with 19 | .Xr go-camo 1 . 20 | .Sh OPTIONS 21 | .Bl -tag -width Ds 22 | .It Fl k Ns , Fl -key Ns = Ns Aq Ar hmac-key 23 | The HMAC key to use. 24 | .It Fl h Ns , Fl -help 25 | Show help output and exit 26 | .El 27 | .Sh COMMANDS 28 | url-tool has two subcommands. 29 | .Bl -tag -width Ds 30 | .It Cm encode Aq Ar url 31 | .Pp 32 | Available 33 | .Cm encode 34 | options: 35 | .Bl -tag -width Ds 36 | .It Fl b Ns , Fl -base Ns = Ns Aq Ar base 37 | The base encoding to use. Can be one of 38 | .Em hex 39 | or 40 | .Em base64 Ns . 41 | .It Fl -prefix Ns = Ns Aq Ar prefix 42 | Optional url prefix used by encode output. 43 | .El 44 | .It Cm decode Aq Ar url 45 | .El 46 | .Sh EXAMPLES 47 | Encode a url as hex: 48 | .Bd -literal 49 | $ ./url-tool -k "test" encode -p "https://img.example.org" "http://golang.org/doc/gopher/frontpage.png" 50 | https://img.example.org/0f6def1cb147b0e84f39cbddc5ea10c80253a6f3/687474703a2f2f676f6c616e672e6f72672f646f632f676f706865722f66726f6e74706167652e706e67 51 | .Ed 52 | .Pp 53 | Encode a url as base64: 54 | .Bd -literal 55 | $ ./url-tool -k "test" encode -b base64 -p "https://img.example.org" "http://golang.org/doc/gopher/frontpage.png" 56 | https://img.example.org/D23vHLFHsOhPOcvdxeoQyAJTpvM/aHR0cDovL2dvbGFuZy5vcmcvZG9jL2dvcGhlci9mcm9udHBhZ2UucG5n 57 | .Ed 58 | .Pp 59 | Decode a hex url: 60 | .Bd -literal 61 | $ ./url-tool -k "test" decode "https://img.example.org/0f6def1cb147b0e84f39cbddc5ea10c80253a6f3/687474703a2f2f676f6c616e672e6f72672f646f632f676f706865722f66726f6e74706167652e706e67" 62 | http://golang.org/doc/gopher/frontpage.png 63 | .Ed 64 | .Pp 65 | Decode a base64 url: 66 | .Bd -literal 67 | $ ./url-tool -k "test" decode "https://img.example.org/D23vHLFHsOhPOcvdxeoQyAJTpvM/aHR0cDovL2dvbGFuZy5vcmcvZG9jL2dvcGhlci9mcm9udHBhZ2UucG5n" 68 | http://golang.org/doc/gopher/frontpage.png 69 | .Ed 70 | .Sh WWW 71 | https://github.com/cactus/go-camo 72 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/flagset.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mlog 6 | 7 | import ( 8 | "sort" 9 | "strings" 10 | ) 11 | 12 | const ( 13 | // Bits or'ed together to control what's printed. 14 | 15 | // Ltimestamp specifies to log the date+time stamp 16 | Ltimestamp FlagSet = 1 << iota 17 | // Ltai64n specifies to use tia64n timestamps 18 | // overrides Ltimestamp. 19 | Ltai64n 20 | // Llevel specifies to log message level. 21 | Llevel 22 | // Llongfile specifies to log file path and line number: /a/b/c/d.go:23 23 | Llongfile 24 | // Lshortfile specifies to log file name and line number: d.go:23. 25 | // overrides Llongfile. 26 | Lshortfile 27 | // Lsort specifies to sort Map key value pairs in output. 28 | Lsort 29 | // Ldebug specifies to enable debug level logging. 30 | Ldebug 31 | // Lstd is the standard log format if none is specified. 32 | Lstd = Ltimestamp | Llevel | Lsort 33 | ) 34 | 35 | var flagNames = map[FlagSet]string{ 36 | Ltimestamp: "Ltimestamp", 37 | Ltai64n: "Ltai64n", 38 | Llevel: "Llevel", 39 | Llongfile: "Llongfile", 40 | Lshortfile: "Lshortfile", 41 | Lsort: "Lsort", 42 | Ldebug: "Ldebug", 43 | } 44 | 45 | // FlagSet defines the output formatting flags (bitfield) type, which define 46 | // certainly fields to appear in the output. 47 | type FlagSet uint64 48 | 49 | // Has returns true if the FlagSet argument is in the set of flags (binary &) 50 | func (f *FlagSet) Has(p FlagSet) bool { 51 | if *f&p != 0 { 52 | return true 53 | } 54 | return false 55 | } 56 | 57 | // GoString fulfills the GoStringer interface, defining the format used for 58 | // the %#v format string. 59 | func (f FlagSet) GoString() string { 60 | s := make([]byte, 0, len(flagNames)) 61 | var p uint64 62 | for p = 256; p > 0; p >>= 1 { 63 | if f&FlagSet(p) != 0 { 64 | s = append(s, '1') 65 | } else { 66 | s = append(s, '0') 67 | } 68 | } 69 | return string(s) 70 | } 71 | 72 | // String fulfills the Stringer interface, defining the format used for 73 | // the %s format string. 74 | func (f FlagSet) String() string { 75 | flags := make([]string, 0, len(flagNames)) 76 | for k, v := range flagNames { 77 | if f&k != 0 { 78 | flags = append(flags, v) 79 | } 80 | } 81 | sort.Strings(flags) 82 | return "FlagSet(" + strings.Join(flags, "|") + ")" 83 | } 84 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/formatwriter_json_bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mlog 6 | 7 | import ( 8 | "io/ioutil" 9 | "testing" 10 | ) 11 | 12 | func BenchmarkFormatWriterJSONBase(b *testing.B) { 13 | logger := New(ioutil.Discard, 0) 14 | logWriter := &FormatWriterJSON{} 15 | b.ResetTimer() 16 | for i := 0; i < b.N; i++ { 17 | logWriter.Emit(logger, 0, "this is a test", nil) 18 | } 19 | } 20 | 21 | func BenchmarkFormatWriterJSONStd(b *testing.B) { 22 | logger := New(ioutil.Discard, Lstd) 23 | logWriter := &FormatWriterJSON{} 24 | b.ResetTimer() 25 | for i := 0; i < b.N; i++ { 26 | logWriter.Emit(logger, 0, "this is a test", nil) 27 | } 28 | } 29 | 30 | func BenchmarkFormatWriterJSONTime(b *testing.B) { 31 | logger := New(ioutil.Discard, Ltimestamp) 32 | logWriter := &FormatWriterJSON{} 33 | b.ResetTimer() 34 | for i := 0; i < b.N; i++ { 35 | logWriter.Emit(logger, 0, "this is a test", nil) 36 | } 37 | } 38 | 39 | func BenchmarkFormatWriterJSONTimeTAI64N(b *testing.B) { 40 | logger := New(ioutil.Discard, Ltai64n) 41 | logWriter := &FormatWriterJSON{} 42 | b.ResetTimer() 43 | for i := 0; i < b.N; i++ { 44 | logWriter.Emit(logger, 0, "this is a test", nil) 45 | } 46 | } 47 | 48 | func BenchmarkFormatWriterJSONShortfile(b *testing.B) { 49 | logger := New(ioutil.Discard, Lshortfile) 50 | logWriter := &FormatWriterJSON{} 51 | b.ResetTimer() 52 | for i := 0; i < b.N; i++ { 53 | logWriter.Emit(logger, 0, "this is a test", nil) 54 | } 55 | } 56 | 57 | func BenchmarkFormatWriterJSONLongfile(b *testing.B) { 58 | logger := New(ioutil.Discard, Llongfile) 59 | logWriter := &FormatWriterJSON{} 60 | b.ResetTimer() 61 | for i := 0; i < b.N; i++ { 62 | logWriter.Emit(logger, 0, "this is a test", nil) 63 | } 64 | } 65 | 66 | func BenchmarkFormatWriterJSONMap(b *testing.B) { 67 | logger := New(ioutil.Discard, 0) 68 | logWriter := &FormatWriterJSON{} 69 | m := Map{"x": 42} 70 | b.ResetTimer() 71 | for i := 0; i < b.N; i++ { 72 | logWriter.Emit(logger, 0, "this is a test", m) 73 | } 74 | } 75 | 76 | func BenchmarkFormatWriterJSONHugeMap(b *testing.B) { 77 | logger := New(ioutil.Discard, 0) 78 | logWriter := &FormatWriterJSON{} 79 | m := Map{} 80 | for i := 1; i <= 100; i++ { 81 | m[randString(6, false)] = randString(10, false) 82 | } 83 | b.ResetTimer() 84 | for i := 0; i < b.N; i++ { 85 | logWriter.Emit(logger, 0, "this is a test", m) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/benchmark.yml: -------------------------------------------------------------------------------- 1 | --- 2 | array: 3 | key1: 4 | - 1 5 | - 2 6 | - 3 7 | key2: 8 | - red 9 | - yellow 10 | - green 11 | key3: 12 | - - 1 13 | - 2 14 | - - 3 15 | - 4 16 | - 5 17 | key4: 18 | - - 1 19 | - 2 20 | - - a 21 | - b 22 | - c 23 | key5: 24 | - 1 25 | - 2 26 | - 3 27 | key6: 28 | - 1 29 | - 2 30 | boolean: 31 | 'False': false 32 | 'True': true 33 | datetime: 34 | key1: '1979-05-27T07:32:00Z' 35 | key2: '1979-05-27T00:32:00-07:00' 36 | key3: '1979-05-27T00:32:00.999999-07:00' 37 | float: 38 | both: 39 | key: 6.626e-34 40 | exponent: 41 | key1: 5.0e+22 42 | key2: 1000000 43 | key3: -0.02 44 | fractional: 45 | key1: 1 46 | key2: 3.1415 47 | key3: -0.01 48 | underscores: 49 | key1: 9224617.445991227 50 | key2: 1.0e+100 51 | fruit: 52 | - name: apple 53 | physical: 54 | color: red 55 | shape: round 56 | variety: 57 | - name: red delicious 58 | - name: granny smith 59 | - name: banana 60 | variety: 61 | - name: plantain 62 | integer: 63 | key1: 99 64 | key2: 42 65 | key3: 0 66 | key4: -17 67 | underscores: 68 | key1: 1000 69 | key2: 5349221 70 | key3: 12345 71 | products: 72 | - name: Hammer 73 | sku: 738594937 74 | - {} 75 | - color: gray 76 | name: Nail 77 | sku: 284758393 78 | string: 79 | basic: 80 | basic: "I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF." 81 | literal: 82 | multiline: 83 | lines: | 84 | The first newline is 85 | trimmed in raw strings. 86 | All other whitespace 87 | is preserved. 88 | regex2: I [dw]on't need \d{2} apples 89 | quoted: Tom "Dubs" Preston-Werner 90 | regex: "<\\i\\c*\\s*>" 91 | winpath: C:\Users\nodejs\templates 92 | winpath2: "\\\\ServerX\\admin$\\system32\\" 93 | multiline: 94 | continued: 95 | key1: The quick brown fox jumps over the lazy dog. 96 | key2: The quick brown fox jumps over the lazy dog. 97 | key3: The quick brown fox jumps over the lazy dog. 98 | key1: |- 99 | One 100 | Two 101 | key2: |- 102 | One 103 | Two 104 | key3: |- 105 | One 106 | Two 107 | table: 108 | inline: 109 | name: 110 | first: Tom 111 | last: Preston-Werner 112 | point: 113 | x: 1 114 | y: 2 115 | key: value 116 | subtable: 117 | key: another value 118 | x: 119 | y: 120 | z: 121 | w: {} 122 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/toml_test.go: -------------------------------------------------------------------------------- 1 | // Testing support for go-toml 2 | 3 | package toml 4 | 5 | import ( 6 | "testing" 7 | ) 8 | 9 | func TestTomlHas(t *testing.T) { 10 | tree, _ := Load(` 11 | [test] 12 | key = "value" 13 | `) 14 | 15 | if !tree.Has("test.key") { 16 | t.Errorf("Has - expected test.key to exists") 17 | } 18 | 19 | if tree.Has("") { 20 | t.Errorf("Should return false if the key is not provided") 21 | } 22 | } 23 | 24 | func TestTomlGet(t *testing.T) { 25 | tree, _ := Load(` 26 | [test] 27 | key = "value" 28 | `) 29 | 30 | if tree.Get("") != tree { 31 | t.Errorf("Get should return the tree itself when given an empty path") 32 | } 33 | 34 | if tree.Get("test.key") != "value" { 35 | t.Errorf("Get should return the value") 36 | } 37 | if tree.Get(`\`) != nil { 38 | t.Errorf("should return nil when the key is malformed") 39 | } 40 | } 41 | 42 | func TestTomlGetDefault(t *testing.T) { 43 | tree, _ := Load(` 44 | [test] 45 | key = "value" 46 | `) 47 | 48 | if tree.GetDefault("", "hello") != tree { 49 | t.Error("GetDefault should return the tree itself when given an empty path") 50 | } 51 | 52 | if tree.GetDefault("test.key", "hello") != "value" { 53 | t.Error("Get should return the value") 54 | } 55 | 56 | if tree.GetDefault("whatever", "hello") != "hello" { 57 | t.Error("GetDefault should return the default value if the key does not exist") 58 | } 59 | } 60 | 61 | func TestTomlHasPath(t *testing.T) { 62 | tree, _ := Load(` 63 | [test] 64 | key = "value" 65 | `) 66 | 67 | if !tree.HasPath([]string{"test", "key"}) { 68 | t.Errorf("HasPath - expected test.key to exists") 69 | } 70 | } 71 | 72 | func TestTomlGetPath(t *testing.T) { 73 | node := newTree() 74 | //TODO: set other node data 75 | 76 | for idx, item := range []struct { 77 | Path []string 78 | Expected *Tree 79 | }{ 80 | { // empty path test 81 | []string{}, 82 | node, 83 | }, 84 | } { 85 | result := node.GetPath(item.Path) 86 | if result != item.Expected { 87 | t.Errorf("GetPath[%d] %v - expected %v, got %v instead.", idx, item.Path, item.Expected, result) 88 | } 89 | } 90 | 91 | tree, _ := Load("[foo.bar]\na=1\nb=2\n[baz.foo]\na=3\nb=4\n[gorf.foo]\na=5\nb=6") 92 | if tree.GetPath([]string{"whatever"}) != nil { 93 | t.Error("GetPath should return nil when the key does not exist") 94 | } 95 | } 96 | 97 | func TestTomlFromMap(t *testing.T) { 98 | simpleMap := map[string]interface{}{"hello": 42} 99 | tree, err := TreeFromMap(simpleMap) 100 | if err != nil { 101 | t.Fatal("unexpected error:", err) 102 | } 103 | if tree.Get("hello") != int64(42) { 104 | t.Fatal("hello should be 42, not", tree.Get("hello")) 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/formatwriter_plain.go: -------------------------------------------------------------------------------- 1 | package mlog 2 | 3 | import ( 4 | "runtime" 5 | "time" 6 | "unicode/utf8" 7 | ) 8 | 9 | // FormatWriterPlain a plain text structured log line. 10 | // Example: 11 | // 2016-04-29T20:49:12Z INFO this is a log 12 | type FormatWriterPlain struct{} 13 | 14 | // Emit constructs and formats a plain text log line, then writes it to logger 15 | func (l *FormatWriterPlain) Emit(logger *Logger, level int, message string, extra Map) { 16 | sb := bufPool.Get() 17 | defer bufPool.Put(sb) 18 | 19 | flags := logger.Flags() 20 | 21 | // if time is being logged, handle time as soon as possible 22 | if flags&(Ltimestamp|Ltai64n) != 0 { 23 | t := time.Now() 24 | if flags&Ltai64n != 0 { 25 | writeTimeTAI64N(sb, &t, flags) 26 | } else { 27 | writeTime(sb, &t, flags) 28 | } 29 | sb.WriteByte(' ') 30 | } 31 | 32 | if flags&Llevel != 0 { 33 | switch level { 34 | case -1: 35 | sb.WriteString(`DEBUG `) 36 | case 1: 37 | sb.WriteString(`FATAL `) 38 | default: 39 | sb.WriteString(`INFO `) 40 | } 41 | } 42 | 43 | if flags&(Lshortfile|Llongfile) != 0 { 44 | _, file, line, ok := runtime.Caller(3) 45 | if !ok { 46 | file = "???" 47 | line = 0 48 | } 49 | 50 | if flags&Lshortfile != 0 { 51 | short := file 52 | for i := len(file) - 1; i > 0; i-- { 53 | if file[i] == '/' { 54 | short = file[i+1:] 55 | break 56 | } 57 | } 58 | file = short 59 | } 60 | 61 | sb.WriteString(file) 62 | sb.WriteByte(':') 63 | sb.AppendIntWidth(line, 0) 64 | sb.WriteByte(' ') 65 | } 66 | 67 | encodeStringPlain(sb, message) 68 | 69 | if extra != nil && len(extra) > 0 { 70 | sb.WriteByte(' ') 71 | if flags&Lsort != 0 { 72 | extra.sortedWriteBuf(sb) 73 | } else { 74 | extra.unsortedWriteBuf(sb) 75 | } 76 | } 77 | 78 | sb.WriteByte('\n') 79 | sb.WriteTo(logger) 80 | } 81 | 82 | // modified from Go stdlib: encoding/json/encode.go:787-862 (approx) 83 | func encodeStringPlain(e byteSliceWriter, s string) { 84 | for i := 0; i < len(s); { 85 | if b := s[i]; b < utf8.RuneSelf { 86 | i++ 87 | if 0x20 <= b { 88 | e.WriteByte(b) 89 | continue 90 | } 91 | 92 | switch b { 93 | case '\n': 94 | e.WriteByte('\\') 95 | e.WriteByte('n') 96 | case '\r': 97 | e.WriteByte('\\') 98 | e.WriteByte('r') 99 | case '\t': 100 | e.WriteByte('\\') 101 | e.WriteByte('t') 102 | default: 103 | e.WriteByte(b) 104 | } 105 | continue 106 | } 107 | 108 | c, size := utf8.DecodeRuneInString(s[i:]) 109 | if c == utf8.RuneError && size == 1 { 110 | e.WriteString(`\ufffd`) 111 | i++ 112 | continue 113 | } 114 | 115 | e.WriteString(s[i : i+size]) 116 | i += size 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/doc_test.go: -------------------------------------------------------------------------------- 1 | // code examples for godoc 2 | 3 | package toml_test 4 | 5 | import ( 6 | "fmt" 7 | "log" 8 | 9 | toml "github.com/pelletier/go-toml" 10 | ) 11 | 12 | func Example_tree() { 13 | config, err := toml.LoadFile("config.toml") 14 | 15 | if err != nil { 16 | fmt.Println("Error ", err.Error()) 17 | } else { 18 | // retrieve data directly 19 | user := config.Get("postgres.user").(string) 20 | password := config.Get("postgres.password").(string) 21 | 22 | // or using an intermediate object 23 | configTree := config.Get("postgres").(*toml.Tree) 24 | user = configTree.Get("user").(string) 25 | password = configTree.Get("password").(string) 26 | fmt.Println("User is", user, " and password is", password) 27 | 28 | // show where elements are in the file 29 | fmt.Printf("User position: %v\n", configTree.GetPosition("user")) 30 | fmt.Printf("Password position: %v\n", configTree.GetPosition("password")) 31 | } 32 | } 33 | 34 | func Example_unmarshal() { 35 | type Employer struct { 36 | Name string 37 | Phone string 38 | } 39 | type Person struct { 40 | Name string 41 | Age int64 42 | Employer Employer 43 | } 44 | 45 | document := []byte(` 46 | name = "John" 47 | age = 30 48 | [employer] 49 | name = "Company Inc." 50 | phone = "+1 234 567 89012" 51 | `) 52 | 53 | person := Person{} 54 | toml.Unmarshal(document, &person) 55 | fmt.Println(person.Name, "is", person.Age, "and works at", person.Employer.Name) 56 | // Output: 57 | // John is 30 and works at Company Inc. 58 | } 59 | 60 | func ExampleMarshal() { 61 | type Postgres struct { 62 | User string `toml:"user"` 63 | Password string `toml:"password"` 64 | Database string `toml:"db" commented:"true" comment:"not used anymore"` 65 | } 66 | type Config struct { 67 | Postgres Postgres `toml:"postgres" comment:"Postgres configuration"` 68 | } 69 | 70 | config := Config{Postgres{User: "pelletier", Password: "mypassword", Database: "old_database"}} 71 | b, err := toml.Marshal(config) 72 | if err != nil { 73 | log.Fatal(err) 74 | } 75 | fmt.Println(string(b)) 76 | // Output: 77 | // # Postgres configuration 78 | // [postgres] 79 | // 80 | // # not used anymore 81 | // # db = "old_database" 82 | // password = "mypassword" 83 | // user = "pelletier" 84 | } 85 | 86 | func ExampleUnmarshal() { 87 | type Postgres struct { 88 | User string 89 | Password string 90 | } 91 | type Config struct { 92 | Postgres Postgres 93 | } 94 | 95 | doc := []byte(` 96 | [postgres] 97 | user = "pelletier" 98 | password = "mypassword"`) 99 | 100 | config := Config{} 101 | toml.Unmarshal(doc, &config) 102 | fmt.Println("user=", config.Postgres.User) 103 | // Output: 104 | // user= pelletier 105 | } 106 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/token.go: -------------------------------------------------------------------------------- 1 | package toml 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "unicode" 7 | ) 8 | 9 | // Define tokens 10 | type tokenType int 11 | 12 | const ( 13 | eof = -(iota + 1) 14 | ) 15 | 16 | const ( 17 | tokenError tokenType = iota 18 | tokenEOF 19 | tokenComment 20 | tokenKey 21 | tokenString 22 | tokenInteger 23 | tokenTrue 24 | tokenFalse 25 | tokenFloat 26 | tokenInf 27 | tokenNan 28 | tokenEqual 29 | tokenLeftBracket 30 | tokenRightBracket 31 | tokenLeftCurlyBrace 32 | tokenRightCurlyBrace 33 | tokenLeftParen 34 | tokenRightParen 35 | tokenDoubleLeftBracket 36 | tokenDoubleRightBracket 37 | tokenDate 38 | tokenKeyGroup 39 | tokenKeyGroupArray 40 | tokenComma 41 | tokenColon 42 | tokenDollar 43 | tokenStar 44 | tokenQuestion 45 | tokenDot 46 | tokenDotDot 47 | tokenEOL 48 | ) 49 | 50 | var tokenTypeNames = []string{ 51 | "Error", 52 | "EOF", 53 | "Comment", 54 | "Key", 55 | "String", 56 | "Integer", 57 | "True", 58 | "False", 59 | "Float", 60 | "Inf", 61 | "NaN", 62 | "=", 63 | "[", 64 | "]", 65 | "{", 66 | "}", 67 | "(", 68 | ")", 69 | "]]", 70 | "[[", 71 | "Date", 72 | "KeyGroup", 73 | "KeyGroupArray", 74 | ",", 75 | ":", 76 | "$", 77 | "*", 78 | "?", 79 | ".", 80 | "..", 81 | "EOL", 82 | } 83 | 84 | type token struct { 85 | Position 86 | typ tokenType 87 | val string 88 | } 89 | 90 | func (tt tokenType) String() string { 91 | idx := int(tt) 92 | if idx < len(tokenTypeNames) { 93 | return tokenTypeNames[idx] 94 | } 95 | return "Unknown" 96 | } 97 | 98 | func (t token) Int() int { 99 | if result, err := strconv.Atoi(t.val); err != nil { 100 | panic(err) 101 | } else { 102 | return result 103 | } 104 | } 105 | 106 | func (t token) String() string { 107 | switch t.typ { 108 | case tokenEOF: 109 | return "EOF" 110 | case tokenError: 111 | return t.val 112 | } 113 | 114 | return fmt.Sprintf("%q", t.val) 115 | } 116 | 117 | func isSpace(r rune) bool { 118 | return r == ' ' || r == '\t' 119 | } 120 | 121 | func isAlphanumeric(r rune) bool { 122 | return unicode.IsLetter(r) || r == '_' 123 | } 124 | 125 | func isKeyChar(r rune) bool { 126 | // Keys start with the first character that isn't whitespace or [ and end 127 | // with the last non-whitespace character before the equals sign. Keys 128 | // cannot contain a # character." 129 | return !(r == '\r' || r == '\n' || r == eof || r == '=') 130 | } 131 | 132 | func isKeyStartChar(r rune) bool { 133 | return !(isSpace(r) || r == '\r' || r == '\n' || r == eof || r == '[') 134 | } 135 | 136 | func isDigit(r rune) bool { 137 | return unicode.IsNumber(r) 138 | } 139 | 140 | func isHexDigit(r rune) bool { 141 | return isDigit(r) || 142 | (r >= 'a' && r <= 'f') || 143 | (r >= 'A' && r <= 'F') 144 | } 145 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # fail out of the script if anything here fails 3 | set -e 4 | set -o pipefail 5 | 6 | # set the path to the present working directory 7 | export GOPATH=`pwd` 8 | 9 | function git_clone() { 10 | path=$1 11 | branch=$2 12 | version=$3 13 | if [ ! -d "src/$path" ]; then 14 | mkdir -p src/$path 15 | git clone https://$path.git src/$path 16 | fi 17 | pushd src/$path 18 | git checkout "$branch" 19 | git reset --hard "$version" 20 | popd 21 | } 22 | 23 | # Remove potential previous runs 24 | rm -rf src test_program_bin toml-test 25 | 26 | # Run go vet 27 | go vet ./... 28 | 29 | go get github.com/pelletier/go-buffruneio 30 | go get github.com/davecgh/go-spew/spew 31 | go get gopkg.in/yaml.v2 32 | go get github.com/BurntSushi/toml 33 | 34 | # get code for BurntSushi TOML validation 35 | # pinning all to 'HEAD' for version 0.3.x work (TODO: pin to commit hash when tests stabilize) 36 | git_clone github.com/BurntSushi/toml master HEAD 37 | git_clone github.com/BurntSushi/toml-test master HEAD #was: 0.2.0 HEAD 38 | 39 | # build the BurntSushi test application 40 | go build -o toml-test github.com/BurntSushi/toml-test 41 | 42 | # vendorize the current lib for testing 43 | # NOTE: this basically mocks an install without having to go back out to github for code 44 | mkdir -p src/github.com/pelletier/go-toml/cmd 45 | mkdir -p src/github.com/pelletier/go-toml/query 46 | cp *.go *.toml src/github.com/pelletier/go-toml 47 | cp -R cmd/* src/github.com/pelletier/go-toml/cmd 48 | cp -R query/* src/github.com/pelletier/go-toml/query 49 | go build -o test_program_bin src/github.com/pelletier/go-toml/cmd/test_program.go 50 | 51 | # Run basic unit tests 52 | go test github.com/pelletier/go-toml -covermode=count -coverprofile=coverage.out 53 | go test github.com/pelletier/go-toml/cmd/tomljson 54 | go test github.com/pelletier/go-toml/query 55 | 56 | # run the entire BurntSushi test suite 57 | if [[ $# -eq 0 ]] ; then 58 | echo "Running all BurntSushi tests" 59 | ./toml-test ./test_program_bin | tee test_out 60 | else 61 | # run a specific test 62 | test=$1 63 | test_path='src/github.com/BurntSushi/toml-test/tests' 64 | valid_test="$test_path/valid/$test" 65 | invalid_test="$test_path/invalid/$test" 66 | 67 | if [ -e "$valid_test.toml" ]; then 68 | echo "Valid Test TOML for $test:" 69 | echo "====" 70 | cat "$valid_test.toml" 71 | 72 | echo "Valid Test JSON for $test:" 73 | echo "====" 74 | cat "$valid_test.json" 75 | 76 | echo "Go-TOML Output for $test:" 77 | echo "====" 78 | cat "$valid_test.toml" | ./test_program_bin 79 | fi 80 | 81 | if [ -e "$invalid_test.toml" ]; then 82 | echo "Invalid Test TOML for $test:" 83 | echo "====" 84 | cat "$invalid_test.toml" 85 | 86 | echo "Go-TOML Output for $test:" 87 | echo "====" 88 | echo "go-toml Output:" 89 | cat "$invalid_test.toml" | ./test_program_bin 90 | fi 91 | fi 92 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/internal_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2016 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /* 18 | This test file is part of the spew package rather than than the spew_test 19 | package because it needs access to internals to properly test certain cases 20 | which are not possible via the public interface since they should never happen. 21 | */ 22 | 23 | package spew 24 | 25 | import ( 26 | "bytes" 27 | "reflect" 28 | "testing" 29 | ) 30 | 31 | // dummyFmtState implements a fake fmt.State to use for testing invalid 32 | // reflect.Value handling. This is necessary because the fmt package catches 33 | // invalid values before invoking the formatter on them. 34 | type dummyFmtState struct { 35 | bytes.Buffer 36 | } 37 | 38 | func (dfs *dummyFmtState) Flag(f int) bool { 39 | if f == int('+') { 40 | return true 41 | } 42 | return false 43 | } 44 | 45 | func (dfs *dummyFmtState) Precision() (int, bool) { 46 | return 0, false 47 | } 48 | 49 | func (dfs *dummyFmtState) Width() (int, bool) { 50 | return 0, false 51 | } 52 | 53 | // TestInvalidReflectValue ensures the dump and formatter code handles an 54 | // invalid reflect value properly. This needs access to internal state since it 55 | // should never happen in real code and therefore can't be tested via the public 56 | // API. 57 | func TestInvalidReflectValue(t *testing.T) { 58 | i := 1 59 | 60 | // Dump invalid reflect value. 61 | v := new(reflect.Value) 62 | buf := new(bytes.Buffer) 63 | d := dumpState{w: buf, cs: &Config} 64 | d.dump(*v) 65 | s := buf.String() 66 | want := "" 67 | if s != want { 68 | t.Errorf("InvalidReflectValue #%d\n got: %s want: %s", i, s, want) 69 | } 70 | i++ 71 | 72 | // Formatter invalid reflect value. 73 | buf2 := new(dummyFmtState) 74 | f := formatState{value: *v, cs: &Config, fs: buf2} 75 | f.format(*v) 76 | s = buf2.String() 77 | want = "" 78 | if s != want { 79 | t.Errorf("InvalidReflectValue #%d got: %s want: %s", i, s, want) 80 | } 81 | } 82 | 83 | // SortValues makes the internal sortValues function available to the test 84 | // package. 85 | func SortValues(values []reflect.Value, cs *ConfigState) { 86 | sortValues(values, cs) 87 | } 88 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/formatwriter_plain_bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mlog 6 | 7 | import ( 8 | "io/ioutil" 9 | "testing" 10 | ) 11 | 12 | func BenchmarkFormatWriterPlainBase(b *testing.B) { 13 | logger := New(ioutil.Discard, 0) 14 | logWriter := &FormatWriterPlain{} 15 | b.ResetTimer() 16 | for i := 0; i < b.N; i++ { 17 | logWriter.Emit(logger, 0, "this is a test", nil) 18 | } 19 | } 20 | 21 | func BenchmarkFormatWriterPlainStd(b *testing.B) { 22 | logger := New(ioutil.Discard, Lstd) 23 | logWriter := &FormatWriterPlain{} 24 | b.ResetTimer() 25 | for i := 0; i < b.N; i++ { 26 | logWriter.Emit(logger, 0, "this is a test", nil) 27 | } 28 | } 29 | 30 | func BenchmarkFormatWriterPlainTime(b *testing.B) { 31 | logger := New(ioutil.Discard, Ltimestamp) 32 | logWriter := &FormatWriterPlain{} 33 | b.ResetTimer() 34 | for i := 0; i < b.N; i++ { 35 | logWriter.Emit(logger, 0, "this is a test", nil) 36 | } 37 | } 38 | 39 | func BenchmarkFormatWriterPlainTimeTAI64N(b *testing.B) { 40 | logger := New(ioutil.Discard, Ltai64n) 41 | logWriter := &FormatWriterPlain{} 42 | b.ResetTimer() 43 | for i := 0; i < b.N; i++ { 44 | logWriter.Emit(logger, 0, "this is a test", nil) 45 | } 46 | } 47 | 48 | func BenchmarkFormatWriterPlainShortfile(b *testing.B) { 49 | logger := New(ioutil.Discard, Lshortfile) 50 | logWriter := &FormatWriterPlain{} 51 | b.ResetTimer() 52 | for i := 0; i < b.N; i++ { 53 | logWriter.Emit(logger, 0, "this is a test", nil) 54 | } 55 | } 56 | 57 | func BenchmarkFormatWriterPlainLongfile(b *testing.B) { 58 | logger := New(ioutil.Discard, Llongfile) 59 | logWriter := &FormatWriterPlain{} 60 | b.ResetTimer() 61 | for i := 0; i < b.N; i++ { 62 | logWriter.Emit(logger, 0, "this is a test", nil) 63 | } 64 | } 65 | 66 | func BenchmarkFormatWriterPlainMap(b *testing.B) { 67 | logger := New(ioutil.Discard, 0) 68 | logWriter := &FormatWriterPlain{} 69 | m := Map{"x": 42} 70 | b.ResetTimer() 71 | for i := 0; i < b.N; i++ { 72 | logWriter.Emit(logger, 0, "this is a test", m) 73 | } 74 | } 75 | 76 | func BenchmarkFormatWriterPlainHugeMapUnsorted(b *testing.B) { 77 | logger := New(ioutil.Discard, 0) 78 | logWriter := &FormatWriterPlain{} 79 | m := Map{} 80 | for i := 1; i <= 100; i++ { 81 | m[randString(6, false)] = randString(10, false) 82 | } 83 | b.ResetTimer() 84 | for i := 0; i < b.N; i++ { 85 | logWriter.Emit(logger, 0, "this is a test", m) 86 | } 87 | } 88 | 89 | func BenchmarkFormatWriterPlainHugeMapSorted(b *testing.B) { 90 | logger := New(ioutil.Discard, Lsort) 91 | logWriter := &FormatWriterPlain{} 92 | m := Map{} 93 | for i := 1; i <= 100; i++ { 94 | m[randString(6, false)] = randString(10, false) 95 | } 96 | b.ResetTimer() 97 | for i := 0; i < b.N; i++ { 98 | logWriter.Emit(logger, 0, "this is a test", m) 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /cmd/url-tool/main.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2018 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // url-tool 6 | package main 7 | 8 | import ( 9 | "errors" 10 | "fmt" 11 | "net/url" 12 | "os" 13 | "strings" 14 | 15 | "github.com/cactus/go-camo/pkg/camo/encoding" 16 | 17 | flags "github.com/jessevdk/go-flags" 18 | ) 19 | 20 | // EncodeCommand holds command options for the encode command 21 | type EncodeCommand struct { 22 | Base string `short:"b" long:"base" default:"hex" description:"Encode/Decode base. Either hex or base64"` 23 | Prefix string `short:"p" long:"prefix" default:"" description:"Optional url prefix used by encode output"` 24 | } 25 | 26 | // Execute runs the encode command 27 | func (c *EncodeCommand) Execute(args []string) error { 28 | if opts.HmacKey == "" { 29 | return errors.New("Empty HMAC") 30 | } 31 | 32 | if len(args) == 0 { 33 | return errors.New("No url argument provided") 34 | } 35 | 36 | oURL := args[0] 37 | if oURL == "" { 38 | return errors.New("No url argument provided") 39 | } 40 | 41 | hmacKeyBytes := []byte(opts.HmacKey) 42 | var outURL string 43 | switch c.Base { 44 | case "base64": 45 | outURL = encoding.B64EncodeURL(hmacKeyBytes, oURL) 46 | case "hex": 47 | outURL = encoding.HexEncodeURL(hmacKeyBytes, oURL) 48 | default: 49 | return errors.New("Invalid base provided") 50 | } 51 | fmt.Println(c.Prefix + outURL) 52 | return nil 53 | } 54 | 55 | // DecodeCommand holds command options for the decode command 56 | type DecodeCommand struct{} 57 | 58 | // Execute runs the decode command 59 | func (c *DecodeCommand) Execute(args []string) error { 60 | if opts.HmacKey == "" { 61 | return errors.New("Empty HMAC") 62 | } 63 | 64 | if len(args) == 0 { 65 | return errors.New("No url argument provided") 66 | } 67 | 68 | oURL := args[0] 69 | if oURL == "" { 70 | return errors.New("No url argument provided") 71 | } 72 | 73 | hmacKeyBytes := []byte(opts.HmacKey) 74 | 75 | u, err := url.Parse(oURL) 76 | if err != nil { 77 | return err 78 | } 79 | comp := strings.SplitN(u.Path, "/", 3) 80 | decURL, valid := encoding.DecodeURL(hmacKeyBytes, comp[1], comp[2]) 81 | if !valid { 82 | return errors.New("hmac is invalid") 83 | } 84 | fmt.Println(decURL) 85 | return nil 86 | } 87 | 88 | var opts struct { 89 | HmacKey string `short:"k" long:"key" description:"HMAC key"` 90 | } 91 | 92 | func main() { 93 | parser := flags.NewParser(&opts, flags.Default) 94 | parser.AddCommand("encode", "Encode a url and print result", 95 | "Encode a url and print result", &EncodeCommand{}) 96 | parser.AddCommand("decode", "Decode a url and print result", 97 | "Decode a url and print result", &DecodeCommand{}) 98 | 99 | // parse said flags 100 | _, err := parser.Parse() 101 | if err != nil { 102 | if e, ok := err.(*flags.Error); ok { 103 | if e.Type == flags.ErrHelp { 104 | os.Exit(0) 105 | } 106 | } 107 | os.Exit(1) 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/formatwriter_structured.go: -------------------------------------------------------------------------------- 1 | package mlog 2 | 3 | import ( 4 | "runtime" 5 | "time" 6 | "unicode/utf8" 7 | ) 8 | 9 | // FormatWriterStructured writes a plain text structured log line. 10 | // Example: 11 | // time="2016-04-29T20:49:12Z" level="I" msg="this is a log" 12 | type FormatWriterStructured struct{} 13 | 14 | // Emit constructs and formats a plain text log line, then writes it to logger 15 | func (l *FormatWriterStructured) Emit(logger *Logger, level int, message string, extra Map) { 16 | sb := bufPool.Get() 17 | defer bufPool.Put(sb) 18 | 19 | flags := logger.Flags() 20 | 21 | // if time is being logged, handle time as soon as possible 22 | if flags&(Ltimestamp|Ltai64n) != 0 { 23 | t := time.Now() 24 | sb.WriteString(`time="`) 25 | if flags&Ltai64n != 0 { 26 | writeTimeTAI64N(sb, &t, flags) 27 | } else { 28 | writeTime(sb, &t, flags) 29 | } 30 | sb.WriteString(`" `) 31 | } 32 | 33 | if flags&Llevel != 0 { 34 | sb.WriteString(`level="`) 35 | switch level { 36 | case -1: 37 | sb.WriteByte('D') 38 | case 1: 39 | sb.WriteByte('F') 40 | default: 41 | sb.WriteByte('I') 42 | } 43 | sb.WriteString(`" `) 44 | } 45 | 46 | if flags&(Lshortfile|Llongfile) != 0 { 47 | _, file, line, ok := runtime.Caller(3) 48 | if !ok { 49 | file = "???" 50 | line = 0 51 | } 52 | 53 | if flags&Lshortfile != 0 { 54 | short := file 55 | for i := len(file) - 1; i > 0; i-- { 56 | if file[i] == '/' { 57 | short = file[i+1:] 58 | break 59 | } 60 | } 61 | file = short 62 | } 63 | 64 | sb.WriteString(`caller="`) 65 | sb.WriteString(file) 66 | sb.WriteByte(':') 67 | sb.AppendIntWidth(line, 0) 68 | sb.WriteString(`" `) 69 | } 70 | 71 | sb.WriteString(`msg="`) 72 | encodeStringStructured(sb, message) 73 | sb.WriteByte('"') 74 | 75 | if extra != nil && len(extra) > 0 { 76 | sb.WriteByte(' ') 77 | if flags&Lsort != 0 { 78 | extra.sortedWriteBuf(sb) 79 | } else { 80 | extra.unsortedWriteBuf(sb) 81 | } 82 | } 83 | 84 | sb.WriteByte('\n') 85 | sb.WriteTo(logger) 86 | } 87 | 88 | // modified from Go stdlib: encoding/json/encode.go:787-862 (approx) 89 | func encodeStringStructured(e byteSliceWriter, s string) { 90 | for i := 0; i < len(s); { 91 | if b := s[i]; b < utf8.RuneSelf { 92 | i++ 93 | if 0x20 <= b && b != '"' { 94 | e.WriteByte(b) 95 | continue 96 | } 97 | 98 | switch b { 99 | case '"': 100 | e.WriteByte('\\') 101 | e.WriteByte(b) 102 | case '\n': 103 | e.WriteByte('\\') 104 | e.WriteByte('n') 105 | case '\r': 106 | e.WriteByte('\\') 107 | e.WriteByte('r') 108 | case '\t': 109 | e.WriteByte('\\') 110 | e.WriteByte('t') 111 | default: 112 | e.WriteByte(b) 113 | } 114 | continue 115 | } 116 | 117 | c, size := utf8.DecodeRuneInString(s[i:]) 118 | if c == utf8.RuneError && size == 1 { 119 | e.WriteString(`\ufffd`) 120 | i++ 121 | continue 122 | } 123 | 124 | e.WriteString(s[i : i+size]) 125 | i += size 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/formatwriter_structured_bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mlog 6 | 7 | import ( 8 | "io/ioutil" 9 | "testing" 10 | ) 11 | 12 | func BenchmarkFormatWriterStructuredBase(b *testing.B) { 13 | logger := New(ioutil.Discard, 0) 14 | logWriter := &FormatWriterStructured{} 15 | b.ResetTimer() 16 | for i := 0; i < b.N; i++ { 17 | logWriter.Emit(logger, 0, "this is a test", nil) 18 | } 19 | } 20 | 21 | func BenchmarkFormatWriterStructuredStd(b *testing.B) { 22 | logger := New(ioutil.Discard, Lstd) 23 | logWriter := &FormatWriterStructured{} 24 | b.ResetTimer() 25 | for i := 0; i < b.N; i++ { 26 | logWriter.Emit(logger, 0, "this is a test", nil) 27 | } 28 | } 29 | 30 | func BenchmarkFormatWriterStructuredTime(b *testing.B) { 31 | logger := New(ioutil.Discard, Ltimestamp) 32 | logWriter := &FormatWriterStructured{} 33 | b.ResetTimer() 34 | for i := 0; i < b.N; i++ { 35 | logWriter.Emit(logger, 0, "this is a test", nil) 36 | } 37 | } 38 | 39 | func BenchmarkFormatWriterStructuredTimeTAI64N(b *testing.B) { 40 | logger := New(ioutil.Discard, Ltai64n) 41 | logWriter := &FormatWriterStructured{} 42 | b.ResetTimer() 43 | for i := 0; i < b.N; i++ { 44 | logWriter.Emit(logger, 0, "this is a test", nil) 45 | } 46 | } 47 | 48 | func BenchmarkFormatWriterStructuredShortfile(b *testing.B) { 49 | logger := New(ioutil.Discard, Lshortfile) 50 | logWriter := &FormatWriterStructured{} 51 | b.ResetTimer() 52 | for i := 0; i < b.N; i++ { 53 | logWriter.Emit(logger, 0, "this is a test", nil) 54 | } 55 | } 56 | 57 | func BenchmarkFormatWriterStructuredLongfile(b *testing.B) { 58 | logger := New(ioutil.Discard, Llongfile) 59 | logWriter := &FormatWriterStructured{} 60 | b.ResetTimer() 61 | for i := 0; i < b.N; i++ { 62 | logWriter.Emit(logger, 0, "this is a test", nil) 63 | } 64 | } 65 | 66 | func BenchmarkFormatWriterStructuredMap(b *testing.B) { 67 | logger := New(ioutil.Discard, 0) 68 | logWriter := &FormatWriterStructured{} 69 | m := Map{"x": 42} 70 | b.ResetTimer() 71 | for i := 0; i < b.N; i++ { 72 | logWriter.Emit(logger, 0, "this is a test", m) 73 | } 74 | } 75 | 76 | func BenchmarkFormatWriterStructuredHugeMapUnsorted(b *testing.B) { 77 | logger := New(ioutil.Discard, 0) 78 | logWriter := &FormatWriterStructured{} 79 | m := Map{} 80 | for i := 1; i <= 100; i++ { 81 | m[randString(6, false)] = randString(10, false) 82 | } 83 | b.ResetTimer() 84 | for i := 0; i < b.N; i++ { 85 | logWriter.Emit(logger, 0, "this is a test", m) 86 | } 87 | } 88 | 89 | func BenchmarkFormatWriterStructuredHugeMapSorted(b *testing.B) { 90 | logger := New(ioutil.Discard, Lsort) 91 | logWriter := &FormatWriterStructured{} 92 | m := Map{} 93 | for i := 1; i <= 100; i++ { 94 | m[randString(6, false)] = randString(10, false) 95 | } 96 | b.ResetTimer() 97 | for i := 0; i < b.N; i++ { 98 | logWriter.Emit(logger, 0, "this is a test", m) 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/marshal_test.go: -------------------------------------------------------------------------------- 1 | package flags 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | type marshalled string 9 | 10 | func (m *marshalled) UnmarshalFlag(value string) error { 11 | if value == "yes" { 12 | *m = "true" 13 | } else if value == "no" { 14 | *m = "false" 15 | } else { 16 | return fmt.Errorf("`%s' is not a valid value, please specify `yes' or `no'", value) 17 | } 18 | 19 | return nil 20 | } 21 | 22 | func (m marshalled) MarshalFlag() (string, error) { 23 | if m == "true" { 24 | return "yes", nil 25 | } 26 | 27 | return "no", nil 28 | } 29 | 30 | type marshalledError bool 31 | 32 | func (m marshalledError) MarshalFlag() (string, error) { 33 | return "", newErrorf(ErrMarshal, "Failed to marshal") 34 | } 35 | 36 | func TestUnmarshal(t *testing.T) { 37 | var opts = struct { 38 | Value marshalled `short:"v"` 39 | }{} 40 | 41 | ret := assertParseSuccess(t, &opts, "-v=yes") 42 | 43 | assertStringArray(t, ret, []string{}) 44 | 45 | if opts.Value != "true" { 46 | t.Errorf("Expected Value to be \"true\"") 47 | } 48 | } 49 | 50 | func TestUnmarshalDefault(t *testing.T) { 51 | var opts = struct { 52 | Value marshalled `short:"v" default:"yes"` 53 | }{} 54 | 55 | ret := assertParseSuccess(t, &opts) 56 | 57 | assertStringArray(t, ret, []string{}) 58 | 59 | if opts.Value != "true" { 60 | t.Errorf("Expected Value to be \"true\"") 61 | } 62 | } 63 | 64 | func TestUnmarshalOptional(t *testing.T) { 65 | var opts = struct { 66 | Value marshalled `short:"v" optional:"yes" optional-value:"yes"` 67 | }{} 68 | 69 | ret := assertParseSuccess(t, &opts, "-v") 70 | 71 | assertStringArray(t, ret, []string{}) 72 | 73 | if opts.Value != "true" { 74 | t.Errorf("Expected Value to be \"true\"") 75 | } 76 | } 77 | 78 | func TestUnmarshalError(t *testing.T) { 79 | var opts = struct { 80 | Value marshalled `short:"v"` 81 | }{} 82 | 83 | assertParseFail(t, ErrMarshal, fmt.Sprintf("invalid argument for flag `%cv' (expected flags.marshalled): `invalid' is not a valid value, please specify `yes' or `no'", defaultShortOptDelimiter), &opts, "-vinvalid") 84 | } 85 | 86 | func TestUnmarshalPositionalError(t *testing.T) { 87 | var opts = struct { 88 | Args struct { 89 | Value marshalled 90 | } `positional-args:"yes"` 91 | }{} 92 | 93 | parser := NewParser(&opts, Default&^PrintErrors) 94 | _, err := parser.ParseArgs([]string{"invalid"}) 95 | 96 | msg := "`invalid' is not a valid value, please specify `yes' or `no'" 97 | 98 | if err == nil { 99 | assertFatalf(t, "Expected error: %s", msg) 100 | return 101 | } 102 | 103 | if err.Error() != msg { 104 | assertErrorf(t, "Expected error message %#v, but got %#v", msg, err.Error()) 105 | } 106 | } 107 | 108 | func TestMarshalError(t *testing.T) { 109 | var opts = struct { 110 | Value marshalledError `short:"v"` 111 | }{} 112 | 113 | p := NewParser(&opts, Default) 114 | o := p.Command.Groups()[0].Options()[0] 115 | 116 | _, err := convertToString(o.value, o.tag) 117 | 118 | assertError(t, err, ErrMarshal, "Failed to marshal") 119 | } 120 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/logger_bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mlog 6 | 7 | import ( 8 | "io/ioutil" 9 | "log" 10 | "math/rand" 11 | "testing" 12 | ) 13 | 14 | const ( 15 | letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 16 | letterBytesAlt = letterBytes + "\"\t\r\n" 17 | letterIdxBits = 6 // 6 bits to represent a letter index 18 | letterIdxMask = 1<= 0; { 30 | if remain == 0 { 31 | cache, remain = rand.Int63(), letterIdxMax 32 | } 33 | if idx := int(cache & letterIdxMask); idx < len(lb) { 34 | b[i] = lb[idx] 35 | i-- 36 | } 37 | cache >>= letterIdxBits 38 | remain-- 39 | } 40 | 41 | return string(b) 42 | } 43 | 44 | func BenchmarkLoggingDebugWithDisabled(b *testing.B) { 45 | logger := New(ioutil.Discard, 0) 46 | b.ResetTimer() 47 | for i := 0; i < b.N; i++ { 48 | logger.Debug("this is a test") 49 | } 50 | } 51 | 52 | func BenchmarkLoggingDebugWithEnabled(b *testing.B) { 53 | logger := New(ioutil.Discard, Ldebug) 54 | b.ResetTimer() 55 | for i := 0; i < b.N; i++ { 56 | logger.Debug("this is a test") 57 | } 58 | } 59 | 60 | func BenchmarkLoggingLikeStdlib(b *testing.B) { 61 | logger := New(ioutil.Discard, Lstd) 62 | b.ResetTimer() 63 | for i := 0; i < b.N; i++ { 64 | logger.Info("this is a test") 65 | } 66 | } 67 | 68 | func BenchmarkLoggingStdlibLog(b *testing.B) { 69 | logger := log.New(ioutil.Discard, "info: ", log.LstdFlags) 70 | b.ResetTimer() 71 | for i := 0; i < b.N; i++ { 72 | logger.Print("this is a test") 73 | } 74 | } 75 | 76 | func BenchmarkLoggingLikeStdlibShortfile(b *testing.B) { 77 | logger := New(ioutil.Discard, Lstd|Lshortfile) 78 | b.ResetTimer() 79 | for i := 0; i < b.N; i++ { 80 | logger.Info("this is a test") 81 | } 82 | } 83 | 84 | func BenchmarkLoggingStdlibLogShortfile(b *testing.B) { 85 | logger := log.New(ioutil.Discard, "info: ", log.LstdFlags|log.Lshortfile) 86 | b.ResetTimer() 87 | for i := 0; i < b.N; i++ { 88 | logger.Print("this is a test") 89 | } 90 | } 91 | 92 | func BenchmarkLoggingParallelLikeStdlib(b *testing.B) { 93 | logger := New(ioutil.Discard, Lstd) 94 | b.ResetTimer() 95 | b.RunParallel(func(pb *testing.PB) { 96 | for pb.Next() { 97 | logger.Info("this is a test") 98 | } 99 | }) 100 | } 101 | 102 | func BenchmarkLoggingParallelStdlibLog(b *testing.B) { 103 | logger := log.New(ioutil.Discard, "info: ", log.LstdFlags) 104 | b.ResetTimer() 105 | b.RunParallel(func(pb *testing.PB) { 106 | for pb.Next() { 107 | logger.Print("this is a test") 108 | } 109 | }) 110 | } 111 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/tai64/time_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package tai64 6 | 7 | import ( 8 | "testing" 9 | "time" 10 | 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | var tests = map[string]struct { 15 | t string 16 | o string 17 | }{ 18 | "a while ago": {"1920-01-01T00:00:00Z", "@3fffffffa1f2cd8a00000000"}, 19 | "before tai swap": {"1969-12-31T23:59:49Z", "@3fffffffffffffff00000000"}, 20 | "at tai swap": {"1969-12-31T23:59:50Z", "@400000000000000000000000"}, 21 | "after tai swap": {"1969-12-31T23:59:51Z", "@400000000000000100000000"}, 22 | "before unix epoch": {"1969-12-31T23:59:59Z", "@400000000000000900000000"}, 23 | "at unix epoch": {"1970-01-01T00:00:00Z", "@400000000000000a00000000"}, 24 | "after unix epoch": {"1970-01-01T00:00:01Z", "@400000000000000b00000000"}, 25 | "before tai-utc epoch": {"1970-01-01T00:00:09Z", "@400000000000001300000000"}, 26 | "at tai-utc epoch": {"1970-01-01T00:00:10Z", "@400000000000001400000000"}, 27 | "after tai-utc epoch": {"1970-01-01T00:00:11Z", "@400000000000001500000000"}, 28 | "a more current date": {"2016-12-31T23:59:59Z", "@40000000586846a300000000"}, 29 | "nanoseconds": {"2015-06-30T23:59:59.908626131Z", "@4000000055932da2362888d3"}, 30 | } 31 | 32 | func TestRoundTripNano(t *testing.T) { 33 | for name, tt := range tests { 34 | tm, err := time.Parse(time.RFC3339Nano, tt.t) 35 | assert.Nil(t, err, "%s: test failed parsing time.Time", name) 36 | o := FormatNano(tm) 37 | p, err := Parse(o) 38 | assert.Nil(t, err, "%s: test failed parsing", name) 39 | assert.Equal(t, tm, p, "%s: test failed date compare: %s", name) 40 | } 41 | } 42 | 43 | func TestRoundTrip(t *testing.T) { 44 | for name, tt := range tests { 45 | tm, err := time.Parse(time.RFC3339Nano, tt.t) 46 | assert.Nil(t, err, "%s: test failed parsing time.Time", name) 47 | o := Format(tm) 48 | p, err := Parse(o[:17]) 49 | assert.Nil(t, err, "%s: test failed parsing", name) 50 | assert.Equal(t, tm.Truncate(time.Second), p, "%s: test failed date compare: %s", name) 51 | } 52 | } 53 | 54 | func TestFormat(t *testing.T) { 55 | for name, tt := range tests { 56 | tm, err := time.Parse(time.RFC3339Nano, tt.t) 57 | assert.Nil(t, err, "%s: test failed parsing time.Time", name) 58 | o := FormatNano(tm) 59 | assert.Equal(t, tt.o, o, "%s: test failed date compare", name) 60 | } 61 | } 62 | 63 | func TestParse(t *testing.T) { 64 | for name, tt := range tests { 65 | tm, err := time.Parse(time.RFC3339Nano, tt.t) 66 | assert.Nil(t, err, "%s: test failed parsing time.Time", name) 67 | p, err := Parse(tt.o) 68 | assert.Nil(t, err, "%s: test failed parsing", name) 69 | assert.Equal(t, tm, p, "%s: test failed date compare", name) 70 | } 71 | } 72 | 73 | func BenchmarkFormat(b *testing.B) { 74 | t := time.Date(2016, 12, 31, 23, 59, 59, 00, time.UTC) 75 | b.ResetTimer() 76 | for i := 0; i < b.N; i++ { 77 | Format(t) 78 | } 79 | } 80 | 81 | func BenchmarkParse(b *testing.B) { 82 | s := "@40000000586846a300000000" 83 | b.ResetTimer() 84 | for i := 0; i < b.N; i++ { 85 | Parse(s) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/multitag.go: -------------------------------------------------------------------------------- 1 | package flags 2 | 3 | import ( 4 | "strconv" 5 | ) 6 | 7 | type multiTag struct { 8 | value string 9 | cache map[string][]string 10 | } 11 | 12 | func newMultiTag(v string) multiTag { 13 | return multiTag{ 14 | value: v, 15 | } 16 | } 17 | 18 | func (x *multiTag) scan() (map[string][]string, error) { 19 | v := x.value 20 | 21 | ret := make(map[string][]string) 22 | 23 | // This is mostly copied from reflect.StructTag.Get 24 | for v != "" { 25 | i := 0 26 | 27 | // Skip whitespace 28 | for i < len(v) && v[i] == ' ' { 29 | i++ 30 | } 31 | 32 | v = v[i:] 33 | 34 | if v == "" { 35 | break 36 | } 37 | 38 | // Scan to colon to find key 39 | i = 0 40 | 41 | for i < len(v) && v[i] != ' ' && v[i] != ':' && v[i] != '"' { 42 | i++ 43 | } 44 | 45 | if i >= len(v) { 46 | return nil, newErrorf(ErrTag, "expected `:' after key name, but got end of tag (in `%v`)", x.value) 47 | } 48 | 49 | if v[i] != ':' { 50 | return nil, newErrorf(ErrTag, "expected `:' after key name, but got `%v' (in `%v`)", v[i], x.value) 51 | } 52 | 53 | if i+1 >= len(v) { 54 | return nil, newErrorf(ErrTag, "expected `\"' to start tag value at end of tag (in `%v`)", x.value) 55 | } 56 | 57 | if v[i+1] != '"' { 58 | return nil, newErrorf(ErrTag, "expected `\"' to start tag value, but got `%v' (in `%v`)", v[i+1], x.value) 59 | } 60 | 61 | name := v[:i] 62 | v = v[i+1:] 63 | 64 | // Scan quoted string to find value 65 | i = 1 66 | 67 | for i < len(v) && v[i] != '"' { 68 | if v[i] == '\n' { 69 | return nil, newErrorf(ErrTag, "unexpected newline in tag value `%v' (in `%v`)", name, x.value) 70 | } 71 | 72 | if v[i] == '\\' { 73 | i++ 74 | } 75 | i++ 76 | } 77 | 78 | if i >= len(v) { 79 | return nil, newErrorf(ErrTag, "expected end of tag value `\"' at end of tag (in `%v`)", x.value) 80 | } 81 | 82 | val, err := strconv.Unquote(v[:i+1]) 83 | 84 | if err != nil { 85 | return nil, newErrorf(ErrTag, "Malformed value of tag `%v:%v` => %v (in `%v`)", name, v[:i+1], err, x.value) 86 | } 87 | 88 | v = v[i+1:] 89 | 90 | ret[name] = append(ret[name], val) 91 | } 92 | 93 | return ret, nil 94 | } 95 | 96 | func (x *multiTag) Parse() error { 97 | vals, err := x.scan() 98 | x.cache = vals 99 | 100 | return err 101 | } 102 | 103 | func (x *multiTag) cached() map[string][]string { 104 | if x.cache == nil { 105 | cache, _ := x.scan() 106 | 107 | if cache == nil { 108 | cache = make(map[string][]string) 109 | } 110 | 111 | x.cache = cache 112 | } 113 | 114 | return x.cache 115 | } 116 | 117 | func (x *multiTag) Get(key string) string { 118 | c := x.cached() 119 | 120 | if v, ok := c[key]; ok { 121 | return v[len(v)-1] 122 | } 123 | 124 | return "" 125 | } 126 | 127 | func (x *multiTag) GetMany(key string) []string { 128 | c := x.cached() 129 | return c[key] 130 | } 131 | 132 | func (x *multiTag) Set(key string, value string) { 133 | c := x.cached() 134 | c[key] = []string{value} 135 | } 136 | 137 | func (x *multiTag) SetMany(key string, value []string) { 138 | c := x.cached() 139 | c[key] = value 140 | } 141 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/tai64/time.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package tai64 6 | 7 | //go:generate go run ./tools/generate.go -pkg $GOPACKAGE -output offsets.go 8 | 9 | import ( 10 | "fmt" 11 | "strconv" 12 | "time" 13 | ) 14 | 15 | const tai64Epoch = 2 << 61 16 | 17 | // GetOffsetUnix returns the TAI64 offset for a UTC unix timestamp 18 | // returns int64 offset 19 | func GetOffsetUnix(utime int64) int64 { 20 | // default offset is 10 21 | offset := int64(10) 22 | for i := tia64nSize - 1; i >= 0; i-- { 23 | if utime < tia64nDifferences[i].utime { 24 | continue 25 | } else { 26 | offset = tia64nDifferences[i].offset 27 | break 28 | } 29 | } 30 | return offset 31 | } 32 | 33 | // GetOffsetTime returns the TAI64 offset for a time.Time in UTC 34 | // returns int64 offset 35 | func GetOffsetTime(t time.Time) int64 { 36 | return GetOffsetUnix(t.UTC().Unix()) 37 | } 38 | 39 | func getInvOffsetUnix(utime int64) int64 { 40 | // default offset is 10 41 | offset := int64(10) 42 | for i := tia64nSize - 1; i >= 0; i-- { 43 | t := tia64nDifferences[i] 44 | if utime < (t.utime + t.offset) { 45 | continue 46 | } else { 47 | offset = t.offset 48 | break 49 | } 50 | } 51 | return offset 52 | } 53 | 54 | // FormatNano formats a time.Time as a TAI64N timestamp 55 | // returns a string TAI64N timestamps 56 | func FormatNano(t time.Time) string { 57 | t = t.UTC() 58 | u := t.Unix() 59 | 60 | if u < 0 { 61 | return fmt.Sprintf("@%016x%08x", (2<<61)+u+10, t.Nanosecond()) 62 | } 63 | return fmt.Sprintf("@4%015x%08x", u+GetOffsetUnix(u), t.Nanosecond()) 64 | } 65 | 66 | // Format formats a time.Time as a TAI64 timestamp 67 | // returns a string TAI64 timestamps 68 | func Format(t time.Time) string { 69 | u := t.UTC().Unix() 70 | 71 | if u < 0 { 72 | return fmt.Sprintf("@%016x", (2<<61)+u+10) 73 | } 74 | return fmt.Sprintf("@4%015x", u+GetOffsetUnix(u)) 75 | } 76 | 77 | // Parse parses a TAI64 or TAI64N timestamp 78 | // returns a time.Time and an error. 79 | func Parse(s string) (time.Time, error) { 80 | var seconds, nanoseconds int64 81 | if s[0] == '@' { 82 | s = s[1:] 83 | } 84 | 85 | if len(s) < 16 { 86 | return time.Time{}, fmt.Errorf("invalid tai64 time string") 87 | } 88 | 89 | i, err := strconv.ParseInt(s[0:16], 16, 64) 90 | if err != nil { 91 | return time.Time{}, err 92 | } 93 | seconds = i 94 | s = s[16:] 95 | 96 | // Check for TAI64N or TAI64NA format 97 | slen := len(s) 98 | if slen == 8 || slen == 16 { 99 | // time.Time is not attoseconds granular, so 100 | // just pull off the TAI64N section. 101 | i, err := strconv.ParseInt(s[:8], 16, 64) 102 | if err != nil { 103 | return time.Time{}, err 104 | } 105 | nanoseconds = i 106 | } 107 | 108 | if seconds >= tai64Epoch { 109 | // fiddle with add/remove time 110 | unix := seconds - tai64Epoch 111 | offset := getInvOffsetUnix(unix) 112 | unix = unix - offset 113 | t := time.Unix(unix, nanoseconds).UTC() 114 | return t, nil 115 | } 116 | 117 | unix := -(tai64Epoch - seconds + 10) 118 | t := time.Unix(unix, nanoseconds).UTC() 119 | return t, nil 120 | } 121 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/slicebuffer.go: -------------------------------------------------------------------------------- 1 | package mlog 2 | 3 | import ( 4 | "io" 5 | "sync" 6 | ) 7 | 8 | var bufPool = newSliceBufferPool() 9 | 10 | type sliceBufferPool struct { 11 | *sync.Pool 12 | } 13 | 14 | func newSliceBufferPool() *sliceBufferPool { 15 | return &sliceBufferPool{ 16 | &sync.Pool{New: func() interface{} { 17 | return &sliceBuffer{make([]byte, 0, 1024)} 18 | }}, 19 | } 20 | } 21 | 22 | func (sp *sliceBufferPool) Get() *sliceBuffer { 23 | return (sp.Pool.Get()).(*sliceBuffer) 24 | } 25 | 26 | func (sp *sliceBufferPool) Put(c *sliceBuffer) { 27 | c.Truncate(0) 28 | sp.Pool.Put(c) 29 | } 30 | 31 | type byteSliceWriter interface { 32 | Write([]byte) (int, error) 33 | WriteByte(byte) error 34 | WriteString(string) (int, error) 35 | Truncate(int) 36 | } 37 | 38 | type intSliceWriter interface { 39 | byteSliceWriter 40 | AppendIntWidth(int, int) 41 | AppendIntWidthHex(int64, int) 42 | } 43 | 44 | type sliceBuffer struct { 45 | data []byte 46 | } 47 | 48 | func (sb *sliceBuffer) AppendIntWidth(i int, wid int) { 49 | digits := 0 50 | // write digits backwards (easier/faster) 51 | for i >= 10 { 52 | q := i / 10 53 | sb.data = append(sb.data, byte('0'+i-q*10)) 54 | i = q 55 | digits++ 56 | } 57 | sb.data = append(sb.data, byte('0'+i)) 58 | digits++ 59 | 60 | for j := wid - digits; j > 0; j-- { 61 | sb.data = append(sb.data, '0') 62 | digits++ 63 | } 64 | 65 | // reverse to proper order 66 | sblen := len(sb.data) 67 | for i, j := sblen-digits, sblen-1; i < j; i, j = i+1, j-1 { 68 | sb.data[i], sb.data[j] = sb.data[j], sb.data[i] 69 | } 70 | } 71 | 72 | const hexdigits = "0123456789abcdefghijklmnopqrstuvwxyz" 73 | 74 | func (sb *sliceBuffer) AppendIntWidthHex(i int64, wid int) { 75 | u := uint64(i) 76 | 77 | digits := 0 78 | b := uint64(16) 79 | m := uintptr(b) - 1 80 | for u >= b { 81 | sb.data = append(sb.data, hexdigits[uintptr(u)&m]) 82 | u >>= 4 83 | digits++ 84 | } 85 | sb.data = append(sb.data, hexdigits[uintptr(u)]) 86 | digits++ 87 | 88 | for j := wid - digits; j > 0; j-- { 89 | sb.data = append(sb.data, '0') 90 | digits++ 91 | } 92 | 93 | // reverse to proper order 94 | sblen := len(sb.data) 95 | for i, j := sblen-digits, sblen-1; i < j; i, j = i+1, j-1 { 96 | sb.data[i], sb.data[j] = sb.data[j], sb.data[i] 97 | } 98 | } 99 | 100 | func (sb *sliceBuffer) Write(b []byte) (int, error) { 101 | sb.data = append(sb.data, b...) 102 | return len(b), nil 103 | } 104 | 105 | func (sb *sliceBuffer) WriteByte(c byte) error { 106 | sb.data = append(sb.data, c) 107 | return nil 108 | } 109 | 110 | func (sb *sliceBuffer) WriteString(s string) (int, error) { 111 | sb.data = append(sb.data, s...) 112 | return len(s), nil 113 | } 114 | 115 | func (sb *sliceBuffer) WriteTo(w io.Writer) (int64, error) { 116 | n, err := w.Write(sb.data) 117 | return int64(n), err 118 | } 119 | 120 | func (sb *sliceBuffer) Bytes() []byte { 121 | return sb.data 122 | } 123 | 124 | func (sb *sliceBuffer) String() string { 125 | return string(sb.data) 126 | } 127 | 128 | func (sb *sliceBuffer) Len() int { 129 | return len(sb.data) 130 | } 131 | 132 | func (sb *sliceBuffer) Reset() { 133 | sb.Truncate(0) 134 | } 135 | 136 | func (sb *sliceBuffer) Truncate(i int) { 137 | sb.data = sb.data[:i] 138 | } 139 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/default_logger.go: -------------------------------------------------------------------------------- 1 | package mlog 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | // DefaultLogger is the default package level Logger 9 | var DefaultLogger = New(os.Stderr, Lstd) 10 | 11 | // SetEmitter sets the Emitter for the degault logger. See 12 | // Logger.SetEmitter. 13 | func SetEmitter(e Emitter) { 14 | DefaultLogger.SetEmitter(e) 15 | } 16 | 17 | // Flags returns the FlagSet of the default Logger. See Logger.Flags. 18 | func Flags() FlagSet { 19 | return DefaultLogger.Flags() 20 | } 21 | 22 | // SetFlags sets the FlagSet on the default Logger. See Logger.SetFlags. 23 | func SetFlags(flags FlagSet) { 24 | DefaultLogger.SetFlags(flags) 25 | } 26 | 27 | // Debugm logs to the default Logger. See Logger.Debugm 28 | func Debugm(message string, v Map) { 29 | if DefaultLogger.HasDebug() { 30 | DefaultLogger.Emit(-1, message, v) 31 | } 32 | } 33 | 34 | // Infom logs to the default Logger. See Logger.Infom 35 | func Infom(message string, v Map) { 36 | DefaultLogger.Emit(0, message, v) 37 | } 38 | 39 | // Printm logs to the default Logger. See Logger.Printm 40 | func Printm(message string, v Map) { 41 | DefaultLogger.Emit(0, message, v) 42 | } 43 | 44 | // Fatalm logs to the default Logger. See Logger.Fatalm 45 | func Fatalm(message string, v Map) { 46 | DefaultLogger.Emit(1, message, v) 47 | os.Exit(1) 48 | } 49 | 50 | // Panicm logs to the default Logger. See Logger.Panicm 51 | func Panicm(message string, v Map) { 52 | DefaultLogger.Panicm(message, v) 53 | } 54 | 55 | // Debugf logs to the default Logger. See Logger.Debugf 56 | func Debugf(format string, v ...interface{}) { 57 | if DefaultLogger.HasDebug() { 58 | DefaultLogger.Emit(-1, fmt.Sprintf(format, v...), nil) 59 | } 60 | } 61 | 62 | // Infof logs to the default Logger. See Logger.Infof 63 | func Infof(format string, v ...interface{}) { 64 | DefaultLogger.Emit(0, fmt.Sprintf(format, v...), nil) 65 | } 66 | 67 | // Printf logs to the default Logger. See Logger.Printf 68 | func Printf(format string, v ...interface{}) { 69 | DefaultLogger.Emit(0, fmt.Sprintf(format, v...), nil) 70 | } 71 | 72 | // Fatalf logs to the default Logger. See Logger.Fatalf 73 | func Fatalf(format string, v ...interface{}) { 74 | DefaultLogger.Emit(1, fmt.Sprintf(format, v...), nil) 75 | os.Exit(1) 76 | } 77 | 78 | // Panicf is equivalent to Printf() followed by a call to panic(). 79 | // See Logger.Panicf 80 | func Panicf(format string, v ...interface{}) { 81 | DefaultLogger.Panicf(format, v...) 82 | } 83 | 84 | // Debug logs to the default Logger. See Logger.Debug 85 | func Debug(v ...interface{}) { 86 | if DefaultLogger.HasDebug() { 87 | DefaultLogger.Emit(-1, fmt.Sprint(v...), nil) 88 | } 89 | } 90 | 91 | // Info logs to the default Logger. See Logger.Info 92 | func Info(v ...interface{}) { 93 | DefaultLogger.Emit(0, fmt.Sprint(v...), nil) 94 | } 95 | 96 | // Print logs to the default Logger. See Logger.Print 97 | func Print(v ...interface{}) { 98 | DefaultLogger.Emit(0, fmt.Sprint(v...), nil) 99 | } 100 | 101 | // Fatal logs to the default Logger. See Logger.Fatal 102 | func Fatal(v ...interface{}) { 103 | DefaultLogger.Emit(1, fmt.Sprint(v...), nil) 104 | os.Exit(1) 105 | } 106 | 107 | // Panic is equivalent to Print() followed by a call to panic(). 108 | // See Logger.Panic 109 | func Panic(v ...interface{}) { 110 | DefaultLogger.Panic(v...) 111 | } 112 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/convert_test.go: -------------------------------------------------------------------------------- 1 | package flags 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func expectConvert(t *testing.T, o *Option, expected string) { 9 | s, err := convertToString(o.value, o.tag) 10 | 11 | if err != nil { 12 | t.Errorf("Unexpected error: %v", err) 13 | return 14 | } 15 | 16 | assertString(t, s, expected) 17 | } 18 | 19 | func TestConvertToString(t *testing.T) { 20 | d, _ := time.ParseDuration("1h2m4s") 21 | 22 | var opts = struct { 23 | String string `long:"string"` 24 | 25 | Int int `long:"int"` 26 | Int8 int8 `long:"int8"` 27 | Int16 int16 `long:"int16"` 28 | Int32 int32 `long:"int32"` 29 | Int64 int64 `long:"int64"` 30 | 31 | Uint uint `long:"uint"` 32 | Uint8 uint8 `long:"uint8"` 33 | Uint16 uint16 `long:"uint16"` 34 | Uint32 uint32 `long:"uint32"` 35 | Uint64 uint64 `long:"uint64"` 36 | 37 | Float32 float32 `long:"float32"` 38 | Float64 float64 `long:"float64"` 39 | 40 | Duration time.Duration `long:"duration"` 41 | 42 | Bool bool `long:"bool"` 43 | 44 | IntSlice []int `long:"int-slice"` 45 | IntFloatMap map[int]float64 `long:"int-float-map"` 46 | 47 | PtrBool *bool `long:"ptr-bool"` 48 | Interface interface{} `long:"interface"` 49 | 50 | Int32Base int32 `long:"int32-base" base:"16"` 51 | Uint32Base uint32 `long:"uint32-base" base:"16"` 52 | }{ 53 | "string", 54 | 55 | -2, 56 | -1, 57 | 0, 58 | 1, 59 | 2, 60 | 61 | 1, 62 | 2, 63 | 3, 64 | 4, 65 | 5, 66 | 67 | 1.2, 68 | -3.4, 69 | 70 | d, 71 | true, 72 | 73 | []int{-3, 4, -2}, 74 | map[int]float64{-2: 4.5}, 75 | 76 | new(bool), 77 | float32(5.2), 78 | 79 | -5823, 80 | 4232, 81 | } 82 | 83 | p := NewNamedParser("test", Default) 84 | grp, _ := p.AddGroup("test group", "", &opts) 85 | 86 | expects := []string{ 87 | "string", 88 | "-2", 89 | "-1", 90 | "0", 91 | "1", 92 | "2", 93 | 94 | "1", 95 | "2", 96 | "3", 97 | "4", 98 | "5", 99 | 100 | "1.2", 101 | "-3.4", 102 | 103 | "1h2m4s", 104 | "true", 105 | 106 | "[-3, 4, -2]", 107 | "{-2:4.5}", 108 | 109 | "false", 110 | "5.2", 111 | 112 | "-16bf", 113 | "1088", 114 | } 115 | 116 | for i, v := range grp.Options() { 117 | expectConvert(t, v, expects[i]) 118 | } 119 | } 120 | 121 | func TestConvertToStringInvalidIntBase(t *testing.T) { 122 | var opts = struct { 123 | Int int `long:"int" base:"no"` 124 | }{ 125 | 2, 126 | } 127 | 128 | p := NewNamedParser("test", Default) 129 | grp, _ := p.AddGroup("test group", "", &opts) 130 | o := grp.Options()[0] 131 | 132 | _, err := convertToString(o.value, o.tag) 133 | 134 | if err != nil { 135 | err = newErrorf(ErrMarshal, "%v", err) 136 | } 137 | 138 | assertError(t, err, ErrMarshal, "strconv.ParseInt: parsing \"no\": invalid syntax") 139 | } 140 | 141 | func TestConvertToStringInvalidUintBase(t *testing.T) { 142 | var opts = struct { 143 | Uint uint `long:"uint" base:"no"` 144 | }{ 145 | 2, 146 | } 147 | 148 | p := NewNamedParser("test", Default) 149 | grp, _ := p.AddGroup("test group", "", &opts) 150 | o := grp.Options()[0] 151 | 152 | _, err := convertToString(o.value, o.tag) 153 | 154 | if err != nil { 155 | err = newErrorf(ErrMarshal, "%v", err) 156 | } 157 | 158 | assertError(t, err, ErrMarshal, "strconv.ParseInt: parsing \"no\": invalid syntax") 159 | } 160 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/optstyle_windows.go: -------------------------------------------------------------------------------- 1 | // +build !forceposix 2 | 3 | package flags 4 | 5 | import ( 6 | "strings" 7 | ) 8 | 9 | // Windows uses a front slash for both short and long options. Also it uses 10 | // a colon for name/argument delimter. 11 | const ( 12 | defaultShortOptDelimiter = '/' 13 | defaultLongOptDelimiter = "/" 14 | defaultNameArgDelimiter = ':' 15 | ) 16 | 17 | func argumentStartsOption(arg string) bool { 18 | return len(arg) > 0 && (arg[0] == '-' || arg[0] == '/') 19 | } 20 | 21 | func argumentIsOption(arg string) bool { 22 | // Windows-style options allow front slash for the option 23 | // delimiter. 24 | if len(arg) > 1 && arg[0] == '/' { 25 | return true 26 | } 27 | 28 | if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' { 29 | return true 30 | } 31 | 32 | if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' { 33 | return true 34 | } 35 | 36 | return false 37 | } 38 | 39 | // stripOptionPrefix returns the option without the prefix and whether or 40 | // not the option is a long option or not. 41 | func stripOptionPrefix(optname string) (prefix string, name string, islong bool) { 42 | // Determine if the argument is a long option or not. Windows 43 | // typically supports both long and short options with a single 44 | // front slash as the option delimiter, so handle this situation 45 | // nicely. 46 | possplit := 0 47 | 48 | if strings.HasPrefix(optname, "--") { 49 | possplit = 2 50 | islong = true 51 | } else if strings.HasPrefix(optname, "-") { 52 | possplit = 1 53 | islong = false 54 | } else if strings.HasPrefix(optname, "/") { 55 | possplit = 1 56 | islong = len(optname) > 2 57 | } 58 | 59 | return optname[:possplit], optname[possplit:], islong 60 | } 61 | 62 | // splitOption attempts to split the passed option into a name and an argument. 63 | // When there is no argument specified, nil will be returned for it. 64 | func splitOption(prefix string, option string, islong bool) (string, string, *string) { 65 | if len(option) == 0 { 66 | return option, "", nil 67 | } 68 | 69 | // Windows typically uses a colon for the option name and argument 70 | // delimiter while POSIX typically uses an equals. Support both styles, 71 | // but don't allow the two to be mixed. That is to say /foo:bar and 72 | // --foo=bar are acceptable, but /foo=bar and --foo:bar are not. 73 | var pos int 74 | var sp string 75 | 76 | if prefix == "/" { 77 | sp = ":" 78 | pos = strings.Index(option, sp) 79 | } else if len(prefix) > 0 { 80 | sp = "=" 81 | pos = strings.Index(option, sp) 82 | } 83 | 84 | if (islong && pos >= 0) || (!islong && pos == 1) { 85 | rest := option[pos+1:] 86 | return option[:pos], sp, &rest 87 | } 88 | 89 | return option, "", nil 90 | } 91 | 92 | // addHelpGroup adds a new group that contains default help parameters. 93 | func (c *Command) addHelpGroup(showHelp func() error) *Group { 94 | // Windows CLI applications typically use /? for help, so make both 95 | // that available as well as the POSIX style h and help. 96 | var help struct { 97 | ShowHelpWindows func() error `short:"?" description:"Show this help message"` 98 | ShowHelpPosix func() error `short:"h" long:"help" description:"Show this help message"` 99 | } 100 | 101 | help.ShowHelpWindows = showHelp 102 | help.ShowHelpPosix = showHelp 103 | 104 | ret, _ := c.AddGroup("Help Options", "", &help) 105 | ret.isBuiltinHelp = true 106 | 107 | return ret 108 | } 109 | -------------------------------------------------------------------------------- /vendor/github.com/cactus/mlog/logmap.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mlog 6 | 7 | import ( 8 | "fmt" 9 | "sort" 10 | ) 11 | 12 | // Map is a key value element used to pass 13 | // data to the Logger functions. 14 | type Map map[string]interface{} 15 | 16 | // Keys returns an unsorted list of keys in the Map as a []string. 17 | func (m Map) Keys() []string { 18 | keys := make([]string, 0, len(m)) 19 | for k := range m { 20 | keys = append(keys, k) 21 | } 22 | return keys 23 | } 24 | 25 | // unsortedWriteBuf writes an unsorted string representation of 26 | // the Map's key value pairs to w. 27 | func (m Map) unsortedWriteBuf(w byteSliceWriter) { 28 | // scratch buffer for intermediate writes 29 | buf := bufPool.Get() 30 | defer bufPool.Put(buf) 31 | 32 | first := true 33 | for k, v := range m { 34 | if first { 35 | first = false 36 | } else { 37 | w.WriteByte(' ') 38 | } 39 | 40 | w.WriteString(k) 41 | w.WriteString(`="`) 42 | 43 | fmt.Fprint(buf, v) 44 | // pull out byte slice from buff 45 | b := buf.Bytes() 46 | blen := buf.Len() 47 | p := 0 48 | for i := 0; i < blen; i++ { 49 | switch b[i] { 50 | case '"': 51 | w.Write(b[p:i]) 52 | w.WriteString(`\"`) 53 | p = i + 1 54 | case '\t': 55 | w.Write(b[p:i]) 56 | w.WriteString(`\t`) 57 | p = i + 1 58 | case '\r': 59 | w.Write(b[p:i]) 60 | w.WriteString(`\r`) 61 | p = i + 1 62 | case '\n': 63 | w.Write(b[p:i]) 64 | w.WriteString(`\n`) 65 | p = i + 1 66 | } 67 | } 68 | if p < blen { 69 | w.Write(b[p:blen]) 70 | } 71 | 72 | w.WriteByte('"') 73 | // truncate intermediate buf so it is clean for next loop 74 | buf.Truncate(0) 75 | } 76 | } 77 | 78 | // sortedWriteBuf writes a sorted string representation of 79 | // the Map's key value pairs to w. 80 | func (m Map) sortedWriteBuf(w byteSliceWriter) { 81 | // scratch buffer for intermediate writes 82 | buf := bufPool.Get() 83 | defer bufPool.Put(buf) 84 | 85 | keys := m.Keys() 86 | sort.Strings(keys) 87 | 88 | first := true 89 | for _, k := range keys { 90 | if first { 91 | first = false 92 | } else { 93 | w.WriteByte(' ') 94 | } 95 | 96 | w.WriteString(k) 97 | w.WriteString(`="`) 98 | 99 | fmt.Fprint(buf, m[k]) 100 | b := buf.Bytes() 101 | blen := buf.Len() 102 | p := 0 103 | for i := 0; i < blen; i++ { 104 | switch b[i] { 105 | case '"': 106 | w.Write(b[p:i]) 107 | w.WriteString(`\"`) 108 | p = i + 1 109 | case '\t': 110 | w.Write(b[p:i]) 111 | w.WriteString(`\t`) 112 | p = i + 1 113 | case '\r': 114 | w.Write(b[p:i]) 115 | w.WriteString(`\r`) 116 | p = i + 1 117 | case '\n': 118 | w.Write(b[p:i]) 119 | w.WriteString(`\n`) 120 | p = i + 1 121 | } 122 | } 123 | if p < blen { 124 | w.Write(b[p:blen]) 125 | } 126 | 127 | w.WriteByte('"') 128 | // truncate intermediate buf so it is clean for next loop 129 | buf.Truncate(0) 130 | } 131 | } 132 | 133 | // String returns an unsorted string representation of 134 | // the Map's key value pairs. 135 | func (m Map) String() string { 136 | buf := bufPool.Get() 137 | defer bufPool.Put(buf) 138 | m.unsortedWriteBuf(buf) 139 | return buf.String() 140 | } 141 | 142 | // SortedString returns a sorted string representation of 143 | // the Map's key value pairs. 144 | func (m Map) SortedString() string { 145 | buf := bufPool.Get() 146 | defer bufPool.Put(buf) 147 | m.sortedWriteBuf(buf) 148 | return buf.String() 149 | } 150 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/example_test.go: -------------------------------------------------------------------------------- 1 | // Example of use of the flags package. 2 | package flags 3 | 4 | import ( 5 | "fmt" 6 | "os/exec" 7 | ) 8 | 9 | func Example() { 10 | var opts struct { 11 | // Slice of bool will append 'true' each time the option 12 | // is encountered (can be set multiple times, like -vvv) 13 | Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"` 14 | 15 | // Example of automatic marshalling to desired type (uint) 16 | Offset uint `long:"offset" description:"Offset"` 17 | 18 | // Example of a callback, called each time the option is found. 19 | Call func(string) `short:"c" description:"Call phone number"` 20 | 21 | // Example of a required flag 22 | Name string `short:"n" long:"name" description:"A name" required:"true"` 23 | 24 | // Example of a value name 25 | File string `short:"f" long:"file" description:"A file" value-name:"FILE"` 26 | 27 | // Example of a pointer 28 | Ptr *int `short:"p" description:"A pointer to an integer"` 29 | 30 | // Example of a slice of strings 31 | StringSlice []string `short:"s" description:"A slice of strings"` 32 | 33 | // Example of a slice of pointers 34 | PtrSlice []*string `long:"ptrslice" description:"A slice of pointers to string"` 35 | 36 | // Example of a map 37 | IntMap map[string]int `long:"intmap" description:"A map from string to int"` 38 | 39 | // Example of a filename (useful for completion) 40 | Filename Filename `long:"filename" description:"A filename"` 41 | 42 | // Example of positional arguments 43 | Args struct { 44 | ID string 45 | Num int 46 | Rest []string 47 | } `positional-args:"yes" required:"yes"` 48 | } 49 | 50 | // Callback which will invoke callto: to call a number. 51 | // Note that this works just on OS X (and probably only with 52 | // Skype) but it shows the idea. 53 | opts.Call = func(num string) { 54 | cmd := exec.Command("open", "callto:"+num) 55 | cmd.Start() 56 | cmd.Process.Release() 57 | } 58 | 59 | // Make some fake arguments to parse. 60 | args := []string{ 61 | "-vv", 62 | "--offset=5", 63 | "-n", "Me", 64 | "-p", "3", 65 | "-s", "hello", 66 | "-s", "world", 67 | "--ptrslice", "hello", 68 | "--ptrslice", "world", 69 | "--intmap", "a:1", 70 | "--intmap", "b:5", 71 | "--filename", "hello.go", 72 | "id", 73 | "10", 74 | "remaining1", 75 | "remaining2", 76 | } 77 | 78 | // Parse flags from `args'. Note that here we use flags.ParseArgs for 79 | // the sake of making a working example. Normally, you would simply use 80 | // flags.Parse(&opts) which uses os.Args 81 | _, err := ParseArgs(&opts, args) 82 | 83 | if err != nil { 84 | panic(err) 85 | } 86 | 87 | fmt.Printf("Verbosity: %v\n", opts.Verbose) 88 | fmt.Printf("Offset: %d\n", opts.Offset) 89 | fmt.Printf("Name: %s\n", opts.Name) 90 | fmt.Printf("Ptr: %d\n", *opts.Ptr) 91 | fmt.Printf("StringSlice: %v\n", opts.StringSlice) 92 | fmt.Printf("PtrSlice: [%v %v]\n", *opts.PtrSlice[0], *opts.PtrSlice[1]) 93 | fmt.Printf("IntMap: [a:%v b:%v]\n", opts.IntMap["a"], opts.IntMap["b"]) 94 | fmt.Printf("Filename: %v\n", opts.Filename) 95 | fmt.Printf("Args.ID: %s\n", opts.Args.ID) 96 | fmt.Printf("Args.Num: %d\n", opts.Args.Num) 97 | fmt.Printf("Args.Rest: %v\n", opts.Args.Rest) 98 | 99 | // Output: Verbosity: [true true] 100 | // Offset: 5 101 | // Name: Me 102 | // Ptr: 3 103 | // StringSlice: [hello world] 104 | // PtrSlice: [hello world] 105 | // IntMap: [a:1 b:5] 106 | // Filename: hello.go 107 | // Args.ID: id 108 | // Args.Num: 10 109 | // Args.Rest: [remaining1 remaining2] 110 | } 111 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/error.go: -------------------------------------------------------------------------------- 1 | package flags 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // ErrorType represents the type of error. 8 | type ErrorType uint 9 | 10 | const ( 11 | // ErrUnknown indicates a generic error. 12 | ErrUnknown ErrorType = iota 13 | 14 | // ErrExpectedArgument indicates that an argument was expected. 15 | ErrExpectedArgument 16 | 17 | // ErrUnknownFlag indicates an unknown flag. 18 | ErrUnknownFlag 19 | 20 | // ErrUnknownGroup indicates an unknown group. 21 | ErrUnknownGroup 22 | 23 | // ErrMarshal indicates a marshalling error while converting values. 24 | ErrMarshal 25 | 26 | // ErrHelp indicates that the built-in help was shown (the error 27 | // contains the help message). 28 | ErrHelp 29 | 30 | // ErrNoArgumentForBool indicates that an argument was given for a 31 | // boolean flag (which don't not take any arguments). 32 | ErrNoArgumentForBool 33 | 34 | // ErrRequired indicates that a required flag was not provided. 35 | ErrRequired 36 | 37 | // ErrShortNameTooLong indicates that a short flag name was specified, 38 | // longer than one character. 39 | ErrShortNameTooLong 40 | 41 | // ErrDuplicatedFlag indicates that a short or long flag has been 42 | // defined more than once 43 | ErrDuplicatedFlag 44 | 45 | // ErrTag indicates an error while parsing flag tags. 46 | ErrTag 47 | 48 | // ErrCommandRequired indicates that a command was required but not 49 | // specified 50 | ErrCommandRequired 51 | 52 | // ErrUnknownCommand indicates that an unknown command was specified. 53 | ErrUnknownCommand 54 | 55 | // ErrInvalidChoice indicates an invalid option value which only allows 56 | // a certain number of choices. 57 | ErrInvalidChoice 58 | 59 | // ErrInvalidTag indicates an invalid tag or invalid use of an existing tag 60 | ErrInvalidTag 61 | ) 62 | 63 | func (e ErrorType) String() string { 64 | switch e { 65 | case ErrUnknown: 66 | return "unknown" 67 | case ErrExpectedArgument: 68 | return "expected argument" 69 | case ErrUnknownFlag: 70 | return "unknown flag" 71 | case ErrUnknownGroup: 72 | return "unknown group" 73 | case ErrMarshal: 74 | return "marshal" 75 | case ErrHelp: 76 | return "help" 77 | case ErrNoArgumentForBool: 78 | return "no argument for bool" 79 | case ErrRequired: 80 | return "required" 81 | case ErrShortNameTooLong: 82 | return "short name too long" 83 | case ErrDuplicatedFlag: 84 | return "duplicated flag" 85 | case ErrTag: 86 | return "tag" 87 | case ErrCommandRequired: 88 | return "command required" 89 | case ErrUnknownCommand: 90 | return "unknown command" 91 | case ErrInvalidChoice: 92 | return "invalid choice" 93 | case ErrInvalidTag: 94 | return "invalid tag" 95 | } 96 | 97 | return "unrecognized error type" 98 | } 99 | 100 | // Error represents a parser error. The error returned from Parse is of this 101 | // type. The error contains both a Type and Message. 102 | type Error struct { 103 | // The type of error 104 | Type ErrorType 105 | 106 | // The error message 107 | Message string 108 | } 109 | 110 | // Error returns the error's message 111 | func (e *Error) Error() string { 112 | return e.Message 113 | } 114 | 115 | func newError(tp ErrorType, message string) *Error { 116 | return &Error{ 117 | Type: tp, 118 | Message: message, 119 | } 120 | } 121 | 122 | func newErrorf(tp ErrorType, format string, args ...interface{}) *Error { 123 | return newError(tp, fmt.Sprintf(format, args...)) 124 | } 125 | 126 | func wrapError(err error) *Error { 127 | ret, ok := err.(*Error) 128 | 129 | if !ok { 130 | return newError(ErrUnknown, err.Error()) 131 | } 132 | 133 | return ret 134 | } 135 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/internalunsafe_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 Dave Collins 2 | 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when the code is not running on Google App Engine, compiled by GopherJS, and 17 | // "-tags safe" is not added to the go build command line. The "disableunsafe" 18 | // tag is deprecated and thus should not be used. 19 | // +build !js,!appengine,!safe,!disableunsafe 20 | 21 | /* 22 | This test file is part of the spew package rather than than the spew_test 23 | package because it needs access to internals to properly test certain cases 24 | which are not possible via the public interface since they should never happen. 25 | */ 26 | 27 | package spew 28 | 29 | import ( 30 | "bytes" 31 | "reflect" 32 | "testing" 33 | "unsafe" 34 | ) 35 | 36 | // changeKind uses unsafe to intentionally change the kind of a reflect.Value to 37 | // the maximum kind value which does not exist. This is needed to test the 38 | // fallback code which punts to the standard fmt library for new types that 39 | // might get added to the language. 40 | func changeKind(v *reflect.Value, readOnly bool) { 41 | rvf := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + offsetFlag)) 42 | *rvf = *rvf | ((1< 0; i-- { 60 | if file[i] == '/' { 61 | short = file[i+1:] 62 | break 63 | } 64 | } 65 | file = short 66 | } 67 | 68 | sb.WriteString(`"caller": "`) 69 | sb.WriteString(file) 70 | sb.WriteByte(':') 71 | sb.AppendIntWidth(line, 0) 72 | sb.WriteString(`", `) 73 | } 74 | 75 | sb.WriteString(`"msg": "`) 76 | encodeStringJSON(sb, message) 77 | sb.WriteByte('"') 78 | 79 | if extra != nil && len(extra) > 0 { 80 | sb.WriteString(`, "extra": {`) 81 | encodeLogMapJSON(sb, extra) 82 | sb.WriteByte('}') 83 | } 84 | 85 | sb.WriteByte('}') 86 | sb.WriteByte('\n') 87 | sb.WriteTo(logger) 88 | } 89 | 90 | func encodeLogMapJSON(w byteSliceWriter, m Map) { 91 | first := true 92 | for k, v := range m { 93 | if first { 94 | first = false 95 | } else { 96 | w.WriteString(`, `) 97 | } 98 | 99 | w.WriteByte('"') 100 | encodeStringJSON(w, k) 101 | w.WriteString(`": "`) 102 | encodeStringJSON(w, fmt.Sprint(v)) 103 | w.WriteByte('"') 104 | } 105 | } 106 | 107 | // modified from Go stdlib: encoding/json/encode.go:787-862 (approx) 108 | func encodeStringJSON(e byteSliceWriter, s string) { 109 | for i := 0; i < len(s); { 110 | if b := s[i]; b < utf8.RuneSelf { 111 | i++ 112 | if 0x20 <= b && b != '\\' && b != '"' { 113 | e.WriteByte(b) 114 | continue 115 | } 116 | 117 | switch b { 118 | case '\\', '"': 119 | e.WriteByte('\\') 120 | e.WriteByte(b) 121 | case '\n': 122 | e.WriteByte('\\') 123 | e.WriteByte('n') 124 | case '\r': 125 | e.WriteByte('\\') 126 | e.WriteByte('r') 127 | case '\t': 128 | e.WriteByte('\\') 129 | e.WriteByte('t') 130 | default: 131 | // This encodes bytes < 0x20 except for escapes above 132 | e.WriteString(`\u00`) 133 | e.WriteByte(hex[b>>4]) 134 | e.WriteByte(hex[b&0xF]) 135 | } 136 | continue 137 | } 138 | 139 | c, size := utf8.DecodeRuneInString(s[i:]) 140 | if c == utf8.RuneError && size == 1 { 141 | e.WriteString(`\ufffd`) 142 | i++ 143 | continue 144 | } 145 | 146 | // U+2028 is LINE SEPARATOR. 147 | // U+2029 is PARAGRAPH SEPARATOR. 148 | // They are both technically valid characters in JSON strings, 149 | // but don't work in JSONP, which has to be evaluated as JavaScript, 150 | // and can lead to security holes there. It is valid JSON to 151 | // escape them, so do so unconditionally. 152 | // See http://timelessrepo.com/json-isnt-a-javascript-subset 153 | if c == '\u2028' || c == '\u2029' { 154 | e.WriteString(`\u202`) 155 | e.WriteByte(hex[c&0xF]) 156 | i += size 157 | continue 158 | } 159 | e.WriteString(s[i : i+size]) 160 | i += size 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/README.md: -------------------------------------------------------------------------------- 1 | # go-toml 2 | 3 | Go library for the [TOML](https://github.com/mojombo/toml) format. 4 | 5 | This library supports TOML version 6 | [v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md) 7 | 8 | [![GoDoc](https://godoc.org/github.com/pelletier/go-toml?status.svg)](http://godoc.org/github.com/pelletier/go-toml) 9 | [![license](https://img.shields.io/github/license/pelletier/go-toml.svg)](https://github.com/pelletier/go-toml/blob/master/LICENSE) 10 | [![Build Status](https://travis-ci.org/pelletier/go-toml.svg?branch=master)](https://travis-ci.org/pelletier/go-toml) 11 | [![Coverage Status](https://coveralls.io/repos/github/pelletier/go-toml/badge.svg?branch=master)](https://coveralls.io/github/pelletier/go-toml?branch=master) 12 | [![Go Report Card](https://goreportcard.com/badge/github.com/pelletier/go-toml)](https://goreportcard.com/report/github.com/pelletier/go-toml) 13 | 14 | ## Features 15 | 16 | Go-toml provides the following features for using data parsed from TOML documents: 17 | 18 | * Load TOML documents from files and string data 19 | * Easily navigate TOML structure using Tree 20 | * Mashaling and unmarshaling to and from data structures 21 | * Line & column position data for all parsed elements 22 | * [Query support similar to JSON-Path](query/) 23 | * Syntax errors contain line and column numbers 24 | 25 | ## Import 26 | 27 | ```go 28 | import "github.com/pelletier/go-toml" 29 | ``` 30 | 31 | ## Usage example 32 | 33 | Read a TOML document: 34 | 35 | ```go 36 | config, _ := toml.Load(` 37 | [postgres] 38 | user = "pelletier" 39 | password = "mypassword"`) 40 | // retrieve data directly 41 | user := config.Get("postgres.user").(string) 42 | 43 | // or using an intermediate object 44 | postgresConfig := config.Get("postgres").(*toml.Tree) 45 | password := postgresConfig.Get("password").(string) 46 | ``` 47 | 48 | Or use Unmarshal: 49 | 50 | ```go 51 | type Postgres struct { 52 | User string 53 | Password string 54 | } 55 | type Config struct { 56 | Postgres Postgres 57 | } 58 | 59 | doc := []byte(` 60 | [Postgres] 61 | User = "pelletier" 62 | Password = "mypassword"`) 63 | 64 | config := Config{} 65 | toml.Unmarshal(doc, &config) 66 | fmt.Println("user=", config.Postgres.User) 67 | ``` 68 | 69 | Or use a query: 70 | 71 | ```go 72 | // use a query to gather elements without walking the tree 73 | q, _ := query.Compile("$..[user,password]") 74 | results := q.Execute(config) 75 | for ii, item := range results.Values() { 76 | fmt.Println("Query result %d: %v", ii, item) 77 | } 78 | ``` 79 | 80 | ## Documentation 81 | 82 | The documentation and additional examples are available at 83 | [godoc.org](http://godoc.org/github.com/pelletier/go-toml). 84 | 85 | ## Tools 86 | 87 | Go-toml provides two handy command line tools: 88 | 89 | * `tomll`: Reads TOML files and lint them. 90 | 91 | ``` 92 | go install github.com/pelletier/go-toml/cmd/tomll 93 | tomll --help 94 | ``` 95 | * `tomljson`: Reads a TOML file and outputs its JSON representation. 96 | 97 | ``` 98 | go install github.com/pelletier/go-toml/cmd/tomljson 99 | tomljson --help 100 | ``` 101 | 102 | ## Contribute 103 | 104 | Feel free to report bugs and patches using GitHub's pull requests system on 105 | [pelletier/go-toml](https://github.com/pelletier/go-toml). Any feedback would be 106 | much appreciated! 107 | 108 | ### Run tests 109 | 110 | You have to make sure two kind of tests run: 111 | 112 | 1. The Go unit tests 113 | 2. The TOML examples base 114 | 115 | You can run both of them using `./test.sh`. 116 | 117 | ### Fuzzing 118 | 119 | The script `./fuzz.sh` is available to 120 | run [go-fuzz](https://github.com/dvyukov/go-fuzz) on go-toml. 121 | 122 | ## Versioning 123 | 124 | Go-toml follows [Semantic Versioning](http://semver.org/). The supported version 125 | of [TOML](https://github.com/toml-lang/toml) is indicated at the beginning of 126 | this document. The last two major versions of Go are supported 127 | (see [Go Release Policy](https://golang.org/doc/devel/release.html#policy)). 128 | 129 | ## License 130 | 131 | The MIT License (MIT). Read [LICENSE](LICENSE). 132 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/dumpcgo_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013-2016 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when both cgo is supported and "-tags testcgo" is added to the go test 17 | // command line. This means the cgo tests are only added (and hence run) when 18 | // specifially requested. This configuration is used because spew itself 19 | // does not require cgo to run even though it does handle certain cgo types 20 | // specially. Rather than forcing all clients to require cgo and an external 21 | // C compiler just to run the tests, this scheme makes them optional. 22 | // +build cgo,testcgo 23 | 24 | package spew_test 25 | 26 | import ( 27 | "fmt" 28 | 29 | "github.com/davecgh/go-spew/spew/testdata" 30 | ) 31 | 32 | func addCgoDumpTests() { 33 | // C char pointer. 34 | v := testdata.GetCgoCharPointer() 35 | nv := testdata.GetCgoNullCharPointer() 36 | pv := &v 37 | vcAddr := fmt.Sprintf("%p", v) 38 | vAddr := fmt.Sprintf("%p", pv) 39 | pvAddr := fmt.Sprintf("%p", &pv) 40 | vt := "*testdata._Ctype_char" 41 | vs := "116" 42 | addDumpTest(v, "("+vt+")("+vcAddr+")("+vs+")\n") 43 | addDumpTest(pv, "(*"+vt+")("+vAddr+"->"+vcAddr+")("+vs+")\n") 44 | addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+"->"+vcAddr+")("+vs+")\n") 45 | addDumpTest(nv, "("+vt+")()\n") 46 | 47 | // C char array. 48 | v2, v2l, v2c := testdata.GetCgoCharArray() 49 | v2Len := fmt.Sprintf("%d", v2l) 50 | v2Cap := fmt.Sprintf("%d", v2c) 51 | v2t := "[6]testdata._Ctype_char" 52 | v2s := "(len=" + v2Len + " cap=" + v2Cap + ") " + 53 | "{\n 00000000 74 65 73 74 32 00 " + 54 | " |test2.|\n}" 55 | addDumpTest(v2, "("+v2t+") "+v2s+"\n") 56 | 57 | // C unsigned char array. 58 | v3, v3l, v3c := testdata.GetCgoUnsignedCharArray() 59 | v3Len := fmt.Sprintf("%d", v3l) 60 | v3Cap := fmt.Sprintf("%d", v3c) 61 | v3t := "[6]testdata._Ctype_unsignedchar" 62 | v3t2 := "[6]testdata._Ctype_uchar" 63 | v3s := "(len=" + v3Len + " cap=" + v3Cap + ") " + 64 | "{\n 00000000 74 65 73 74 33 00 " + 65 | " |test3.|\n}" 66 | addDumpTest(v3, "("+v3t+") "+v3s+"\n", "("+v3t2+") "+v3s+"\n") 67 | 68 | // C signed char array. 69 | v4, v4l, v4c := testdata.GetCgoSignedCharArray() 70 | v4Len := fmt.Sprintf("%d", v4l) 71 | v4Cap := fmt.Sprintf("%d", v4c) 72 | v4t := "[6]testdata._Ctype_schar" 73 | v4t2 := "testdata._Ctype_schar" 74 | v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " + 75 | "{\n (" + v4t2 + ") 116,\n (" + v4t2 + ") 101,\n (" + v4t2 + 76 | ") 115,\n (" + v4t2 + ") 116,\n (" + v4t2 + ") 52,\n (" + v4t2 + 77 | ") 0\n}" 78 | addDumpTest(v4, "("+v4t+") "+v4s+"\n") 79 | 80 | // C uint8_t array. 81 | v5, v5l, v5c := testdata.GetCgoUint8tArray() 82 | v5Len := fmt.Sprintf("%d", v5l) 83 | v5Cap := fmt.Sprintf("%d", v5c) 84 | v5t := "[6]testdata._Ctype_uint8_t" 85 | v5s := "(len=" + v5Len + " cap=" + v5Cap + ") " + 86 | "{\n 00000000 74 65 73 74 35 00 " + 87 | " |test5.|\n}" 88 | addDumpTest(v5, "("+v5t+") "+v5s+"\n") 89 | 90 | // C typedefed unsigned char array. 91 | v6, v6l, v6c := testdata.GetCgoTypdefedUnsignedCharArray() 92 | v6Len := fmt.Sprintf("%d", v6l) 93 | v6Cap := fmt.Sprintf("%d", v6c) 94 | v6t := "[6]testdata._Ctype_custom_uchar_t" 95 | v6s := "(len=" + v6Len + " cap=" + v6Cap + ") " + 96 | "{\n 00000000 74 65 73 74 36 00 " + 97 | " |test6.|\n}" 98 | addDumpTest(v6, "("+v6t+") "+v6s+"\n") 99 | } 100 | -------------------------------------------------------------------------------- /pkg/camo/encoding/url.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2018 Eli Janssen 2 | // Use of this source code is governed by an MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package encoding 6 | 7 | import ( 8 | "crypto/hmac" 9 | "crypto/sha1" 10 | "crypto/subtle" 11 | "encoding/base64" 12 | "encoding/hex" 13 | "fmt" 14 | "strings" 15 | 16 | "github.com/cactus/mlog" 17 | ) 18 | 19 | // DecoderFunc is a function type that defines a url decoder. 20 | type DecoderFunc func([]byte, string, string) (string, error) 21 | 22 | // EncoderFunc is a function type that defines a url encoder. 23 | type EncoderFunc func([]byte, string) string 24 | 25 | func validateURL(hmackey *[]byte, macbytes *[]byte, urlbytes *[]byte) error { 26 | mac := hmac.New(sha1.New, *hmackey) 27 | mac.Write(*urlbytes) 28 | macSum := mac.Sum(nil) 29 | 30 | // ensure lengths are equal. if not, return false 31 | if len(macSum) != len(*macbytes) { 32 | return fmt.Errorf("mismatched length") 33 | } 34 | 35 | if subtle.ConstantTimeCompare(macSum, *macbytes) != 1 { 36 | return fmt.Errorf("invalid mac") 37 | } 38 | return nil 39 | } 40 | 41 | func b64encode(data []byte) string { 42 | return strings.TrimRight(base64.URLEncoding.EncodeToString(data), "=") 43 | } 44 | 45 | func b64decode(str string) ([]byte, error) { 46 | padChars := (4 - (len(str) % 4)) % 4 47 | for i := 0; i < padChars; i++ { 48 | str = str + "=" 49 | } 50 | decBytes, ok := base64.URLEncoding.DecodeString(str) 51 | return decBytes, ok 52 | } 53 | 54 | // HexDecodeURL ensures the url is properly verified via HMAC, and then 55 | // unencodes the url, returning the url (if valid) and whether the 56 | // HMAC was verified. 57 | func HexDecodeURL(hmackey []byte, hexdig string, hexURL string) (string, error) { 58 | urlBytes, err := hex.DecodeString(hexURL) 59 | if err != nil { 60 | return "", fmt.Errorf("bad url decode") 61 | } 62 | macBytes, err := hex.DecodeString(hexdig) 63 | if err != nil { 64 | return "", fmt.Errorf("bad mac decode") 65 | } 66 | 67 | if err = validateURL(&hmackey, &macBytes, &urlBytes); err != nil { 68 | return "", fmt.Errorf("invalid signature: %s", err) 69 | } 70 | return string(urlBytes), nil 71 | } 72 | 73 | // HexEncodeURL takes an HMAC key and a url, and returns url 74 | // path partial consisitent of signature and encoded url. 75 | func HexEncodeURL(hmacKey []byte, oURL string) string { 76 | oBytes := []byte(oURL) 77 | mac := hmac.New(sha1.New, hmacKey) 78 | mac.Write(oBytes) 79 | macSum := hex.EncodeToString(mac.Sum(nil)) 80 | encodedURL := hex.EncodeToString(oBytes) 81 | hexURL := "/" + macSum + "/" + encodedURL 82 | return hexURL 83 | } 84 | 85 | // B64DecodeURL ensures the url is properly verified via HMAC, and then 86 | // unencodes the url, returning the url (if valid) and whether the 87 | // HMAC was verified. 88 | func B64DecodeURL(hmackey []byte, encdig string, encURL string) (string, error) { 89 | urlBytes, err := b64decode(encURL) 90 | if err != nil { 91 | return "", fmt.Errorf("bad url decode") 92 | } 93 | macBytes, err := b64decode(encdig) 94 | if err != nil { 95 | return "", fmt.Errorf("bad mac decode") 96 | } 97 | 98 | if err := validateURL(&hmackey, &macBytes, &urlBytes); err != nil { 99 | return "", fmt.Errorf("invalid signature: %s", err) 100 | } 101 | return string(urlBytes), nil 102 | } 103 | 104 | // B64EncodeURL takes an HMAC key and a url, and returns url 105 | // path partial consisitent of signature and encoded url. 106 | func B64EncodeURL(hmacKey []byte, oURL string) string { 107 | oBytes := []byte(oURL) 108 | mac := hmac.New(sha1.New, hmacKey) 109 | mac.Write(oBytes) 110 | macSum := b64encode(mac.Sum(nil)) 111 | encodedURL := b64encode(oBytes) 112 | encURL := "/" + macSum + "/" + encodedURL 113 | return encURL 114 | } 115 | 116 | // DecodeURL ensures the url is properly verified via HMAC, and then 117 | // unencodes the url, returning the url (if valid) and whether the 118 | // HMAC was verified. Tries either HexDecode or B64Decode, depending on the 119 | // length of the encoded hmac. 120 | func DecodeURL(hmackey []byte, encdig string, encURL string) (string, bool) { 121 | var decoder DecoderFunc 122 | if len(encdig) == 40 { 123 | decoder = HexDecodeURL 124 | } else { 125 | decoder = B64DecodeURL 126 | } 127 | 128 | urlBytes, err := decoder(hmackey, encdig, encURL) 129 | if err != nil { 130 | mlog.Debugf("Bad Decode of URL: %s", err) 131 | return "", false 132 | } 133 | return urlBytes, true 134 | } 135 | -------------------------------------------------------------------------------- /vendor/github.com/pelletier/go-toml/benchmark.json: -------------------------------------------------------------------------------- 1 | { 2 | "array": { 3 | "key1": [ 4 | 1, 5 | 2, 6 | 3 7 | ], 8 | "key2": [ 9 | "red", 10 | "yellow", 11 | "green" 12 | ], 13 | "key3": [ 14 | [ 15 | 1, 16 | 2 17 | ], 18 | [ 19 | 3, 20 | 4, 21 | 5 22 | ] 23 | ], 24 | "key4": [ 25 | [ 26 | 1, 27 | 2 28 | ], 29 | [ 30 | "a", 31 | "b", 32 | "c" 33 | ] 34 | ], 35 | "key5": [ 36 | 1, 37 | 2, 38 | 3 39 | ], 40 | "key6": [ 41 | 1, 42 | 2 43 | ] 44 | }, 45 | "boolean": { 46 | "False": false, 47 | "True": true 48 | }, 49 | "datetime": { 50 | "key1": "1979-05-27T07:32:00Z", 51 | "key2": "1979-05-27T00:32:00-07:00", 52 | "key3": "1979-05-27T00:32:00.999999-07:00" 53 | }, 54 | "float": { 55 | "both": { 56 | "key": 6.626e-34 57 | }, 58 | "exponent": { 59 | "key1": 5e+22, 60 | "key2": 1000000, 61 | "key3": -0.02 62 | }, 63 | "fractional": { 64 | "key1": 1, 65 | "key2": 3.1415, 66 | "key3": -0.01 67 | }, 68 | "underscores": { 69 | "key1": 9224617.445991227, 70 | "key2": 1e+100 71 | } 72 | }, 73 | "fruit": [{ 74 | "name": "apple", 75 | "physical": { 76 | "color": "red", 77 | "shape": "round" 78 | }, 79 | "variety": [{ 80 | "name": "red delicious" 81 | }, 82 | { 83 | "name": "granny smith" 84 | } 85 | ] 86 | }, 87 | { 88 | "name": "banana", 89 | "variety": [{ 90 | "name": "plantain" 91 | }] 92 | } 93 | ], 94 | "integer": { 95 | "key1": 99, 96 | "key2": 42, 97 | "key3": 0, 98 | "key4": -17, 99 | "underscores": { 100 | "key1": 1000, 101 | "key2": 5349221, 102 | "key3": 12345 103 | } 104 | }, 105 | "products": [{ 106 | "name": "Hammer", 107 | "sku": 738594937 108 | }, 109 | {}, 110 | { 111 | "color": "gray", 112 | "name": "Nail", 113 | "sku": 284758393 114 | } 115 | ], 116 | "string": { 117 | "basic": { 118 | "basic": "I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF." 119 | }, 120 | "literal": { 121 | "multiline": { 122 | "lines": "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", 123 | "regex2": "I [dw]on't need \\d{2} apples" 124 | }, 125 | "quoted": "Tom \"Dubs\" Preston-Werner", 126 | "regex": "\u003c\\i\\c*\\s*\u003e", 127 | "winpath": "C:\\Users\\nodejs\\templates", 128 | "winpath2": "\\\\ServerX\\admin$\\system32\\" 129 | }, 130 | "multiline": { 131 | "continued": { 132 | "key1": "The quick brown fox jumps over the lazy dog.", 133 | "key2": "The quick brown fox jumps over the lazy dog.", 134 | "key3": "The quick brown fox jumps over the lazy dog." 135 | }, 136 | "key1": "One\nTwo", 137 | "key2": "One\nTwo", 138 | "key3": "One\nTwo" 139 | } 140 | }, 141 | "table": { 142 | "inline": { 143 | "name": { 144 | "first": "Tom", 145 | "last": "Preston-Werner" 146 | }, 147 | "point": { 148 | "x": 1, 149 | "y": 2 150 | } 151 | }, 152 | "key": "value", 153 | "subtable": { 154 | "key": "another value" 155 | } 156 | }, 157 | "x": { 158 | "y": { 159 | "z": { 160 | "w": {} 161 | } 162 | } 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /vendor/github.com/jessevdk/go-flags/assert_test.go: -------------------------------------------------------------------------------- 1 | package flags 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "io/ioutil" 7 | "os" 8 | "os/exec" 9 | "path" 10 | "runtime" 11 | "testing" 12 | ) 13 | 14 | func assertCallerInfo() (string, int) { 15 | ptr := make([]uintptr, 15) 16 | n := runtime.Callers(1, ptr) 17 | 18 | if n == 0 { 19 | return "", 0 20 | } 21 | 22 | mef := runtime.FuncForPC(ptr[0]) 23 | mefile, meline := mef.FileLine(ptr[0]) 24 | 25 | for i := 2; i < n; i++ { 26 | f := runtime.FuncForPC(ptr[i]) 27 | file, line := f.FileLine(ptr[i]) 28 | 29 | if file != mefile { 30 | return file, line 31 | } 32 | } 33 | 34 | return mefile, meline 35 | } 36 | 37 | func assertErrorf(t *testing.T, format string, args ...interface{}) { 38 | msg := fmt.Sprintf(format, args...) 39 | 40 | file, line := assertCallerInfo() 41 | 42 | t.Errorf("%s:%d: %s", path.Base(file), line, msg) 43 | } 44 | 45 | func assertFatalf(t *testing.T, format string, args ...interface{}) { 46 | msg := fmt.Sprintf(format, args...) 47 | 48 | file, line := assertCallerInfo() 49 | 50 | t.Fatalf("%s:%d: %s", path.Base(file), line, msg) 51 | } 52 | 53 | func assertString(t *testing.T, a string, b string) { 54 | if a != b { 55 | assertErrorf(t, "Expected %#v, but got %#v", b, a) 56 | } 57 | } 58 | 59 | func assertStringArray(t *testing.T, a []string, b []string) { 60 | if len(a) != len(b) { 61 | assertErrorf(t, "Expected %#v, but got %#v", b, a) 62 | return 63 | } 64 | 65 | for i, v := range a { 66 | if b[i] != v { 67 | assertErrorf(t, "Expected %#v, but got %#v", b, a) 68 | return 69 | } 70 | } 71 | } 72 | 73 | func assertBoolArray(t *testing.T, a []bool, b []bool) { 74 | if len(a) != len(b) { 75 | assertErrorf(t, "Expected %#v, but got %#v", b, a) 76 | return 77 | } 78 | 79 | for i, v := range a { 80 | if b[i] != v { 81 | assertErrorf(t, "Expected %#v, but got %#v", b, a) 82 | return 83 | } 84 | } 85 | } 86 | 87 | func assertParserSuccess(t *testing.T, data interface{}, args ...string) (*Parser, []string) { 88 | parser := NewParser(data, Default&^PrintErrors) 89 | ret, err := parser.ParseArgs(args) 90 | 91 | if err != nil { 92 | t.Fatalf("Unexpected parse error: %s", err) 93 | return nil, nil 94 | } 95 | 96 | return parser, ret 97 | } 98 | 99 | func assertParseSuccess(t *testing.T, data interface{}, args ...string) []string { 100 | _, ret := assertParserSuccess(t, data, args...) 101 | return ret 102 | } 103 | 104 | func assertError(t *testing.T, err error, typ ErrorType, msg string) { 105 | if err == nil { 106 | assertFatalf(t, "Expected error: %s", msg) 107 | return 108 | } 109 | 110 | if e, ok := err.(*Error); !ok { 111 | assertFatalf(t, "Expected Error type, but got %#v", err) 112 | } else { 113 | if e.Type != typ { 114 | assertErrorf(t, "Expected error type {%s}, but got {%s}", typ, e.Type) 115 | } 116 | 117 | if e.Message != msg { 118 | assertErrorf(t, "Expected error message %#v, but got %#v", msg, e.Message) 119 | } 120 | } 121 | } 122 | 123 | func assertParseFail(t *testing.T, typ ErrorType, msg string, data interface{}, args ...string) []string { 124 | parser := NewParser(data, Default&^PrintErrors) 125 | ret, err := parser.ParseArgs(args) 126 | 127 | assertError(t, err, typ, msg) 128 | return ret 129 | } 130 | 131 | func diff(a, b string) (string, error) { 132 | atmp, err := ioutil.TempFile("", "help-diff") 133 | 134 | if err != nil { 135 | return "", err 136 | } 137 | 138 | btmp, err := ioutil.TempFile("", "help-diff") 139 | 140 | if err != nil { 141 | return "", err 142 | } 143 | 144 | if _, err := io.WriteString(atmp, a); err != nil { 145 | return "", err 146 | } 147 | 148 | if _, err := io.WriteString(btmp, b); err != nil { 149 | return "", err 150 | } 151 | 152 | ret, err := exec.Command("diff", "-u", "-d", "--label", "got", atmp.Name(), "--label", "expected", btmp.Name()).Output() 153 | 154 | os.Remove(atmp.Name()) 155 | os.Remove(btmp.Name()) 156 | 157 | if err.Error() == "exit status 1" { 158 | return string(ret), nil 159 | } 160 | 161 | return string(ret), err 162 | } 163 | 164 | func assertDiff(t *testing.T, actual, expected, msg string) { 165 | if actual == expected { 166 | return 167 | } 168 | 169 | ret, err := diff(actual, expected) 170 | 171 | if err != nil { 172 | assertErrorf(t, "Unexpected diff error: %s", err) 173 | assertErrorf(t, "Unexpected %s, expected:\n\n%s\n\nbut got\n\n%s", msg, expected, actual) 174 | } else { 175 | assertErrorf(t, "Unexpected %s:\n\n%s", msg, ret) 176 | } 177 | } 178 | --------------------------------------------------------------------------------