Browse Source

tech: upgraded macaron & macaron inject, binding, session

Torkel Ödegaard 8 years ago
parent
commit
4720216e5e
39 changed files with 737 additions and 1316 deletions
  1. 0 24
      vendor/github.com/Unknwon/com/.gitignore
  2. 4 8
      vendor/github.com/Unknwon/com/README.md
  3. 0 140
      vendor/github.com/Unknwon/com/cmd_test.go
  4. 1 1
      vendor/github.com/Unknwon/com/convert.go
  5. 0 56
      vendor/github.com/Unknwon/com/convert_test.go
  6. 0 58
      vendor/github.com/Unknwon/com/dir_test.go
  7. 0 299
      vendor/github.com/Unknwon/com/example_test.go
  8. 0 61
      vendor/github.com/Unknwon/com/file_test.go
  9. 0 35
      vendor/github.com/Unknwon/com/html_test.go
  10. 0 111
      vendor/github.com/Unknwon/com/http_test.go
  11. 10 5
      vendor/github.com/Unknwon/com/math.go
  12. 3 3
      vendor/github.com/Unknwon/com/path.go
  13. 0 67
      vendor/github.com/Unknwon/com/path_test.go
  14. 0 70
      vendor/github.com/Unknwon/com/regex_test.go
  15. 0 99
      vendor/github.com/Unknwon/com/slice_test.go
  16. 134 21
      vendor/github.com/Unknwon/com/string.go
  17. 0 82
      vendor/github.com/Unknwon/com/string_test.go
  18. 0 14
      vendor/github.com/go-macaron/binding/.travis.yml
  19. 28 22
      vendor/github.com/go-macaron/binding/binding.go
  20. 0 14
      vendor/github.com/go-macaron/inject/.travis.yml
  21. 68 8
      vendor/github.com/go-macaron/inject/inject.go
  22. 0 2
      vendor/github.com/go-macaron/session/.gitignore
  23. 0 14
      vendor/github.com/go-macaron/session/.travis.yml
  24. 2 2
      vendor/github.com/go-macaron/session/README.md
  25. 6 6
      vendor/github.com/go-macaron/session/file.go
  26. 27 0
      vendor/golang.org/x/crypto/LICENSE
  27. 22 0
      vendor/golang.org/x/crypto/PATENTS
  28. 77 0
      vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
  29. 0 2
      vendor/gopkg.in/macaron.v1/.gitignore
  30. 0 13
      vendor/gopkg.in/macaron.v1/.travis.yml
  31. 6 8
      vendor/gopkg.in/macaron.v1/README.md
  32. 33 16
      vendor/gopkg.in/macaron.v1/context.go
  33. 15 3
      vendor/gopkg.in/macaron.v1/logger.go
  34. 70 14
      vendor/gopkg.in/macaron.v1/macaron.go
  35. BIN
      vendor/gopkg.in/macaron.v1/macaronlogo.png
  36. 164 32
      vendor/gopkg.in/macaron.v1/render.go
  37. 16 6
      vendor/gopkg.in/macaron.v1/router.go
  38. 15 0
      vendor/gopkg.in/macaron.v1/static.go
  39. 36 0
      vendor/vendor.json

+ 0 - 24
vendor/github.com/Unknwon/com/.gitignore

@@ -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

+ 4 - 8
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** .

+ 0 - 140
vendor/github.com/Unknwon/com/cmd_test.go

@@ -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")
-	}
-}

+ 1 - 1
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
 }
 

+ 0 - 56
vendor/github.com/Unknwon/com/convert_test.go

@@ -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)
-		}
-	})
-}

+ 0 - 58
vendor/github.com/Unknwon/com/dir_test.go

@@ -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")
-	}
-}

+ 0 - 299
vendor/github.com/Unknwon/com/example_test.go

@@ -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 := "<div id=\"button\" class=\"btn\">Click me</div>\n\r"
-	js := string(com.Html2JS([]byte(htm)))
-	fmt.Println(js)
-	// Output: <div id=\"button\" class=\"btn\">Click me</div>\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 ------------

