diff --git a/vendor/github.com/Unknwon/com/.gitignore b/vendor/github.com/Unknwon/com/.gitignore deleted file mode 100644 index 0da157fe9ce..00000000000 --- a/vendor/github.com/Unknwon/com/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test -.idea - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.iml diff --git a/vendor/github.com/Unknwon/com/README.md b/vendor/github.com/Unknwon/com/README.md index 55d01d62137..8d821abd65e 100644 --- a/vendor/github.com/Unknwon/com/README.md +++ b/vendor/github.com/Unknwon/com/README.md @@ -1,7 +1,7 @@ -Common functions -=== +Common Functions +================ -[![Build Status](https://drone.io/github.com/Unknwon/com/status.png)](https://drone.io/github.com/Unknwon/com/latest) [![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/Unknwon/com) +[![Build Status](https://travis-ci.org/Unknwon/com.svg)](https://travis-ci.org/Unknwon/com) [![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/Unknwon/com) This is an open source project for commonly used functions for the Go programming language. @@ -17,8 +17,4 @@ Your contribute is welcome, but you have to check following steps after you adde 2. Make sure you wrote test cases with any possible condition for **all functions** in file `*_test.go`. 3. Make sure you wrote benchmarks for **all functions** in file `*_test.go`. 4. Make sure you wrote useful examples for **all functions** in file `example_test.go`. -5. Make sure you ran `go test -bench="."` and got **PASS** . - -## Performance - -See results on [drone.io](https://drone.io/github.com/Unknwon/com/latest) by `go test -bench="."`. +5. Make sure you ran `go test` and got **PASS** . diff --git a/vendor/github.com/Unknwon/com/cmd_test.go b/vendor/github.com/Unknwon/com/cmd_test.go deleted file mode 100644 index 97ad78f2e5c..00000000000 --- a/vendor/github.com/Unknwon/com/cmd_test.go +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2013 com authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package com - -import ( - "fmt" - "runtime" - "strings" - "testing" -) - -func TestColorLogS(t *testing.T) { - if runtime.GOOS != "windows" { - // Trace + path. - cls := ColorLogS("[TRAC] Trace level test with path( %s )", "/path/to/somethere") - clsR := fmt.Sprintf( - "[\033[%dmTRAC%s] Trace level test with path(\033[%dm%s%s)", - Blue, EndColor, Yellow, "/path/to/somethere", EndColor) - if cls != clsR { - t.Errorf("ColorLogS:\n Expect => %s\n Got => %s\n", clsR, cls) - } - - // Error + error. - cls = ColorLogS("[ERRO] Error level test with error[ %s ]", "test error") - clsR = fmt.Sprintf( - "[\033[%dmERRO%s] Error level test with error[\033[%dm%s%s]", - Red, EndColor, Red, "test error", EndColor) - if cls != clsR { - t.Errorf("ColorLogS:\n Expect => %s\n Got => %s\n", clsR, cls) - } - - // Warning + highlight. - cls = ColorLogS("[WARN] Warnning level test with highlight # %s #", "special offer!") - clsR = fmt.Sprintf( - "[\033[%dmWARN%s] Warnning level test with highlight \033[%dm%s%s", - Magenta, EndColor, Gray, "special offer!", EndColor) - if cls != clsR { - t.Errorf("ColorLogS:\n Expect => %s\n Got => %s\n", clsR, cls) - } - - // Success. - cls = ColorLogS("[SUCC] Success level test") - clsR = fmt.Sprintf( - "[\033[%dmSUCC%s] Success level test", - Green, EndColor) - if cls != clsR { - t.Errorf("ColorLogS:\n Expect => %s\n Got => %s\n", clsR, cls) - } - - // Default. - cls = ColorLogS("[INFO] Default level test") - clsR = fmt.Sprintf( - "[INFO] Default level test") - if cls != clsR { - t.Errorf("ColorLogS:\n Expect => %s\n Got => %s\n", clsR, cls) - } - } else { - // Trace + path. - cls := ColorLogS("[TRAC] Trace level test with path( %s )", "/path/to/somethere") - clsR := fmt.Sprintf( - "[TRAC] Trace level test with path(%s)", - "/path/to/somethere") - if cls != clsR { - t.Errorf("ColorLogS:\n Expect => %s\n Got => %s\n", clsR, cls) - } - - // Error + error. - cls = ColorLogS("[ERRO] Error level test with error[ %s ]", "test error") - clsR = fmt.Sprintf( - "[ERRO] Error level test with error[%s]", - "test error") - if cls != clsR { - t.Errorf("ColorLogS:\n Expect => %s\n Got => %s\n", clsR, cls) - } - - // Warning + highlight. - cls = ColorLogS("[WARN] Warnning level test with highlight # %s #", "special offer!") - clsR = fmt.Sprintf( - "[WARN] Warnning level test with highlight %s", - "special offer!") - if cls != clsR { - t.Errorf("ColorLogS:\n Expect => %s\n Got => %s\n", clsR, cls) - } - - // Success. - cls = ColorLogS("[SUCC] Success level test") - clsR = fmt.Sprintf( - "[SUCC] Success level test") - if cls != clsR { - t.Errorf("ColorLogS:\n Expect => %s\n Got => %s\n", clsR, cls) - } - - // Default. - cls = ColorLogS("[INFO] Default level test") - clsR = fmt.Sprintf( - "[INFO] Default level test") - if cls != clsR { - t.Errorf("ColorLogS:\n Expect => %s\n Got => %s\n", clsR, cls) - } - } -} - -func TestExecCmd(t *testing.T) { - stdout, stderr, err := ExecCmd("go", "help", "get") - if err != nil { - t.Errorf("ExecCmd:\n Expect => %v\n Got => %v\n", nil, err) - } else if len(stderr) != 0 { - t.Errorf("ExecCmd:\n Expect => %s\n Got => %s\n", "", stderr) - } else if !strings.HasPrefix(stdout, "usage: go get") { - t.Errorf("ExecCmd:\n Expect => %s\n Got => %s\n", "usage: go get", stdout) - } -} - -func BenchmarkColorLogS(b *testing.B) { - log := fmt.Sprintf( - "[WARN] This is a tesing log that should be colored, path( %s ),"+ - " highlight # %s #, error [ %s ].", - "path to somewhere", "highlighted content", "tesing error") - for i := 0; i < b.N; i++ { - ColorLogS(log) - } -} - -func BenchmarkExecCmd(b *testing.B) { - for i := 0; i < b.N; i++ { - ExecCmd("go", "help", "get") - } -} diff --git a/vendor/github.com/Unknwon/com/convert.go b/vendor/github.com/Unknwon/com/convert.go index 9c3af84aa18..25b3e0e5620 100644 --- a/vendor/github.com/Unknwon/com/convert.go +++ b/vendor/github.com/Unknwon/com/convert.go @@ -32,7 +32,7 @@ func (f StrTo) Uint8() (uint8, error) { } func (f StrTo) Int() (int, error) { - v, err := strconv.ParseInt(f.String(), 10, 32) + v, err := strconv.ParseInt(f.String(), 10, 0) return int(v), err } diff --git a/vendor/github.com/Unknwon/com/convert_test.go b/vendor/github.com/Unknwon/com/convert_test.go deleted file mode 100644 index e97e27f42e5..00000000000 --- a/vendor/github.com/Unknwon/com/convert_test.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2014 com authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package com - -import ( - "testing" - - . "github.com/smartystreets/goconvey/convey" -) - -func TestHexStr2int(t *testing.T) { - Convey("Convert hex format string to decimal", t, func() { - hexDecs := map[string]int{ - "1": 1, - "002": 2, - "011": 17, - "0a1": 161, - "35e": 862, - } - - for hex, dec := range hexDecs { - val, err := HexStr2int(hex) - So(err, ShouldBeNil) - So(val, ShouldEqual, dec) - } - }) -} - -func TestInt2HexStr(t *testing.T) { - Convey("Convert decimal to hex format string", t, func() { - decHexs := map[int]string{ - 1: "1", - 2: "2", - 17: "11", - 161: "a1", - 862: "35e", - } - - for dec, hex := range decHexs { - val := Int2HexStr(dec) - So(val, ShouldEqual, hex) - } - }) -} diff --git a/vendor/github.com/Unknwon/com/dir_test.go b/vendor/github.com/Unknwon/com/dir_test.go deleted file mode 100644 index c6fbf9d27d3..00000000000 --- a/vendor/github.com/Unknwon/com/dir_test.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2013 com authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package com - -import ( - "os" - "testing" - - . "github.com/smartystreets/goconvey/convey" -) - -func TestIsDir(t *testing.T) { - Convey("Check if given path is a directory", t, func() { - Convey("Pass a file name", func() { - So(IsDir("file.go"), ShouldEqual, false) - }) - Convey("Pass a directory name", func() { - So(IsDir("testdata"), ShouldEqual, true) - }) - Convey("Pass a invalid path", func() { - So(IsDir("foo"), ShouldEqual, false) - }) - }) -} - -func TestCopyDir(t *testing.T) { - Convey("Items of two slices should be same", t, func() { - s1, err := StatDir("testdata", true) - So(err, ShouldEqual, nil) - - err = CopyDir("testdata", "testdata2") - So(err, ShouldEqual, nil) - - s2, err := StatDir("testdata2", true) - os.RemoveAll("testdata2") - So(err, ShouldEqual, nil) - - So(CompareSliceStr(s1, s2), ShouldEqual, true) - }) -} - -func BenchmarkIsDir(b *testing.B) { - for i := 0; i < b.N; i++ { - IsDir("file.go") - } -} diff --git a/vendor/github.com/Unknwon/com/example_test.go b/vendor/github.com/Unknwon/com/example_test.go deleted file mode 100644 index bc1930bf84a..00000000000 --- a/vendor/github.com/Unknwon/com/example_test.go +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright 2013 com authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package com_test - -import ( - "fmt" - "io/ioutil" - "net/http" - - "github.com/Unknwon/com" -) - -// ------------------------------ -// cmd.go -// ------------------------------ - -func ExampleColorLogS() { - coloredLog := com.ColorLogS(fmt.Sprintf( - "[WARN] This is a tesing log that should be colored, path( %s ),"+ - " highlight # %s #, error [ %s ].", - "path to somewhere", "highlighted content", "tesing error")) - fmt.Println(coloredLog) -} - -func ExampleColorLog() { - com.ColorLog(fmt.Sprintf( - "[WARN] This is a tesing log that should be colored, path( %s ),"+ - " highlight # %s #, error [ %s ].", - "path to somewhere", "highlighted content", "tesing error")) -} - -func ExampleExecCmd() { - stdout, stderr, err := com.ExecCmd("go", "help", "get") - fmt.Println(stdout, stderr, err) -} - -// ------------- END ------------ - -// ------------------------------ -// html.go -// ------------------------------ - -func ExampleHtml2JS() { - htm := "
Click me
\n\r" - js := string(com.Html2JS([]byte(htm))) - fmt.Println(js) - // Output:
Click me
\n -} - -// ------------- END ------------ - -// ------------------------------ -// path.go -// ------------------------------ - -func ExampleGetGOPATHs() { - gps := com.GetGOPATHs() - fmt.Println(gps) -} - -func ExampleGetSrcPath() { - srcPath, err := com.GetSrcPath("github.com/Unknwon/com") - if err != nil { - fmt.Println(err) - return - } - fmt.Println(srcPath) -} - -func ExampleHomeDir() { - hd, err := com.HomeDir() - fmt.Println(hd, err) -} - -// ------------- END ------------ - -// ------------------------------ -// file.go -// ------------------------------ - -func ExampleIsFile() { - if com.IsFile("file.go") { - fmt.Println("file.go exists") - return - } - fmt.Println("file.go is not a file or does not exist") -} - -func ExampleIsExist() { - if com.IsExist("file.go") { - fmt.Println("file.go exists") - return - } - fmt.Println("file.go does not exist") -} - -// ------------- END ------------ - -// ------------------------------ -// dir.go -// ------------------------------ - -func ExampleIsDir() { - if com.IsDir("files") { - fmt.Println("directory 'files' exists") - return - } - fmt.Println("'files' is not a directory or does not exist") -} - -// ------------- END ------------ - -// ------------------------------ -// string.go -// ------------------------------ - -func ExampleIsLetter() { - fmt.Println(com.IsLetter('1')) - fmt.Println(com.IsLetter('[')) - fmt.Println(com.IsLetter('a')) - fmt.Println(com.IsLetter('Z')) - // Output: - // false - // false - // true - // true -} - -func ExampleExpand() { - match := map[string]string{ - "domain": "gowalker.org", - "subdomain": "github.com", - } - s := "http://{domain}/{subdomain}/{0}/{1}" - fmt.Println(com.Expand(s, match, "Unknwon", "gowalker")) - // Output: http://gowalker.org/github.com/Unknwon/gowalker -} - -// ------------- END ------------ - -// ------------------------------ -// http.go -// ------------------------------ - -func ExampleHttpGet() ([]byte, error) { - rc, err := com.HttpGet(&http.Client{}, "http://gowalker.org", nil) - if err != nil { - return nil, err - } - p, err := ioutil.ReadAll(rc) - rc.Close() - return p, err -} - -func ExampleHttpGetBytes() ([]byte, error) { - p, err := com.HttpGetBytes(&http.Client{}, "http://gowalker.org", nil) - return p, err -} - -func ExampleHttpGetJSON() interface{} { - j := com.HttpGetJSON(&http.Client{}, "http://gowalker.org", nil) - return j -} - -type rawFile struct { - name string - rawURL string - data []byte -} - -func (rf *rawFile) Name() string { - return rf.name -} - -func (rf *rawFile) RawUrl() string { - return rf.rawURL -} - -func (rf *rawFile) Data() []byte { - return rf.data -} - -func (rf *rawFile) SetData(p []byte) { - rf.data = p -} - -func ExampleFetchFiles() { - // Code that should be outside of your function body. - // type rawFile struct { - // name string - // rawURL string - // data []byte - // } - - // func (rf *rawFile) Name() string { - // return rf.name - // } - - // func (rf *rawFile) RawUrl() string { - // return rf.rawURL - // } - - // func (rf *rawFile) Data() []byte { - // return rf.data - // } - - // func (rf *rawFile) SetData(p []byte) { - // rf.data = p - // } - - files := []com.RawFile{ - &rawFile{rawURL: "http://example.com"}, - &rawFile{rawURL: "http://example.com/foo"}, - } - err := com.FetchFiles(&http.Client{}, files, nil) - fmt.Println(err, len(files[0].Data()), len(files[1].Data())) -} - -func ExampleFetchFilesCurl() { - // Code that should be outside of your function body. - // type rawFile struct { - // name string - // rawURL string - // data []byte - // } - - // func (rf *rawFile) Name() string { - // return rf.name - // } - - // func (rf *rawFile) RawUrl() string { - // return rf.rawURL - // } - - // func (rf *rawFile) Data() []byte { - // return rf.data - // } - - // func (rf *rawFile) SetData(p []byte) { - // rf.data = p - // } - - files := []com.RawFile{ - &rawFile{rawURL: "http://example.com"}, - &rawFile{rawURL: "http://example.com/foo"}, - } - err := com.FetchFilesCurl(files) - fmt.Println(err, len(files[0].Data()), len(files[1].Data())) -} - -// ------------- END ------------ - -// ------------------------------ -// regex.go -// ------------------------------ - -func ExampleIsEmail() { - fmt.Println(com.IsEmail("test@example.com")) - fmt.Println(com.IsEmail("@example.com")) - // Output: - // true - // false -} - -func ExampleIsUrl() { - fmt.Println(com.IsUrl("http://example.com")) - fmt.Println(com.IsUrl("http//example.com")) - // Output: - // true - // false -} - -// ------------- END ------------ - -// ------------------------------ -// slice.go -// ------------------------------ - -func ExampleAppendStr() { - s := []string{"a"} - s = com.AppendStr(s, "a") - s = com.AppendStr(s, "b") - fmt.Println(s) - // Output: [a b] -} - -// ------------- END ------------ diff --git a/vendor/github.com/Unknwon/com/file_test.go b/vendor/github.com/Unknwon/com/file_test.go deleted file mode 100644 index 4ff00dcd2d9..00000000000 --- a/vendor/github.com/Unknwon/com/file_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2013 com authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package com - -import ( - "testing" - - . "github.com/smartystreets/goconvey/convey" -) - -func TestIsFile(t *testing.T) { - if !IsFile("file.go") { - t.Errorf("IsExist:\n Expect => %v\n Got => %v\n", true, false) - } - - if IsFile("testdata") { - t.Errorf("IsExist:\n Expect => %v\n Got => %v\n", false, true) - } - - if IsFile("files.go") { - t.Errorf("IsExist:\n Expect => %v\n Got => %v\n", false, true) - } -} - -func TestIsExist(t *testing.T) { - Convey("Check if file or directory exists", t, func() { - Convey("Pass a file name that exists", func() { - So(IsExist("file.go"), ShouldEqual, true) - }) - Convey("Pass a directory name that exists", func() { - So(IsExist("testdata"), ShouldEqual, true) - }) - Convey("Pass a directory name that does not exist", func() { - So(IsExist(".hg"), ShouldEqual, false) - }) - }) -} - -func BenchmarkIsFile(b *testing.B) { - for i := 0; i < b.N; i++ { - IsFile("file.go") - } -} - -func BenchmarkIsExist(b *testing.B) { - for i := 0; i < b.N; i++ { - IsExist("file.go") - } -} diff --git a/vendor/github.com/Unknwon/com/html_test.go b/vendor/github.com/Unknwon/com/html_test.go deleted file mode 100644 index 2c9f4047870..00000000000 --- a/vendor/github.com/Unknwon/com/html_test.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2013 com authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package com - -import ( - "testing" -) - -func TestHtml2JS(t *testing.T) { - htm := "
Click me
\n\r" - js := string(Html2JS([]byte(htm))) - jsR := `
Click me
\n` - if js != jsR { - t.Errorf("Html2JS:\n Expect => %s\n Got => %s\n", jsR, js) - } -} - -func BenchmarkHtml2JS(b *testing.B) { - htm := "
Click me
\n\r" - for i := 0; i < b.N; i++ { - Html2JS([]byte(htm)) - } -} diff --git a/vendor/github.com/Unknwon/com/http_test.go b/vendor/github.com/Unknwon/com/http_test.go deleted file mode 100644 index 902b6607a5d..00000000000 --- a/vendor/github.com/Unknwon/com/http_test.go +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2013 com authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package com - -import ( - "io/ioutil" - "net/http" - "strings" - "testing" -) - -var examplePrefix = ` - - - Example Domain -` - -func TestHttpGet(t *testing.T) { - // 200. - rc, err := HttpGet(&http.Client{}, "http://example.com", nil) - if err != nil { - t.Fatalf("HttpGet:\n Expect => %v\n Got => %s\n", nil, err) - } - p, err := ioutil.ReadAll(rc) - if err != nil { - t.Errorf("HttpGet:\n Expect => %v\n Got => %s\n", nil, err) - } - s := string(p) - if !strings.HasPrefix(s, examplePrefix) { - t.Errorf("HttpGet:\n Expect => %s\n Got => %s\n", examplePrefix, s) - } -} - -func TestHttpGetBytes(t *testing.T) { - p, err := HttpGetBytes(&http.Client{}, "http://example.com", nil) - if err != nil { - t.Errorf("HttpGetBytes:\n Expect => %v\n Got => %s\n", nil, err) - } - s := string(p) - if !strings.HasPrefix(s, examplePrefix) { - t.Errorf("HttpGet:\n Expect => %s\n Got => %s\n", examplePrefix, s) - } -} - -func TestHttpGetJSON(t *testing.T) { - -} - -type rawFile struct { - name string - rawURL string - data []byte -} - -func (rf *rawFile) Name() string { - return rf.name -} - -func (rf *rawFile) RawUrl() string { - return rf.rawURL -} - -func (rf *rawFile) Data() []byte { - return rf.data -} - -func (rf *rawFile) SetData(p []byte) { - rf.data = p -} - -func TestFetchFiles(t *testing.T) { - files := []RawFile{ - &rawFile{rawURL: "http://example.com"}, - &rawFile{rawURL: "http://example.com"}, - } - err := FetchFiles(&http.Client{}, files, nil) - if err != nil { - t.Errorf("FetchFiles:\n Expect => %v\n Got => %s\n", nil, err) - } else if len(files[0].Data()) != 1270 { - t.Errorf("FetchFiles:\n Expect => %d\n Got => %d\n", 1270, len(files[0].Data())) - } else if len(files[1].Data()) != 1270 { - t.Errorf("FetchFiles:\n Expect => %d\n Got => %d\n", 1270, len(files[1].Data())) - } -} - -func TestFetchFilesCurl(t *testing.T) { - files := []RawFile{ - &rawFile{rawURL: "http://example.com"}, - &rawFile{rawURL: "http://example.com"}, - } - err := FetchFilesCurl(files) - if err != nil { - t.Errorf("FetchFilesCurl:\n Expect => %v\n Got => %s\n", nil, err) - } else if len(files[0].Data()) != 1270 { - t.Errorf("FetchFilesCurl:\n Expect => %d\n Got => %d\n", 1270, len(files[0].Data())) - } else if len(files[1].Data()) != 1270 { - t.Errorf("FetchFilesCurl:\n Expect => %d\n Got => %d\n", 1270, len(files[1].Data())) - } -} diff --git a/vendor/github.com/Unknwon/com/math.go b/vendor/github.com/Unknwon/com/math.go index 70b7e251fb4..99c56b65947 100644 --- a/vendor/github.com/Unknwon/com/math.go +++ b/vendor/github.com/Unknwon/com/math.go @@ -14,11 +14,16 @@ package com -// PowInt is int type of math.Pow function. +// PowInt is int type of math.Pow function. func PowInt(x int, y int) int { - num := 1 - for i := 0; i < y; i++ { - num *= x + if y <= 0 { + return 1 + } else { + if y % 2 == 0 { + sqrt := PowInt(x, y/2) + return sqrt * sqrt + } else { + return PowInt(x, y-1) * x + } } - return num } diff --git a/vendor/github.com/Unknwon/com/path.go b/vendor/github.com/Unknwon/com/path.go index a501c8538d8..b1e860def42 100644 --- a/vendor/github.com/Unknwon/com/path.go +++ b/vendor/github.com/Unknwon/com/path.go @@ -64,9 +64,9 @@ func GetSrcPath(importPath string) (appPath string, err error) { // it returns error when the variable does not exist. func HomeDir() (home string, err error) { if runtime.GOOS == "windows" { - home = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") - if home == "" { - home = os.Getenv("USERPROFILE") + home = os.Getenv("USERPROFILE") + if len(home) == 0 { + home = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") } } else { home = os.Getenv("HOME") diff --git a/vendor/github.com/Unknwon/com/path_test.go b/vendor/github.com/Unknwon/com/path_test.go deleted file mode 100644 index da5488d4400..00000000000 --- a/vendor/github.com/Unknwon/com/path_test.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2013 com authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package com - -import ( - "os" - "runtime" - "testing" -) - -func TestGetGOPATHs(t *testing.T) { - var gpsR []string - - if runtime.GOOS != "windows" { - gpsR = []string{"path/to/gopath1", "path/to/gopath2", "path/to/gopath3"} - os.Setenv("GOPATH", "path/to/gopath1:path/to/gopath2:path/to/gopath3") - } else { - gpsR = []string{"path/to/gopath1", "path/to/gopath2", "path/to/gopath3"} - os.Setenv("GOPATH", "path\\to\\gopath1;path\\to\\gopath2;path\\to\\gopath3") - } - - gps := GetGOPATHs() - if !CompareSliceStr(gps, gpsR) { - t.Errorf("GetGOPATHs:\n Expect => %s\n Got => %s\n", gpsR, gps) - } -} - -func TestGetSrcPath(t *testing.T) { - -} - -func TestHomeDir(t *testing.T) { - _, err := HomeDir() - if err != nil { - t.Errorf("HomeDir:\n Expect => %v\n Got => %s\n", nil, err) - } -} - -func BenchmarkGetGOPATHs(b *testing.B) { - for i := 0; i < b.N; i++ { - GetGOPATHs() - } -} - -func BenchmarkGetSrcPath(b *testing.B) { - for i := 0; i < b.N; i++ { - GetSrcPath("github.com/Unknwon/com") - } -} - -func BenchmarkHomeDir(b *testing.B) { - for i := 0; i < b.N; i++ { - HomeDir() - } -} diff --git a/vendor/github.com/Unknwon/com/regex_test.go b/vendor/github.com/Unknwon/com/regex_test.go deleted file mode 100644 index b027bd1c8de..00000000000 --- a/vendor/github.com/Unknwon/com/regex_test.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2013 com authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package com - -import ( - "testing" -) - -func TestIsEmail(t *testing.T) { - emails := map[string]bool{ - `test@example.com`: true, - `single-character@b.org`: true, - `uncommon_address@test.museum`: true, - `local@sld.UPPER`: true, - `@missing.org`: false, - `missing@.com`: false, - `missing@qq.`: false, - `wrong-ip@127.1.1.1.26`: false, - } - for e, r := range emails { - b := IsEmail(e) - if b != r { - t.Errorf("IsEmail:\n Expect => %v\n Got => %v\n", r, b) - } - } -} - -func TestIsUrl(t *testing.T) { - urls := map[string]bool{ - "http://www.example.com": true, - "http://example.com": true, - "http://example.com?user=test&password=test": true, - "http://example.com?user=test#login": true, - "ftp://example.com": true, - "https://example.com": true, - "htp://example.com": false, - "http//example.com": false, - "http://example": true, - } - for u, r := range urls { - b := IsUrl(u) - if b != r { - t.Errorf("IsUrl:\n Expect => %v\n Got => %v\n", r, b) - } - } -} - -func BenchmarkIsEmail(b *testing.B) { - for i := 0; i < b.N; i++ { - IsEmail("test@example.com") - } -} - -func BenchmarkIsUrl(b *testing.B) { - for i := 0; i < b.N; i++ { - IsEmail("http://example.com") - } -} diff --git a/vendor/github.com/Unknwon/com/slice_test.go b/vendor/github.com/Unknwon/com/slice_test.go deleted file mode 100644 index 6a94156c231..00000000000 --- a/vendor/github.com/Unknwon/com/slice_test.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2013 com authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package com - -import ( - "fmt" - "testing" - - . "github.com/smartystreets/goconvey/convey" -) - -func TestAppendStr(t *testing.T) { - Convey("Append a string to a slice with no duplicates", t, func() { - s := []string{"a"} - - Convey("Append a string that does not exist in slice", func() { - s = AppendStr(s, "b") - So(len(s), ShouldEqual, 2) - }) - - Convey("Append a string that does exist in slice", func() { - s = AppendStr(s, "b") - So(len(s), ShouldEqual, 2) - }) - }) -} - -func TestCompareSliceStr(t *testing.T) { - Convey("Compares two 'string' type slices with elements and order", t, func() { - Convey("Compare two slices that do have same elements and order", func() { - So(CompareSliceStr( - []string{"1", "2", "3"}, []string{"1", "2", "3"}), ShouldBeTrue) - }) - - Convey("Compare two slices that do have same elements but does not have same order", func() { - So(!CompareSliceStr( - []string{"2", "1", "3"}, []string{"1", "2", "3"}), ShouldBeTrue) - }) - - Convey("Compare two slices that have different number of elements", func() { - So(!CompareSliceStr( - []string{"2", "1"}, []string{"1", "2", "3"}), ShouldBeTrue) - }) - }) -} - -func TestCompareSliceStrU(t *testing.T) { - Convey("Compare two 'string' type slices with elements and ignore the order", t, func() { - Convey("Compare two slices that do have same elements and order", func() { - So(CompareSliceStrU( - []string{"1", "2", "3"}, []string{"1", "2", "3"}), ShouldBeTrue) - }) - - Convey("Compare two slices that do have same elements but does not have same order", func() { - So(CompareSliceStrU( - []string{"2", "1", "3"}, []string{"1", "2", "3"}), ShouldBeTrue) - }) - - Convey("Compare two slices that have different number of elements", func() { - So(!CompareSliceStrU( - []string{"2", "1"}, []string{"1", "2", "3"}), ShouldBeTrue) - }) - }) -} - -func BenchmarkAppendStr(b *testing.B) { - s := []string{"a"} - for i := 0; i < b.N; i++ { - s = AppendStr(s, fmt.Sprint(b.N%3)) - } -} - -func BenchmarkCompareSliceStr(b *testing.B) { - s1 := []string{"1", "2", "3"} - s2 := []string{"1", "2", "3"} - for i := 0; i < b.N; i++ { - CompareSliceStr(s1, s2) - } -} - -func BenchmarkCompareSliceStrU(b *testing.B) { - s1 := []string{"1", "4", "2", "3"} - s2 := []string{"1", "2", "3", "4"} - for i := 0; i < b.N; i++ { - CompareSliceStrU(s1, s2) - } -} diff --git a/vendor/github.com/Unknwon/com/string.go b/vendor/github.com/Unknwon/com/string.go index 1ebb9014040..7080d174a81 100644 --- a/vendor/github.com/Unknwon/com/string.go +++ b/vendor/github.com/Unknwon/com/string.go @@ -15,53 +15,66 @@ package com import ( + "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" - "encoding/base64" "errors" - "io" r "math/rand" "strconv" "strings" "time" + "unicode" + "unicode/utf8" ) -// AESEncrypt encrypts text and given key with AES. -func AESEncrypt(key, text []byte) ([]byte, error) { +// AESGCMEncrypt encrypts plaintext with the given key using AES in GCM mode. +func AESGCMEncrypt(key, plaintext []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } - b := base64.StdEncoding.EncodeToString(text) - ciphertext := make([]byte, aes.BlockSize+len(b)) - iv := ciphertext[:aes.BlockSize] - if _, err := io.ReadFull(rand.Reader, iv); err != nil { + + gcm, err := cipher.NewGCM(block) + if err != nil { return nil, err } - cfb := cipher.NewCFBEncrypter(block, iv) - cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b)) - return ciphertext, nil + + nonce := make([]byte, gcm.NonceSize()) + if _, err := rand.Read(nonce); err != nil { + return nil, err + } + + ciphertext := gcm.Seal(nil, nonce, plaintext, nil) + return append(nonce, ciphertext...), nil } -// AESDecrypt decrypts text and given key with AES. -func AESDecrypt(key, text []byte) ([]byte, error) { +// AESGCMDecrypt decrypts ciphertext with the given key using AES in GCM mode. +func AESGCMDecrypt(key, ciphertext []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } - if len(text) < aes.BlockSize { - return nil, errors.New("ciphertext too short") - } - iv := text[:aes.BlockSize] - text = text[aes.BlockSize:] - cfb := cipher.NewCFBDecrypter(block, iv) - cfb.XORKeyStream(text, text) - data, err := base64.StdEncoding.DecodeString(string(text)) + + gcm, err := cipher.NewGCM(block) if err != nil { return nil, err } - return data, nil + + size := gcm.NonceSize() + if len(ciphertext)-size <= 0 { + return nil, errors.New("Ciphertext is empty") + } + + nonce := ciphertext[:size] + ciphertext = ciphertext[size:] + + plainText, err := gcm.Open(nil, nonce, ciphertext, nil) + if err != nil { + return nil, err + } + + return plainText, nil } // IsLetter returns true if the 'l' is an English letter. @@ -138,3 +151,103 @@ func RandomCreateBytes(n int, alphabets ...byte) []byte { } return bytes } + +// ToSnakeCase can convert all upper case characters in a string to +// underscore format. +// +// Some samples. +// "FirstName" => "first_name" +// "HTTPServer" => "http_server" +// "NoHTTPS" => "no_https" +// "GO_PATH" => "go_path" +// "GO PATH" => "go_path" // space is converted to underscore. +// "GO-PATH" => "go_path" // hyphen is converted to underscore. +// +// From https://github.com/huandu/xstrings +func ToSnakeCase(str string) string { + if len(str) == 0 { + return "" + } + + buf := &bytes.Buffer{} + var prev, r0, r1 rune + var size int + + r0 = '_' + + for len(str) > 0 { + prev = r0 + r0, size = utf8.DecodeRuneInString(str) + str = str[size:] + + switch { + case r0 == utf8.RuneError: + buf.WriteByte(byte(str[0])) + + case unicode.IsUpper(r0): + if prev != '_' { + buf.WriteRune('_') + } + + buf.WriteRune(unicode.ToLower(r0)) + + if len(str) == 0 { + break + } + + r0, size = utf8.DecodeRuneInString(str) + str = str[size:] + + if !unicode.IsUpper(r0) { + buf.WriteRune(r0) + break + } + + // find next non-upper-case character and insert `_` properly. + // it's designed to convert `HTTPServer` to `http_server`. + // if there are more than 2 adjacent upper case characters in a word, + // treat them as an abbreviation plus a normal word. + for len(str) > 0 { + r1 = r0 + r0, size = utf8.DecodeRuneInString(str) + str = str[size:] + + if r0 == utf8.RuneError { + buf.WriteRune(unicode.ToLower(r1)) + buf.WriteByte(byte(str[0])) + break + } + + if !unicode.IsUpper(r0) { + if r0 == '_' || r0 == ' ' || r0 == '-' { + r0 = '_' + + buf.WriteRune(unicode.ToLower(r1)) + } else { + buf.WriteRune('_') + buf.WriteRune(unicode.ToLower(r1)) + buf.WriteRune(r0) + } + + break + } + + buf.WriteRune(unicode.ToLower(r1)) + } + + if len(str) == 0 || r0 == '_' { + buf.WriteRune(unicode.ToLower(r0)) + break + } + + default: + if r0 == ' ' || r0 == '-' { + r0 = '_' + } + + buf.WriteRune(r0) + } + } + + return buf.String() +} diff --git a/vendor/github.com/Unknwon/com/string_test.go b/vendor/github.com/Unknwon/com/string_test.go deleted file mode 100644 index ed90977b04a..00000000000 --- a/vendor/github.com/Unknwon/com/string_test.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2013 com authors -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package com - -import ( - "testing" -) - -func TestIsLetter(t *testing.T) { - if IsLetter('1') { - t.Errorf("IsLetter:\n Expect => %v\n Got => %v\n", false, true) - } - - if IsLetter('[') { - t.Errorf("IsLetter:\n Expect => %v\n Got => %v\n", false, true) - } - - if !IsLetter('a') { - t.Errorf("IsLetter:\n Expect => %v\n Got => %v\n", true, false) - } - - if !IsLetter('Z') { - t.Errorf("IsLetter:\n Expect => %v\n Got => %v\n", true, false) - } -} - -func TestExpand(t *testing.T) { - match := map[string]string{ - "domain": "gowalker.org", - "subdomain": "github.com", - } - s := "http://{domain}/{subdomain}/{0}/{1}" - sR := "http://gowalker.org/github.com/Unknwon/gowalker" - if Expand(s, match, "Unknwon", "gowalker") != sR { - t.Errorf("Expand:\n Expect => %s\n Got => %s\n", sR, s) - } -} - -func TestReverse(t *testing.T) { - if Reverse("abcdefg") != "gfedcba" { - t.Errorf("Reverse:\n Except => %s\n Got =>%s\n", "gfedcba", Reverse("abcdefg")) - } - if Reverse("上善若水厚德载物") != "物载德厚水若善上" { - t.Errorf("Reverse:\n Except => %s\n Got =>%s\n", "物载德厚水若善上", Reverse("上善若水厚德载物")) - } -} - -func BenchmarkIsLetter(b *testing.B) { - for i := 0; i < b.N; i++ { - IsLetter('a') - } -} - -func BenchmarkExpand(b *testing.B) { - match := map[string]string{ - "domain": "gowalker.org", - "subdomain": "github.com", - } - s := "http://{domain}/{subdomain}/{0}/{1}" - for i := 0; i < b.N; i++ { - Expand(s, match, "Unknwon", "gowalker") - } -} - -func BenchmarkReverse(b *testing.B) { - s := "abscef中文" - for i := 0; i < b.N; i++ { - Reverse(s) - } -} diff --git a/vendor/github.com/go-macaron/binding/.travis.yml b/vendor/github.com/go-macaron/binding/.travis.yml deleted file mode 100644 index 2774fb35d50..00000000000 --- a/vendor/github.com/go-macaron/binding/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -sudo: false -language: go - -go: - - 1.3 - - 1.4 - - 1.5 - - tip - -script: go test -v -cover -race - -notifications: - email: - - u@gogs.io diff --git a/vendor/github.com/go-macaron/binding/binding.go b/vendor/github.com/go-macaron/binding/binding.go index 4b958ec964d..dbd7beb45f6 100644 --- a/vendor/github.com/go-macaron/binding/binding.go +++ b/vendor/github.com/go-macaron/binding/binding.go @@ -32,7 +32,7 @@ import ( "gopkg.in/macaron.v1" ) -const _VERSION = "0.2.0" +const _VERSION = "0.3.2" func Version() string { return _VERSION @@ -145,7 +145,7 @@ func Form(formStruct interface{}, ifacePtr ...interface{}) macaron.Handler { if parseErr != nil { errors.Add([]string{}, ERR_DESERIALIZATION, parseErr.Error()) } - mapForm(formStruct, ctx.Req.Form, nil, errors) + errors = mapForm(formStruct, ctx.Req.Form, nil, errors) validateAndMap(formStruct, ctx, errors, ifacePtr...) } } @@ -185,7 +185,7 @@ func MultipartForm(formStruct interface{}, ifacePtr ...interface{}) macaron.Hand ctx.Req.MultipartForm = form } } - mapForm(formStruct, ctx.Req.MultipartForm.Value, ctx.Req.MultipartForm.File, errors) + errors = mapForm(formStruct, ctx.Req.MultipartForm.Value, ctx.Req.MultipartForm.File, errors) validateAndMap(formStruct, ctx, errors, ifacePtr...) } } @@ -243,10 +243,10 @@ func Validate(obj interface{}) macaron.Handler { } var ( - alphaDashPattern = regexp.MustCompile("[^\\d\\w-_]") - alphaDashDotPattern = regexp.MustCompile("[^\\d\\w-_\\.]") - emailPattern = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?") - urlPattern = regexp.MustCompile(`(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?`) + AlphaDashPattern = regexp.MustCompile("[^\\d\\w-_]") + AlphaDashDotPattern = regexp.MustCompile("[^\\d\\w-_\\.]") + EmailPattern = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?") + URLPattern = regexp.MustCompile(`(http|https):\/\/(?:\\S+(?::\\S*)?@)?[\w\-_]+(\.[\w\-_]+)*([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?`) ) type ( @@ -255,7 +255,7 @@ type ( // IsMatch checks if rule matches. IsMatch func(string) bool // IsValid applies validation rule to condition. - IsValid func(Errors, string, interface{}) bool + IsValid func(Errors, string, interface{}) (bool, Errors) } // RuleMapper represents a validation rule mapper, // it allwos users to add custom validation rules. @@ -361,12 +361,12 @@ VALIDATE_RULES: break VALIDATE_RULES } case rule == "AlphaDash": - if alphaDashPattern.MatchString(fmt.Sprintf("%v", fieldValue)) { + if AlphaDashPattern.MatchString(fmt.Sprintf("%v", fieldValue)) { errors.Add([]string{field.Name}, ERR_ALPHA_DASH, "AlphaDash") break VALIDATE_RULES } case rule == "AlphaDashDot": - if alphaDashDotPattern.MatchString(fmt.Sprintf("%v", fieldValue)) { + if AlphaDashDotPattern.MatchString(fmt.Sprintf("%v", fieldValue)) { errors.Add([]string{field.Name}, ERR_ALPHA_DASH_DOT, "AlphaDashDot") break VALIDATE_RULES } @@ -414,7 +414,7 @@ VALIDATE_RULES: break VALIDATE_RULES } case rule == "Email": - if !emailPattern.MatchString(fmt.Sprintf("%v", fieldValue)) { + if !EmailPattern.MatchString(fmt.Sprintf("%v", fieldValue)) { errors.Add([]string{field.Name}, ERR_EMAIL, "Email") break VALIDATE_RULES } @@ -422,7 +422,7 @@ VALIDATE_RULES: str := fmt.Sprintf("%v", fieldValue) if len(str) == 0 { continue - } else if !urlPattern.MatchString(str) { + } else if !URLPattern.MatchString(str) { errors.Add([]string{field.Name}, ERR_URL, "Url") break VALIDATE_RULES } @@ -449,7 +449,7 @@ VALIDATE_RULES: case strings.HasPrefix(rule, "Default("): if reflect.DeepEqual(zero, fieldValue) { if fieldVal.CanAddr() { - setWithProperType(field.Type.Kind(), rule[8:len(rule)-1], fieldVal, field.Tag.Get("form"), errors) + errors = setWithProperType(field.Type.Kind(), rule[8:len(rule)-1], fieldVal, field.Tag.Get("form"), errors) } else { errors.Add([]string{field.Name}, ERR_EXCLUDE, "Default") break VALIDATE_RULES @@ -457,9 +457,13 @@ VALIDATE_RULES: } default: // Apply custom validation rules. + var isValid bool for i := range ruleMapper { - if ruleMapper[i].IsMatch(rule) && !ruleMapper[i].IsValid(errors, field.Name, fieldValue) { - break VALIDATE_RULES + if ruleMapper[i].IsMatch(rule) { + isValid, errors = ruleMapper[i].IsValid(errors, field.Name, fieldValue) + if !isValid { + break VALIDATE_RULES + } } } } @@ -493,7 +497,7 @@ func SetNameMapper(nm NameMapper) { // Takes values from the form data and puts them into a struct func mapForm(formStruct reflect.Value, form map[string][]string, - formfile map[string][]*multipart.FileHeader, errors Errors) { + formfile map[string][]*multipart.FileHeader, errors Errors) Errors { if formStruct.Kind() == reflect.Ptr { formStruct = formStruct.Elem() @@ -506,12 +510,12 @@ func mapForm(formStruct reflect.Value, form map[string][]string, if typeField.Type.Kind() == reflect.Ptr && typeField.Anonymous { structField.Set(reflect.New(typeField.Type.Elem())) - mapForm(structField.Elem(), form, formfile, errors) + errors = mapForm(structField.Elem(), form, formfile, errors) if reflect.DeepEqual(structField.Elem().Interface(), reflect.Zero(structField.Elem().Type()).Interface()) { structField.Set(reflect.Zero(structField.Type())) } } else if typeField.Type.Kind() == reflect.Struct { - mapForm(structField, form, formfile, errors) + errors = mapForm(structField, form, formfile, errors) } inputFieldName := parseFormName(typeField.Name, typeField.Tag.Get("form")) @@ -526,11 +530,11 @@ func mapForm(formStruct reflect.Value, form map[string][]string, sliceOf := structField.Type().Elem().Kind() slice := reflect.MakeSlice(structField.Type(), numElems, numElems) for i := 0; i < numElems; i++ { - setWithProperType(sliceOf, inputValue[i], slice.Index(i), inputFieldName, errors) + errors = setWithProperType(sliceOf, inputValue[i], slice.Index(i), inputFieldName, errors) } formStruct.Field(i).Set(slice) } else { - setWithProperType(typeField.Type.Kind(), inputValue[0], structField, inputFieldName, errors) + errors = setWithProperType(typeField.Type.Kind(), inputValue[0], structField, inputFieldName, errors) } continue } @@ -551,13 +555,14 @@ func mapForm(formStruct reflect.Value, form map[string][]string, structField.Set(reflect.ValueOf(inputFile[0])) } } + return errors } // This sets the value in a struct of an indeterminate type to the // matching value from the request (via Form middleware) in the // same type, so that not all deserialized values have to be strings. // Supported types are string, int, float, and bool. -func setWithProperType(valueKind reflect.Kind, val string, structField reflect.Value, nameInTag string, errors Errors) { +func setWithProperType(valueKind reflect.Kind, val string, structField reflect.Value, nameInTag string, errors Errors) Errors { switch valueKind { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: if val == "" { @@ -582,7 +587,7 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V case reflect.Bool: if val == "on" { structField.SetBool(true) - return + break } if val == "" { @@ -617,6 +622,7 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V case reflect.String: structField.SetString(val) } + return errors } // Don't pass in pointers to bind to. Can lead to bugs. diff --git a/vendor/github.com/go-macaron/inject/.travis.yml b/vendor/github.com/go-macaron/inject/.travis.yml deleted file mode 100644 index 2774fb35d50..00000000000 --- a/vendor/github.com/go-macaron/inject/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -sudo: false -language: go - -go: - - 1.3 - - 1.4 - - 1.5 - - tip - -script: go test -v -cover -race - -notifications: - email: - - u@gogs.io diff --git a/vendor/github.com/go-macaron/inject/inject.go b/vendor/github.com/go-macaron/inject/inject.go index b4a6ea45fe7..1c1f98eaaa0 100644 --- a/vendor/github.com/go-macaron/inject/inject.go +++ b/vendor/github.com/go-macaron/inject/inject.go @@ -50,6 +50,34 @@ type Invoker interface { Invoke(interface{}) ([]reflect.Value, error) } +// FastInvoker represents an interface in order to avoid the calling function via reflection. +// +// example: +// type handlerFuncHandler func(http.ResponseWriter, *http.Request) error +// func (f handlerFuncHandler)Invoke([]interface{}) ([]reflect.Value, error){ +// ret := f(p[0].(http.ResponseWriter), p[1].(*http.Request)) +// return []reflect.Value{reflect.ValueOf(ret)}, nil +// } +// +// type funcHandler func(int, string) +// func (f funcHandler)Invoke([]interface{}) ([]reflect.Value, error){ +// f(p[0].(int), p[1].(string)) +// return nil, nil +// } +type FastInvoker interface { + // Invoke attempts to call the ordinary functions. If f is a function + // with the appropriate signature, f.Invoke([]interface{}) is a Call that calls f. + // Returns a slice of reflect.Value representing the returned values of the function. + // Returns an error if the injection fails. + Invoke([]interface{}) ([]reflect.Value, error) +} + +// IsFastInvoker check interface is FastInvoker +func IsFastInvoker(h interface{}) bool { + _, ok := h.(FastInvoker) + return ok +} + // TypeMapper represents an interface for mapping interface{} values based on type. type TypeMapper interface { // Maps the interface{} value based on its immediate type from reflect.TypeOf. @@ -102,18 +130,50 @@ func New() Injector { // It panics if f is not a function func (inj *injector) Invoke(f interface{}) ([]reflect.Value, error) { t := reflect.TypeOf(f) - - var in = make([]reflect.Value, t.NumIn()) //Panic if t is not kind of Func - for i := 0; i < t.NumIn(); i++ { - argType := t.In(i) - val := inj.GetVal(argType) - if !val.IsValid() { - return nil, fmt.Errorf("Value not found for type %v", argType) - } - - in[i] = val + switch v := f.(type) { + case FastInvoker: + return inj.fastInvoke(v, t, t.NumIn()) + default: + return inj.callInvoke(f, t, t.NumIn()) } +} +func (inj *injector) fastInvoke(f FastInvoker, t reflect.Type, numIn int) ([]reflect.Value, error) { + var in []interface{} + if numIn > 0 { + in = make([]interface{}, numIn) // Panic if t is not kind of Func + var argType reflect.Type + var val reflect.Value + for i := 0; i < numIn; i++ { + argType = t.In(i) + val = inj.GetVal(argType) + if !val.IsValid() { + return nil, fmt.Errorf("Value not found for type %v", argType) + } + + in[i] = val.Interface() + } + } + return f.Invoke(in) +} + +// callInvoke reflect.Value.Call +func (inj *injector) callInvoke(f interface{}, t reflect.Type, numIn int) ([]reflect.Value, error) { + var in []reflect.Value + if numIn > 0 { + in = make([]reflect.Value, numIn) + var argType reflect.Type + var val reflect.Value + for i := 0; i < numIn; i++ { + argType = t.In(i) + val = inj.GetVal(argType) + if !val.IsValid() { + return nil, fmt.Errorf("Value not found for type %v", argType) + } + + in[i] = val + } + } return reflect.ValueOf(f).Call(in), nil } diff --git a/vendor/github.com/go-macaron/session/.gitignore b/vendor/github.com/go-macaron/session/.gitignore deleted file mode 100644 index 9297dbcd7c4..00000000000 --- a/vendor/github.com/go-macaron/session/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -ledis/tmp.db -nodb/tmp.db \ No newline at end of file diff --git a/vendor/github.com/go-macaron/session/.travis.yml b/vendor/github.com/go-macaron/session/.travis.yml deleted file mode 100644 index 2774fb35d50..00000000000 --- a/vendor/github.com/go-macaron/session/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -sudo: false -language: go - -go: - - 1.3 - - 1.4 - - 1.5 - - tip - -script: go test -v -cover -race - -notifications: - email: - - u@gogs.io diff --git a/vendor/github.com/go-macaron/session/README.md b/vendor/github.com/go-macaron/session/README.md index 280ace36dc7..b11bd4a793d 100644 --- a/vendor/github.com/go-macaron/session/README.md +++ b/vendor/github.com/go-macaron/session/README.md @@ -1,4 +1,4 @@ -# session [![Build Status](https://travis-ci.org/go-macaron/session.svg?branch=master)](https://travis-ci.org/go-macaron/session) [![](http://gocover.io/_badge/github.com/go-macaron/session)](http://gocover.io/github.com/go-macaron/session) +# session [![Build Status](https://travis-ci.org/go-macaron/session.svg?branch=master)](https://travis-ci.org/go-macaron/session) Middleware session provides session management for [Macaron](https://github.com/go-macaron/macaron). It can use many session providers, including memory, file, Redis, Memcache, PostgreSQL, MySQL, Couchbase, Ledis and Nodb. @@ -9,7 +9,7 @@ Middleware session provides session management for [Macaron](https://github.com/ ## Getting Help - [API Reference](https://gowalker.org/github.com/go-macaron/session) -- [Documentation](http://go-macaron.com/docs/middlewares/session) +- [Documentation](https://go-macaron.com/docs/middlewares/session) ## Credits diff --git a/vendor/github.com/go-macaron/session/file.go b/vendor/github.com/go-macaron/session/file.go index 438269ea845..9bbc7aed20b 100644 --- a/vendor/github.com/go-macaron/session/file.go +++ b/vendor/github.com/go-macaron/session/file.go @@ -86,7 +86,7 @@ func (s *FileStore) Release() error { return err } - return ioutil.WriteFile(s.p.filepath(s.sid), data, os.ModePerm) + return ioutil.WriteFile(s.p.filepath(s.sid), data, 0600) } // Flush deletes all session data. @@ -121,7 +121,7 @@ func (p *FileProvider) filepath(sid string) string { // Read returns raw session store by session ID. func (p *FileProvider) Read(sid string) (_ RawStore, err error) { filename := p.filepath(sid) - if err = os.MkdirAll(path.Dir(filename), os.ModePerm); err != nil { + if err = os.MkdirAll(path.Dir(filename), 0700); err != nil { return nil, err } p.lock.RLock() @@ -129,7 +129,7 @@ func (p *FileProvider) Read(sid string) (_ RawStore, err error) { var f *os.File if com.IsFile(filename) { - f, err = os.OpenFile(filename, os.O_RDWR, os.ModePerm) + f, err = os.OpenFile(filename, os.O_RDONLY, 0600) } else { f, err = os.Create(filename) } @@ -187,15 +187,15 @@ func (p *FileProvider) regenerate(oldsid, sid string) (err error) { if err != nil { return err } - if err = os.MkdirAll(path.Dir(oldname), os.ModePerm); err != nil { + if err = os.MkdirAll(path.Dir(oldname), 0700); err != nil { return err } - if err = ioutil.WriteFile(oldname, data, os.ModePerm); err != nil { + if err = ioutil.WriteFile(oldname, data, 0600); err != nil { return err } } - if err = os.MkdirAll(path.Dir(filename), os.ModePerm); err != nil { + if err = os.MkdirAll(path.Dir(filename), 0700); err != nil { return err } if err = os.Rename(oldname, filename); err != nil { diff --git a/vendor/golang.org/x/crypto/LICENSE b/vendor/golang.org/x/crypto/LICENSE new file mode 100644 index 00000000000..6a66aea5eaf --- /dev/null +++ b/vendor/golang.org/x/crypto/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/crypto/PATENTS b/vendor/golang.org/x/crypto/PATENTS new file mode 100644 index 00000000000..733099041f8 --- /dev/null +++ b/vendor/golang.org/x/crypto/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go new file mode 100644 index 00000000000..593f6530084 --- /dev/null +++ b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go @@ -0,0 +1,77 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package pbkdf2 implements the key derivation function PBKDF2 as defined in RFC +2898 / PKCS #5 v2.0. + +A key derivation function is useful when encrypting data based on a password +or any other not-fully-random data. It uses a pseudorandom function to derive +a secure encryption key based on the password. + +While v2.0 of the standard defines only one pseudorandom function to use, +HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved +Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To +choose, you can pass the `New` functions from the different SHA packages to +pbkdf2.Key. +*/ +package pbkdf2 // import "golang.org/x/crypto/pbkdf2" + +import ( + "crypto/hmac" + "hash" +) + +// Key derives a key from the password, salt and iteration count, returning a +// []byte of length keylen that can be used as cryptographic key. The key is +// derived based on the method described as PBKDF2 with the HMAC variant using +// the supplied hash function. +// +// For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you +// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by +// doing: +// +// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New) +// +// Remember to get a good random salt. At least 8 bytes is recommended by the +// RFC. +// +// Using a higher iteration count will increase the cost of an exhaustive +// search but will also make derivation proportionally slower. +func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte { + prf := hmac.New(h, password) + hashLen := prf.Size() + numBlocks := (keyLen + hashLen - 1) / hashLen + + var buf [4]byte + dk := make([]byte, 0, numBlocks*hashLen) + U := make([]byte, hashLen) + for block := 1; block <= numBlocks; block++ { + // N.B.: || means concatenation, ^ means XOR + // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter + // U_1 = PRF(password, salt || uint(i)) + prf.Reset() + prf.Write(salt) + buf[0] = byte(block >> 24) + buf[1] = byte(block >> 16) + buf[2] = byte(block >> 8) + buf[3] = byte(block) + prf.Write(buf[:4]) + dk = prf.Sum(dk) + T := dk[len(dk)-hashLen:] + copy(U, T) + + // U_n = PRF(password, U_(n-1)) + for n := 2; n <= iter; n++ { + prf.Reset() + prf.Write(U) + U = U[:0] + U = prf.Sum(U) + for x := range U { + T[x] ^= U[x] + } + } + } + return dk[:keyLen] +} diff --git a/vendor/gopkg.in/macaron.v1/.gitignore b/vendor/gopkg.in/macaron.v1/.gitignore deleted file mode 100644 index 57ee3ec50fe..00000000000 --- a/vendor/gopkg.in/macaron.v1/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -macaron.sublime-project -macaron.sublime-workspace \ No newline at end of file diff --git a/vendor/gopkg.in/macaron.v1/.travis.yml b/vendor/gopkg.in/macaron.v1/.travis.yml deleted file mode 100644 index 6eeb32a4e38..00000000000 --- a/vendor/gopkg.in/macaron.v1/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -sudo: false -language: go - -go: - - 1.3 - - 1.4 - - 1.5 - -script: go test -v -cover -race - -notifications: - email: - - u@gogs.io diff --git a/vendor/gopkg.in/macaron.v1/README.md b/vendor/gopkg.in/macaron.v1/README.md index 704ecf34077..cfc7f6fdb4d 100644 --- a/vendor/gopkg.in/macaron.v1/README.md +++ b/vendor/gopkg.in/macaron.v1/README.md @@ -1,12 +1,10 @@ -Macaron [![Build Status](https://travis-ci.org/go-macaron/macaron.svg?branch=v1)](https://travis-ci.org/go-macaron/macaron) [![](http://gocover.io/_badge/github.com/go-macaron/macaron)](http://gocover.io/github.com/go-macaron/macaron) +Macaron [![Build Status](https://travis-ci.org/go-macaron/macaron.svg?branch=v1)](https://travis-ci.org/go-macaron/macaron) ======================= ![Macaron Logo](https://raw.githubusercontent.com/go-macaron/macaron/v1/macaronlogo.png) Package macaron is a high productive and modular web framework in Go. -##### Current version: 0.8.0 - ## Getting Started The minimum requirement of Go is **1.3**. @@ -70,18 +68,18 @@ There are already many [middlewares](https://github.com/go-macaron) to simplify ## Use Cases -- [Gogs](http://gogs.io): A painless self-hosted Git Service -- [Peach](http://peachdocs.org): A modern web documentation server +- [Gogs](https://gogs.io): A painless self-hosted Git Service +- [Peach](https://peachdocs.org): A modern web documentation server - [Go Walker](https://gowalker.org): Go online API documentation -- [Switch](http://gopm.io): Gopm registry +- [Switch](https://gopm.io): Gopm registry - [YouGam](http://yougam.com): Online Forum - [Critical Stack Intel](https://intel.criticalstack.com/): A 100% free intel marketplace from Critical Stack, Inc. ## Getting Help - [API Reference](https://gowalker.org/gopkg.in/macaron.v1) -- [Documentation](http://go-macaron.com) -- [FAQs](http://go-macaron.com/docs/faqs) +- [Documentation](https://go-macaron.com) +- [FAQs](https://go-macaron.com/docs/faqs) - [![Join the chat at https://gitter.im/Unknwon/macaron](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-macaron/macaron?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ## Credits diff --git a/vendor/gopkg.in/macaron.v1/context.go b/vendor/gopkg.in/macaron.v1/context.go index bb6caa41414..dffc50cf6f6 100644 --- a/vendor/gopkg.in/macaron.v1/context.go +++ b/vendor/gopkg.in/macaron.v1/context.go @@ -15,7 +15,7 @@ package macaron import ( - "crypto/md5" + "crypto/sha256" "encoding/hex" "html/template" "io" @@ -32,8 +32,8 @@ import ( "time" "github.com/Unknwon/com" - "github.com/go-macaron/inject" + "golang.org/x/crypto/pbkdf2" ) // Locale reprents a localization interface. @@ -72,6 +72,14 @@ func (r *Request) Body() *RequestBody { return &RequestBody{r.Request.Body} } +// ContextInvoker is an inject.FastInvoker wrapper of func(ctx *Context). +type ContextInvoker func(ctx *Context) + +func (invoke ContextInvoker) Invoke(params []interface{}) ([]reflect.Value, error) { + invoke(params[0].(*Context)) + return nil, nil +} + // Context represents the runtime context of current request of Macaron instance. // It is the integration of most frequently used middlewares and helper methods. type Context struct { @@ -84,7 +92,7 @@ type Context struct { Req Request Resp ResponseWriter params Params - Render // Not nil only if you use macaran.Render middleware. + Render Locale Data map[string]interface{} } @@ -145,9 +153,6 @@ func (ctx *Context) RemoteAddr() string { } func (ctx *Context) renderHTML(status int, setName, tplName string, data ...interface{}) { - if ctx.Render == nil { - panic("renderer middleware hasn't been registered") - } if len(data) <= 0 { ctx.Render.HTMLSet(status, setName, tplName, ctx.Data) } else if len(data) == 1 { @@ -159,7 +164,7 @@ func (ctx *Context) renderHTML(status int, setName, tplName string, data ...inte // HTML calls Render.HTML but allows less arguments. func (ctx *Context) HTML(status int, name string, data ...interface{}) { - ctx.renderHTML(status, _DEFAULT_TPL_SET_NAME, name, data...) + ctx.renderHTML(status, DEFAULT_TPL_SET_NAME, name, data...) } // HTML calls Render.HTMLSet but allows less arguments. @@ -221,6 +226,12 @@ func (ctx *Context) QueryEscape(name string) string { return template.HTMLEscapeString(ctx.Query(name)) } +// QueryBool returns query result in bool type. +func (ctx *Context) QueryBool(name string) bool { + v, _ := strconv.ParseBool(ctx.Query(name)) + return v +} + // QueryInt returns query result in int type. func (ctx *Context) QueryInt(name string) int { return com.StrTo(ctx.Query(name)).MustInt() @@ -353,6 +364,13 @@ func (ctx *Context) SetCookie(name string, value string, others ...interface{}) } } + if len(others) > 5 { + if v, ok := others[5].(time.Time); ok { + cookie.Expires = v + cookie.RawExpires = v.Format(time.UnixDate) + } + } + ctx.Resp.Header().Add("Set-Cookie", cookie.String()) } @@ -401,30 +419,29 @@ func (ctx *Context) GetSecureCookie(key string) (string, bool) { // SetSuperSecureCookie sets given cookie value to response header with secret string. func (ctx *Context) SetSuperSecureCookie(secret, name, value string, others ...interface{}) { - m := md5.Sum([]byte(secret)) - secret = hex.EncodeToString(m[:]) - text, err := com.AESEncrypt([]byte(secret), []byte(value)) + key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New) + text, err := com.AESGCMEncrypt(key, []byte(value)) if err != nil { panic("error encrypting cookie: " + err.Error()) } + ctx.SetCookie(name, hex.EncodeToString(text), others...) } // GetSuperSecureCookie returns given cookie value from request header with secret string. -func (ctx *Context) GetSuperSecureCookie(secret, key string) (string, bool) { - val := ctx.GetCookie(key) +func (ctx *Context) GetSuperSecureCookie(secret, name string) (string, bool) { + val := ctx.GetCookie(name) if val == "" { return "", false } - data, err := hex.DecodeString(val) + text, err := hex.DecodeString(val) if err != nil { return "", false } - m := md5.Sum([]byte(secret)) - secret = hex.EncodeToString(m[:]) - text, err := com.AESDecrypt([]byte(secret), data) + key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New) + text, err = com.AESGCMDecrypt(key, text) return string(text), err == nil } diff --git a/vendor/gopkg.in/macaron.v1/logger.go b/vendor/gopkg.in/macaron.v1/logger.go index 109b7b3330d..3c54c24d57e 100644 --- a/vendor/gopkg.in/macaron.v1/logger.go +++ b/vendor/gopkg.in/macaron.v1/logger.go @@ -19,27 +19,39 @@ import ( "fmt" "log" "net/http" + "reflect" "runtime" "time" ) -var ColorLog = true +var ( + ColorLog = true + LogTimeFormat = "2006-01-02 15:04:05" +) func init() { ColorLog = runtime.GOOS != "windows" } +// LoggerInvoker is an inject.FastInvoker wrapper of func(ctx *Context, log *log.Logger). +type LoggerInvoker func(ctx *Context, log *log.Logger) + +func (invoke LoggerInvoker) Invoke(params []interface{}) ([]reflect.Value, error) { + invoke(params[0].(*Context), params[1].(*log.Logger)) + return nil, nil +} + // Logger returns a middleware handler that logs the request as it goes in and the response as it goes out. func Logger() Handler { return func(ctx *Context, log *log.Logger) { start := time.Now() - log.Printf("Started %s %s for %s", ctx.Req.Method, ctx.Req.RequestURI, ctx.RemoteAddr()) + log.Printf("%s: Started %s %s for %s", time.Now().Format(LogTimeFormat), ctx.Req.Method, ctx.Req.RequestURI, ctx.RemoteAddr()) rw := ctx.Resp.(ResponseWriter) ctx.Next() - content := fmt.Sprintf("Completed %s %v %s in %v", ctx.Req.RequestURI, rw.Status(), http.StatusText(rw.Status()), time.Since(start)) + content := fmt.Sprintf("%s: Completed %s %v %s in %v", time.Now().Format(LogTimeFormat), ctx.Req.RequestURI, rw.Status(), http.StatusText(rw.Status()), time.Since(start)) if ColorLog { switch rw.Status() { case 200, 201, 202: diff --git a/vendor/gopkg.in/macaron.v1/macaron.go b/vendor/gopkg.in/macaron.v1/macaron.go index 94fd3f0ce20..30ffca1cd18 100644 --- a/vendor/gopkg.in/macaron.v1/macaron.go +++ b/vendor/gopkg.in/macaron.v1/macaron.go @@ -24,6 +24,7 @@ import ( "os" "reflect" "strings" + "sync" "github.com/Unknwon/com" "gopkg.in/ini.v1" @@ -31,7 +32,7 @@ import ( "github.com/go-macaron/inject" ) -const _VERSION = "0.8.0.1013" +const _VERSION = "1.2.1.0213" func Version() string { return _VERSION @@ -42,20 +43,63 @@ func Version() string { // and panics if an argument could not be fullfilled via dependency injection. type Handler interface{} -// validateHandler makes sure a handler is a callable function, -// and panics if it is not. -func validateHandler(h Handler) { +// handlerFuncInvoker is an inject.FastInvoker wrapper of func(http.ResponseWriter, *http.Request). +type handlerFuncInvoker func(http.ResponseWriter, *http.Request) + +func (invoke handlerFuncInvoker) Invoke(params []interface{}) ([]reflect.Value, error) { + invoke(params[0].(http.ResponseWriter), params[1].(*http.Request)) + return nil, nil +} + +// internalServerErrorInvoker is an inject.FastInvoker wrapper of func(rw http.ResponseWriter, err error). +type internalServerErrorInvoker func(rw http.ResponseWriter, err error) + +func (invoke internalServerErrorInvoker) Invoke(params []interface{}) ([]reflect.Value, error) { + invoke(params[0].(http.ResponseWriter), params[1].(error)) + return nil, nil +} + +// validateAndWrapHandler makes sure a handler is a callable function, it panics if not. +// When the handler is also potential to be any built-in inject.FastInvoker, +// it wraps the handler automatically to have some performance gain. +func validateAndWrapHandler(h Handler) Handler { if reflect.TypeOf(h).Kind() != reflect.Func { panic("Macaron handler must be a callable function") } + + if !inject.IsFastInvoker(h) { + switch v := h.(type) { + case func(*Context): + return ContextInvoker(v) + case func(*Context, *log.Logger): + return LoggerInvoker(v) + case func(http.ResponseWriter, *http.Request): + return handlerFuncInvoker(v) + case func(http.ResponseWriter, error): + return internalServerErrorInvoker(v) + } + } + return h } -// validateHandlers makes sure handlers are callable functions, -// and panics if any of them is not. -func validateHandlers(handlers []Handler) { - for _, h := range handlers { - validateHandler(h) +// validateAndWrapHandlers preforms validation and wrapping for each input handler. +// It accepts an optional wrapper function to perform custom wrapping on handlers. +func validateAndWrapHandlers(handlers []Handler, wrappers ...func(Handler) Handler) []Handler { + var wrapper func(Handler) Handler + if len(wrappers) > 0 { + wrapper = wrappers[0] } + + wrappedHandlers := make([]Handler, len(handlers)) + for i, h := range handlers { + h = validateAndWrapHandler(h) + if wrapper != nil && !inject.IsFastInvoker(h) { + h = wrapper(h) + } + wrappedHandlers[i] = h + } + + return wrappedHandlers } // Macaron represents the top level web application. @@ -100,7 +144,7 @@ func New() *Macaron { } // Classic creates a classic Macaron with some basic default middleware: -// mocaron.Logger, mocaron.Recovery and mocaron.Static. +// macaron.Logger, macaron.Recovery and macaron.Static. func Classic() *Macaron { m := New() m.Use(Logger()) @@ -122,7 +166,7 @@ func (m *Macaron) Handlers(handlers ...Handler) { // Action sets the handler that will be called after all the middleware has been invoked. // This is set to macaron.Router in a macaron.Classic(). func (m *Macaron) Action(handler Handler) { - validateHandler(handler) + handler = validateAndWrapHandler(handler) m.action = handler } @@ -138,7 +182,7 @@ func (m *Macaron) Before(handler BeforeHandler) { // and panics if the handler is not a callable func. // Middleware Handlers are invoked in the order that they are added. func (m *Macaron) Use(handler Handler) { - validateHandler(handler) + handler = validateAndWrapHandler(handler) m.handlers = append(m.handlers, handler) } @@ -151,6 +195,7 @@ func (m *Macaron) createContext(rw http.ResponseWriter, req *http.Request) *Cont Router: m.Router, Req: Request{req}, Resp: NewResponseWriter(rw), + Render: &DummyRender{rw}, Data: make(map[string]interface{}), } c.SetParent(m) @@ -208,7 +253,7 @@ func (m *Macaron) Run(args ...interface{}) { addr := host + ":" + com.ToStr(port) logger := m.GetVal(reflect.TypeOf(m.logger)).Interface().(*log.Logger) - logger.Printf("listening on %s (%s)\n", addr, Env) + logger.Printf("listening on %s (%s)\n", addr, safeEnv()) logger.Fatalln(http.ListenAndServe(addr, m)) } @@ -234,7 +279,8 @@ const ( var ( // Env is the environment that Macaron is executing in. // The MACARON_ENV is read on initialization to set this variable. - Env = DEV + Env = DEV + envLock sync.Mutex // Path of work directory. Root string @@ -247,11 +293,21 @@ var ( ) func setENV(e string) { + envLock.Lock() + defer envLock.Unlock() + if len(e) > 0 { Env = e } } +func safeEnv() string { + envLock.Lock() + defer envLock.Unlock() + + return Env +} + func init() { setENV(os.Getenv("MACARON_ENV")) diff --git a/vendor/gopkg.in/macaron.v1/macaronlogo.png b/vendor/gopkg.in/macaron.v1/macaronlogo.png index a2ab537b6d8..399759769a8 100644 Binary files a/vendor/gopkg.in/macaron.v1/macaronlogo.png and b/vendor/gopkg.in/macaron.v1/macaronlogo.png differ diff --git a/vendor/gopkg.in/macaron.v1/render.go b/vendor/gopkg.in/macaron.v1/render.go index 3706e4fe414..f45e431240a 100644 --- a/vendor/gopkg.in/macaron.v1/render.go +++ b/vendor/gopkg.in/macaron.v1/render.go @@ -21,6 +21,7 @@ import ( "encoding/xml" "fmt" "html/template" + "io" "io/ioutil" "net/http" "os" @@ -72,6 +73,7 @@ type ( // TemplateFileSystem represents a interface of template file system that able to list all files. TemplateFileSystem interface { ListFiles() []TemplateFile + Get(string) (io.Reader, error) } // Delims represents a set of Left and Right delimiters for HTML template rendering @@ -86,6 +88,8 @@ type ( RenderOptions struct { // Directory to load templates. Default is "templates". Directory string + // Addtional directories to overwite templates. + AppendDirectories []string // Layout template name. Will not render a layout if "". Default is to "". Layout string // Extensions to parse template files from. Defaults are [".tmpl", ".html"]. @@ -172,8 +176,32 @@ func NewTemplateFileSystem(opt RenderOptions, omitData bool) TplFileSystem { fs := TplFileSystem{} fs.files = make([]TemplateFile, 0, 10) - if err := filepath.Walk(opt.Directory, func(path string, info os.FileInfo, err error) error { - r, err := filepath.Rel(opt.Directory, path) + // Directories are composed in reverse order because later one overwrites previous ones, + // so once found, we can directly jump out of the loop. + dirs := make([]string, 0, len(opt.AppendDirectories)+1) + for i := len(opt.AppendDirectories) - 1; i >= 0; i-- { + dirs = append(dirs, opt.AppendDirectories[i]) + } + dirs = append(dirs, opt.Directory) + + var err error + for i := range dirs { + // Skip ones that does not exists for symlink test, + // but allow non-symlink ones added after start. + if !com.IsExist(dirs[i]) { + continue + } + + dirs[i], err = filepath.EvalSymlinks(dirs[i]) + if err != nil { + panic("EvalSymlinks(" + dirs[i] + "): " + err.Error()) + } + } + lastDir := dirs[len(dirs)-1] + + // We still walk the last (original) directory because it's non-sense we load templates not exist in original directory. + if err = filepath.Walk(lastDir, func(path string, info os.FileInfo, err error) error { + r, err := filepath.Rel(lastDir, path) if err != nil { return err } @@ -181,19 +209,31 @@ func NewTemplateFileSystem(opt RenderOptions, omitData bool) TplFileSystem { ext := GetExt(r) for _, extension := range opt.Extensions { - if ext == extension { - var data []byte - if !omitData { + if ext != extension { + continue + } + + var data []byte + if !omitData { + // Loop over candidates of directory, break out once found. + // The file always exists because it's inside the walk function, + // and read original file is the worst case. + for i := range dirs { + path = filepath.Join(dirs[i], r) + if !com.IsFile(path) { + continue + } + data, err = ioutil.ReadFile(path) if err != nil { return err } + break } - - name := filepath.ToSlash((r[0 : len(r)-len(ext)])) - fs.files = append(fs.files, NewTplFile(name, data, ext)) - break } + + name := filepath.ToSlash((r[0 : len(r)-len(ext)])) + fs.files = append(fs.files, NewTplFile(name, data, ext)) } return nil @@ -208,6 +248,15 @@ func (fs TplFileSystem) ListFiles() []TemplateFile { return fs.files } +func (fs TplFileSystem) Get(name string) (io.Reader, error) { + for i := range fs.files { + if fs.files[i].Name()+fs.files[i].Ext() == name { + return bytes.NewReader(fs.files[i].Data()), nil + } + } + return nil, fmt.Errorf("file '%s' not found", name) +} + func PrepareCharset(charset string) string { if len(charset) != 0 { return "; charset=" + charset @@ -225,8 +274,7 @@ func GetExt(s string) string { } func compile(opt RenderOptions) *template.Template { - dir := opt.Directory - t := template.New(dir) + t := template.New(opt.Directory) t.Delims(opt.Delims.Left, opt.Delims.Right) // Parse an initial template in case we don't have any. template.Must(t.Parse("Macaron")) @@ -248,24 +296,25 @@ func compile(opt RenderOptions) *template.Template { } const ( - _DEFAULT_TPL_SET_NAME = "DEFAULT" + DEFAULT_TPL_SET_NAME = "DEFAULT" ) -// templateSet represents a template set of type *template.Template. -type templateSet struct { +// TemplateSet represents a template set of type *template.Template. +type TemplateSet struct { lock sync.RWMutex sets map[string]*template.Template dirs map[string]string } -func newTemplateSet() *templateSet { - return &templateSet{ +// NewTemplateSet initializes a new empty template set. +func NewTemplateSet() *TemplateSet { + return &TemplateSet{ sets: make(map[string]*template.Template), dirs: make(map[string]string), } } -func (ts *templateSet) Set(name string, opt *RenderOptions) *template.Template { +func (ts *TemplateSet) Set(name string, opt *RenderOptions) *template.Template { t := compile(*opt) ts.lock.Lock() @@ -276,14 +325,14 @@ func (ts *templateSet) Set(name string, opt *RenderOptions) *template.Template { return t } -func (ts *templateSet) Get(name string) *template.Template { +func (ts *TemplateSet) Get(name string) *template.Template { ts.lock.RLock() defer ts.lock.RUnlock() return ts.sets[name] } -func (ts *templateSet) GetDir(name string) string { +func (ts *TemplateSet) GetDir(name string) string { ts.lock.RLock() defer ts.lock.RUnlock() @@ -332,8 +381,8 @@ func ParseTplSet(tplSet string) (tplName string, tplDir string) { func renderHandler(opt RenderOptions, tplSets []string) Handler { cs := PrepareCharset(opt.Charset) - ts := newTemplateSet() - ts.Set(_DEFAULT_TPL_SET_NAME, &opt) + ts := NewTemplateSet() + ts.Set(DEFAULT_TPL_SET_NAME, &opt) var tmpOpt RenderOptions for _, tplSet := range tplSets { @@ -346,7 +395,7 @@ func renderHandler(opt RenderOptions, tplSets []string) Handler { return func(ctx *Context) { r := &TplRender{ ResponseWriter: ctx.Resp, - templateSet: ts, + TemplateSet: ts, Opt: &opt, CompiledCharset: cs, } @@ -379,7 +428,7 @@ func Renderers(options RenderOptions, tplSets ...string) Handler { type TplRender struct { http.ResponseWriter - *templateSet + *TemplateSet Opt *RenderOptions CompiledCharset string @@ -486,11 +535,11 @@ func (r *TplRender) addYield(t *template.Template, tplName string, data interfac } func (r *TplRender) renderBytes(setName, tplName string, data interface{}, htmlOpt ...HTMLOptions) (*bytes.Buffer, error) { - t := r.templateSet.Get(setName) + t := r.TemplateSet.Get(setName) if Env == DEV { opt := *r.Opt - opt.Directory = r.templateSet.GetDir(setName) - t = r.templateSet.Set(setName, &opt) + opt.Directory = r.TemplateSet.GetDir(setName) + t = r.TemplateSet.Set(setName, &opt) } if t == nil { return nil, fmt.Errorf("html/template: template \"%s\" is undefined", tplName) @@ -523,12 +572,14 @@ func (r *TplRender) renderHTML(status int, setName, tplName string, data interfa r.Header().Set(_CONTENT_TYPE, r.Opt.HTMLContentType+r.CompiledCharset) r.WriteHeader(status) - out.WriteTo(r) + if _, err := out.WriteTo(r); err != nil { + out.Reset() + } bufpool.Put(out) } func (r *TplRender) HTML(status int, name string, data interface{}, htmlOpt ...HTMLOptions) { - r.renderHTML(status, _DEFAULT_TPL_SET_NAME, name, data, htmlOpt...) + r.renderHTML(status, DEFAULT_TPL_SET_NAME, name, data, htmlOpt...) } func (r *TplRender) HTMLSet(status int, setName, tplName string, data interface{}, htmlOpt ...HTMLOptions) { @@ -544,7 +595,7 @@ func (r *TplRender) HTMLSetBytes(setName, tplName string, data interface{}, html } func (r *TplRender) HTMLBytes(name string, data interface{}, htmlOpt ...HTMLOptions) ([]byte, error) { - return r.HTMLSetBytes(_DEFAULT_TPL_SET_NAME, name, data, htmlOpt...) + return r.HTMLSetBytes(DEFAULT_TPL_SET_NAME, name, data, htmlOpt...) } func (r *TplRender) HTMLSetString(setName, tplName string, data interface{}, htmlOpt ...HTMLOptions) (string, error) { @@ -581,13 +632,94 @@ func (r *TplRender) prepareHTMLOptions(htmlOpt []HTMLOptions) HTMLOptions { func (r *TplRender) SetTemplatePath(setName, dir string) { if len(setName) == 0 { - setName = _DEFAULT_TPL_SET_NAME + setName = DEFAULT_TPL_SET_NAME } opt := *r.Opt opt.Directory = dir - r.templateSet.Set(setName, &opt) + r.TemplateSet.Set(setName, &opt) } func (r *TplRender) HasTemplateSet(name string) bool { - return r.templateSet.Get(name) != nil + return r.TemplateSet.Get(name) != nil +} + +// DummyRender is used when user does not choose any real render to use. +// This way, we can print out friendly message which asks them to register one, +// instead of ugly and confusing 'nil pointer' panic. +type DummyRender struct { + http.ResponseWriter +} + +func renderNotRegistered() { + panic("middleware render hasn't been registered") +} + +func (r *DummyRender) SetResponseWriter(http.ResponseWriter) { + renderNotRegistered() +} + +func (r *DummyRender) JSON(int, interface{}) { + renderNotRegistered() +} + +func (r *DummyRender) JSONString(interface{}) (string, error) { + renderNotRegistered() + return "", nil +} + +func (r *DummyRender) RawData(int, []byte) { + renderNotRegistered() +} + +func (r *DummyRender) PlainText(int, []byte) { + renderNotRegistered() +} + +func (r *DummyRender) HTML(int, string, interface{}, ...HTMLOptions) { + renderNotRegistered() +} + +func (r *DummyRender) HTMLSet(int, string, string, interface{}, ...HTMLOptions) { + renderNotRegistered() +} + +func (r *DummyRender) HTMLSetString(string, string, interface{}, ...HTMLOptions) (string, error) { + renderNotRegistered() + return "", nil +} + +func (r *DummyRender) HTMLString(string, interface{}, ...HTMLOptions) (string, error) { + renderNotRegistered() + return "", nil +} + +func (r *DummyRender) HTMLSetBytes(string, string, interface{}, ...HTMLOptions) ([]byte, error) { + renderNotRegistered() + return nil, nil +} + +func (r *DummyRender) HTMLBytes(string, interface{}, ...HTMLOptions) ([]byte, error) { + renderNotRegistered() + return nil, nil +} + +func (r *DummyRender) XML(int, interface{}) { + renderNotRegistered() +} + +func (r *DummyRender) Error(int, ...string) { + renderNotRegistered() +} + +func (r *DummyRender) Status(int) { + renderNotRegistered() +} + +func (r *DummyRender) SetTemplatePath(string, string) { + renderNotRegistered() +} + +func (r *DummyRender) HasTemplateSet(string) bool { + renderNotRegistered() + return false } diff --git a/vendor/gopkg.in/macaron.v1/router.go b/vendor/gopkg.in/macaron.v1/router.go index f9b421a3302..21b00ec98ca 100644 --- a/vendor/gopkg.in/macaron.v1/router.go +++ b/vendor/gopkg.in/macaron.v1/router.go @@ -82,6 +82,9 @@ type Router struct { groups []group notFound http.HandlerFunc internalServerError func(*Context, error) + + // handlerWrapper is used to wrap arbitrary function from Handler to inject.FastInvoker. + handlerWrapper func(Handler) Handler } func NewRouter() *Router { @@ -173,7 +176,7 @@ func (r *Router) Handle(method string, pattern string, handlers []Handler) *Rout h = append(h, handlers...) handlers = h } - validateHandlers(handlers) + handlers = validateAndWrapHandlers(handlers, r.handlerWrapper) return r.handle(method, pattern, func(resp http.ResponseWriter, req *http.Request, params Params) { c := r.m.createContext(resp, req) @@ -251,23 +254,25 @@ func (r *Router) Combo(pattern string, h ...Handler) *ComboRouter { return &ComboRouter{r, pattern, h, map[string]bool{}, nil} } -// Configurable http.HandlerFunc which is called when no matching route is +// NotFound configurates http.HandlerFunc which is called when no matching route is // found. If it is not set, http.NotFound is used. // Be sure to set 404 response code in your handler. func (r *Router) NotFound(handlers ...Handler) { - validateHandlers(handlers) + handlers = validateAndWrapHandlers(handlers) r.notFound = func(rw http.ResponseWriter, req *http.Request) { c := r.m.createContext(rw, req) - c.handlers = append(r.m.handlers, handlers...) + c.handlers = make([]Handler, 0, len(r.m.handlers)+len(handlers)) + c.handlers = append(c.handlers, r.m.handlers...) + c.handlers = append(c.handlers, handlers...) c.run() } } -// Configurable handler which is called when route handler returns +// InternalServerError configurates handler which is called when route handler returns // error. If it is not set, default handler is used. // Be sure to set 500 response code in your handler. func (r *Router) InternalServerError(handlers ...Handler) { - validateHandlers(handlers) + handlers = validateAndWrapHandlers(handlers) r.internalServerError = func(c *Context, err error) { c.index = 0 c.handlers = handlers @@ -276,6 +281,11 @@ func (r *Router) InternalServerError(handlers ...Handler) { } } +// SetHandlerWrapper sets handlerWrapper for the router. +func (r *Router) SetHandlerWrapper(f func(Handler) Handler) { + r.handlerWrapper = f +} + func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) { if t, ok := r.routers[req.Method]; ok { h, p, ok := t.Match(req.URL.Path) diff --git a/vendor/gopkg.in/macaron.v1/static.go b/vendor/gopkg.in/macaron.v1/static.go index 4ff8342fc5e..60c521110e7 100644 --- a/vendor/gopkg.in/macaron.v1/static.go +++ b/vendor/gopkg.in/macaron.v1/static.go @@ -16,6 +16,7 @@ package macaron import ( + "encoding/base64" "log" "net/http" "path" @@ -35,6 +36,9 @@ type StaticOptions struct { // Expires defines which user-defined function to use for producing a HTTP Expires Header // https://developers.google.com/speed/docs/insights/LeverageBrowserCaching Expires func() string + // ETag defines if we should add an ETag header + // https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#validating-cached-responses-with-etags + ETag bool // FileSystem is the interface for supporting any implmentation of file system. FileSystem http.FileSystem } @@ -172,10 +176,21 @@ func staticHandler(ctx *Context, log *log.Logger, opt StaticOptions) bool { ctx.Resp.Header().Set("Expires", opt.Expires()) } + if opt.ETag { + tag := GenerateETag(string(fi.Size()), fi.Name(), fi.ModTime().UTC().Format(http.TimeFormat)) + ctx.Resp.Header().Set("ETag", tag) + } + http.ServeContent(ctx.Resp, ctx.Req.Request, file, fi.ModTime(), f) return true } +// GenerateETag generates an ETag based on size, filename and file modification time +func GenerateETag(fileSize, fileName, modTime string) string { + etag := fileSize + fileName + modTime + return base64.StdEncoding.EncodeToString([]byte(etag)) +} + // Static returns a middleware handler that serves static files in the given directory. func Static(directory string, staticOpt ...StaticOptions) Handler { opt := prepareStaticOptions(directory, staticOpt) diff --git a/vendor/vendor.json b/vendor/vendor.json index ee79351492d..4e884428eb7 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -6,6 +6,12 @@ "path": "appengine/cloudsql", "revision": "" }, + { + "checksumSHA1": "7HXb3cry6luicWeJM9Uxwzfo9Rs=", + "path": "github.com/Unknwon/com", + "revision": "0db4a625e949e956314d7d1adea9bf82384cc10c", + "revisionTime": "2017-02-13T07:20:14Z" + }, { "checksumSHA1": "6nleggdedlS1mdzSnu1xf1Pnd+8=", "path": "github.com/aws/aws-sdk-go", @@ -358,6 +364,24 @@ "version": "v1.21.1", "versionExact": "v1.21.1" }, + { + "checksumSHA1": "OkqfwXeTVoiIxNMDA7HKvmrCDw8=", + "path": "github.com/go-macaron/binding", + "revision": "48920167fa152d02f228cfbece7e0f1e452d200a", + "revisionTime": "2016-12-22T07:05:54Z" + }, + { + "checksumSHA1": "y0olVbiMQ6/UOa/eh52XYnies90=", + "path": "github.com/go-macaron/inject", + "revision": "d8a0b8677191f4380287cfebd08e462217bac7ad", + "revisionTime": "2016-06-27T17:00:12Z" + }, + { + "checksumSHA1": "gO0dj0NqsmBTkf4D0JzJDtOEx+U=", + "path": "github.com/go-macaron/session", + "revision": "b8e286a0dba8f4999042d6b258daf51b31d08938", + "revisionTime": "2017-03-20T17:22:09Z" + }, { "checksumSHA1": "42vkdsxNaLyPu+FktCzZ/8zsNSE=", "path": "github.com/go-sql-driver/mysql", @@ -452,6 +476,12 @@ "revision": "5db88ed452e937f2fd557de6f4f1af7f2eabed0b", "revisionTime": "2016-08-23T18:01:44Z" }, + { + "checksumSHA1": "1MGpGDQqnUoRpv7VEcQrXOBydXE=", + "path": "golang.org/x/crypto/pbkdf2", + "revision": "3543873453996aaab2fc6b3928a35fc5ca2b5afb", + "revisionTime": "2017-04-18T16:44:36Z" + }, { "checksumSHA1": "WHc3uByvGaMcnSoI21fhzYgbOgg=", "path": "golang.org/x/net/context/ctxhttp", @@ -487,6 +517,12 @@ "path": "gopkg.in/gomail.v2", "revision": "81ebce5c23dfd25c6c67194b37d3dd3f338c98b1", "revisionTime": "2016-04-11T21:29:32Z" + }, + { + "checksumSHA1": "1HJvJZheB5NNl3i1R9zZJpiJ1G0=", + "path": "gopkg.in/macaron.v1", + "revision": "a325110f8b392bce3e5cdeb8c44bf98078ada3be", + "revisionTime": "2017-02-13T09:12:08Z" } ], "rootPath": "github.com/grafana/grafana"