+ 0 - 61
vendor/github.com/Unknwon/com/file_test.go

@@ -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")
-	}
-}

+ 0 - 35
vendor/github.com/Unknwon/com/html_test.go

@@ -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 := "<div id=\"button\" class=\"btn\">Click me</div>\n\r"
-	js := string(Html2JS([]byte(htm)))
-	jsR := `<div id=\"button\" class=\"btn\">Click me</div>\n`
-	if js != jsR {
-		t.Errorf("Html2JS:\n Expect => %s\n Got => %s\n", jsR, js)
-	}
-}
-
-func BenchmarkHtml2JS(b *testing.B) {
-	htm := "<div id=\"button\" class=\"btn\">Click me</div>\n\r"
-	for i := 0; i < b.N; i++ {
-		Html2JS([]byte(htm))
-	}
-}

+ 0 - 111
vendor/github.com/Unknwon/com/http_test.go

@@ -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 = `<!doctype html>
-<html>
-<head>
-    <title>Example Domain</title>
-`
-
-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()))
-	}
-}

+ 10 - 5
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
 }

+ 3 - 3
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")

+ 0 - 67
vendor/github.com/Unknwon/com/path_test.go

@@ -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()
-	}
-}

+ 0 - 70
vendor/github.com/Unknwon/com/regex_test.go

@@ -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")
-	}
-}

+ 0 - 99
vendor/github.com/Unknwon/com/slice_test.go

@@ -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)
-	}
-}

+ 134 - 21
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
+	}
+
+	nonce := make([]byte, gcm.NonceSize())
+	if _, err := rand.Read(nonce); err != nil {
 		return nil, err
 	}
-	cfb := cipher.NewCFBEncrypter(block, iv)
-	cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
-	return ciphertext, nil
+
+	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")
+
+	gcm, err := cipher.NewGCM(block)
+	if err != nil {
+		return nil, err
 	}
-	iv := text[:aes.BlockSize]
-	text = text[aes.BlockSize:]
-	cfb := cipher.NewCFBDecrypter(block, iv)
-	cfb.XORKeyStream(text, text)
-	data, err := base64.StdEncoding.DecodeString(string(text))
+
+	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 data, nil
+
+	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()
+}

+ 0 - 82
vendor/github.com/Unknwon/com/string_test.go

@@ -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)
-	}
-}

+ 0 - 14
vendor/github.com/go-macaron/binding/.travis.yml

@@ -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

+ 28 - 22
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\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?`)
+	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\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?`)
 )
 
 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.

+ 0 - 14
vendor/github.com/go-macaron/inject/.travis.yml

@@ -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

+ 68 - 8
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)
+	switch v := f.(type) {
+	case FastInvoker:
+		return inj.fastInvoke(v, t, t.NumIn())
+	default:
+		return inj.callInvoke(f, t, t.NumIn())
+	}
+}
 
-	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)
-		}
+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
+			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
 }
 

+ 0 - 2
vendor/github.com/go-macaron/session/.gitignore

@@ -1,2 +0,0 @@
-ledis/tmp.db
-nodb/tmp.db

+ 0 - 14
vendor/github.com/go-macaron/session/.travis.yml

@@ -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

+ 2 - 2
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
 

+ 6 - 6
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 {

+ 27 - 0
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.

+ 22 - 0
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.

+ 77 - 0
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]
+}

+ 0 - 2
vendor/gopkg.in/macaron.v1/.gitignore

@@ -1,2 +0,0 @@
-macaron.sublime-project
-macaron.sublime-workspace

+ 0 - 13
vendor/gopkg.in/macaron.v1/.travis.yml

@@ -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

+ 6 - 8
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

+ 33 - 16
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
 }
 

+ 15 - 3
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:

+ 70 - 14
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"))
 

BIN
vendor/gopkg.in/macaron.v1/macaronlogo.png


+ 164 - 32
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
 }

+ 16 - 6
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)

+ 15 - 0
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)

+ 36 - 0
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"