9 | );
10 | }
11 |
12 | });
13 |
14 | module.exports = HelloWorld;
--------------------------------------------------------------------------------
/modules/assets.go:
--------------------------------------------------------------------------------
1 | // +build !bindata
2 |
3 | package modules
4 |
5 | import "github.com/go-macaron/macaron"
6 |
7 | var (
8 | Public = macaron.Static("public", macaron.StaticOptions{
9 | Prefix: "-",
10 | })
11 | Renderer = macaron.Renderer()
12 | )
13 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 | .idea
10 |
11 | # Architecture specific extensions/prefixes
12 | *.[568vq]
13 | [568vq].out
14 |
15 | *.cgo1.go
16 | *.cgo2.c
17 | _cgo_defun.c
18 | _cgo_gotypes.go
19 | _cgo_export.*
20 |
21 | _testmain.go
22 |
23 | *.exe
24 | *.iml
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | _testmain.go
21 |
22 | *.exe
23 | *.test
24 | *.prof
25 | node_modules/
26 | bindata.go
27 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var WebpackDevServer = require('webpack-dev-server');
3 | var config = require('./webpack.config');
4 |
5 | new WebpackDevServer(webpack(config), {
6 | publicPath: config.output.publicPath,
7 | hot: true,
8 | historyApiFallback: true
9 | }).listen(3000, 'localhost', function (err, result) {
10 | if (err) {
11 | console.log(err);
12 | }
13 |
14 | console.log('Listening at localhost:3000');
15 | });
16 |
--------------------------------------------------------------------------------
/vendor/github.com/elazarl/go-bindata-assetfs/doc.go:
--------------------------------------------------------------------------------
1 | // assetfs allows packages to serve static content embedded
2 | // with the go-bindata tool with the standard net/http package.
3 | //
4 | // See https://github.com/jteeuwen/go-bindata for more information
5 | // about embedding binary data with go-bindata.
6 | //
7 | // Usage example, after running
8 | // $ go-bindata data/...
9 | // use:
10 | // http.Handle("/",
11 | // http.FileServer(
12 | // &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, Prefix: "data"}))
13 | package assetfs
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "codeskyblue@gmail.com",
3 | "license": "MIT",
4 | "scripts": {
5 | "start": "node server.js"
6 | },
7 | "devDependencies": {
8 | "babel-core": "^5.4.7",
9 | "babel-eslint": "^4.1.3",
10 | "babel-loader": "^5.1.2",
11 | "css-loader": "^0.19.0",
12 | "eslint-plugin-react": "^3.5.1",
13 | "json-loader": "^0.5.3",
14 | "react-hot-loader": "^1.3.0",
15 | "style-loader": "^0.12.4",
16 | "webpack": "^1.12.2",
17 | "webpack-dev-server": "^1.8.2"
18 | },
19 | "dependencies": {
20 | "react": "^0.14.0",
21 | "react-dom": "^0.14.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/vendor/github.com/go-macaron/inject/README.md:
--------------------------------------------------------------------------------
1 | # inject [](https://travis-ci.org/go-macaron/inject) [](http://gocover.io/github.com/go-macaron/inject)
2 |
3 | Package inject provides utilities for mapping and injecting dependencies in various ways.
4 |
5 | **This a modified version of [codegangsta/inject](https://github.com/codegangsta/inject) for special purpose of Macaron**
6 |
7 | **Please use the original version if you need dependency injection feature**
8 |
9 | ## License
10 |
11 | This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text.
--------------------------------------------------------------------------------
/vendor/github.com/macaron-contrib/bindata/README.md:
--------------------------------------------------------------------------------
1 | bindata [](https://drone.io/github.com/macaron-contrib/bindata/latest)
2 | =======
3 |
4 | Package bindata is a helper module that allows to use in-memory static and template files for Macaron via [go-bindata](https://github.com/jteeuwen/go-bindata).
5 |
6 | ### Installation
7 |
8 | go get github.com/macaron-contrib/bindata
9 |
10 | ## Getting Help
11 |
12 | - [API Reference](https://gowalker.org/github.com/macaron-contrib/bindata)
13 | - [Documentation](http://macaron.gogs.io/docs/middlewares/bindata)
14 |
15 | ## License
16 |
17 | This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text.
--------------------------------------------------------------------------------
/templates/homepage.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Go-Reactjs-Example
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/webpack.config.prod.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var path = require('path');
3 |
4 | module.exports = {
5 | evtool: 'eval',
6 | entry: [
7 | "./public/entry.js"
8 | ],
9 | output: {
10 | path: path.join(__dirname, 'public'),
11 | filename: "bundle.js",
12 | publicPath: "/-/"
13 | },
14 | module: {
15 | loaders: [
16 | {test: /\.css$/, loader: "style!css"},
17 | {
18 | test: /\.jsx$/,
19 | loaders: ['babel'],
20 | include: [path.join(__dirname, 'public')]
21 | }
22 | ]
23 | },
24 | plugins: [
25 | new webpack.HotModuleReplacementPlugin(),
26 | new webpack.ProvidePlugin({
27 | $: "jquery",
28 | jQuery: "jquery",
29 | "window.jQuery": "jquery"
30 | })
31 | ],
32 | resolve: {
33 | extensions: ['', '.js', 'jsx']
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/modules/assets_bindata.go:
--------------------------------------------------------------------------------
1 | // +build bindata
2 |
3 | package modules
4 |
5 | import (
6 | "github.com/Unknwon/macaron"
7 | "github.com/codeskyblue/go-reactjs-example/public"
8 | "github.com/codeskyblue/go-reactjs-example/templates"
9 | "github.com/macaron-contrib/bindata"
10 | )
11 |
12 | var Public = macaron.Static("public",
13 | macaron.StaticOptions{
14 | Prefix: "-",
15 | FileSystem: bindata.Static(bindata.Options{
16 | Asset: public.Asset,
17 | AssetDir: public.AssetDir,
18 | AssetNames: public.AssetNames,
19 | Prefix: "",
20 | }),
21 | })
22 |
23 | var Renderer = macaron.Renderer(macaron.RenderOptions{
24 | TemplateFileSystem: bindata.Templates(bindata.Options{
25 | Asset: templates.Asset,
26 | AssetDir: templates.AssetDir,
27 | AssetNames: templates.AssetNames,
28 | Prefix: "",
29 | }),
30 | })
31 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Makefile
3 | # hzsunshx, 2015-02-11 13:17
4 | #
5 |
6 | dev: clean
7 | npm start
8 |
9 | prod: bundle binary
10 |
11 | bundle:
12 | webpack -p --progress --config webpack.config.prod.js
13 |
14 | binary:
15 | go get github.com/jteeuwen/go-bindata/...
16 | (cd public; go-bindata -pkg public favicon.ico bundle.js js/ css/)
17 | (cd templates; go-bindata -pkg templates ./...)
18 | go get -tags "bindata"
19 | go build -tags "bindata"
20 |
21 | install-deps:
22 | sudo apt-get update -qq
23 | sudo apt-get install -qq nodejs npm
24 |
25 | deps:
26 | npm install
27 |
28 | cross-build:
29 | GOOS=windows GOARCH=386 go build
30 | GOOS=linux GOARCH=386 go build -o fileserv-linux-386
31 | GOOS=linux GOARCH=amd64 go build -o fileserv-linux-amd64
32 |
33 | webpack:
34 | webpack
35 |
36 | clean:
37 | rm -f public/bundle.js
38 | # vim:ft=make
39 | #
40 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var path = require('path');
3 |
4 | module.exports = {
5 | evtool: 'eval',
6 | entry: [
7 | 'webpack-dev-server/client?http://localhost:3000',
8 | 'webpack/hot/only-dev-server',
9 | "./public/entry.js"
10 | ],
11 | output: {
12 | path: path.join(__dirname, 'public'),
13 | filename: "bundle.js",
14 | publicPath: "/-/"
15 | },
16 | module: {
17 | loaders: [
18 | {test: /\.css$/, loader: "style!css"},
19 | {
20 | test: /\.jsx$/,
21 | loaders: ['react-hot', 'babel'],
22 | include: [path.join(__dirname, 'public')]
23 | }
24 | ]
25 | },
26 | plugins: [
27 | new webpack.HotModuleReplacementPlugin(),
28 | new webpack.ProvidePlugin({
29 | $: "jquery",
30 | jQuery: "jquery",
31 | "window.jQuery": "jquery"
32 | })
33 | ],
34 | resolve: {
35 | extensions: ['', '.js', 'jsx']
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/math.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | // PowInt is int type of math.Pow function.
18 | func PowInt(x int, y int) int {
19 | if y <= 0 {
20 | return 1
21 | } else {
22 | if y % 2 == 0 {
23 | sqrt := PowInt(x, y/2)
24 | return sqrt * sqrt
25 | } else {
26 | return PowInt(x, y-1) * x
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/README.md:
--------------------------------------------------------------------------------
1 | Common Functions
2 | ================
3 |
4 | [](https://travis-ci.org/Unknwon/com) [](http://gowalker.org/github.com/Unknwon/com)
5 |
6 | This is an open source project for commonly used functions for the Go programming language.
7 |
8 | This package need >= **go 1.2**
9 |
10 | Code Convention: based on [Go Code Convention](https://github.com/Unknwon/go-code-convention).
11 |
12 | ## Contribute
13 |
14 | Your contribute is welcome, but you have to check following steps after you added some functions and commit them:
15 |
16 | 1. Make sure you wrote user-friendly comments for **all functions** .
17 | 2. Make sure you wrote test cases with any possible condition for **all functions** in file `*_test.go`.
18 | 3. Make sure you wrote benchmarks for **all functions** in file `*_test.go`.
19 | 4. Make sure you wrote useful examples for **all functions** in file `example_test.go`.
20 | 5. Make sure you ran `go test` and got **PASS** .
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # go-reactjs-example
2 | This is an exmple web use Golang([macaron](https://github.com/Unknwon/macaron)) And ReactJS
3 |
4 | A real world project use go and reactjs. example: [file-server](https://github.com/codeskyblue/file-server)
5 |
6 | ## Build
7 | Suggest install node through [nvm](https://github.com/creationix/nvm)
8 |
9 | npm install -g webpack
10 | npm install
11 | make prod
12 |
13 | ### Develop
14 | Your need to know what is react, and golang.
15 | In develop mode, Support react hot reload
16 |
17 | npm install
18 | make dev
19 |
20 | Open another terminal
21 |
22 | go run main.go
23 |
24 | Open browser, navgate to
25 |
26 | Edit file `public/HelloWorld.jsx` Can see live change.
27 |
28 | Good luck. ^0^
29 |
30 | ## Thanks
31 | 1.
32 | 1. [update package.json dependencies](http://stackoverflow.com/questions/16073603/how-do-i-update-each-dependency-in-package-json-to-the-latest-version)
33 | 1. [react hot reload QA](https://github.com/gaearon/react-hot-loader/blob/master/docs/Troubleshooting.md)
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 shengxiang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Godeps/Godeps.json:
--------------------------------------------------------------------------------
1 | {
2 | "ImportPath": "github.com/codeskyblue/go-reactjs-example",
3 | "GoVersion": "go1.7",
4 | "GodepVersion": "v74",
5 | "Deps": [
6 | {
7 | "ImportPath": "github.com/Unknwon/com",
8 | "Comment": "v1",
9 | "Rev": "28b053d5a2923b87ce8c5a08f3af779894a72758"
10 | },
11 | {
12 | "ImportPath": "github.com/Unknwon/macaron",
13 | "Rev": "9b82b0372a4edf52f66fbc8feaa6aafe0123001d"
14 | },
15 | {
16 | "ImportPath": "github.com/Unknwon/macaron/inject",
17 | "Rev": "9b82b0372a4edf52f66fbc8feaa6aafe0123001d"
18 | },
19 | {
20 | "ImportPath": "github.com/elazarl/go-bindata-assetfs",
21 | "Rev": "d5cac425555ca5cf00694df246e04f05e6a55150"
22 | },
23 | {
24 | "ImportPath": "github.com/go-macaron/inject",
25 | "Rev": "c5ab7bf3a307593cd44cb272d1a5beea473dd072"
26 | },
27 | {
28 | "ImportPath": "github.com/go-macaron/macaron",
29 | "Rev": "93b6fdef06cc9bc57b18a85318b58fe7c42e5fee"
30 | },
31 | {
32 | "ImportPath": "github.com/macaron-contrib/bindata",
33 | "Rev": "8034104f1486732c68b88433eaac22a20ee9040a"
34 | },
35 | {
36 | "ImportPath": "gopkg.in/ini.v1",
37 | "Comment": "v0-43-gaea5e9f",
38 | "Rev": "aea5e9fd2e7dc7701717f980b20ccbced24cbb85"
39 | }
40 | ]
41 | }
42 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/url.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | import (
18 | "encoding/base64"
19 | "net/url"
20 | )
21 |
22 | // url encode string, is + not %20
23 | func UrlEncode(str string) string {
24 | return url.QueryEscape(str)
25 | }
26 |
27 | // url decode string
28 | func UrlDecode(str string) (string, error) {
29 | return url.QueryUnescape(str)
30 | }
31 |
32 | // base64 encode
33 | func Base64Encode(str string) string {
34 | return base64.StdEncoding.EncodeToString([]byte(str))
35 | }
36 |
37 | // base64 decode
38 | func Base64Decode(str string) (string, error) {
39 | s, e := base64.StdEncoding.DecodeString(str)
40 | return string(s), e
41 | }
42 |
--------------------------------------------------------------------------------
/vendor/github.com/elazarl/go-bindata-assetfs/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014, Elazar Leibovich
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
--------------------------------------------------------------------------------
/vendor/github.com/elazarl/go-bindata-assetfs/README.md:
--------------------------------------------------------------------------------
1 | # go-bindata-assetfs
2 |
3 | Serve embedded files from [jteeuwen/go-bindata](https://github.com/jteeuwen/go-bindata) with `net/http`.
4 |
5 | [GoDoc](http://godoc.org/github.com/elazarl/go-bindata-assetfs)
6 |
7 | ### Installation
8 |
9 | Install with
10 |
11 | $ go get github.com/jteeuwen/go-bindata/...
12 | $ go get github.com/elazarl/go-bindata-assetfs/...
13 |
14 | ### Creating embedded data
15 |
16 | Usage is identical to [jteeuwen/go-bindata](https://github.com/jteeuwen/go-bindata) usage,
17 | instead of running `go-bindata` run `go-bindata-assetfs`.
18 |
19 | The tool will create a `bindata_assetfs.go` file, which contains the embedded data.
20 |
21 | A typical use case is
22 |
23 | $ go-bindata-assetfs data/...
24 |
25 | ### Using assetFS in your code
26 |
27 | The generated file provides an `assetFS()` function that returns a `http.Filesystem`
28 | wrapping the embedded files. What you usually want to do is:
29 |
30 | http.Handle("/", http.FileServer(assetFS()))
31 |
32 | This would run an HTTP server serving the embedded files.
33 |
34 | ## Without running binary tool
35 |
36 | You can always just run the `go-bindata` tool, and then
37 |
38 | use
39 |
40 | import "github.com/elazarl/go-bindata-assetfs"
41 | ...
42 | http.Handle("/",
43 | http.FileServer(
44 | &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, Prefix: "data"}))
45 |
46 | to serve files embedded from the `data` directory.
47 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "io"
6 | "log"
7 | "net/http"
8 | "strconv"
9 |
10 | "github.com/go-macaron/macaron"
11 | "github.com/codeskyblue/go-reactjs-example/modules"
12 | )
13 |
14 | type Configure struct {
15 | port int
16 | root string
17 | private bool
18 | }
19 |
20 | var gcfg = Configure{}
21 |
22 | var m *macaron.Macaron
23 |
24 | func init() {
25 | m = macaron.Classic()
26 | m.Use(modules.Public)
27 | m.Use(modules.Renderer)
28 |
29 | flag.IntVar(&gcfg.port, "port", 8000, "Which port to listen")
30 | flag.BoolVar(&gcfg.private, "private", false, "Only listen on lookback interface, otherwise listen on all interface")
31 | }
32 |
33 | func initRouters() {
34 | m.Get("/", func(ctx *macaron.Context) {
35 | ctx.HTML(200, "homepage", nil)
36 | })
37 |
38 | ReloadProxy := func(w http.ResponseWriter, r *http.Request) {
39 | log.Println("Debug, Hot reload", r.Host)
40 | resp, err := http.Get("http://localhost:3000" + r.RequestURI)
41 | if err != nil {
42 | http.Error(w, err.Error(), 500)
43 | return
44 | }
45 | defer resp.Body.Close()
46 | io.Copy(w, resp.Body)
47 | }
48 | m.Get("/-/:rand(.*).hot-update.:ext(.*)", ReloadProxy)
49 | m.Get("/-/bundle.js", ReloadProxy)
50 | }
51 |
52 | func main() {
53 | flag.Parse()
54 | initRouters()
55 |
56 | http.Handle("/", m)
57 |
58 | int := ":" + strconv.Itoa(gcfg.port)
59 | p := strconv.Itoa(gcfg.port)
60 | mesg := "; please visit http://127.0.0.1:" + p
61 | if gcfg.private {
62 | int = "localhost" + int
63 | log.Printf("listens on 127.0.0.1@" + p + mesg)
64 | } else {
65 | log.Printf("listens on 0.0.0.0@" + p + mesg)
66 | }
67 | if err := http.ListenAndServe(int, nil); err != nil {
68 | log.Fatal(err)
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/html.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | import (
18 | "html"
19 | "regexp"
20 | "strings"
21 | )
22 |
23 | // Html2JS converts []byte type of HTML content into JS format.
24 | func Html2JS(data []byte) []byte {
25 | s := string(data)
26 | s = strings.Replace(s, `\`, `\\`, -1)
27 | s = strings.Replace(s, "\n", `\n`, -1)
28 | s = strings.Replace(s, "\r", "", -1)
29 | s = strings.Replace(s, "\"", `\"`, -1)
30 | s = strings.Replace(s, "
", "<table>", -1)
31 | return []byte(s)
32 | }
33 |
34 | // encode html chars to string
35 | func HtmlEncode(str string) string {
36 | return html.EscapeString(str)
37 | }
38 |
39 | // decode string to html chars
40 | func HtmlDecode(str string) string {
41 | return html.UnescapeString(str)
42 | }
43 |
44 | // strip tags in html string
45 | func StripTags(src string) string {
46 | //去除style,script,html tag
47 | re := regexp.MustCompile(`(?s)<(?:style|script)[^<>]*>.*?(?:style|script)>|?[a-z][a-z0-9]*[^<>]*>|`)
48 | src = re.ReplaceAllString(src, "")
49 |
50 | //trim all spaces(2+) into \n
51 | re = regexp.MustCompile(`\s{2,}`)
52 | src = re.ReplaceAllString(src, "\n")
53 |
54 | return strings.TrimSpace(src)
55 | }
56 |
57 | // change \n to
58 | func Nl2br(str string) string {
59 | return strings.Replace(str, "\n", " ", -1)
60 | }
61 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/macaron/logger.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Martini Authors
2 | // Copyright 2014 Unknwon
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
5 | // not use this file except in compliance with the License. You may obtain
6 | // a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | // License for the specific language governing permissions and limitations
14 | // under the License.
15 |
16 | package macaron
17 |
18 | import (
19 | "fmt"
20 | "log"
21 | "net/http"
22 | "runtime"
23 | "time"
24 | )
25 |
26 | var ColorLog = true
27 |
28 | func init() {
29 | ColorLog = runtime.GOOS != "windows"
30 | }
31 |
32 | // Logger returns a middleware handler that logs the request as it goes in and the response as it goes out.
33 | func Logger() Handler {
34 | return func(ctx *Context, log *log.Logger) {
35 | start := time.Now()
36 |
37 | log.Printf("Started %s %s for %s", ctx.Req.Method, ctx.Req.RequestURI, ctx.RemoteAddr())
38 |
39 | rw := ctx.Resp.(ResponseWriter)
40 | ctx.Next()
41 |
42 | content := fmt.Sprintf("Completed %s %v %s in %v", ctx.Req.RequestURI, rw.Status(), http.StatusText(rw.Status()), time.Since(start))
43 | if ColorLog {
44 | switch rw.Status() {
45 | case 200, 201, 202:
46 | content = fmt.Sprintf("\033[1;32m%s\033[0m", content)
47 | case 301, 302:
48 | content = fmt.Sprintf("\033[1;37m%s\033[0m", content)
49 | case 304:
50 | content = fmt.Sprintf("\033[1;33m%s\033[0m", content)
51 | case 401, 403:
52 | content = fmt.Sprintf("\033[4;31m%s\033[0m", content)
53 | case 404:
54 | content = fmt.Sprintf("\033[1;31m%s\033[0m", content)
55 | case 500:
56 | content = fmt.Sprintf("\033[1;36m%s\033[0m", content)
57 | }
58 | }
59 | log.Println(content)
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/vendor/github.com/go-macaron/macaron/logger.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Martini Authors
2 | // Copyright 2014 The Macaron Authors
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
5 | // not use this file except in compliance with the License. You may obtain
6 | // a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | // License for the specific language governing permissions and limitations
14 | // under the License.
15 |
16 | package macaron
17 |
18 | import (
19 | "fmt"
20 | "log"
21 | "net/http"
22 | "runtime"
23 | "time"
24 | )
25 |
26 | var ColorLog = true
27 |
28 | func init() {
29 | ColorLog = runtime.GOOS != "windows"
30 | }
31 |
32 | // Logger returns a middleware handler that logs the request as it goes in and the response as it goes out.
33 | func Logger() Handler {
34 | return func(ctx *Context, log *log.Logger) {
35 | start := time.Now()
36 |
37 | log.Printf("Started %s %s for %s", ctx.Req.Method, ctx.Req.RequestURI, ctx.RemoteAddr())
38 |
39 | rw := ctx.Resp.(ResponseWriter)
40 | ctx.Next()
41 |
42 | content := fmt.Sprintf("Completed %s %v %s in %v", ctx.Req.RequestURI, rw.Status(), http.StatusText(rw.Status()), time.Since(start))
43 | if ColorLog {
44 | switch rw.Status() {
45 | case 200, 201, 202:
46 | content = fmt.Sprintf("\033[1;32m%s\033[0m", content)
47 | case 301, 302:
48 | content = fmt.Sprintf("\033[1;37m%s\033[0m", content)
49 | case 304:
50 | content = fmt.Sprintf("\033[1;33m%s\033[0m", content)
51 | case 401, 403:
52 | content = fmt.Sprintf("\033[4;31m%s\033[0m", content)
53 | case 404:
54 | content = fmt.Sprintf("\033[1;31m%s\033[0m", content)
55 | case 500:
56 | content = fmt.Sprintf("\033[1;36m%s\033[0m", content)
57 | }
58 | }
59 | log.Println(content)
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/regex.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | import "regexp"
18 |
19 | const (
20 | regex_email_pattern = `(?i)[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}`
21 | regex_strict_email_pattern = `(?i)[A-Z0-9!#$%&'*+/=?^_{|}~-]+` +
22 | `(?:\.[A-Z0-9!#$%&'*+/=?^_{|}~-]+)*` +
23 | `@(?:[A-Z0-9](?:[A-Z0-9-]*[A-Z0-9])?\.)+` +
24 | `[A-Z0-9](?:[A-Z0-9-]*[A-Z0-9])?`
25 | regex_url_pattern = `(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?`
26 | )
27 |
28 | var (
29 | regex_email *regexp.Regexp
30 | regex_strict_email *regexp.Regexp
31 | regex_url *regexp.Regexp
32 | )
33 |
34 | func init() {
35 | regex_email = regexp.MustCompile(regex_email_pattern)
36 | regex_strict_email = regexp.MustCompile(regex_strict_email_pattern)
37 | regex_url = regexp.MustCompile(regex_url_pattern)
38 | }
39 |
40 | // validate string is an email address, if not return false
41 | // basically validation can match 99% cases
42 | func IsEmail(email string) bool {
43 | return regex_email.MatchString(email)
44 | }
45 |
46 | // validate string is an email address, if not return false
47 | // this validation omits RFC 2822
48 | func IsEmailRFC(email string) bool {
49 | return regex_strict_email.MatchString(email)
50 | }
51 |
52 | // validate string is a url link, if not return false
53 | // simple validation can match 99% cases
54 | func IsUrl(url string) bool {
55 | return regex_url.MatchString(url)
56 | }
57 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/slice.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | import (
18 | "strings"
19 | )
20 |
21 | // AppendStr appends string to slice with no duplicates.
22 | func AppendStr(strs []string, str string) []string {
23 | for _, s := range strs {
24 | if s == str {
25 | return strs
26 | }
27 | }
28 | return append(strs, str)
29 | }
30 |
31 | // CompareSliceStr compares two 'string' type slices.
32 | // It returns true if elements and order are both the same.
33 | func CompareSliceStr(s1, s2 []string) bool {
34 | if len(s1) != len(s2) {
35 | return false
36 | }
37 |
38 | for i := range s1 {
39 | if s1[i] != s2[i] {
40 | return false
41 | }
42 | }
43 |
44 | return true
45 | }
46 |
47 | // CompareSliceStr compares two 'string' type slices.
48 | // It returns true if elements are the same, and ignores the order.
49 | func CompareSliceStrU(s1, s2 []string) bool {
50 | if len(s1) != len(s2) {
51 | return false
52 | }
53 |
54 | for i := range s1 {
55 | for j := len(s2) - 1; j >= 0; j-- {
56 | if s1[i] == s2[j] {
57 | s2 = append(s2[:j], s2[j+1:]...)
58 | break
59 | }
60 | }
61 | }
62 | if len(s2) > 0 {
63 | return false
64 | }
65 | return true
66 | }
67 |
68 | // IsSliceContainsStr returns true if the string exists in given slice, ignore case.
69 | func IsSliceContainsStr(sl []string, str string) bool {
70 | str = strings.ToLower(str)
71 | for _, s := range sl {
72 | if strings.ToLower(s) == str {
73 | return true
74 | }
75 | }
76 | return false
77 | }
78 |
79 | // IsSliceContainsInt64 returns true if the int64 exists in given slice.
80 | func IsSliceContainsInt64(sl []int64, i int64) bool {
81 | for _, s := range sl {
82 | if s == i {
83 | return true
84 | }
85 | }
86 | return false
87 | }
88 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/path.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | import (
18 | "errors"
19 | "os"
20 | "path/filepath"
21 | "runtime"
22 | "strings"
23 | )
24 |
25 | // GetGOPATHs returns all paths in GOPATH variable.
26 | func GetGOPATHs() []string {
27 | gopath := os.Getenv("GOPATH")
28 | var paths []string
29 | if runtime.GOOS == "windows" {
30 | gopath = strings.Replace(gopath, "\\", "/", -1)
31 | paths = strings.Split(gopath, ";")
32 | } else {
33 | paths = strings.Split(gopath, ":")
34 | }
35 | return paths
36 | }
37 |
38 | // GetSrcPath returns app. source code path.
39 | // It only works when you have src. folder in GOPATH,
40 | // it returns error not able to locate source folder path.
41 | func GetSrcPath(importPath string) (appPath string, err error) {
42 | paths := GetGOPATHs()
43 | for _, p := range paths {
44 | if IsExist(p + "/src/" + importPath + "/") {
45 | appPath = p + "/src/" + importPath + "/"
46 | break
47 | }
48 | }
49 |
50 | if len(appPath) == 0 {
51 | return "", errors.New("Unable to locate source folder path")
52 | }
53 |
54 | appPath = filepath.Dir(appPath) + "/"
55 | if runtime.GOOS == "windows" {
56 | // Replace all '\' to '/'.
57 | appPath = strings.Replace(appPath, "\\", "/", -1)
58 | }
59 |
60 | return appPath, nil
61 | }
62 |
63 | // HomeDir returns path of '~'(in Linux) on Windows,
64 | // it returns error when the variable does not exist.
65 | func HomeDir() (home string, err error) {
66 | if runtime.GOOS == "windows" {
67 | home = os.Getenv("USERPROFILE")
68 | if len(home) == 0 {
69 | home = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
70 | }
71 | } else {
72 | home = os.Getenv("HOME")
73 | }
74 |
75 | if len(home) == 0 {
76 | return "", errors.New("Cannot specify home directory because it's empty")
77 | }
78 |
79 | return home, nil
80 | }
81 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/macaron/return_handler.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Martini Authors
2 | // Copyright 2014 Unknwon
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
5 | // not use this file except in compliance with the License. You may obtain
6 | // a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | // License for the specific language governing permissions and limitations
14 | // under the License.
15 |
16 | package macaron
17 |
18 | import (
19 | "net/http"
20 | "reflect"
21 |
22 | "github.com/Unknwon/macaron/inject"
23 | )
24 |
25 | // ReturnHandler is a service that Martini provides that is called
26 | // when a route handler returns something. The ReturnHandler is
27 | // responsible for writing to the ResponseWriter based on the values
28 | // that are passed into this function.
29 | type ReturnHandler func(*Context, []reflect.Value)
30 |
31 | func canDeref(val reflect.Value) bool {
32 | return val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr
33 | }
34 |
35 | func isError(val reflect.Value) bool {
36 | _, ok := val.Interface().(error)
37 | return ok
38 | }
39 |
40 | func isByteSlice(val reflect.Value) bool {
41 | return val.Kind() == reflect.Slice && val.Type().Elem().Kind() == reflect.Uint8
42 | }
43 |
44 | func defaultReturnHandler() ReturnHandler {
45 | return func(ctx *Context, vals []reflect.Value) {
46 | rv := ctx.GetVal(inject.InterfaceOf((*http.ResponseWriter)(nil)))
47 | resp := rv.Interface().(http.ResponseWriter)
48 | var respVal reflect.Value
49 | if len(vals) > 1 && vals[0].Kind() == reflect.Int {
50 | resp.WriteHeader(int(vals[0].Int()))
51 | respVal = vals[1]
52 | } else if len(vals) > 0 {
53 | respVal = vals[0]
54 |
55 | if isError(respVal) {
56 | err := respVal.Interface().(error)
57 | if err != nil {
58 | ctx.internalServerError(ctx, err)
59 | }
60 | return
61 | } else if canDeref(respVal) {
62 | if respVal.IsNil() {
63 | return // Ignore nil error
64 | }
65 | }
66 | }
67 | if canDeref(respVal) {
68 | respVal = respVal.Elem()
69 | }
70 | if isByteSlice(respVal) {
71 | resp.Write(respVal.Bytes())
72 | } else {
73 | resp.Write([]byte(respVal.String()))
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/vendor/github.com/go-macaron/macaron/return_handler.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Martini Authors
2 | // Copyright 2014 The Macaron Authors
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
5 | // not use this file except in compliance with the License. You may obtain
6 | // a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | // License for the specific language governing permissions and limitations
14 | // under the License.
15 |
16 | package macaron
17 |
18 | import (
19 | "net/http"
20 | "reflect"
21 |
22 | "github.com/go-macaron/inject"
23 | )
24 |
25 | // ReturnHandler is a service that Martini provides that is called
26 | // when a route handler returns something. The ReturnHandler is
27 | // responsible for writing to the ResponseWriter based on the values
28 | // that are passed into this function.
29 | type ReturnHandler func(*Context, []reflect.Value)
30 |
31 | func canDeref(val reflect.Value) bool {
32 | return val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr
33 | }
34 |
35 | func isError(val reflect.Value) bool {
36 | _, ok := val.Interface().(error)
37 | return ok
38 | }
39 |
40 | func isByteSlice(val reflect.Value) bool {
41 | return val.Kind() == reflect.Slice && val.Type().Elem().Kind() == reflect.Uint8
42 | }
43 |
44 | func defaultReturnHandler() ReturnHandler {
45 | return func(ctx *Context, vals []reflect.Value) {
46 | rv := ctx.GetVal(inject.InterfaceOf((*http.ResponseWriter)(nil)))
47 | resp := rv.Interface().(http.ResponseWriter)
48 | var respVal reflect.Value
49 | if len(vals) > 1 && vals[0].Kind() == reflect.Int {
50 | resp.WriteHeader(int(vals[0].Int()))
51 | respVal = vals[1]
52 | } else if len(vals) > 0 {
53 | respVal = vals[0]
54 |
55 | if isError(respVal) {
56 | err := respVal.Interface().(error)
57 | if err != nil {
58 | ctx.internalServerError(ctx, err)
59 | }
60 | return
61 | } else if canDeref(respVal) {
62 | if respVal.IsNil() {
63 | return // Ignore nil error
64 | }
65 | }
66 | }
67 | if canDeref(respVal) {
68 | respVal = respVal.Elem()
69 | }
70 | if isByteSlice(respVal) {
71 | resp.Write(respVal.Bytes())
72 | } else {
73 | resp.Write([]byte(respVal.String()))
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/macaron/response_writer.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Martini Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package macaron
16 |
17 | import (
18 | "bufio"
19 | "fmt"
20 | "net"
21 | "net/http"
22 | )
23 |
24 | // ResponseWriter is a wrapper around http.ResponseWriter that provides extra information about
25 | // the response. It is recommended that middleware handlers use this construct to wrap a responsewriter
26 | // if the functionality calls for it.
27 | type ResponseWriter interface {
28 | http.ResponseWriter
29 | http.Flusher
30 | // Status returns the status code of the response or 0 if the response has not been written.
31 | Status() int
32 | // Written returns whether or not the ResponseWriter has been written.
33 | Written() bool
34 | // Size returns the size of the response body.
35 | Size() int
36 | // Before allows for a function to be called before the ResponseWriter has been written to. This is
37 | // useful for setting headers or any other operations that must happen before a response has been written.
38 | Before(BeforeFunc)
39 | }
40 |
41 | // BeforeFunc is a function that is called before the ResponseWriter has been written to.
42 | type BeforeFunc func(ResponseWriter)
43 |
44 | // NewResponseWriter creates a ResponseWriter that wraps an http.ResponseWriter
45 | func NewResponseWriter(rw http.ResponseWriter) ResponseWriter {
46 | return &responseWriter{rw, 0, 0, nil}
47 | }
48 |
49 | type responseWriter struct {
50 | http.ResponseWriter
51 | status int
52 | size int
53 | beforeFuncs []BeforeFunc
54 | }
55 |
56 | func (rw *responseWriter) WriteHeader(s int) {
57 | rw.callBefore()
58 | rw.ResponseWriter.WriteHeader(s)
59 | rw.status = s
60 | }
61 |
62 | func (rw *responseWriter) Write(b []byte) (int, error) {
63 | if !rw.Written() {
64 | // The status will be StatusOK if WriteHeader has not been called yet
65 | rw.WriteHeader(http.StatusOK)
66 | }
67 | size, err := rw.ResponseWriter.Write(b)
68 | rw.size += size
69 | return size, err
70 | }
71 |
72 | func (rw *responseWriter) Status() int {
73 | return rw.status
74 | }
75 |
76 | func (rw *responseWriter) Size() int {
77 | return rw.size
78 | }
79 |
80 | func (rw *responseWriter) Written() bool {
81 | return rw.status != 0
82 | }
83 |
84 | func (rw *responseWriter) Before(before BeforeFunc) {
85 | rw.beforeFuncs = append(rw.beforeFuncs, before)
86 | }
87 |
88 | func (rw *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
89 | hijacker, ok := rw.ResponseWriter.(http.Hijacker)
90 | if !ok {
91 | return nil, nil, fmt.Errorf("the ResponseWriter doesn't support the Hijacker interface")
92 | }
93 | return hijacker.Hijack()
94 | }
95 |
96 | func (rw *responseWriter) CloseNotify() <-chan bool {
97 | return rw.ResponseWriter.(http.CloseNotifier).CloseNotify()
98 | }
99 |
100 | func (rw *responseWriter) callBefore() {
101 | for i := len(rw.beforeFuncs) - 1; i >= 0; i-- {
102 | rw.beforeFuncs[i](rw)
103 | }
104 | }
105 |
106 | func (rw *responseWriter) Flush() {
107 | flusher, ok := rw.ResponseWriter.(http.Flusher)
108 | if ok {
109 | flusher.Flush()
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/vendor/github.com/go-macaron/macaron/response_writer.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Martini Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package macaron
16 |
17 | import (
18 | "bufio"
19 | "fmt"
20 | "net"
21 | "net/http"
22 | )
23 |
24 | // ResponseWriter is a wrapper around http.ResponseWriter that provides extra information about
25 | // the response. It is recommended that middleware handlers use this construct to wrap a responsewriter
26 | // if the functionality calls for it.
27 | type ResponseWriter interface {
28 | http.ResponseWriter
29 | http.Flusher
30 | // Status returns the status code of the response or 0 if the response has not been written.
31 | Status() int
32 | // Written returns whether or not the ResponseWriter has been written.
33 | Written() bool
34 | // Size returns the size of the response body.
35 | Size() int
36 | // Before allows for a function to be called before the ResponseWriter has been written to. This is
37 | // useful for setting headers or any other operations that must happen before a response has been written.
38 | Before(BeforeFunc)
39 | }
40 |
41 | // BeforeFunc is a function that is called before the ResponseWriter has been written to.
42 | type BeforeFunc func(ResponseWriter)
43 |
44 | // NewResponseWriter creates a ResponseWriter that wraps an http.ResponseWriter
45 | func NewResponseWriter(rw http.ResponseWriter) ResponseWriter {
46 | return &responseWriter{rw, 0, 0, nil}
47 | }
48 |
49 | type responseWriter struct {
50 | http.ResponseWriter
51 | status int
52 | size int
53 | beforeFuncs []BeforeFunc
54 | }
55 |
56 | func (rw *responseWriter) WriteHeader(s int) {
57 | rw.callBefore()
58 | rw.ResponseWriter.WriteHeader(s)
59 | rw.status = s
60 | }
61 |
62 | func (rw *responseWriter) Write(b []byte) (int, error) {
63 | if !rw.Written() {
64 | // The status will be StatusOK if WriteHeader has not been called yet
65 | rw.WriteHeader(http.StatusOK)
66 | }
67 | size, err := rw.ResponseWriter.Write(b)
68 | rw.size += size
69 | return size, err
70 | }
71 |
72 | func (rw *responseWriter) Status() int {
73 | return rw.status
74 | }
75 |
76 | func (rw *responseWriter) Size() int {
77 | return rw.size
78 | }
79 |
80 | func (rw *responseWriter) Written() bool {
81 | return rw.status != 0
82 | }
83 |
84 | func (rw *responseWriter) Before(before BeforeFunc) {
85 | rw.beforeFuncs = append(rw.beforeFuncs, before)
86 | }
87 |
88 | func (rw *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
89 | hijacker, ok := rw.ResponseWriter.(http.Hijacker)
90 | if !ok {
91 | return nil, nil, fmt.Errorf("the ResponseWriter doesn't support the Hijacker interface")
92 | }
93 | return hijacker.Hijack()
94 | }
95 |
96 | func (rw *responseWriter) CloseNotify() <-chan bool {
97 | return rw.ResponseWriter.(http.CloseNotifier).CloseNotify()
98 | }
99 |
100 | func (rw *responseWriter) callBefore() {
101 | for i := len(rw.beforeFuncs) - 1; i >= 0; i-- {
102 | rw.beforeFuncs[i](rw)
103 | }
104 | }
105 |
106 | func (rw *responseWriter) Flush() {
107 | flusher, ok := rw.ResponseWriter.(http.Flusher)
108 | if ok {
109 | flusher.Flush()
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/macaron/gzip.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Martini Authors
2 | // Copyright 2014 Unknwon
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
5 | // not use this file except in compliance with the License. You may obtain
6 | // a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | // License for the specific language governing permissions and limitations
14 | // under the License.
15 |
16 | package macaron
17 |
18 | import (
19 | "bufio"
20 | "compress/gzip"
21 | "fmt"
22 | "net"
23 | "net/http"
24 | "strings"
25 | )
26 |
27 | const (
28 | HeaderAcceptEncoding = "Accept-Encoding"
29 | HeaderContentEncoding = "Content-Encoding"
30 | HeaderContentLength = "Content-Length"
31 | HeaderContentType = "Content-Type"
32 | HeaderVary = "Vary"
33 | )
34 |
35 | // GzipOptions represents a struct for specifying configuration options for the GZip middleware.
36 | type GzipOptions struct {
37 | // Compression level. Can be DefaultCompression(-1) or any integer value between BestSpeed(1) and BestCompression(9) inclusive.
38 | CompressionLevel int
39 | }
40 |
41 | func isCompressionLevelValid(level int) bool {
42 | return level == gzip.DefaultCompression ||
43 | (level >= gzip.BestSpeed && level <= gzip.BestCompression)
44 | }
45 |
46 | func prepareGzipOptions(options []GzipOptions) GzipOptions {
47 | var opt GzipOptions
48 | if len(options) > 0 {
49 | opt = options[0]
50 | }
51 |
52 | if !isCompressionLevelValid(opt.CompressionLevel) {
53 | opt.CompressionLevel = gzip.DefaultCompression
54 | }
55 | return opt
56 | }
57 |
58 | // Gziper returns a Handler that adds gzip compression to all requests.
59 | // Make sure to include the Gzip middleware above other middleware
60 | // that alter the response body (like the render middleware).
61 | func Gziper(options ...GzipOptions) Handler {
62 | opt := prepareGzipOptions(options)
63 |
64 | return func(ctx *Context) {
65 | if !strings.Contains(ctx.Req.Header.Get(HeaderAcceptEncoding), "gzip") {
66 | return
67 | }
68 |
69 | headers := ctx.Resp.Header()
70 | headers.Set(HeaderContentEncoding, "gzip")
71 | headers.Set(HeaderVary, HeaderAcceptEncoding)
72 |
73 | // We've made sure compression level is valid in prepareGzipOptions,
74 | // no need to check same error again.
75 | gz, err := gzip.NewWriterLevel(ctx.Resp, opt.CompressionLevel)
76 | if err != nil {
77 | panic(err.Error())
78 | }
79 | defer gz.Close()
80 |
81 | gzw := gzipResponseWriter{gz, ctx.Resp}
82 | ctx.Resp = gzw
83 | ctx.MapTo(gzw, (*http.ResponseWriter)(nil))
84 | if ctx.Render != nil {
85 | ctx.Render.SetResponseWriter(gzw)
86 | }
87 |
88 | ctx.Next()
89 |
90 | // delete content length after we know we have been written to
91 | gzw.Header().Del("Content-Length")
92 | }
93 | }
94 |
95 | type gzipResponseWriter struct {
96 | w *gzip.Writer
97 | ResponseWriter
98 | }
99 |
100 | func (grw gzipResponseWriter) Write(p []byte) (int, error) {
101 | if len(grw.Header().Get(HeaderContentType)) == 0 {
102 | grw.Header().Set(HeaderContentType, http.DetectContentType(p))
103 | }
104 | return grw.w.Write(p)
105 | }
106 |
107 | func (grw gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
108 | hijacker, ok := grw.ResponseWriter.(http.Hijacker)
109 | if !ok {
110 | return nil, nil, fmt.Errorf("the ResponseWriter doesn't support the Hijacker interface")
111 | }
112 | return hijacker.Hijack()
113 | }
114 |
--------------------------------------------------------------------------------
/vendor/github.com/elazarl/go-bindata-assetfs/assetfs.go:
--------------------------------------------------------------------------------
1 | package assetfs
2 |
3 | import (
4 | "bytes"
5 | "errors"
6 | "io"
7 | "io/ioutil"
8 | "net/http"
9 | "os"
10 | "path"
11 | "path/filepath"
12 | "time"
13 | )
14 |
15 | var (
16 | fileTimestamp = time.Now()
17 | )
18 |
19 | // FakeFile implements os.FileInfo interface for a given path and size
20 | type FakeFile struct {
21 | // Path is the path of this file
22 | Path string
23 | // Dir marks of the path is a directory
24 | Dir bool
25 | // Len is the length of the fake file, zero if it is a directory
26 | Len int64
27 | }
28 |
29 | func (f *FakeFile) Name() string {
30 | _, name := filepath.Split(f.Path)
31 | return name
32 | }
33 |
34 | func (f *FakeFile) Mode() os.FileMode {
35 | mode := os.FileMode(0644)
36 | if f.Dir {
37 | return mode | os.ModeDir
38 | }
39 | return mode
40 | }
41 |
42 | func (f *FakeFile) ModTime() time.Time {
43 | return fileTimestamp
44 | }
45 |
46 | func (f *FakeFile) Size() int64 {
47 | return f.Len
48 | }
49 |
50 | func (f *FakeFile) IsDir() bool {
51 | return f.Mode().IsDir()
52 | }
53 |
54 | func (f *FakeFile) Sys() interface{} {
55 | return nil
56 | }
57 |
58 | // AssetFile implements http.File interface for a no-directory file with content
59 | type AssetFile struct {
60 | *bytes.Reader
61 | io.Closer
62 | FakeFile
63 | }
64 |
65 | func NewAssetFile(name string, content []byte) *AssetFile {
66 | return &AssetFile{
67 | bytes.NewReader(content),
68 | ioutil.NopCloser(nil),
69 | FakeFile{name, false, int64(len(content))}}
70 | }
71 |
72 | func (f *AssetFile) Readdir(count int) ([]os.FileInfo, error) {
73 | return nil, errors.New("not a directory")
74 | }
75 |
76 | func (f *AssetFile) Size() int64 {
77 | return f.FakeFile.Size()
78 | }
79 |
80 | func (f *AssetFile) Stat() (os.FileInfo, error) {
81 | return f, nil
82 | }
83 |
84 | // AssetDirectory implements http.File interface for a directory
85 | type AssetDirectory struct {
86 | AssetFile
87 | ChildrenRead int
88 | Children []os.FileInfo
89 | }
90 |
91 | func NewAssetDirectory(name string, children []string, fs *AssetFS) *AssetDirectory {
92 | fileinfos := make([]os.FileInfo, 0, len(children))
93 | for _, child := range children {
94 | _, err := fs.AssetDir(filepath.Join(name, child))
95 | fileinfos = append(fileinfos, &FakeFile{child, err == nil, 0})
96 | }
97 | return &AssetDirectory{
98 | AssetFile{
99 | bytes.NewReader(nil),
100 | ioutil.NopCloser(nil),
101 | FakeFile{name, true, 0},
102 | },
103 | 0,
104 | fileinfos}
105 | }
106 |
107 | func (f *AssetDirectory) Readdir(count int) ([]os.FileInfo, error) {
108 | if count <= 0 {
109 | return f.Children, nil
110 | }
111 | if f.ChildrenRead+count > len(f.Children) {
112 | count = len(f.Children) - f.ChildrenRead
113 | }
114 | rv := f.Children[f.ChildrenRead : f.ChildrenRead+count]
115 | f.ChildrenRead += count
116 | return rv, nil
117 | }
118 |
119 | func (f *AssetDirectory) Stat() (os.FileInfo, error) {
120 | return f, nil
121 | }
122 |
123 | // AssetFS implements http.FileSystem, allowing
124 | // embedded files to be served from net/http package.
125 | type AssetFS struct {
126 | // Asset should return content of file in path if exists
127 | Asset func(path string) ([]byte, error)
128 | // AssetDir should return list of files in the path
129 | AssetDir func(path string) ([]string, error)
130 | // Prefix would be prepended to http requests
131 | Prefix string
132 | }
133 |
134 | func (fs *AssetFS) Open(name string) (http.File, error) {
135 | name = path.Join(fs.Prefix, name)
136 | if len(name) > 0 && name[0] == '/' {
137 | name = name[1:]
138 | }
139 | if b, err := fs.Asset(name); err == nil {
140 | return NewAssetFile(name, b), nil
141 | }
142 | if children, err := fs.AssetDir(name); err == nil {
143 | return NewAssetDirectory(name, children, fs), nil
144 | } else {
145 | return nil, err
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/file.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | import (
18 | "fmt"
19 | "io"
20 | "io/ioutil"
21 | "math"
22 | "os"
23 | "path"
24 | )
25 |
26 | // Storage unit constants.
27 | const (
28 | Byte = 1
29 | KByte = Byte * 1024
30 | MByte = KByte * 1024
31 | GByte = MByte * 1024
32 | TByte = GByte * 1024
33 | PByte = TByte * 1024
34 | EByte = PByte * 1024
35 | )
36 |
37 | func logn(n, b float64) float64 {
38 | return math.Log(n) / math.Log(b)
39 | }
40 |
41 | func humanateBytes(s uint64, base float64, sizes []string) string {
42 | if s < 10 {
43 | return fmt.Sprintf("%dB", s)
44 | }
45 | e := math.Floor(logn(float64(s), base))
46 | suffix := sizes[int(e)]
47 | val := float64(s) / math.Pow(base, math.Floor(e))
48 | f := "%.0f"
49 | if val < 10 {
50 | f = "%.1f"
51 | }
52 |
53 | return fmt.Sprintf(f+"%s", val, suffix)
54 | }
55 |
56 | // HumaneFileSize calculates the file size and generate user-friendly string.
57 | func HumaneFileSize(s uint64) string {
58 | sizes := []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"}
59 | return humanateBytes(s, 1024, sizes)
60 | }
61 |
62 | // FileMTime returns file modified time and possible error.
63 | func FileMTime(file string) (int64, error) {
64 | f, err := os.Stat(file)
65 | if err != nil {
66 | return 0, err
67 | }
68 | return f.ModTime().Unix(), nil
69 | }
70 |
71 | // FileSize returns file size in bytes and possible error.
72 | func FileSize(file string) (int64, error) {
73 | f, err := os.Stat(file)
74 | if err != nil {
75 | return 0, err
76 | }
77 | return f.Size(), nil
78 | }
79 |
80 | // Copy copies file from source to target path.
81 | func Copy(src, dest string) error {
82 | // Gather file information to set back later.
83 | si, err := os.Lstat(src)
84 | if err != nil {
85 | return err
86 | }
87 |
88 | // Handle symbolic link.
89 | if si.Mode()&os.ModeSymlink != 0 {
90 | target, err := os.Readlink(src)
91 | if err != nil {
92 | return err
93 | }
94 | // NOTE: os.Chmod and os.Chtimes don't recoganize symbolic link,
95 | // which will lead "no such file or directory" error.
96 | return os.Symlink(target, dest)
97 | }
98 |
99 | sr, err := os.Open(src)
100 | if err != nil {
101 | return err
102 | }
103 | defer sr.Close()
104 |
105 | dw, err := os.Create(dest)
106 | if err != nil {
107 | return err
108 | }
109 | defer dw.Close()
110 |
111 | if _, err = io.Copy(dw, sr); err != nil {
112 | return err
113 | }
114 |
115 | // Set back file information.
116 | if err = os.Chtimes(dest, si.ModTime(), si.ModTime()); err != nil {
117 | return err
118 | }
119 | return os.Chmod(dest, si.Mode())
120 | }
121 |
122 | // WriteFile writes data to a file named by filename.
123 | // If the file does not exist, WriteFile creates it
124 | // and its upper level paths.
125 | func WriteFile(filename string, data []byte) error {
126 | os.MkdirAll(path.Dir(filename), os.ModePerm)
127 | return ioutil.WriteFile(filename, data, 0655)
128 | }
129 |
130 | // IsFile returns true if given path is a file,
131 | // or returns false when it's a directory or does not exist.
132 | func IsFile(filePath string) bool {
133 | f, e := os.Stat(filePath)
134 | if e != nil {
135 | return false
136 | }
137 | return !f.IsDir()
138 | }
139 |
140 | // IsExist checks whether a file or directory exists.
141 | // It returns false when the file or directory does not exist.
142 | func IsExist(path string) bool {
143 | _, err := os.Stat(path)
144 | return err == nil || os.IsExist(err)
145 | }
146 |
--------------------------------------------------------------------------------
/vendor/github.com/go-macaron/macaron/README.md:
--------------------------------------------------------------------------------
1 | Macaron [](https://travis-ci.org/go-macaron/macaron) [](http://gocover.io/github.com/go-macaron/macaron)
2 | =======================
3 |
4 | 
5 |
6 | Package macaron is a high productive and modular web framework in Go.
7 |
8 | ##### Current version: 0.8.0
9 |
10 | ## Getting Started
11 |
12 | The minimum requirement of Go is **1.3**.
13 |
14 | To install Macaron:
15 |
16 | go get gopkg.in/macaron.v1
17 |
18 | The very basic usage of Macaron:
19 |
20 | ```go
21 | package main
22 |
23 | import "gopkg.in/macaron.v1"
24 |
25 | func main() {
26 | m := macaron.Classic()
27 | m.Get("/", func() string {
28 | return "Hello world!"
29 | })
30 | m.Run()
31 | }
32 | ```
33 |
34 | ## Features
35 |
36 | - Powerful routing with suburl.
37 | - Flexible routes combinations.
38 | - Unlimited nested group routers.
39 | - Directly integrate with existing services.
40 | - Dynamically change template files at runtime.
41 | - Allow to use in-memory template and static files.
42 | - Easy to plugin/unplugin features with modular design.
43 | - Handy dependency injection powered by [inject](https://github.com/codegangsta/inject).
44 | - Better router layer and less reflection make faster speed.
45 |
46 | ## Middlewares
47 |
48 | Middlewares allow you easily plugin/unplugin features for your Macaron applications.
49 |
50 | There are already many [middlewares](https://github.com/go-macaron) to simplify your work:
51 |
52 | - render - Go template engine
53 | - static - Serves static files
54 | - [gzip](https://github.com/go-macaron/gzip) - Gzip compression to all responses
55 | - [binding](https://github.com/go-macaron/binding) - Request data binding and validation
56 | - [i18n](https://github.com/go-macaron/i18n) - Internationalization and Localization
57 | - [cache](https://github.com/go-macaron/cache) - Cache manager
58 | - [session](https://github.com/go-macaron/session) - Session manager
59 | - [csrf](https://github.com/go-macaron/csrf) - Generates and validates csrf tokens
60 | - [captcha](https://github.com/go-macaron/captcha) - Captcha service
61 | - [pongo2](https://github.com/go-macaron/pongo2) - Pongo2 template engine support
62 | - [sockets](https://github.com/go-macaron/sockets) - WebSockets channels binding
63 | - [bindata](https://github.com/go-macaron/bindata) - Embed binary data as static and template files
64 | - [toolbox](https://github.com/go-macaron/toolbox) - Health check, pprof, profile and statistic services
65 | - [oauth2](https://github.com/go-macaron/oauth2) - OAuth 2.0 backend
66 | - [switcher](https://github.com/go-macaron/switcher) - Multiple-site support
67 | - [method](https://github.com/go-macaron/method) - HTTP method override
68 | - [permissions2](https://github.com/xyproto/permissions2) - Cookies, users and permissions
69 | - [renders](https://github.com/go-macaron/renders) - Beego-like render engine(Macaron has built-in template engine, this is another option)
70 |
71 | ## Use Cases
72 |
73 | - [Gogs](http://gogs.io): A painless self-hosted Git Service
74 | - [Peach](http://peachdocs.org): A modern web documentation server
75 | - [Go Walker](https://gowalker.org): Go online API documentation
76 | - [Switch](http://gopm.io): Gopm registry
77 | - [YouGam](http://yougam.com): Online Forum
78 | - [Critical Stack Intel](https://intel.criticalstack.com/): A 100% free intel marketplace from Critical Stack, Inc.
79 |
80 | ## Getting Help
81 |
82 | - [API Reference](https://gowalker.org/gopkg.in/macaron.v1)
83 | - [Documentation](http://go-macaron.com)
84 | - [FAQs](http://go-macaron.com/docs/faqs)
85 | - [](https://gitter.im/Unknwon/macaron?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
86 |
87 | ## Credits
88 |
89 | - Basic design of [Martini](https://github.com/go-martini/martini).
90 | - Logo is modified by [@insionng](https://github.com/insionng) based on [Tribal Dragon](http://xtremeyamazaki.deviantart.com/art/Tribal-Dragon-27005087).
91 |
92 | ## License
93 |
94 | This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text.
95 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/convert.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | import (
18 | "fmt"
19 | "strconv"
20 | )
21 |
22 | // Convert string to specify type.
23 | type StrTo string
24 |
25 | func (f StrTo) Exist() bool {
26 | return string(f) != string(0x1E)
27 | }
28 |
29 | func (f StrTo) Uint8() (uint8, error) {
30 | v, err := strconv.ParseUint(f.String(), 10, 8)
31 | return uint8(v), err
32 | }
33 |
34 | func (f StrTo) Int() (int, error) {
35 | v, err := strconv.ParseInt(f.String(), 10, 0)
36 | return int(v), err
37 | }
38 |
39 | func (f StrTo) Int64() (int64, error) {
40 | v, err := strconv.ParseInt(f.String(), 10, 64)
41 | return int64(v), err
42 | }
43 |
44 | func (f StrTo) MustUint8() uint8 {
45 | v, _ := f.Uint8()
46 | return v
47 | }
48 |
49 | func (f StrTo) MustInt() int {
50 | v, _ := f.Int()
51 | return v
52 | }
53 |
54 | func (f StrTo) MustInt64() int64 {
55 | v, _ := f.Int64()
56 | return v
57 | }
58 |
59 | func (f StrTo) String() string {
60 | if f.Exist() {
61 | return string(f)
62 | }
63 | return ""
64 | }
65 |
66 | // Convert any type to string.
67 | func ToStr(value interface{}, args ...int) (s string) {
68 | switch v := value.(type) {
69 | case bool:
70 | s = strconv.FormatBool(v)
71 | case float32:
72 | s = strconv.FormatFloat(float64(v), 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 32))
73 | case float64:
74 | s = strconv.FormatFloat(v, 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 64))
75 | case int:
76 | s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
77 | case int8:
78 | s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
79 | case int16:
80 | s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
81 | case int32:
82 | s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
83 | case int64:
84 | s = strconv.FormatInt(v, argInt(args).Get(0, 10))
85 | case uint:
86 | s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
87 | case uint8:
88 | s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
89 | case uint16:
90 | s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
91 | case uint32:
92 | s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
93 | case uint64:
94 | s = strconv.FormatUint(v, argInt(args).Get(0, 10))
95 | case string:
96 | s = v
97 | case []byte:
98 | s = string(v)
99 | default:
100 | s = fmt.Sprintf("%v", v)
101 | }
102 | return s
103 | }
104 |
105 | type argInt []int
106 |
107 | func (a argInt) Get(i int, args ...int) (r int) {
108 | if i >= 0 && i < len(a) {
109 | r = a[i]
110 | } else if len(args) > 0 {
111 | r = args[0]
112 | }
113 | return
114 | }
115 |
116 | // HexStr2int converts hex format string to decimal number.
117 | func HexStr2int(hexStr string) (int, error) {
118 | num := 0
119 | length := len(hexStr)
120 | for i := 0; i < length; i++ {
121 | char := hexStr[length-i-1]
122 | factor := -1
123 |
124 | switch {
125 | case char >= '0' && char <= '9':
126 | factor = int(char) - '0'
127 | case char >= 'a' && char <= 'f':
128 | factor = int(char) - 'a' + 10
129 | default:
130 | return -1, fmt.Errorf("invalid hex: %s", string(char))
131 | }
132 |
133 | num += factor * PowInt(16, i)
134 | }
135 | return num, nil
136 | }
137 |
138 | // Int2HexStr converts decimal number to hex format string.
139 | func Int2HexStr(num int) (hex string) {
140 | if num == 0 {
141 | return "0"
142 | }
143 |
144 | for num > 0 {
145 | r := num % 16
146 |
147 | c := "?"
148 | if r >= 0 && r <= 9 {
149 | c = string(r + '0')
150 | } else {
151 | c = string(r + 'a' - 10)
152 | }
153 | hex = c + hex
154 | num = num / 16
155 | }
156 | return hex
157 | }
158 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/macaron/README.md:
--------------------------------------------------------------------------------
1 | Macaron [](https://drone.io/github.com/Unknwon/macaron/latest) [](http://gocover.io/github.com/Unknwon/macaron)
2 | =======================
3 |
4 | 
5 |
6 | Package macaron is a high productive and modular web framework in Go.
7 |
8 | ##### Current version: 0.6.8
9 |
10 | ## Getting Started
11 |
12 | The minimum requirement of Go is **1.3**.
13 |
14 | To install Macaron:
15 |
16 | go get github.com/Unknwon/macaron
17 |
18 | The very basic usage of Macaron:
19 |
20 | ```go
21 | package main
22 |
23 | import "github.com/Unknwon/macaron"
24 |
25 | func main() {
26 | m := macaron.Classic()
27 | m.Get("/", func() string {
28 | return "Hello world!"
29 | })
30 | m.Run()
31 | }
32 | ```
33 |
34 | ## Features
35 |
36 | - Powerful routing with suburl.
37 | - Flexible routes combinations.
38 | - Unlimited nested group routers.
39 | - Directly integrate with existing services.
40 | - Dynamically change template files at runtime.
41 | - Allow to use in-memory template and static files.
42 | - Easy to plugin/unplugin features with modular design.
43 | - Handy dependency injection powered by [inject](https://github.com/codegangsta/inject).
44 | - Better router layer and less reflection make faster speed.
45 |
46 | ## Middlewares
47 |
48 | Middlewares allow you easily plugin/unplugin features for your Macaron applications.
49 |
50 | There are already many [middlewares](https://github.com/macaron-contrib) to simplify your work:
51 |
52 | - gzip - Gzip compression to all requests
53 | - render - Go template engine
54 | - static - Serves static files
55 | - [binding](https://github.com/macaron-contrib/binding) - Request data binding and validation
56 | - [i18n](https://github.com/macaron-contrib/i18n) - Internationalization and Localization
57 | - [cache](https://github.com/macaron-contrib/cache) - Cache manager
58 | - [session](https://github.com/macaron-contrib/session) - Session manager
59 | - [csrf](https://github.com/macaron-contrib/csrf) - Generates and validates csrf tokens
60 | - [captcha](https://github.com/macaron-contrib/captcha) - Captcha service
61 | - [pongo2](https://github.com/macaron-contrib/pongo2) - Pongo2 template engine support
62 | - [sockets](https://github.com/macaron-contrib/sockets) - WebSockets channels binding
63 | - [bindata](https://github.com/macaron-contrib/bindata) - Embed binary data as static and template files
64 | - [toolbox](https://github.com/macaron-contrib/toolbox) - Health check, pprof, profile and statistic services
65 | - [oauth2](https://github.com/macaron-contrib/oauth2) - OAuth 2.0 backend
66 | - [switcher](https://github.com/macaron-contrib/switcher) - Multiple-site support
67 | - [method](https://github.com/macaron-contrib/method) - HTTP method override
68 | - [permissions2](https://github.com/xyproto/permissions2) - Cookies, users and permissions
69 | - [renders](https://github.com/macaron-contrib/renders) - Beego-like render engine(Macaron has built-in template engine, this is another option)
70 |
71 | ## Use Cases
72 |
73 | - [Gogs](http://gogs.io): A painless self-hosted Git Service
74 | - [Peach](http://peachdocs.org): A modern web documentation server
75 | - [Go Walker](https://gowalker.org): Go online API documentation
76 | - [Switch](http://gopm.io): Gopm registry
77 | - [YouGam](http://yougam.com): Online Forum
78 | - [Critical Stack Intel](https://intel.criticalstack.com/): A 100% free intel marketplace from Critical Stack, Inc.
79 |
80 | ## Getting Help
81 |
82 | - [API Reference](https://gowalker.org/github.com/Unknwon/macaron)
83 | - [Documentation](http://go-macaron.com)
84 | - [FAQs](http://go-macaron.com/docs/faqs)
85 | - [](https://gitter.im/Unknwon/macaron?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
86 |
87 | ## Credits
88 |
89 | - Basic design of [Martini](https://github.com/go-martini/martini).
90 | - Logo is modified by [@insionng](https://github.com/insionng) based on [Tribal Dragon](http://xtremeyamazaki.deviantart.com/art/Tribal-Dragon-27005087).
91 |
92 | ## License
93 |
94 | This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text.
95 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/time.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | import (
18 | "fmt"
19 | "strconv"
20 | "strings"
21 | "time"
22 | )
23 |
24 | // Format unix time int64 to string
25 | func Date(ti int64, format string) string {
26 | t := time.Unix(int64(ti), 0)
27 | return DateT(t, format)
28 | }
29 |
30 | // Format unix time string to string
31 | func DateS(ts string, format string) string {
32 | i, _ := strconv.ParseInt(ts, 10, 64)
33 | return Date(i, format)
34 | }
35 |
36 | // Format time.Time struct to string
37 | // MM - month - 01
38 | // M - month - 1, single bit
39 | // DD - day - 02
40 | // D - day 2
41 | // YYYY - year - 2006
42 | // YY - year - 06
43 | // HH - 24 hours - 03
44 | // H - 24 hours - 3
45 | // hh - 12 hours - 03
46 | // h - 12 hours - 3
47 | // mm - minute - 04
48 | // m - minute - 4
49 | // ss - second - 05
50 | // s - second = 5
51 | func DateT(t time.Time, format string) string {
52 | res := strings.Replace(format, "MM", t.Format("01"), -1)
53 | res = strings.Replace(res, "M", t.Format("1"), -1)
54 | res = strings.Replace(res, "DD", t.Format("02"), -1)
55 | res = strings.Replace(res, "D", t.Format("2"), -1)
56 | res = strings.Replace(res, "YYYY", t.Format("2006"), -1)
57 | res = strings.Replace(res, "YY", t.Format("06"), -1)
58 | res = strings.Replace(res, "HH", fmt.Sprintf("%02d", t.Hour()), -1)
59 | res = strings.Replace(res, "H", fmt.Sprintf("%d", t.Hour()), -1)
60 | res = strings.Replace(res, "hh", t.Format("03"), -1)
61 | res = strings.Replace(res, "h", t.Format("3"), -1)
62 | res = strings.Replace(res, "mm", t.Format("04"), -1)
63 | res = strings.Replace(res, "m", t.Format("4"), -1)
64 | res = strings.Replace(res, "ss", t.Format("05"), -1)
65 | res = strings.Replace(res, "s", t.Format("5"), -1)
66 | return res
67 | }
68 |
69 | // DateFormat pattern rules.
70 | var datePatterns = []string{
71 | // year
72 | "Y", "2006", // A full numeric representation of a year, 4 digits Examples: 1999 or 2003
73 | "y", "06", //A two digit representation of a year Examples: 99 or 03
74 |
75 | // month
76 | "m", "01", // Numeric representation of a month, with leading zeros 01 through 12
77 | "n", "1", // Numeric representation of a month, without leading zeros 1 through 12
78 | "M", "Jan", // A short textual representation of a month, three letters Jan through Dec
79 | "F", "January", // A full textual representation of a month, such as January or March January through December
80 |
81 | // day
82 | "d", "02", // Day of the month, 2 digits with leading zeros 01 to 31
83 | "j", "2", // Day of the month without leading zeros 1 to 31
84 |
85 | // week
86 | "D", "Mon", // A textual representation of a day, three letters Mon through Sun
87 | "l", "Monday", // A full textual representation of the day of the week Sunday through Saturday
88 |
89 | // time
90 | "g", "3", // 12-hour format of an hour without leading zeros 1 through 12
91 | "G", "15", // 24-hour format of an hour without leading zeros 0 through 23
92 | "h", "03", // 12-hour format of an hour with leading zeros 01 through 12
93 | "H", "15", // 24-hour format of an hour with leading zeros 00 through 23
94 |
95 | "a", "pm", // Lowercase Ante meridiem and Post meridiem am or pm
96 | "A", "PM", // Uppercase Ante meridiem and Post meridiem AM or PM
97 |
98 | "i", "04", // Minutes with leading zeros 00 to 59
99 | "s", "05", // Seconds, with leading zeros 00 through 59
100 |
101 | // time zone
102 | "T", "MST",
103 | "P", "-07:00",
104 | "O", "-0700",
105 |
106 | // RFC 2822
107 | "r", time.RFC1123Z,
108 | }
109 |
110 | // Parse Date use PHP time format.
111 | func DateParse(dateString, format string) (time.Time, error) {
112 | replacer := strings.NewReplacer(datePatterns...)
113 | format = replacer.Replace(format)
114 | return time.ParseInLocation(format, dateString, time.Local)
115 | }
116 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/macaron/recovery.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Martini Authors
2 | // Copyright 2014 Unknwon
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
5 | // not use this file except in compliance with the License. You may obtain
6 | // a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | // License for the specific language governing permissions and limitations
14 | // under the License.
15 |
16 | package macaron
17 |
18 | import (
19 | "bytes"
20 | "fmt"
21 | "io/ioutil"
22 | "log"
23 | "net/http"
24 | "runtime"
25 |
26 | "github.com/Unknwon/macaron/inject"
27 | )
28 |
29 | const (
30 | panicHtml = `
31 | PANIC: %s
32 |
33 |
58 |
59 |
PANIC
60 |
%s
61 |
%s
62 |
63 | `
64 | )
65 |
66 | var (
67 | dunno = []byte("???")
68 | centerDot = []byte("·")
69 | dot = []byte(".")
70 | slash = []byte("/")
71 | )
72 |
73 | // stack returns a nicely formated stack frame, skipping skip frames
74 | func stack(skip int) []byte {
75 | buf := new(bytes.Buffer) // the returned data
76 | // As we loop, we open files and read them. These variables record the currently
77 | // loaded file.
78 | var lines [][]byte
79 | var lastFile string
80 | for i := skip; ; i++ { // Skip the expected number of frames
81 | pc, file, line, ok := runtime.Caller(i)
82 | if !ok {
83 | break
84 | }
85 | // Print this much at least. If we can't find the source, it won't show.
86 | fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc)
87 | if file != lastFile {
88 | data, err := ioutil.ReadFile(file)
89 | if err != nil {
90 | continue
91 | }
92 | lines = bytes.Split(data, []byte{'\n'})
93 | lastFile = file
94 | }
95 | fmt.Fprintf(buf, "\t%s: %s\n", function(pc), source(lines, line))
96 | }
97 | return buf.Bytes()
98 | }
99 |
100 | // source returns a space-trimmed slice of the n'th line.
101 | func source(lines [][]byte, n int) []byte {
102 | n-- // in stack trace, lines are 1-indexed but our array is 0-indexed
103 | if n < 0 || n >= len(lines) {
104 | return dunno
105 | }
106 | return bytes.TrimSpace(lines[n])
107 | }
108 |
109 | // function returns, if possible, the name of the function containing the PC.
110 | func function(pc uintptr) []byte {
111 | fn := runtime.FuncForPC(pc)
112 | if fn == nil {
113 | return dunno
114 | }
115 | name := []byte(fn.Name())
116 | // The name includes the path name to the package, which is unnecessary
117 | // since the file name is already included. Plus, it has center dots.
118 | // That is, we see
119 | // runtime/debug.*T·ptrmethod
120 | // and want
121 | // *T.ptrmethod
122 | // Also the package path might contains dot (e.g. code.google.com/...),
123 | // so first eliminate the path prefix
124 | if lastslash := bytes.LastIndex(name, slash); lastslash >= 0 {
125 | name = name[lastslash+1:]
126 | }
127 | if period := bytes.Index(name, dot); period >= 0 {
128 | name = name[period+1:]
129 | }
130 | name = bytes.Replace(name, centerDot, dot, -1)
131 | return name
132 | }
133 |
134 | // Recovery returns a middleware that recovers from any panics and writes a 500 if there was one.
135 | // While Martini is in development mode, Recovery will also output the panic as HTML.
136 | func Recovery() Handler {
137 | return func(c *Context, log *log.Logger) {
138 | defer func() {
139 | if err := recover(); err != nil {
140 | stack := stack(3)
141 | log.Printf("PANIC: %s\n%s", err, stack)
142 |
143 | // Lookup the current responsewriter
144 | val := c.GetVal(inject.InterfaceOf((*http.ResponseWriter)(nil)))
145 | res := val.Interface().(http.ResponseWriter)
146 |
147 | // respond with panic message while in development mode
148 | var body []byte
149 | if Env == DEV {
150 | res.Header().Set("Content-Type", "text/html")
151 | body = []byte(fmt.Sprintf(panicHtml, err, err, stack))
152 | }
153 |
154 | res.WriteHeader(http.StatusInternalServerError)
155 | if nil != body {
156 | res.Write(body)
157 | }
158 | }
159 | }()
160 |
161 | c.Next()
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/vendor/github.com/go-macaron/macaron/recovery.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Martini Authors
2 | // Copyright 2014 The Macaron Authors
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
5 | // not use this file except in compliance with the License. You may obtain
6 | // a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | // License for the specific language governing permissions and limitations
14 | // under the License.
15 |
16 | package macaron
17 |
18 | import (
19 | "bytes"
20 | "fmt"
21 | "io/ioutil"
22 | "log"
23 | "net/http"
24 | "runtime"
25 |
26 | "github.com/go-macaron/inject"
27 | )
28 |
29 | const (
30 | panicHtml = `
31 | PANIC: %s
32 |
33 |
58 |
59 |
PANIC
60 |
%s
61 |
%s
62 |
63 | `
64 | )
65 |
66 | var (
67 | dunno = []byte("???")
68 | centerDot = []byte("·")
69 | dot = []byte(".")
70 | slash = []byte("/")
71 | )
72 |
73 | // stack returns a nicely formated stack frame, skipping skip frames
74 | func stack(skip int) []byte {
75 | buf := new(bytes.Buffer) // the returned data
76 | // As we loop, we open files and read them. These variables record the currently
77 | // loaded file.
78 | var lines [][]byte
79 | var lastFile string
80 | for i := skip; ; i++ { // Skip the expected number of frames
81 | pc, file, line, ok := runtime.Caller(i)
82 | if !ok {
83 | break
84 | }
85 | // Print this much at least. If we can't find the source, it won't show.
86 | fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc)
87 | if file != lastFile {
88 | data, err := ioutil.ReadFile(file)
89 | if err != nil {
90 | continue
91 | }
92 | lines = bytes.Split(data, []byte{'\n'})
93 | lastFile = file
94 | }
95 | fmt.Fprintf(buf, "\t%s: %s\n", function(pc), source(lines, line))
96 | }
97 | return buf.Bytes()
98 | }
99 |
100 | // source returns a space-trimmed slice of the n'th line.
101 | func source(lines [][]byte, n int) []byte {
102 | n-- // in stack trace, lines are 1-indexed but our array is 0-indexed
103 | if n < 0 || n >= len(lines) {
104 | return dunno
105 | }
106 | return bytes.TrimSpace(lines[n])
107 | }
108 |
109 | // function returns, if possible, the name of the function containing the PC.
110 | func function(pc uintptr) []byte {
111 | fn := runtime.FuncForPC(pc)
112 | if fn == nil {
113 | return dunno
114 | }
115 | name := []byte(fn.Name())
116 | // The name includes the path name to the package, which is unnecessary
117 | // since the file name is already included. Plus, it has center dots.
118 | // That is, we see
119 | // runtime/debug.*T·ptrmethod
120 | // and want
121 | // *T.ptrmethod
122 | // Also the package path might contains dot (e.g. code.google.com/...),
123 | // so first eliminate the path prefix
124 | if lastslash := bytes.LastIndex(name, slash); lastslash >= 0 {
125 | name = name[lastslash+1:]
126 | }
127 | if period := bytes.Index(name, dot); period >= 0 {
128 | name = name[period+1:]
129 | }
130 | name = bytes.Replace(name, centerDot, dot, -1)
131 | return name
132 | }
133 |
134 | // Recovery returns a middleware that recovers from any panics and writes a 500 if there was one.
135 | // While Martini is in development mode, Recovery will also output the panic as HTML.
136 | func Recovery() Handler {
137 | return func(c *Context, log *log.Logger) {
138 | defer func() {
139 | if err := recover(); err != nil {
140 | stack := stack(3)
141 | log.Printf("PANIC: %s\n%s", err, stack)
142 |
143 | // Lookup the current responsewriter
144 | val := c.GetVal(inject.InterfaceOf((*http.ResponseWriter)(nil)))
145 | res := val.Interface().(http.ResponseWriter)
146 |
147 | // respond with panic message while in development mode
148 | var body []byte
149 | if Env == DEV {
150 | res.Header().Set("Content-Type", "text/html")
151 | body = []byte(fmt.Sprintf(panicHtml, err, err, stack))
152 | }
153 |
154 | res.WriteHeader(http.StatusInternalServerError)
155 | if nil != body {
156 | res.Write(body)
157 | }
158 | }
159 | }()
160 |
161 | c.Next()
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/dir.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | import (
18 | "errors"
19 | "fmt"
20 | "os"
21 | "path"
22 | "strings"
23 | )
24 |
25 | // IsDir returns true if given path is a directory,
26 | // or returns false when it's a file or does not exist.
27 | func IsDir(dir string) bool {
28 | f, e := os.Stat(dir)
29 | if e != nil {
30 | return false
31 | }
32 | return f.IsDir()
33 | }
34 |
35 | func statDir(dirPath, recPath string, includeDir, isDirOnly bool) ([]string, error) {
36 | dir, err := os.Open(dirPath)
37 | if err != nil {
38 | return nil, err
39 | }
40 | defer dir.Close()
41 |
42 | fis, err := dir.Readdir(0)
43 | if err != nil {
44 | return nil, err
45 | }
46 |
47 | statList := make([]string, 0)
48 | for _, fi := range fis {
49 | if strings.Contains(fi.Name(), ".DS_Store") {
50 | continue
51 | }
52 |
53 | relPath := path.Join(recPath, fi.Name())
54 | curPath := path.Join(dirPath, fi.Name())
55 | if fi.IsDir() {
56 | if includeDir {
57 | statList = append(statList, relPath+"/")
58 | }
59 | s, err := statDir(curPath, relPath, includeDir, isDirOnly)
60 | if err != nil {
61 | return nil, err
62 | }
63 | statList = append(statList, s...)
64 | } else if !isDirOnly {
65 | statList = append(statList, relPath)
66 | }
67 | }
68 | return statList, nil
69 | }
70 |
71 | // StatDir gathers information of given directory by depth-first.
72 | // It returns slice of file list and includes subdirectories if enabled;
73 | // it returns error and nil slice when error occurs in underlying functions,
74 | // or given path is not a directory or does not exist.
75 | //
76 | // Slice does not include given path itself.
77 | // If subdirectories is enabled, they will have suffix '/'.
78 | func StatDir(rootPath string, includeDir ...bool) ([]string, error) {
79 | if !IsDir(rootPath) {
80 | return nil, errors.New("not a directory or does not exist: " + rootPath)
81 | }
82 |
83 | isIncludeDir := false
84 | if len(includeDir) >= 1 {
85 | isIncludeDir = includeDir[0]
86 | }
87 | return statDir(rootPath, "", isIncludeDir, false)
88 | }
89 |
90 | // GetAllSubDirs returns all subdirectories of given root path.
91 | // Slice does not include given path itself.
92 | func GetAllSubDirs(rootPath string) ([]string, error) {
93 | if !IsDir(rootPath) {
94 | return nil, errors.New("not a directory or does not exist: " + rootPath)
95 | }
96 | return statDir(rootPath, "", true, true)
97 | }
98 |
99 | // GetFileListBySuffix returns an ordered list of file paths.
100 | // It recognize if given path is a file, and don't do recursive find.
101 | func GetFileListBySuffix(dirPath, suffix string) ([]string, error) {
102 | if !IsExist(dirPath) {
103 | return nil, fmt.Errorf("given path does not exist: %s", dirPath)
104 | } else if IsFile(dirPath) {
105 | return []string{dirPath}, nil
106 | }
107 |
108 | // Given path is a directory.
109 | dir, err := os.Open(dirPath)
110 | if err != nil {
111 | return nil, err
112 | }
113 |
114 | fis, err := dir.Readdir(0)
115 | if err != nil {
116 | return nil, err
117 | }
118 |
119 | files := make([]string, 0, len(fis))
120 | for _, fi := range fis {
121 | if strings.HasSuffix(fi.Name(), suffix) {
122 | files = append(files, path.Join(dirPath, fi.Name()))
123 | }
124 | }
125 |
126 | return files, nil
127 | }
128 |
129 | // CopyDir copy files recursively from source to target directory.
130 | //
131 | // The filter accepts a function that process the path info.
132 | // and should return true for need to filter.
133 | //
134 | // It returns error when error occurs in underlying functions.
135 | func CopyDir(srcPath, destPath string, filters ...func(filePath string) bool) error {
136 | // Check if target directory exists.
137 | if IsExist(destPath) {
138 | return errors.New("file or directory alreay exists: " + destPath)
139 | }
140 |
141 | err := os.MkdirAll(destPath, os.ModePerm)
142 | if err != nil {
143 | return err
144 | }
145 |
146 | // Gather directory info.
147 | infos, err := StatDir(srcPath, true)
148 | if err != nil {
149 | return err
150 | }
151 |
152 | var filter func(filePath string) bool
153 | if len(filters) > 0 {
154 | filter = filters[0]
155 | }
156 |
157 | for _, info := range infos {
158 | if filter != nil && filter(info) {
159 | continue
160 | }
161 |
162 | curPath := path.Join(destPath, info)
163 | if strings.HasSuffix(info, "/") {
164 | err = os.MkdirAll(curPath, os.ModePerm)
165 | } else {
166 | err = Copy(path.Join(srcPath, info), curPath)
167 | }
168 | if err != nil {
169 | return err
170 | }
171 | }
172 | return nil
173 | }
174 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/cmd.go:
--------------------------------------------------------------------------------
1 | // +build go1.2
2 |
3 | // Copyright 2013 com authors
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
6 | // not use this file except in compliance with the License. You may obtain
7 | // a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | // License for the specific language governing permissions and limitations
15 | // under the License.
16 |
17 | // Package com is an open source project for commonly used functions for the Go programming language.
18 | package com
19 |
20 | import (
21 | "bytes"
22 | "fmt"
23 | "os/exec"
24 | "runtime"
25 | "strings"
26 | )
27 |
28 | // ExecCmdDirBytes executes system command in given directory
29 | // and return stdout, stderr in bytes type, along with possible error.
30 | func ExecCmdDirBytes(dir, cmdName string, args ...string) ([]byte, []byte, error) {
31 | bufOut := new(bytes.Buffer)
32 | bufErr := new(bytes.Buffer)
33 |
34 | cmd := exec.Command(cmdName, args...)
35 | cmd.Dir = dir
36 | cmd.Stdout = bufOut
37 | cmd.Stderr = bufErr
38 |
39 | err := cmd.Run()
40 | return bufOut.Bytes(), bufErr.Bytes(), err
41 | }
42 |
43 | // ExecCmdBytes executes system command
44 | // and return stdout, stderr in bytes type, along with possible error.
45 | func ExecCmdBytes(cmdName string, args ...string) ([]byte, []byte, error) {
46 | return ExecCmdDirBytes("", cmdName, args...)
47 | }
48 |
49 | // ExecCmdDir executes system command in given directory
50 | // and return stdout, stderr in string type, along with possible error.
51 | func ExecCmdDir(dir, cmdName string, args ...string) (string, string, error) {
52 | bufOut, bufErr, err := ExecCmdDirBytes(dir, cmdName, args...)
53 | return string(bufOut), string(bufErr), err
54 | }
55 |
56 | // ExecCmd executes system command
57 | // and return stdout, stderr in string type, along with possible error.
58 | func ExecCmd(cmdName string, args ...string) (string, string, error) {
59 | return ExecCmdDir("", cmdName, args...)
60 | }
61 |
62 | // _________ .__ .____
63 | // \_ ___ \ ____ | | ___________ | | ____ ____
64 | // / \ \/ / _ \| | / _ \_ __ \ | | / _ \ / ___\
65 | // \ \___( <_> ) |_( <_> ) | \/ | |__( <_> ) /_/ >
66 | // \______ /\____/|____/\____/|__| |_______ \____/\___ /
67 | // \/ \/ /_____/
68 |
69 | // Color number constants.
70 | const (
71 | Gray = uint8(iota + 90)
72 | Red
73 | Green
74 | Yellow
75 | Blue
76 | Magenta
77 | //NRed = uint8(31) // Normal
78 | EndColor = "\033[0m"
79 | )
80 |
81 | // getColorLevel returns colored level string by given level.
82 | func getColorLevel(level string) string {
83 | level = strings.ToUpper(level)
84 | switch level {
85 | case "TRAC":
86 | return fmt.Sprintf("\033[%dm%s\033[0m", Blue, level)
87 | case "ERRO":
88 | return fmt.Sprintf("\033[%dm%s\033[0m", Red, level)
89 | case "WARN":
90 | return fmt.Sprintf("\033[%dm%s\033[0m", Magenta, level)
91 | case "SUCC":
92 | return fmt.Sprintf("\033[%dm%s\033[0m", Green, level)
93 | default:
94 | return level
95 | }
96 | }
97 |
98 | // ColorLogS colors log and return colored content.
99 | // Log format: [ error ].
100 | // Level: TRAC -> blue; ERRO -> red; WARN -> Magenta; SUCC -> green; others -> default.
101 | // Content: default; path: yellow; error -> red.
102 | // Level has to be surrounded by "[" and "]".
103 | // Highlights have to be surrounded by "# " and " #"(space), "#" will be deleted.
104 | // Paths have to be surrounded by "( " and " )"(space).
105 | // Errors have to be surrounded by "[ " and " ]"(space).
106 | // Note: it hasn't support windows yet, contribute is welcome.
107 | func ColorLogS(format string, a ...interface{}) string {
108 | log := fmt.Sprintf(format, a...)
109 |
110 | var clog string
111 |
112 | if runtime.GOOS != "windows" {
113 | // Level.
114 | i := strings.Index(log, "]")
115 | if log[0] == '[' && i > -1 {
116 | clog += "[" + getColorLevel(log[1:i]) + "]"
117 | }
118 |
119 | log = log[i+1:]
120 |
121 | // Error.
122 | log = strings.Replace(log, "[ ", fmt.Sprintf("[\033[%dm", Red), -1)
123 | log = strings.Replace(log, " ]", EndColor+"]", -1)
124 |
125 | // Path.
126 | log = strings.Replace(log, "( ", fmt.Sprintf("(\033[%dm", Yellow), -1)
127 | log = strings.Replace(log, " )", EndColor+")", -1)
128 |
129 | // Highlights.
130 | log = strings.Replace(log, "# ", fmt.Sprintf("\033[%dm", Gray), -1)
131 | log = strings.Replace(log, " #", EndColor, -1)
132 |
133 | } else {
134 | // Level.
135 | i := strings.Index(log, "]")
136 | if log[0] == '[' && i > -1 {
137 | clog += "[" + log[1:i] + "]"
138 | }
139 |
140 | log = log[i+1:]
141 |
142 | // Error.
143 | log = strings.Replace(log, "[ ", "[", -1)
144 | log = strings.Replace(log, " ]", "]", -1)
145 |
146 | // Path.
147 | log = strings.Replace(log, "( ", "(", -1)
148 | log = strings.Replace(log, " )", ")", -1)
149 |
150 | // Highlights.
151 | log = strings.Replace(log, "# ", "", -1)
152 | log = strings.Replace(log, " #", "", -1)
153 | }
154 | return clog + log
155 | }
156 |
157 | // ColorLog prints colored log to stdout.
158 | // See color rules in function 'ColorLogS'.
159 | func ColorLog(format string, a ...interface{}) {
160 | fmt.Print(ColorLogS(format, a...))
161 | }
162 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/macaron/static.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Martini Authors
2 | // Copyright 2014 Unknwon
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
5 | // not use this file except in compliance with the License. You may obtain
6 | // a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | // License for the specific language governing permissions and limitations
14 | // under the License.
15 |
16 | package macaron
17 |
18 | import (
19 | "log"
20 | "net/http"
21 | "path"
22 | "path/filepath"
23 | "strings"
24 | "sync"
25 | )
26 |
27 | // StaticOptions is a struct for specifying configuration options for the macaron.Static middleware.
28 | type StaticOptions struct {
29 | // Prefix is the optional prefix used to serve the static directory content
30 | Prefix string
31 | // SkipLogging will disable [Static] log messages when a static file is served.
32 | SkipLogging bool
33 | // IndexFile defines which file to serve as index if it exists.
34 | IndexFile string
35 | // Expires defines which user-defined function to use for producing a HTTP Expires Header
36 | // https://developers.google.com/speed/docs/insights/LeverageBrowserCaching
37 | Expires func() string
38 | // FileSystem is the interface for supporting any implmentation of file system.
39 | FileSystem http.FileSystem
40 | }
41 |
42 | // FIXME: to be deleted.
43 | type staticMap struct {
44 | lock sync.RWMutex
45 | data map[string]*http.Dir
46 | }
47 |
48 | func (sm *staticMap) Set(dir *http.Dir) {
49 | sm.lock.Lock()
50 | defer sm.lock.Unlock()
51 |
52 | sm.data[string(*dir)] = dir
53 | }
54 |
55 | func (sm *staticMap) Get(name string) *http.Dir {
56 | sm.lock.RLock()
57 | defer sm.lock.RUnlock()
58 |
59 | return sm.data[name]
60 | }
61 |
62 | func (sm *staticMap) Delete(name string) {
63 | sm.lock.Lock()
64 | defer sm.lock.Unlock()
65 |
66 | delete(sm.data, name)
67 | }
68 |
69 | var statics = staticMap{sync.RWMutex{}, map[string]*http.Dir{}}
70 |
71 | // staticFileSystem implements http.FileSystem interface.
72 | type staticFileSystem struct {
73 | dir *http.Dir
74 | }
75 |
76 | func newStaticFileSystem(directory string) staticFileSystem {
77 | if !filepath.IsAbs(directory) {
78 | directory = filepath.Join(Root, directory)
79 | }
80 | dir := http.Dir(directory)
81 | statics.Set(&dir)
82 | return staticFileSystem{&dir}
83 | }
84 |
85 | func (fs staticFileSystem) Open(name string) (http.File, error) {
86 | return fs.dir.Open(name)
87 | }
88 |
89 | func prepareStaticOption(dir string, opt StaticOptions) StaticOptions {
90 | // Defaults
91 | if len(opt.IndexFile) == 0 {
92 | opt.IndexFile = "index.html"
93 | }
94 | // Normalize the prefix if provided
95 | if opt.Prefix != "" {
96 | // Ensure we have a leading '/'
97 | if opt.Prefix[0] != '/' {
98 | opt.Prefix = "/" + opt.Prefix
99 | }
100 | // Remove any trailing '/'
101 | opt.Prefix = strings.TrimRight(opt.Prefix, "/")
102 | }
103 | if opt.FileSystem == nil {
104 | opt.FileSystem = newStaticFileSystem(dir)
105 | }
106 | return opt
107 | }
108 |
109 | func prepareStaticOptions(dir string, options []StaticOptions) StaticOptions {
110 | var opt StaticOptions
111 | if len(options) > 0 {
112 | opt = options[0]
113 | }
114 | return prepareStaticOption(dir, opt)
115 | }
116 |
117 | func staticHandler(ctx *Context, log *log.Logger, opt StaticOptions) bool {
118 | if ctx.Req.Method != "GET" && ctx.Req.Method != "HEAD" {
119 | return false
120 | }
121 |
122 | file := ctx.Req.URL.Path
123 | // if we have a prefix, filter requests by stripping the prefix
124 | if opt.Prefix != "" {
125 | if !strings.HasPrefix(file, opt.Prefix) {
126 | return false
127 | }
128 | file = file[len(opt.Prefix):]
129 | if file != "" && file[0] != '/' {
130 | return false
131 | }
132 | }
133 |
134 | f, err := opt.FileSystem.Open(file)
135 | if err != nil {
136 | return false
137 | }
138 | defer f.Close()
139 |
140 | fi, err := f.Stat()
141 | if err != nil {
142 | return true // File exists but fail to open.
143 | }
144 |
145 | // Try to serve index file
146 | if fi.IsDir() {
147 | // Redirect if missing trailing slash.
148 | if !strings.HasSuffix(ctx.Req.URL.Path, "/") {
149 | http.Redirect(ctx.Resp, ctx.Req.Request, ctx.Req.URL.Path+"/", http.StatusFound)
150 | return true
151 | }
152 |
153 | file = path.Join(file, opt.IndexFile)
154 | f, err = opt.FileSystem.Open(file)
155 | if err != nil {
156 | return false // Discard error.
157 | }
158 | defer f.Close()
159 |
160 | fi, err = f.Stat()
161 | if err != nil || fi.IsDir() {
162 | return true
163 | }
164 | }
165 |
166 | if !opt.SkipLogging {
167 | log.Println("[Static] Serving " + file)
168 | }
169 |
170 | // Add an Expires header to the static content
171 | if opt.Expires != nil {
172 | ctx.Resp.Header().Set("Expires", opt.Expires())
173 | }
174 |
175 | http.ServeContent(ctx.Resp, ctx.Req.Request, file, fi.ModTime(), f)
176 | return true
177 | }
178 |
179 | // Static returns a middleware handler that serves static files in the given directory.
180 | func Static(directory string, staticOpt ...StaticOptions) Handler {
181 | opt := prepareStaticOptions(directory, staticOpt)
182 |
183 | return func(ctx *Context, log *log.Logger) {
184 | staticHandler(ctx, log, opt)
185 | }
186 | }
187 |
188 | // Statics registers multiple static middleware handlers all at once.
189 | func Statics(opt StaticOptions, dirs ...string) Handler {
190 | if len(dirs) == 0 {
191 | panic("no static directory is given")
192 | }
193 | opts := make([]StaticOptions, len(dirs))
194 | for i := range dirs {
195 | opts[i] = prepareStaticOption(dirs[i], opt)
196 | }
197 |
198 | return func(ctx *Context, log *log.Logger) {
199 | for i := range opts {
200 | if staticHandler(ctx, log, opts[i]) {
201 | return
202 | }
203 | }
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/vendor/github.com/go-macaron/macaron/static.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Martini Authors
2 | // Copyright 2014 The Macaron Authors
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
5 | // not use this file except in compliance with the License. You may obtain
6 | // a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | // License for the specific language governing permissions and limitations
14 | // under the License.
15 |
16 | package macaron
17 |
18 | import (
19 | "log"
20 | "net/http"
21 | "path"
22 | "path/filepath"
23 | "strings"
24 | "sync"
25 | )
26 |
27 | // StaticOptions is a struct for specifying configuration options for the macaron.Static middleware.
28 | type StaticOptions struct {
29 | // Prefix is the optional prefix used to serve the static directory content
30 | Prefix string
31 | // SkipLogging will disable [Static] log messages when a static file is served.
32 | SkipLogging bool
33 | // IndexFile defines which file to serve as index if it exists.
34 | IndexFile string
35 | // Expires defines which user-defined function to use for producing a HTTP Expires Header
36 | // https://developers.google.com/speed/docs/insights/LeverageBrowserCaching
37 | Expires func() string
38 | // FileSystem is the interface for supporting any implmentation of file system.
39 | FileSystem http.FileSystem
40 | }
41 |
42 | // FIXME: to be deleted.
43 | type staticMap struct {
44 | lock sync.RWMutex
45 | data map[string]*http.Dir
46 | }
47 |
48 | func (sm *staticMap) Set(dir *http.Dir) {
49 | sm.lock.Lock()
50 | defer sm.lock.Unlock()
51 |
52 | sm.data[string(*dir)] = dir
53 | }
54 |
55 | func (sm *staticMap) Get(name string) *http.Dir {
56 | sm.lock.RLock()
57 | defer sm.lock.RUnlock()
58 |
59 | return sm.data[name]
60 | }
61 |
62 | func (sm *staticMap) Delete(name string) {
63 | sm.lock.Lock()
64 | defer sm.lock.Unlock()
65 |
66 | delete(sm.data, name)
67 | }
68 |
69 | var statics = staticMap{sync.RWMutex{}, map[string]*http.Dir{}}
70 |
71 | // staticFileSystem implements http.FileSystem interface.
72 | type staticFileSystem struct {
73 | dir *http.Dir
74 | }
75 |
76 | func newStaticFileSystem(directory string) staticFileSystem {
77 | if !filepath.IsAbs(directory) {
78 | directory = filepath.Join(Root, directory)
79 | }
80 | dir := http.Dir(directory)
81 | statics.Set(&dir)
82 | return staticFileSystem{&dir}
83 | }
84 |
85 | func (fs staticFileSystem) Open(name string) (http.File, error) {
86 | return fs.dir.Open(name)
87 | }
88 |
89 | func prepareStaticOption(dir string, opt StaticOptions) StaticOptions {
90 | // Defaults
91 | if len(opt.IndexFile) == 0 {
92 | opt.IndexFile = "index.html"
93 | }
94 | // Normalize the prefix if provided
95 | if opt.Prefix != "" {
96 | // Ensure we have a leading '/'
97 | if opt.Prefix[0] != '/' {
98 | opt.Prefix = "/" + opt.Prefix
99 | }
100 | // Remove any trailing '/'
101 | opt.Prefix = strings.TrimRight(opt.Prefix, "/")
102 | }
103 | if opt.FileSystem == nil {
104 | opt.FileSystem = newStaticFileSystem(dir)
105 | }
106 | return opt
107 | }
108 |
109 | func prepareStaticOptions(dir string, options []StaticOptions) StaticOptions {
110 | var opt StaticOptions
111 | if len(options) > 0 {
112 | opt = options[0]
113 | }
114 | return prepareStaticOption(dir, opt)
115 | }
116 |
117 | func staticHandler(ctx *Context, log *log.Logger, opt StaticOptions) bool {
118 | if ctx.Req.Method != "GET" && ctx.Req.Method != "HEAD" {
119 | return false
120 | }
121 |
122 | file := ctx.Req.URL.Path
123 | // if we have a prefix, filter requests by stripping the prefix
124 | if opt.Prefix != "" {
125 | if !strings.HasPrefix(file, opt.Prefix) {
126 | return false
127 | }
128 | file = file[len(opt.Prefix):]
129 | if file != "" && file[0] != '/' {
130 | return false
131 | }
132 | }
133 |
134 | f, err := opt.FileSystem.Open(file)
135 | if err != nil {
136 | return false
137 | }
138 | defer f.Close()
139 |
140 | fi, err := f.Stat()
141 | if err != nil {
142 | return true // File exists but fail to open.
143 | }
144 |
145 | // Try to serve index file
146 | if fi.IsDir() {
147 | // Redirect if missing trailing slash.
148 | if !strings.HasSuffix(ctx.Req.URL.Path, "/") {
149 | http.Redirect(ctx.Resp, ctx.Req.Request, ctx.Req.URL.Path+"/", http.StatusFound)
150 | return true
151 | }
152 |
153 | file = path.Join(file, opt.IndexFile)
154 | f, err = opt.FileSystem.Open(file)
155 | if err != nil {
156 | return false // Discard error.
157 | }
158 | defer f.Close()
159 |
160 | fi, err = f.Stat()
161 | if err != nil || fi.IsDir() {
162 | return true
163 | }
164 | }
165 |
166 | if !opt.SkipLogging {
167 | log.Println("[Static] Serving " + file)
168 | }
169 |
170 | // Add an Expires header to the static content
171 | if opt.Expires != nil {
172 | ctx.Resp.Header().Set("Expires", opt.Expires())
173 | }
174 |
175 | http.ServeContent(ctx.Resp, ctx.Req.Request, file, fi.ModTime(), f)
176 | return true
177 | }
178 |
179 | // Static returns a middleware handler that serves static files in the given directory.
180 | func Static(directory string, staticOpt ...StaticOptions) Handler {
181 | opt := prepareStaticOptions(directory, staticOpt)
182 |
183 | return func(ctx *Context, log *log.Logger) {
184 | staticHandler(ctx, log, opt)
185 | }
186 | }
187 |
188 | // Statics registers multiple static middleware handlers all at once.
189 | func Statics(opt StaticOptions, dirs ...string) Handler {
190 | if len(dirs) == 0 {
191 | panic("no static directory is given")
192 | }
193 | opts := make([]StaticOptions, len(dirs))
194 | for i := range dirs {
195 | opts[i] = prepareStaticOption(dirs[i], opt)
196 | }
197 |
198 | return func(ctx *Context, log *log.Logger) {
199 | for i := range opts {
200 | if staticHandler(ctx, log, opts[i]) {
201 | return
202 | }
203 | }
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/http.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | import (
18 | "bytes"
19 | "encoding/json"
20 | "fmt"
21 | "io"
22 | "io/ioutil"
23 | "net/http"
24 | "os"
25 | "path"
26 | )
27 |
28 | type NotFoundError struct {
29 | Message string
30 | }
31 |
32 | func (e NotFoundError) Error() string {
33 | return e.Message
34 | }
35 |
36 | type RemoteError struct {
37 | Host string
38 | Err error
39 | }
40 |
41 | func (e *RemoteError) Error() string {
42 | return e.Err.Error()
43 | }
44 |
45 | var UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1541.0 Safari/537.36"
46 |
47 | // HttpCall makes HTTP method call.
48 | func HttpCall(client *http.Client, method, url string, header http.Header, body io.Reader) (io.ReadCloser, error) {
49 | req, err := http.NewRequest(method, url, body)
50 | if err != nil {
51 | return nil, err
52 | }
53 | req.Header.Set("User-Agent", UserAgent)
54 | for k, vs := range header {
55 | req.Header[k] = vs
56 | }
57 | resp, err := client.Do(req)
58 | if err != nil {
59 | return nil, err
60 | }
61 | if resp.StatusCode == 200 {
62 | return resp.Body, nil
63 | }
64 | resp.Body.Close()
65 | if resp.StatusCode == 404 { // 403 can be rate limit error. || resp.StatusCode == 403 {
66 | err = fmt.Errorf("resource not found: %s", url)
67 | } else {
68 | err = fmt.Errorf("%s %s -> %d", method, url, resp.StatusCode)
69 | }
70 | return nil, err
71 | }
72 |
73 | // HttpGet gets the specified resource.
74 | // ErrNotFound is returned if the server responds with status 404.
75 | func HttpGet(client *http.Client, url string, header http.Header) (io.ReadCloser, error) {
76 | return HttpCall(client, "GET", url, header, nil)
77 | }
78 |
79 | // HttpPost posts the specified resource.
80 | // ErrNotFound is returned if the server responds with status 404.
81 | func HttpPost(client *http.Client, url string, header http.Header, body []byte) (io.ReadCloser, error) {
82 | return HttpCall(client, "POST", url, header, bytes.NewBuffer(body))
83 | }
84 |
85 | // HttpGetToFile gets the specified resource and writes to file.
86 | // ErrNotFound is returned if the server responds with status 404.
87 | func HttpGetToFile(client *http.Client, url string, header http.Header, fileName string) error {
88 | rc, err := HttpGet(client, url, header)
89 | if err != nil {
90 | return err
91 | }
92 | defer rc.Close()
93 |
94 | os.MkdirAll(path.Dir(fileName), os.ModePerm)
95 | f, err := os.Create(fileName)
96 | if err != nil {
97 | return err
98 | }
99 | defer f.Close()
100 | _, err = io.Copy(f, rc)
101 | return err
102 | }
103 |
104 | // HttpGetBytes gets the specified resource. ErrNotFound is returned if the server
105 | // responds with status 404.
106 | func HttpGetBytes(client *http.Client, url string, header http.Header) ([]byte, error) {
107 | rc, err := HttpGet(client, url, header)
108 | if err != nil {
109 | return nil, err
110 | }
111 | defer rc.Close()
112 | return ioutil.ReadAll(rc)
113 | }
114 |
115 | // HttpGetJSON gets the specified resource and mapping to struct.
116 | // ErrNotFound is returned if the server responds with status 404.
117 | func HttpGetJSON(client *http.Client, url string, v interface{}) error {
118 | rc, err := HttpGet(client, url, nil)
119 | if err != nil {
120 | return err
121 | }
122 | defer rc.Close()
123 | err = json.NewDecoder(rc).Decode(v)
124 | if _, ok := err.(*json.SyntaxError); ok {
125 | return fmt.Errorf("JSON syntax error at %s", url)
126 | }
127 | return nil
128 | }
129 |
130 | // HttpPostJSON posts the specified resource with struct values,
131 | // and maps results to struct.
132 | // ErrNotFound is returned if the server responds with status 404.
133 | func HttpPostJSON(client *http.Client, url string, body, v interface{}) error {
134 | data, err := json.Marshal(body)
135 | if err != nil {
136 | return err
137 | }
138 | rc, err := HttpPost(client, url, http.Header{"content-type": []string{"application/json"}}, data)
139 | if err != nil {
140 | return err
141 | }
142 | defer rc.Close()
143 | err = json.NewDecoder(rc).Decode(v)
144 | if _, ok := err.(*json.SyntaxError); ok {
145 | return fmt.Errorf("JSON syntax error at %s", url)
146 | }
147 | return nil
148 | }
149 |
150 | // A RawFile describes a file that can be downloaded.
151 | type RawFile interface {
152 | Name() string
153 | RawUrl() string
154 | Data() []byte
155 | SetData([]byte)
156 | }
157 |
158 | // FetchFiles fetches files specified by the rawURL field in parallel.
159 | func FetchFiles(client *http.Client, files []RawFile, header http.Header) error {
160 | ch := make(chan error, len(files))
161 | for i := range files {
162 | go func(i int) {
163 | p, err := HttpGetBytes(client, files[i].RawUrl(), nil)
164 | if err != nil {
165 | ch <- err
166 | return
167 | }
168 | files[i].SetData(p)
169 | ch <- nil
170 | }(i)
171 | }
172 | for _ = range files {
173 | if err := <-ch; err != nil {
174 | return err
175 | }
176 | }
177 | return nil
178 | }
179 |
180 | // FetchFiles uses command `curl` to fetch files specified by the rawURL field in parallel.
181 | func FetchFilesCurl(files []RawFile, curlOptions ...string) error {
182 | ch := make(chan error, len(files))
183 | for i := range files {
184 | go func(i int) {
185 | stdout, _, err := ExecCmd("curl", append(curlOptions, files[i].RawUrl())...)
186 | if err != nil {
187 | ch <- err
188 | return
189 | }
190 |
191 | files[i].SetData([]byte(stdout))
192 | ch <- nil
193 | }(i)
194 | }
195 | for _ = range files {
196 | if err := <-ch; err != nil {
197 | return err
198 | }
199 | }
200 | return nil
201 | }
202 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/string.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 com authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package com
16 |
17 | import (
18 | "bytes"
19 | "crypto/aes"
20 | "crypto/cipher"
21 | "crypto/rand"
22 | "encoding/base64"
23 | "errors"
24 | "io"
25 | r "math/rand"
26 | "strconv"
27 | "strings"
28 | "time"
29 | "unicode"
30 | "unicode/utf8"
31 | )
32 |
33 | // AESEncrypt encrypts text and given key with AES.
34 | func AESEncrypt(key, text []byte) ([]byte, error) {
35 | block, err := aes.NewCipher(key)
36 | if err != nil {
37 | return nil, err
38 | }
39 | b := base64.StdEncoding.EncodeToString(text)
40 | ciphertext := make([]byte, aes.BlockSize+len(b))
41 | iv := ciphertext[:aes.BlockSize]
42 | if _, err := io.ReadFull(rand.Reader, iv); err != nil {
43 | return nil, err
44 | }
45 | cfb := cipher.NewCFBEncrypter(block, iv)
46 | cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
47 | return ciphertext, nil
48 | }
49 |
50 | // AESDecrypt decrypts text and given key with AES.
51 | func AESDecrypt(key, text []byte) ([]byte, error) {
52 | block, err := aes.NewCipher(key)
53 | if err != nil {
54 | return nil, err
55 | }
56 | if len(text) < aes.BlockSize {
57 | return nil, errors.New("ciphertext too short")
58 | }
59 | iv := text[:aes.BlockSize]
60 | text = text[aes.BlockSize:]
61 | cfb := cipher.NewCFBDecrypter(block, iv)
62 | cfb.XORKeyStream(text, text)
63 | data, err := base64.StdEncoding.DecodeString(string(text))
64 | if err != nil {
65 | return nil, err
66 | }
67 | return data, nil
68 | }
69 |
70 | // IsLetter returns true if the 'l' is an English letter.
71 | func IsLetter(l uint8) bool {
72 | n := (l | 0x20) - 'a'
73 | if n >= 0 && n < 26 {
74 | return true
75 | }
76 | return false
77 | }
78 |
79 | // Expand replaces {k} in template with match[k] or subs[atoi(k)] if k is not in match.
80 | func Expand(template string, match map[string]string, subs ...string) string {
81 | var p []byte
82 | var i int
83 | for {
84 | i = strings.Index(template, "{")
85 | if i < 0 {
86 | break
87 | }
88 | p = append(p, template[:i]...)
89 | template = template[i+1:]
90 | i = strings.Index(template, "}")
91 | if s, ok := match[template[:i]]; ok {
92 | p = append(p, s...)
93 | } else {
94 | j, _ := strconv.Atoi(template[:i])
95 | if j >= len(subs) {
96 | p = append(p, []byte("Missing")...)
97 | } else {
98 | p = append(p, subs[j]...)
99 | }
100 | }
101 | template = template[i+1:]
102 | }
103 | p = append(p, template...)
104 | return string(p)
105 | }
106 |
107 | // Reverse s string, support unicode
108 | func Reverse(s string) string {
109 | n := len(s)
110 | runes := make([]rune, n)
111 | for _, rune := range s {
112 | n--
113 | runes[n] = rune
114 | }
115 | return string(runes[n:])
116 | }
117 |
118 | // RandomCreateBytes generate random []byte by specify chars.
119 | func RandomCreateBytes(n int, alphabets ...byte) []byte {
120 | const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
121 | var bytes = make([]byte, n)
122 | var randby bool
123 | if num, err := rand.Read(bytes); num != n || err != nil {
124 | r.Seed(time.Now().UnixNano())
125 | randby = true
126 | }
127 | for i, b := range bytes {
128 | if len(alphabets) == 0 {
129 | if randby {
130 | bytes[i] = alphanum[r.Intn(len(alphanum))]
131 | } else {
132 | bytes[i] = alphanum[b%byte(len(alphanum))]
133 | }
134 | } else {
135 | if randby {
136 | bytes[i] = alphabets[r.Intn(len(alphabets))]
137 | } else {
138 | bytes[i] = alphabets[b%byte(len(alphabets))]
139 | }
140 | }
141 | }
142 | return bytes
143 | }
144 |
145 | // ToSnakeCase can convert all upper case characters in a string to
146 | // underscore format.
147 | //
148 | // Some samples.
149 | // "FirstName" => "first_name"
150 | // "HTTPServer" => "http_server"
151 | // "NoHTTPS" => "no_https"
152 | // "GO_PATH" => "go_path"
153 | // "GO PATH" => "go_path" // space is converted to underscore.
154 | // "GO-PATH" => "go_path" // hyphen is converted to underscore.
155 | //
156 | // From https://github.com/huandu/xstrings
157 | func ToSnakeCase(str string) string {
158 | if len(str) == 0 {
159 | return ""
160 | }
161 |
162 | buf := &bytes.Buffer{}
163 | var prev, r0, r1 rune
164 | var size int
165 |
166 | r0 = '_'
167 |
168 | for len(str) > 0 {
169 | prev = r0
170 | r0, size = utf8.DecodeRuneInString(str)
171 | str = str[size:]
172 |
173 | switch {
174 | case r0 == utf8.RuneError:
175 | buf.WriteByte(byte(str[0]))
176 |
177 | case unicode.IsUpper(r0):
178 | if prev != '_' {
179 | buf.WriteRune('_')
180 | }
181 |
182 | buf.WriteRune(unicode.ToLower(r0))
183 |
184 | if len(str) == 0 {
185 | break
186 | }
187 |
188 | r0, size = utf8.DecodeRuneInString(str)
189 | str = str[size:]
190 |
191 | if !unicode.IsUpper(r0) {
192 | buf.WriteRune(r0)
193 | break
194 | }
195 |
196 | // find next non-upper-case character and insert `_` properly.
197 | // it's designed to convert `HTTPServer` to `http_server`.
198 | // if there are more than 2 adjacent upper case characters in a word,
199 | // treat them as an abbreviation plus a normal word.
200 | for len(str) > 0 {
201 | r1 = r0
202 | r0, size = utf8.DecodeRuneInString(str)
203 | str = str[size:]
204 |
205 | if r0 == utf8.RuneError {
206 | buf.WriteRune(unicode.ToLower(r1))
207 | buf.WriteByte(byte(str[0]))
208 | break
209 | }
210 |
211 | if !unicode.IsUpper(r0) {
212 | if r0 == '_' || r0 == ' ' || r0 == '-' {
213 | r0 = '_'
214 |
215 | buf.WriteRune(unicode.ToLower(r1))
216 | } else {
217 | buf.WriteRune('_')
218 | buf.WriteRune(unicode.ToLower(r1))
219 | buf.WriteRune(r0)
220 | }
221 |
222 | break
223 | }
224 |
225 | buf.WriteRune(unicode.ToLower(r1))
226 | }
227 |
228 | if len(str) == 0 || r0 == '_' {
229 | buf.WriteRune(unicode.ToLower(r0))
230 | break
231 | }
232 |
233 | default:
234 | if r0 == ' ' || r0 == '-' {
235 | r0 = '_'
236 | }
237 |
238 | buf.WriteRune(r0)
239 | }
240 | }
241 |
242 | return buf.String()
243 | }
244 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/macaron/inject/inject.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Jeremy Saenz
2 | // Copyright 2014 Unknwon
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
5 | // not use this file except in compliance with the License. You may obtain
6 | // a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | // License for the specific language governing permissions and limitations
14 | // under the License.
15 |
16 | // Package inject provides utilities for mapping and injecting dependencies in various ways.
17 | package inject
18 |
19 | import (
20 | "fmt"
21 | "reflect"
22 | )
23 |
24 | // Injector represents an interface for mapping and injecting dependencies into structs
25 | // and function arguments.
26 | type Injector interface {
27 | Applicator
28 | Invoker
29 | TypeMapper
30 | // SetParent sets the parent of the injector. If the injector cannot find a
31 | // dependency in its Type map it will check its parent before returning an
32 | // error.
33 | SetParent(Injector)
34 | }
35 |
36 | // Applicator represents an interface for mapping dependencies to a struct.
37 | type Applicator interface {
38 | // Maps dependencies in the Type map to each field in the struct
39 | // that is tagged with 'inject'. Returns an error if the injection
40 | // fails.
41 | Apply(interface{}) error
42 | }
43 |
44 | // Invoker represents an interface for calling functions via reflection.
45 | type Invoker interface {
46 | // Invoke attempts to call the interface{} provided as a function,
47 | // providing dependencies for function arguments based on Type. Returns
48 | // a slice of reflect.Value representing the returned values of the function.
49 | // Returns an error if the injection fails.
50 | Invoke(interface{}) ([]reflect.Value, error)
51 | }
52 |
53 | // TypeMapper represents an interface for mapping interface{} values based on type.
54 | type TypeMapper interface {
55 | // Maps the interface{} value based on its immediate type from reflect.TypeOf.
56 | Map(interface{}) TypeMapper
57 | // Maps the interface{} value based on the pointer of an Interface provided.
58 | // This is really only useful for mapping a value as an interface, as interfaces
59 | // cannot at this time be referenced directly without a pointer.
60 | MapTo(interface{}, interface{}) TypeMapper
61 | // Provides a possibility to directly insert a mapping based on type and value.
62 | // This makes it possible to directly map type arguments not possible to instantiate
63 | // with reflect like unidirectional channels.
64 | Set(reflect.Type, reflect.Value) TypeMapper
65 | // Returns the Value that is mapped to the current type. Returns a zeroed Value if
66 | // the Type has not been mapped.
67 | GetVal(reflect.Type) reflect.Value
68 | }
69 |
70 | type injector struct {
71 | values map[reflect.Type]reflect.Value
72 | parent Injector
73 | }
74 |
75 | // InterfaceOf dereferences a pointer to an Interface type.
76 | // It panics if value is not an pointer to an interface.
77 | func InterfaceOf(value interface{}) reflect.Type {
78 | t := reflect.TypeOf(value)
79 |
80 | for t.Kind() == reflect.Ptr {
81 | t = t.Elem()
82 | }
83 |
84 | if t.Kind() != reflect.Interface {
85 | panic("Called inject.InterfaceOf with a value that is not a pointer to an interface. (*MyInterface)(nil)")
86 | }
87 |
88 | return t
89 | }
90 |
91 | // New returns a new Injector.
92 | func New() Injector {
93 | return &injector{
94 | values: make(map[reflect.Type]reflect.Value),
95 | }
96 | }
97 |
98 | // Invoke attempts to call the interface{} provided as a function,
99 | // providing dependencies for function arguments based on Type.
100 | // Returns a slice of reflect.Value representing the returned values of the function.
101 | // Returns an error if the injection fails.
102 | // It panics if f is not a function
103 | func (inj *injector) Invoke(f interface{}) ([]reflect.Value, error) {
104 | t := reflect.TypeOf(f)
105 |
106 | var in = make([]reflect.Value, t.NumIn()) //Panic if t is not kind of Func
107 | for i := 0; i < t.NumIn(); i++ {
108 | argType := t.In(i)
109 | val := inj.GetVal(argType)
110 | if !val.IsValid() {
111 | return nil, fmt.Errorf("Value not found for type %v", argType)
112 | }
113 |
114 | in[i] = val
115 | }
116 |
117 | return reflect.ValueOf(f).Call(in), nil
118 | }
119 |
120 | // Maps dependencies in the Type map to each field in the struct
121 | // that is tagged with 'inject'.
122 | // Returns an error if the injection fails.
123 | func (inj *injector) Apply(val interface{}) error {
124 | v := reflect.ValueOf(val)
125 |
126 | for v.Kind() == reflect.Ptr {
127 | v = v.Elem()
128 | }
129 |
130 | if v.Kind() != reflect.Struct {
131 | return nil // Should not panic here ?
132 | }
133 |
134 | t := v.Type()
135 |
136 | for i := 0; i < v.NumField(); i++ {
137 | f := v.Field(i)
138 | structField := t.Field(i)
139 | if f.CanSet() && (structField.Tag == "inject" || structField.Tag.Get("inject") != "") {
140 | ft := f.Type()
141 | v := inj.GetVal(ft)
142 | if !v.IsValid() {
143 | return fmt.Errorf("Value not found for type %v", ft)
144 | }
145 |
146 | f.Set(v)
147 | }
148 |
149 | }
150 |
151 | return nil
152 | }
153 |
154 | // Maps the concrete value of val to its dynamic type using reflect.TypeOf,
155 | // It returns the TypeMapper registered in.
156 | func (i *injector) Map(val interface{}) TypeMapper {
157 | i.values[reflect.TypeOf(val)] = reflect.ValueOf(val)
158 | return i
159 | }
160 |
161 | func (i *injector) MapTo(val interface{}, ifacePtr interface{}) TypeMapper {
162 | i.values[InterfaceOf(ifacePtr)] = reflect.ValueOf(val)
163 | return i
164 | }
165 |
166 | // Maps the given reflect.Type to the given reflect.Value and returns
167 | // the Typemapper the mapping has been registered in.
168 | func (i *injector) Set(typ reflect.Type, val reflect.Value) TypeMapper {
169 | i.values[typ] = val
170 | return i
171 | }
172 |
173 | func (i *injector) GetVal(t reflect.Type) reflect.Value {
174 | val := i.values[t]
175 |
176 | if val.IsValid() {
177 | return val
178 | }
179 |
180 | // no concrete types found, try to find implementors
181 | // if t is an interface
182 | if t.Kind() == reflect.Interface {
183 | for k, v := range i.values {
184 | if k.Implements(t) {
185 | val = v
186 | break
187 | }
188 | }
189 | }
190 |
191 | // Still no type found, try to look it up on the parent
192 | if !val.IsValid() && i.parent != nil {
193 | val = i.parent.GetVal(t)
194 | }
195 |
196 | return val
197 |
198 | }
199 |
200 | func (i *injector) SetParent(parent Injector) {
201 | i.parent = parent
202 | }
203 |
--------------------------------------------------------------------------------
/vendor/github.com/go-macaron/inject/inject.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Jeremy Saenz
2 | // Copyright 2015 The Macaron Authors
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
5 | // not use this file except in compliance with the License. You may obtain
6 | // a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | // License for the specific language governing permissions and limitations
14 | // under the License.
15 |
16 | // Package inject provides utilities for mapping and injecting dependencies in various ways.
17 | package inject
18 |
19 | import (
20 | "fmt"
21 | "reflect"
22 | )
23 |
24 | // Injector represents an interface for mapping and injecting dependencies into structs
25 | // and function arguments.
26 | type Injector interface {
27 | Applicator
28 | Invoker
29 | TypeMapper
30 | // SetParent sets the parent of the injector. If the injector cannot find a
31 | // dependency in its Type map it will check its parent before returning an
32 | // error.
33 | SetParent(Injector)
34 | }
35 |
36 | // Applicator represents an interface for mapping dependencies to a struct.
37 | type Applicator interface {
38 | // Maps dependencies in the Type map to each field in the struct
39 | // that is tagged with 'inject'. Returns an error if the injection
40 | // fails.
41 | Apply(interface{}) error
42 | }
43 |
44 | // Invoker represents an interface for calling functions via reflection.
45 | type Invoker interface {
46 | // Invoke attempts to call the interface{} provided as a function,
47 | // providing dependencies for function arguments based on Type. Returns
48 | // a slice of reflect.Value representing the returned values of the function.
49 | // Returns an error if the injection fails.
50 | Invoke(interface{}) ([]reflect.Value, error)
51 | }
52 |
53 | // TypeMapper represents an interface for mapping interface{} values based on type.
54 | type TypeMapper interface {
55 | // Maps the interface{} value based on its immediate type from reflect.TypeOf.
56 | Map(interface{}) TypeMapper
57 | // Maps the interface{} value based on the pointer of an Interface provided.
58 | // This is really only useful for mapping a value as an interface, as interfaces
59 | // cannot at this time be referenced directly without a pointer.
60 | MapTo(interface{}, interface{}) TypeMapper
61 | // Provides a possibility to directly insert a mapping based on type and value.
62 | // This makes it possible to directly map type arguments not possible to instantiate
63 | // with reflect like unidirectional channels.
64 | Set(reflect.Type, reflect.Value) TypeMapper
65 | // Returns the Value that is mapped to the current type. Returns a zeroed Value if
66 | // the Type has not been mapped.
67 | GetVal(reflect.Type) reflect.Value
68 | }
69 |
70 | type injector struct {
71 | values map[reflect.Type]reflect.Value
72 | parent Injector
73 | }
74 |
75 | // InterfaceOf dereferences a pointer to an Interface type.
76 | // It panics if value is not an pointer to an interface.
77 | func InterfaceOf(value interface{}) reflect.Type {
78 | t := reflect.TypeOf(value)
79 |
80 | for t.Kind() == reflect.Ptr {
81 | t = t.Elem()
82 | }
83 |
84 | if t.Kind() != reflect.Interface {
85 | panic("Called inject.InterfaceOf with a value that is not a pointer to an interface. (*MyInterface)(nil)")
86 | }
87 |
88 | return t
89 | }
90 |
91 | // New returns a new Injector.
92 | func New() Injector {
93 | return &injector{
94 | values: make(map[reflect.Type]reflect.Value),
95 | }
96 | }
97 |
98 | // Invoke attempts to call the interface{} provided as a function,
99 | // providing dependencies for function arguments based on Type.
100 | // Returns a slice of reflect.Value representing the returned values of the function.
101 | // Returns an error if the injection fails.
102 | // It panics if f is not a function
103 | func (inj *injector) Invoke(f interface{}) ([]reflect.Value, error) {
104 | t := reflect.TypeOf(f)
105 |
106 | var in = make([]reflect.Value, t.NumIn()) //Panic if t is not kind of Func
107 | for i := 0; i < t.NumIn(); i++ {
108 | argType := t.In(i)
109 | val := inj.GetVal(argType)
110 | if !val.IsValid() {
111 | return nil, fmt.Errorf("Value not found for type %v", argType)
112 | }
113 |
114 | in[i] = val
115 | }
116 |
117 | return reflect.ValueOf(f).Call(in), nil
118 | }
119 |
120 | // Maps dependencies in the Type map to each field in the struct
121 | // that is tagged with 'inject'.
122 | // Returns an error if the injection fails.
123 | func (inj *injector) Apply(val interface{}) error {
124 | v := reflect.ValueOf(val)
125 |
126 | for v.Kind() == reflect.Ptr {
127 | v = v.Elem()
128 | }
129 |
130 | if v.Kind() != reflect.Struct {
131 | return nil // Should not panic here ?
132 | }
133 |
134 | t := v.Type()
135 |
136 | for i := 0; i < v.NumField(); i++ {
137 | f := v.Field(i)
138 | structField := t.Field(i)
139 | if f.CanSet() && (structField.Tag == "inject" || structField.Tag.Get("inject") != "") {
140 | ft := f.Type()
141 | v := inj.GetVal(ft)
142 | if !v.IsValid() {
143 | return fmt.Errorf("Value not found for type %v", ft)
144 | }
145 |
146 | f.Set(v)
147 | }
148 |
149 | }
150 |
151 | return nil
152 | }
153 |
154 | // Maps the concrete value of val to its dynamic type using reflect.TypeOf,
155 | // It returns the TypeMapper registered in.
156 | func (i *injector) Map(val interface{}) TypeMapper {
157 | i.values[reflect.TypeOf(val)] = reflect.ValueOf(val)
158 | return i
159 | }
160 |
161 | func (i *injector) MapTo(val interface{}, ifacePtr interface{}) TypeMapper {
162 | i.values[InterfaceOf(ifacePtr)] = reflect.ValueOf(val)
163 | return i
164 | }
165 |
166 | // Maps the given reflect.Type to the given reflect.Value and returns
167 | // the Typemapper the mapping has been registered in.
168 | func (i *injector) Set(typ reflect.Type, val reflect.Value) TypeMapper {
169 | i.values[typ] = val
170 | return i
171 | }
172 |
173 | func (i *injector) GetVal(t reflect.Type) reflect.Value {
174 | val := i.values[t]
175 |
176 | if val.IsValid() {
177 | return val
178 | }
179 |
180 | // no concrete types found, try to find implementors
181 | // if t is an interface
182 | if t.Kind() == reflect.Interface {
183 | for k, v := range i.values {
184 | if k.Implements(t) {
185 | val = v
186 | break
187 | }
188 | }
189 | }
190 |
191 | // Still no type found, try to look it up on the parent
192 | if !val.IsValid() && i.parent != nil {
193 | val = i.parent.GetVal(t)
194 | }
195 |
196 | return val
197 |
198 | }
199 |
200 | func (i *injector) SetParent(parent Injector) {
201 | i.parent = parent
202 | }
203 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/macaron/macaron.go:
--------------------------------------------------------------------------------
1 | // +build go1.3
2 |
3 | // Copyright 2014 Unknwon
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
6 | // not use this file except in compliance with the License. You may obtain
7 | // a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | // License for the specific language governing permissions and limitations
15 | // under the License.
16 |
17 | // Package macaron is a high productive and modular web framework in Go.
18 | package macaron
19 |
20 | import (
21 | "io"
22 | "log"
23 | "net/http"
24 | "os"
25 | "reflect"
26 | "strings"
27 |
28 | "github.com/Unknwon/com"
29 | "gopkg.in/ini.v1"
30 |
31 | "github.com/Unknwon/macaron/inject"
32 | )
33 |
34 | const _VERSION = "0.6.8.1010"
35 |
36 | func Version() string {
37 | return _VERSION
38 | }
39 |
40 | // Handler can be any callable function.
41 | // Macaron attempts to inject services into the handler's argument list,
42 | // and panics if an argument could not be fullfilled via dependency injection.
43 | type Handler interface{}
44 |
45 | // validateHandler makes sure a handler is a callable function,
46 | // and panics if it is not.
47 | func validateHandler(h Handler) {
48 | if reflect.TypeOf(h).Kind() != reflect.Func {
49 | panic("Macaron handler must be a callable function")
50 | }
51 | }
52 |
53 | // validateHandlers makes sure handlers are callable functions,
54 | // and panics if any of them is not.
55 | func validateHandlers(handlers []Handler) {
56 | for _, h := range handlers {
57 | validateHandler(h)
58 | }
59 | }
60 |
61 | // Macaron represents the top level web application.
62 | // inject.Injector methods can be invoked to map services on a global level.
63 | type Macaron struct {
64 | inject.Injector
65 | befores []BeforeHandler
66 | handlers []Handler
67 | action Handler
68 |
69 | hasURLPrefix bool
70 | urlPrefix string // For suburl support.
71 | *Router
72 |
73 | logger *log.Logger
74 | }
75 |
76 | // NewWithLogger creates a bare bones Macaron instance.
77 | // Use this method if you want to have full control over the middleware that is used.
78 | // You can specify logger output writer with this function.
79 | func NewWithLogger(out io.Writer) *Macaron {
80 | m := &Macaron{
81 | Injector: inject.New(),
82 | action: func() {},
83 | Router: NewRouter(),
84 | logger: log.New(out, "[Macaron] ", 0),
85 | }
86 | m.Router.m = m
87 | m.Map(m.logger)
88 | m.Map(defaultReturnHandler())
89 | m.NotFound(http.NotFound)
90 | m.InternalServerError(func(rw http.ResponseWriter, err error) {
91 | http.Error(rw, err.Error(), 500)
92 | })
93 | return m
94 | }
95 |
96 | // New creates a bare bones Macaron instance.
97 | // Use this method if you want to have full control over the middleware that is used.
98 | func New() *Macaron {
99 | return NewWithLogger(os.Stdout)
100 | }
101 |
102 | // Classic creates a classic Macaron with some basic default middleware:
103 | // mocaron.Logger, mocaron.Recovery and mocaron.Static.
104 | func Classic() *Macaron {
105 | m := New()
106 | m.Use(Logger())
107 | m.Use(Recovery())
108 | m.Use(Static("public"))
109 | return m
110 | }
111 |
112 | // Handlers sets the entire middleware stack with the given Handlers.
113 | // This will clear any current middleware handlers,
114 | // and panics if any of the handlers is not a callable function
115 | func (m *Macaron) Handlers(handlers ...Handler) {
116 | m.handlers = make([]Handler, 0)
117 | for _, handler := range handlers {
118 | m.Use(handler)
119 | }
120 | }
121 |
122 | // Action sets the handler that will be called after all the middleware has been invoked.
123 | // This is set to macaron.Router in a macaron.Classic().
124 | func (m *Macaron) Action(handler Handler) {
125 | validateHandler(handler)
126 | m.action = handler
127 | }
128 |
129 | // BeforeHandler represents a handler executes at beginning of every request.
130 | // Macaron stops future process when it returns true.
131 | type BeforeHandler func(rw http.ResponseWriter, req *http.Request) bool
132 |
133 | func (m *Macaron) Before(handler BeforeHandler) {
134 | m.befores = append(m.befores, handler)
135 | }
136 |
137 | // Use adds a middleware Handler to the stack,
138 | // and panics if the handler is not a callable func.
139 | // Middleware Handlers are invoked in the order that they are added.
140 | func (m *Macaron) Use(handler Handler) {
141 | validateHandler(handler)
142 | m.handlers = append(m.handlers, handler)
143 | }
144 |
145 | func (m *Macaron) createContext(rw http.ResponseWriter, req *http.Request) *Context {
146 | c := &Context{
147 | Injector: inject.New(),
148 | handlers: m.handlers,
149 | action: m.action,
150 | index: 0,
151 | Router: m.Router,
152 | Req: Request{req},
153 | Resp: NewResponseWriter(rw),
154 | Data: make(map[string]interface{}),
155 | }
156 | c.SetParent(m)
157 | c.Map(c)
158 | c.MapTo(c.Resp, (*http.ResponseWriter)(nil))
159 | c.Map(req)
160 | return c
161 | }
162 |
163 | // ServeHTTP is the HTTP Entry point for a Macaron instance.
164 | // Useful if you want to control your own HTTP server.
165 | // Be aware that none of middleware will run without registering any router.
166 | func (m *Macaron) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
167 | if m.hasURLPrefix {
168 | req.URL.Path = strings.TrimPrefix(req.URL.Path, m.urlPrefix)
169 | }
170 | for _, h := range m.befores {
171 | if h(rw, req) {
172 | return
173 | }
174 | }
175 | m.Router.ServeHTTP(rw, req)
176 | }
177 |
178 | func GetDefaultListenInfo() (string, int) {
179 | host := os.Getenv("HOST")
180 | if len(host) == 0 {
181 | host = "0.0.0.0"
182 | }
183 | port := com.StrTo(os.Getenv("PORT")).MustInt()
184 | if port == 0 {
185 | port = 4000
186 | }
187 | return host, port
188 | }
189 |
190 | // Run the http server. Listening on os.GetEnv("PORT") or 4000 by default.
191 | func (m *Macaron) Run(args ...interface{}) {
192 | host, port := GetDefaultListenInfo()
193 | if len(args) == 1 {
194 | switch arg := args[0].(type) {
195 | case string:
196 | host = arg
197 | case int:
198 | port = arg
199 | }
200 | } else if len(args) >= 2 {
201 | if arg, ok := args[0].(string); ok {
202 | host = arg
203 | }
204 | if arg, ok := args[1].(int); ok {
205 | port = arg
206 | }
207 | }
208 |
209 | addr := host + ":" + com.ToStr(port)
210 | logger := m.Injector.GetVal(reflect.TypeOf(m.logger)).Interface().(*log.Logger)
211 | logger.Printf("listening on %s (%s)\n", addr, Env)
212 | logger.Fatalln(http.ListenAndServe(addr, m))
213 | }
214 |
215 | // SetURLPrefix sets URL prefix of router layer, so that it support suburl.
216 | func (m *Macaron) SetURLPrefix(prefix string) {
217 | m.urlPrefix = prefix
218 | m.hasURLPrefix = len(m.urlPrefix) > 0
219 | }
220 |
221 | // ____ ____ .__ ___. .__
222 | // \ \ / /____ _______|__|____ \_ |__ | | ____ ______
223 | // \ Y /\__ \\_ __ \ \__ \ | __ \| | _/ __ \ / ___/
224 | // \ / / __ \| | \/ |/ __ \| \_\ \ |_\ ___/ \___ \
225 | // \___/ (____ /__| |__(____ /___ /____/\___ >____ >
226 | // \/ \/ \/ \/ \/
227 |
228 | const (
229 | DEV = "development"
230 | PROD = "production"
231 | TEST = "test"
232 | )
233 |
234 | var (
235 | // Env is the environment that Macaron is executing in.
236 | // The MACARON_ENV is read on initialization to set this variable.
237 | Env = DEV
238 |
239 | // Path of work directory.
240 | Root string
241 |
242 | // Flash applies to current request.
243 | FlashNow bool
244 |
245 | // Configuration convention object.
246 | cfg *ini.File
247 | )
248 |
249 | func setENV(e string) {
250 | if len(e) > 0 {
251 | Env = e
252 | }
253 | }
254 |
255 | func init() {
256 | setENV(os.Getenv("MACARON_ENV"))
257 |
258 | var err error
259 | Root, err = os.Getwd()
260 | if err != nil {
261 | panic("error getting work directory: " + err.Error())
262 | }
263 | }
264 |
265 | // SetConfig sets data sources for configuration.
266 | func SetConfig(source interface{}, others ...interface{}) (_ *ini.File, err error) {
267 | cfg, err = ini.Load(source, others...)
268 | return Config(), err
269 | }
270 |
271 | // Config returns configuration convention object.
272 | // It returns an empty object if there is no one available.
273 | func Config() *ini.File {
274 | if cfg == nil {
275 | return ini.Empty()
276 | }
277 | return cfg
278 | }
279 |
--------------------------------------------------------------------------------
/vendor/github.com/go-macaron/macaron/macaron.go:
--------------------------------------------------------------------------------
1 | // +build go1.3
2 |
3 | // Copyright 2014 The Macaron Authors
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
6 | // not use this file except in compliance with the License. You may obtain
7 | // a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | // License for the specific language governing permissions and limitations
15 | // under the License.
16 |
17 | // Package macaron is a high productive and modular web framework in Go.
18 | package macaron
19 |
20 | import (
21 | "io"
22 | "log"
23 | "net/http"
24 | "os"
25 | "reflect"
26 | "strings"
27 |
28 | "github.com/Unknwon/com"
29 | "gopkg.in/ini.v1"
30 |
31 | "github.com/go-macaron/inject"
32 | )
33 |
34 | const _VERSION = "0.8.0.1013"
35 |
36 | func Version() string {
37 | return _VERSION
38 | }
39 |
40 | // Handler can be any callable function.
41 | // Macaron attempts to inject services into the handler's argument list,
42 | // and panics if an argument could not be fullfilled via dependency injection.
43 | type Handler interface{}
44 |
45 | // validateHandler makes sure a handler is a callable function,
46 | // and panics if it is not.
47 | func validateHandler(h Handler) {
48 | if reflect.TypeOf(h).Kind() != reflect.Func {
49 | panic("Macaron handler must be a callable function")
50 | }
51 | }
52 |
53 | // validateHandlers makes sure handlers are callable functions,
54 | // and panics if any of them is not.
55 | func validateHandlers(handlers []Handler) {
56 | for _, h := range handlers {
57 | validateHandler(h)
58 | }
59 | }
60 |
61 | // Macaron represents the top level web application.
62 | // inject.Injector methods can be invoked to map services on a global level.
63 | type Macaron struct {
64 | inject.Injector
65 | befores []BeforeHandler
66 | handlers []Handler
67 | action Handler
68 |
69 | hasURLPrefix bool
70 | urlPrefix string // For suburl support.
71 | *Router
72 |
73 | logger *log.Logger
74 | }
75 |
76 | // NewWithLogger creates a bare bones Macaron instance.
77 | // Use this method if you want to have full control over the middleware that is used.
78 | // You can specify logger output writer with this function.
79 | func NewWithLogger(out io.Writer) *Macaron {
80 | m := &Macaron{
81 | Injector: inject.New(),
82 | action: func() {},
83 | Router: NewRouter(),
84 | logger: log.New(out, "[Macaron] ", 0),
85 | }
86 | m.Router.m = m
87 | m.Map(m.logger)
88 | m.Map(defaultReturnHandler())
89 | m.NotFound(http.NotFound)
90 | m.InternalServerError(func(rw http.ResponseWriter, err error) {
91 | http.Error(rw, err.Error(), 500)
92 | })
93 | return m
94 | }
95 |
96 | // New creates a bare bones Macaron instance.
97 | // Use this method if you want to have full control over the middleware that is used.
98 | func New() *Macaron {
99 | return NewWithLogger(os.Stdout)
100 | }
101 |
102 | // Classic creates a classic Macaron with some basic default middleware:
103 | // mocaron.Logger, mocaron.Recovery and mocaron.Static.
104 | func Classic() *Macaron {
105 | m := New()
106 | m.Use(Logger())
107 | m.Use(Recovery())
108 | m.Use(Static("public"))
109 | return m
110 | }
111 |
112 | // Handlers sets the entire middleware stack with the given Handlers.
113 | // This will clear any current middleware handlers,
114 | // and panics if any of the handlers is not a callable function
115 | func (m *Macaron) Handlers(handlers ...Handler) {
116 | m.handlers = make([]Handler, 0)
117 | for _, handler := range handlers {
118 | m.Use(handler)
119 | }
120 | }
121 |
122 | // Action sets the handler that will be called after all the middleware has been invoked.
123 | // This is set to macaron.Router in a macaron.Classic().
124 | func (m *Macaron) Action(handler Handler) {
125 | validateHandler(handler)
126 | m.action = handler
127 | }
128 |
129 | // BeforeHandler represents a handler executes at beginning of every request.
130 | // Macaron stops future process when it returns true.
131 | type BeforeHandler func(rw http.ResponseWriter, req *http.Request) bool
132 |
133 | func (m *Macaron) Before(handler BeforeHandler) {
134 | m.befores = append(m.befores, handler)
135 | }
136 |
137 | // Use adds a middleware Handler to the stack,
138 | // and panics if the handler is not a callable func.
139 | // Middleware Handlers are invoked in the order that they are added.
140 | func (m *Macaron) Use(handler Handler) {
141 | validateHandler(handler)
142 | m.handlers = append(m.handlers, handler)
143 | }
144 |
145 | func (m *Macaron) createContext(rw http.ResponseWriter, req *http.Request) *Context {
146 | c := &Context{
147 | Injector: inject.New(),
148 | handlers: m.handlers,
149 | action: m.action,
150 | index: 0,
151 | Router: m.Router,
152 | Req: Request{req},
153 | Resp: NewResponseWriter(rw),
154 | Data: make(map[string]interface{}),
155 | }
156 | c.SetParent(m)
157 | c.Map(c)
158 | c.MapTo(c.Resp, (*http.ResponseWriter)(nil))
159 | c.Map(req)
160 | return c
161 | }
162 |
163 | // ServeHTTP is the HTTP Entry point for a Macaron instance.
164 | // Useful if you want to control your own HTTP server.
165 | // Be aware that none of middleware will run without registering any router.
166 | func (m *Macaron) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
167 | if m.hasURLPrefix {
168 | req.URL.Path = strings.TrimPrefix(req.URL.Path, m.urlPrefix)
169 | }
170 | for _, h := range m.befores {
171 | if h(rw, req) {
172 | return
173 | }
174 | }
175 | m.Router.ServeHTTP(rw, req)
176 | }
177 |
178 | func GetDefaultListenInfo() (string, int) {
179 | host := os.Getenv("HOST")
180 | if len(host) == 0 {
181 | host = "0.0.0.0"
182 | }
183 | port := com.StrTo(os.Getenv("PORT")).MustInt()
184 | if port == 0 {
185 | port = 4000
186 | }
187 | return host, port
188 | }
189 |
190 | // Run the http server. Listening on os.GetEnv("PORT") or 4000 by default.
191 | func (m *Macaron) Run(args ...interface{}) {
192 | host, port := GetDefaultListenInfo()
193 | if len(args) == 1 {
194 | switch arg := args[0].(type) {
195 | case string:
196 | host = arg
197 | case int:
198 | port = arg
199 | }
200 | } else if len(args) >= 2 {
201 | if arg, ok := args[0].(string); ok {
202 | host = arg
203 | }
204 | if arg, ok := args[1].(int); ok {
205 | port = arg
206 | }
207 | }
208 |
209 | addr := host + ":" + com.ToStr(port)
210 | logger := m.GetVal(reflect.TypeOf(m.logger)).Interface().(*log.Logger)
211 | logger.Printf("listening on %s (%s)\n", addr, Env)
212 | logger.Fatalln(http.ListenAndServe(addr, m))
213 | }
214 |
215 | // SetURLPrefix sets URL prefix of router layer, so that it support suburl.
216 | func (m *Macaron) SetURLPrefix(prefix string) {
217 | m.urlPrefix = prefix
218 | m.hasURLPrefix = len(m.urlPrefix) > 0
219 | }
220 |
221 | // ____ ____ .__ ___. .__
222 | // \ \ / /____ _______|__|____ \_ |__ | | ____ ______
223 | // \ Y /\__ \\_ __ \ \__ \ | __ \| | _/ __ \ / ___/
224 | // \ / / __ \| | \/ |/ __ \| \_\ \ |_\ ___/ \___ \
225 | // \___/ (____ /__| |__(____ /___ /____/\___ >____ >
226 | // \/ \/ \/ \/ \/
227 |
228 | const (
229 | DEV = "development"
230 | PROD = "production"
231 | TEST = "test"
232 | )
233 |
234 | var (
235 | // Env is the environment that Macaron is executing in.
236 | // The MACARON_ENV is read on initialization to set this variable.
237 | Env = DEV
238 |
239 | // Path of work directory.
240 | Root string
241 |
242 | // Flash applies to current request.
243 | FlashNow bool
244 |
245 | // Configuration convention object.
246 | cfg *ini.File
247 | )
248 |
249 | func setENV(e string) {
250 | if len(e) > 0 {
251 | Env = e
252 | }
253 | }
254 |
255 | func init() {
256 | setENV(os.Getenv("MACARON_ENV"))
257 |
258 | var err error
259 | Root, err = os.Getwd()
260 | if err != nil {
261 | panic("error getting work directory: " + err.Error())
262 | }
263 | }
264 |
265 | // SetConfig sets data sources for configuration.
266 | func SetConfig(source interface{}, others ...interface{}) (_ *ini.File, err error) {
267 | cfg, err = ini.Load(source, others...)
268 | return Config(), err
269 | }
270 |
271 | // Config returns configuration convention object.
272 | // It returns an empty object if there is no one available.
273 | func Config() *ini.File {
274 | if cfg == nil {
275 | return ini.Empty()
276 | }
277 | return cfg
278 | }
279 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/ini.v1/struct.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Unknwon
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package ini
16 |
17 | import (
18 | "bytes"
19 | "errors"
20 | "fmt"
21 | "reflect"
22 | "time"
23 | "unicode"
24 | )
25 |
26 | // NameMapper represents a ini tag name mapper.
27 | type NameMapper func(string) string
28 |
29 | // Built-in name getters.
30 | var (
31 | // AllCapsUnderscore converts to format ALL_CAPS_UNDERSCORE.
32 | AllCapsUnderscore NameMapper = func(raw string) string {
33 | newstr := make([]rune, 0, len(raw))
34 | for i, chr := range raw {
35 | if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
36 | if i > 0 {
37 | newstr = append(newstr, '_')
38 | }
39 | }
40 | newstr = append(newstr, unicode.ToUpper(chr))
41 | }
42 | return string(newstr)
43 | }
44 | // TitleUnderscore converts to format title_underscore.
45 | TitleUnderscore NameMapper = func(raw string) string {
46 | newstr := make([]rune, 0, len(raw))
47 | for i, chr := range raw {
48 | if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
49 | if i > 0 {
50 | newstr = append(newstr, '_')
51 | }
52 | chr -= ('A' - 'a')
53 | }
54 | newstr = append(newstr, chr)
55 | }
56 | return string(newstr)
57 | }
58 | )
59 |
60 | func (s *Section) parseFieldName(raw, actual string) string {
61 | if len(actual) > 0 {
62 | return actual
63 | }
64 | if s.f.NameMapper != nil {
65 | return s.f.NameMapper(raw)
66 | }
67 | return raw
68 | }
69 |
70 | func parseDelim(actual string) string {
71 | if len(actual) > 0 {
72 | return actual
73 | }
74 | return ","
75 | }
76 |
77 | var reflectTime = reflect.TypeOf(time.Now()).Kind()
78 |
79 | // setWithProperType sets proper value to field based on its type,
80 | // but it does not return error for failing parsing,
81 | // because we want to use default value that is already assigned to strcut.
82 | func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error {
83 | switch t.Kind() {
84 | case reflect.String:
85 | if len(key.String()) == 0 {
86 | return nil
87 | }
88 | field.SetString(key.String())
89 | case reflect.Bool:
90 | boolVal, err := key.Bool()
91 | if err != nil {
92 | return nil
93 | }
94 | field.SetBool(boolVal)
95 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
96 | durationVal, err := key.Duration()
97 | if err == nil {
98 | field.Set(reflect.ValueOf(durationVal))
99 | return nil
100 | }
101 |
102 | intVal, err := key.Int64()
103 | if err != nil {
104 | return nil
105 | }
106 | field.SetInt(intVal)
107 | case reflect.Float64:
108 | floatVal, err := key.Float64()
109 | if err != nil {
110 | return nil
111 | }
112 | field.SetFloat(floatVal)
113 | case reflectTime:
114 | timeVal, err := key.Time()
115 | if err != nil {
116 | return nil
117 | }
118 | field.Set(reflect.ValueOf(timeVal))
119 | case reflect.Slice:
120 | vals := key.Strings(delim)
121 | numVals := len(vals)
122 | if numVals == 0 {
123 | return nil
124 | }
125 |
126 | sliceOf := field.Type().Elem().Kind()
127 |
128 | var times []time.Time
129 | if sliceOf == reflectTime {
130 | times = key.Times(delim)
131 | }
132 |
133 | slice := reflect.MakeSlice(field.Type(), numVals, numVals)
134 | for i := 0; i < numVals; i++ {
135 | switch sliceOf {
136 | case reflectTime:
137 | slice.Index(i).Set(reflect.ValueOf(times[i]))
138 | default:
139 | slice.Index(i).Set(reflect.ValueOf(vals[i]))
140 | }
141 | }
142 | field.Set(slice)
143 | default:
144 | return fmt.Errorf("unsupported type '%s'", t)
145 | }
146 | return nil
147 | }
148 |
149 | func (s *Section) mapTo(val reflect.Value) error {
150 | if val.Kind() == reflect.Ptr {
151 | val = val.Elem()
152 | }
153 | typ := val.Type()
154 |
155 | for i := 0; i < typ.NumField(); i++ {
156 | field := val.Field(i)
157 | tpField := typ.Field(i)
158 |
159 | tag := tpField.Tag.Get("ini")
160 | if tag == "-" {
161 | continue
162 | }
163 |
164 | fieldName := s.parseFieldName(tpField.Name, tag)
165 | if len(fieldName) == 0 || !field.CanSet() {
166 | continue
167 | }
168 |
169 | isAnonymous := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous
170 | isStruct := tpField.Type.Kind() == reflect.Struct
171 | if isAnonymous {
172 | field.Set(reflect.New(tpField.Type.Elem()))
173 | }
174 |
175 | if isAnonymous || isStruct {
176 | if sec, err := s.f.GetSection(fieldName); err == nil {
177 | if err = sec.mapTo(field); err != nil {
178 | return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
179 | }
180 | continue
181 | }
182 | }
183 |
184 | if key, err := s.GetKey(fieldName); err == nil {
185 | if err = setWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil {
186 | return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
187 | }
188 | }
189 | }
190 | return nil
191 | }
192 |
193 | // MapTo maps section to given struct.
194 | func (s *Section) MapTo(v interface{}) error {
195 | typ := reflect.TypeOf(v)
196 | val := reflect.ValueOf(v)
197 | if typ.Kind() == reflect.Ptr {
198 | typ = typ.Elem()
199 | val = val.Elem()
200 | } else {
201 | return errors.New("cannot map to non-pointer struct")
202 | }
203 |
204 | return s.mapTo(val)
205 | }
206 |
207 | // MapTo maps file to given struct.
208 | func (f *File) MapTo(v interface{}) error {
209 | return f.Section("").MapTo(v)
210 | }
211 |
212 | // MapTo maps data sources to given struct with name mapper.
213 | func MapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error {
214 | cfg, err := Load(source, others...)
215 | if err != nil {
216 | return err
217 | }
218 | cfg.NameMapper = mapper
219 | return cfg.MapTo(v)
220 | }
221 |
222 | // MapTo maps data sources to given struct.
223 | func MapTo(v, source interface{}, others ...interface{}) error {
224 | return MapToWithMapper(v, nil, source, others...)
225 | }
226 |
227 | // reflectWithProperType does the opposite thing with setWithProperType.
228 | func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error {
229 | switch t.Kind() {
230 | case reflect.String:
231 | key.SetValue(field.String())
232 | case reflect.Bool,
233 | reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
234 | reflect.Float64,
235 | reflectTime:
236 | key.SetValue(fmt.Sprint(field))
237 | case reflect.Slice:
238 | vals := field.Slice(0, field.Len())
239 | if field.Len() == 0 {
240 | return nil
241 | }
242 |
243 | var buf bytes.Buffer
244 | isTime := fmt.Sprint(field.Type()) == "[]time.Time"
245 | for i := 0; i < field.Len(); i++ {
246 | if isTime {
247 | buf.WriteString(vals.Index(i).Interface().(time.Time).Format(time.RFC3339))
248 | } else {
249 | buf.WriteString(fmt.Sprint(vals.Index(i)))
250 | }
251 | buf.WriteString(delim)
252 | }
253 | key.SetValue(buf.String()[:buf.Len()-1])
254 | default:
255 | return fmt.Errorf("unsupported type '%s'", t)
256 | }
257 | return nil
258 | }
259 |
260 | func (s *Section) reflectFrom(val reflect.Value) error {
261 | if val.Kind() == reflect.Ptr {
262 | val = val.Elem()
263 | }
264 | typ := val.Type()
265 |
266 | for i := 0; i < typ.NumField(); i++ {
267 | field := val.Field(i)
268 | tpField := typ.Field(i)
269 |
270 | tag := tpField.Tag.Get("ini")
271 | if tag == "-" {
272 | continue
273 | }
274 |
275 | fieldName := s.parseFieldName(tpField.Name, tag)
276 | if len(fieldName) == 0 || !field.CanSet() {
277 | continue
278 | }
279 |
280 | if (tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous) ||
281 | (tpField.Type.Kind() == reflect.Struct) {
282 | // Note: The only error here is section doesn't exist.
283 | sec, err := s.f.GetSection(fieldName)
284 | if err != nil {
285 | // Note: fieldName can never be empty here, ignore error.
286 | sec, _ = s.f.NewSection(fieldName)
287 | }
288 | if err = sec.reflectFrom(field); err != nil {
289 | return fmt.Errorf("error reflecting field(%s): %v", fieldName, err)
290 | }
291 | continue
292 | }
293 |
294 | // Note: Same reason as secion.
295 | key, err := s.GetKey(fieldName)
296 | if err != nil {
297 | key, _ = s.NewKey(fieldName, "")
298 | }
299 | if err = reflectWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil {
300 | return fmt.Errorf("error reflecting field(%s): %v", fieldName, err)
301 | }
302 |
303 | }
304 | return nil
305 | }
306 |
307 | // ReflectFrom reflects secion from given struct.
308 | func (s *Section) ReflectFrom(v interface{}) error {
309 | typ := reflect.TypeOf(v)
310 | val := reflect.ValueOf(v)
311 | if typ.Kind() == reflect.Ptr {
312 | typ = typ.Elem()
313 | val = val.Elem()
314 | } else {
315 | return errors.New("cannot reflect from non-pointer struct")
316 | }
317 |
318 | return s.reflectFrom(val)
319 | }
320 |
321 | // ReflectFrom reflects file from given struct.
322 | func (f *File) ReflectFrom(v interface{}) error {
323 | return f.Section("").ReflectFrom(v)
324 | }
325 |
326 | // ReflectFrom reflects data sources from given struct with name mapper.
327 | func ReflectFromWithMapper(cfg *File, v interface{}, mapper NameMapper) error {
328 | cfg.NameMapper = mapper
329 | return cfg.ReflectFrom(v)
330 | }
331 |
332 | // ReflectFrom reflects data sources from given struct.
333 | func ReflectFrom(cfg *File, v interface{}) error {
334 | return ReflectFromWithMapper(cfg, v, nil)
335 | }
336 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/com/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction, and
10 | distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
13 | owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all other entities
16 | that control, are controlled by, or are under common control with that entity.
17 | For the purposes of this definition, "control" means (i) the power, direct or
18 | indirect, to cause the direction or management of such entity, whether by
19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 | outstanding shares, or (iii) beneficial ownership of such entity.
21 |
22 | "You" (or "Your") shall mean an individual or Legal Entity exercising
23 | permissions granted by this License.
24 |
25 | "Source" form shall mean the preferred form for making modifications, including
26 | but not limited to software source code, documentation source, and configuration
27 | files.
28 |
29 | "Object" form shall mean any form resulting from mechanical transformation or
30 | translation of a Source form, including but not limited to compiled object code,
31 | generated documentation, and conversions to other media types.
32 |
33 | "Work" shall mean the work of authorship, whether in Source or Object form, made
34 | available under the License, as indicated by a copyright notice that is included
35 | in or attached to the work (an example is provided in the Appendix below).
36 |
37 | "Derivative Works" shall mean any work, whether in Source or Object form, that
38 | is based on (or derived from) the Work and for which the editorial revisions,
39 | annotations, elaborations, or other modifications represent, as a whole, an
40 | original work of authorship. For the purposes of this License, Derivative Works
41 | shall not include works that remain separable from, or merely link (or bind by
42 | name) to the interfaces of, the Work and Derivative Works thereof.
43 |
44 | "Contribution" shall mean any work of authorship, including the original version
45 | of the Work and any modifications or additions to that Work or Derivative Works
46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work
47 | by the copyright owner or by an individual or Legal Entity authorized to submit
48 | on behalf of the copyright owner. For the purposes of this definition,
49 | "submitted" means any form of electronic, verbal, or written communication sent
50 | to the Licensor or its representatives, including but not limited to
51 | communication on electronic mailing lists, source code control systems, and
52 | issue tracking systems that are managed by, or on behalf of, the Licensor for
53 | the purpose of discussing and improving the Work, but excluding communication
54 | that is conspicuously marked or otherwise designated in writing by the copyright
55 | owner as "Not a Contribution."
56 |
57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58 | of whom a Contribution has been received by Licensor and subsequently
59 | incorporated within the Work.
60 |
61 | 2. Grant of Copyright License.
62 |
63 | Subject to the terms and conditions of this License, each Contributor hereby
64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65 | irrevocable copyright license to reproduce, prepare Derivative Works of,
66 | publicly display, publicly perform, sublicense, and distribute the Work and such
67 | Derivative Works in Source or Object form.
68 |
69 | 3. Grant of Patent License.
70 |
71 | Subject to the terms and conditions of this License, each Contributor hereby
72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73 | irrevocable (except as stated in this section) patent license to make, have
74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75 | such license applies only to those patent claims licensable by such Contributor
76 | that are necessarily infringed by their Contribution(s) alone or by combination
77 | of their Contribution(s) with the Work to which such Contribution(s) was
78 | submitted. If You institute patent litigation against any entity (including a
79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80 | Contribution incorporated within the Work constitutes direct or contributory
81 | patent infringement, then any patent licenses granted to You under this License
82 | for that Work shall terminate as of the date such litigation is filed.
83 |
84 | 4. Redistribution.
85 |
86 | You may reproduce and distribute copies of the Work or Derivative Works thereof
87 | in any medium, with or without modifications, and in Source or Object form,
88 | provided that You meet the following conditions:
89 |
90 | You must give any other recipients of the Work or Derivative Works a copy of
91 | this License; and
92 | You must cause any modified files to carry prominent notices stating that You
93 | changed the files; and
94 | You must retain, in the Source form of any Derivative Works that You distribute,
95 | all copyright, patent, trademark, and attribution notices from the Source form
96 | of the Work, excluding those notices that do not pertain to any part of the
97 | Derivative Works; and
98 | If the Work includes a "NOTICE" text file as part of its distribution, then any
99 | Derivative Works that You distribute must include a readable copy of the
100 | attribution notices contained within such NOTICE file, excluding those notices
101 | that do not pertain to any part of the Derivative Works, in at least one of the
102 | following places: within a NOTICE text file distributed as part of the
103 | Derivative Works; within the Source form or documentation, if provided along
104 | with the Derivative Works; or, within a display generated by the Derivative
105 | Works, if and wherever such third-party notices normally appear. The contents of
106 | the NOTICE file are for informational purposes only and do not modify the
107 | License. You may add Your own attribution notices within Derivative Works that
108 | You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 | provided that such additional attribution notices cannot be construed as
110 | modifying the License.
111 | You may add Your own copyright statement to Your modifications and may provide
112 | additional or different license terms and conditions for use, reproduction, or
113 | distribution of Your modifications, or for any such Derivative Works as a whole,
114 | provided Your use, reproduction, and distribution of the Work otherwise complies
115 | with the conditions stated in this License.
116 |
117 | 5. Submission of Contributions.
118 |
119 | Unless You explicitly state otherwise, any Contribution intentionally submitted
120 | for inclusion in the Work by You to the Licensor shall be under the terms and
121 | conditions of this License, without any additional terms or conditions.
122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 | any separate license agreement you may have executed with Licensor regarding
124 | such Contributions.
125 |
126 | 6. Trademarks.
127 |
128 | This License does not grant permission to use the trade names, trademarks,
129 | service marks, or product names of the Licensor, except as required for
130 | reasonable and customary use in describing the origin of the Work and
131 | reproducing the content of the NOTICE file.
132 |
133 | 7. Disclaimer of Warranty.
134 |
135 | Unless required by applicable law or agreed to in writing, Licensor provides the
136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 | including, without limitation, any warranties or conditions of TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 | solely responsible for determining the appropriateness of using or
141 | redistributing the Work and assume any risks associated with Your exercise of
142 | permissions under this License.
143 |
144 | 8. Limitation of Liability.
145 |
146 | In no event and under no legal theory, whether in tort (including negligence),
147 | contract, or otherwise, unless required by applicable law (such as deliberate
148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 | liable to You for damages, including any direct, indirect, special, incidental,
150 | or consequential damages of any character arising as a result of this License or
151 | out of the use or inability to use the Work (including but not limited to
152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 | any and all other commercial damages or losses), even if such Contributor has
154 | been advised of the possibility of such damages.
155 |
156 | 9. Accepting Warranty or Additional Liability.
157 |
158 | While redistributing the Work or Derivative Works thereof, You may choose to
159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 | other liability obligations and/or rights consistent with this License. However,
161 | in accepting such obligations, You may act only on Your own behalf and on Your
162 | sole responsibility, not on behalf of any other Contributor, and only if You
163 | agree to indemnify, defend, and hold each Contributor harmless for any liability
164 | incurred by, or claims asserted against, such Contributor by reason of your
165 | accepting any such warranty or additional liability.
166 |
167 | END OF TERMS AND CONDITIONS
168 |
169 | APPENDIX: How to apply the Apache License to your work
170 |
171 | To apply the Apache License to your work, attach the following boilerplate
172 | notice, with the fields enclosed by brackets "[]" replaced with your own
173 | identifying information. (Don't include the brackets!) The text should be
174 | enclosed in the appropriate comment syntax for the file format. We also
175 | recommend that a file or class name and description of purpose be included on
176 | the same "printed page" as the copyright notice for easier identification within
177 | third-party archives.
178 |
179 | Copyright [yyyy] [name of copyright owner]
180 |
181 | Licensed under the Apache License, Version 2.0 (the "License");
182 | you may not use this file except in compliance with the License.
183 | You may obtain a copy of the License at
184 |
185 | http://www.apache.org/licenses/LICENSE-2.0
186 |
187 | Unless required by applicable law or agreed to in writing, software
188 | distributed under the License is distributed on an "AS IS" BASIS,
189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 | See the License for the specific language governing permissions and
191 | limitations under the License.
--------------------------------------------------------------------------------
/vendor/gopkg.in/ini.v1/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction, and
10 | distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
13 | owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all other entities
16 | that control, are controlled by, or are under common control with that entity.
17 | For the purposes of this definition, "control" means (i) the power, direct or
18 | indirect, to cause the direction or management of such entity, whether by
19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 | outstanding shares, or (iii) beneficial ownership of such entity.
21 |
22 | "You" (or "Your") shall mean an individual or Legal Entity exercising
23 | permissions granted by this License.
24 |
25 | "Source" form shall mean the preferred form for making modifications, including
26 | but not limited to software source code, documentation source, and configuration
27 | files.
28 |
29 | "Object" form shall mean any form resulting from mechanical transformation or
30 | translation of a Source form, including but not limited to compiled object code,
31 | generated documentation, and conversions to other media types.
32 |
33 | "Work" shall mean the work of authorship, whether in Source or Object form, made
34 | available under the License, as indicated by a copyright notice that is included
35 | in or attached to the work (an example is provided in the Appendix below).
36 |
37 | "Derivative Works" shall mean any work, whether in Source or Object form, that
38 | is based on (or derived from) the Work and for which the editorial revisions,
39 | annotations, elaborations, or other modifications represent, as a whole, an
40 | original work of authorship. For the purposes of this License, Derivative Works
41 | shall not include works that remain separable from, or merely link (or bind by
42 | name) to the interfaces of, the Work and Derivative Works thereof.
43 |
44 | "Contribution" shall mean any work of authorship, including the original version
45 | of the Work and any modifications or additions to that Work or Derivative Works
46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work
47 | by the copyright owner or by an individual or Legal Entity authorized to submit
48 | on behalf of the copyright owner. For the purposes of this definition,
49 | "submitted" means any form of electronic, verbal, or written communication sent
50 | to the Licensor or its representatives, including but not limited to
51 | communication on electronic mailing lists, source code control systems, and
52 | issue tracking systems that are managed by, or on behalf of, the Licensor for
53 | the purpose of discussing and improving the Work, but excluding communication
54 | that is conspicuously marked or otherwise designated in writing by the copyright
55 | owner as "Not a Contribution."
56 |
57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58 | of whom a Contribution has been received by Licensor and subsequently
59 | incorporated within the Work.
60 |
61 | 2. Grant of Copyright License.
62 |
63 | Subject to the terms and conditions of this License, each Contributor hereby
64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65 | irrevocable copyright license to reproduce, prepare Derivative Works of,
66 | publicly display, publicly perform, sublicense, and distribute the Work and such
67 | Derivative Works in Source or Object form.
68 |
69 | 3. Grant of Patent License.
70 |
71 | Subject to the terms and conditions of this License, each Contributor hereby
72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73 | irrevocable (except as stated in this section) patent license to make, have
74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75 | such license applies only to those patent claims licensable by such Contributor
76 | that are necessarily infringed by their Contribution(s) alone or by combination
77 | of their Contribution(s) with the Work to which such Contribution(s) was
78 | submitted. If You institute patent litigation against any entity (including a
79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80 | Contribution incorporated within the Work constitutes direct or contributory
81 | patent infringement, then any patent licenses granted to You under this License
82 | for that Work shall terminate as of the date such litigation is filed.
83 |
84 | 4. Redistribution.
85 |
86 | You may reproduce and distribute copies of the Work or Derivative Works thereof
87 | in any medium, with or without modifications, and in Source or Object form,
88 | provided that You meet the following conditions:
89 |
90 | You must give any other recipients of the Work or Derivative Works a copy of
91 | this License; and
92 | You must cause any modified files to carry prominent notices stating that You
93 | changed the files; and
94 | You must retain, in the Source form of any Derivative Works that You distribute,
95 | all copyright, patent, trademark, and attribution notices from the Source form
96 | of the Work, excluding those notices that do not pertain to any part of the
97 | Derivative Works; and
98 | If the Work includes a "NOTICE" text file as part of its distribution, then any
99 | Derivative Works that You distribute must include a readable copy of the
100 | attribution notices contained within such NOTICE file, excluding those notices
101 | that do not pertain to any part of the Derivative Works, in at least one of the
102 | following places: within a NOTICE text file distributed as part of the
103 | Derivative Works; within the Source form or documentation, if provided along
104 | with the Derivative Works; or, within a display generated by the Derivative
105 | Works, if and wherever such third-party notices normally appear. The contents of
106 | the NOTICE file are for informational purposes only and do not modify the
107 | License. You may add Your own attribution notices within Derivative Works that
108 | You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 | provided that such additional attribution notices cannot be construed as
110 | modifying the License.
111 | You may add Your own copyright statement to Your modifications and may provide
112 | additional or different license terms and conditions for use, reproduction, or
113 | distribution of Your modifications, or for any such Derivative Works as a whole,
114 | provided Your use, reproduction, and distribution of the Work otherwise complies
115 | with the conditions stated in this License.
116 |
117 | 5. Submission of Contributions.
118 |
119 | Unless You explicitly state otherwise, any Contribution intentionally submitted
120 | for inclusion in the Work by You to the Licensor shall be under the terms and
121 | conditions of this License, without any additional terms or conditions.
122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 | any separate license agreement you may have executed with Licensor regarding
124 | such Contributions.
125 |
126 | 6. Trademarks.
127 |
128 | This License does not grant permission to use the trade names, trademarks,
129 | service marks, or product names of the Licensor, except as required for
130 | reasonable and customary use in describing the origin of the Work and
131 | reproducing the content of the NOTICE file.
132 |
133 | 7. Disclaimer of Warranty.
134 |
135 | Unless required by applicable law or agreed to in writing, Licensor provides the
136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 | including, without limitation, any warranties or conditions of TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 | solely responsible for determining the appropriateness of using or
141 | redistributing the Work and assume any risks associated with Your exercise of
142 | permissions under this License.
143 |
144 | 8. Limitation of Liability.
145 |
146 | In no event and under no legal theory, whether in tort (including negligence),
147 | contract, or otherwise, unless required by applicable law (such as deliberate
148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 | liable to You for damages, including any direct, indirect, special, incidental,
150 | or consequential damages of any character arising as a result of this License or
151 | out of the use or inability to use the Work (including but not limited to
152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 | any and all other commercial damages or losses), even if such Contributor has
154 | been advised of the possibility of such damages.
155 |
156 | 9. Accepting Warranty or Additional Liability.
157 |
158 | While redistributing the Work or Derivative Works thereof, You may choose to
159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 | other liability obligations and/or rights consistent with this License. However,
161 | in accepting such obligations, You may act only on Your own behalf and on Your
162 | sole responsibility, not on behalf of any other Contributor, and only if You
163 | agree to indemnify, defend, and hold each Contributor harmless for any liability
164 | incurred by, or claims asserted against, such Contributor by reason of your
165 | accepting any such warranty or additional liability.
166 |
167 | END OF TERMS AND CONDITIONS
168 |
169 | APPENDIX: How to apply the Apache License to your work
170 |
171 | To apply the Apache License to your work, attach the following boilerplate
172 | notice, with the fields enclosed by brackets "[]" replaced with your own
173 | identifying information. (Don't include the brackets!) The text should be
174 | enclosed in the appropriate comment syntax for the file format. We also
175 | recommend that a file or class name and description of purpose be included on
176 | the same "printed page" as the copyright notice for easier identification within
177 | third-party archives.
178 |
179 | Copyright [yyyy] [name of copyright owner]
180 |
181 | Licensed under the Apache License, Version 2.0 (the "License");
182 | you may not use this file except in compliance with the License.
183 | You may obtain a copy of the License at
184 |
185 | http://www.apache.org/licenses/LICENSE-2.0
186 |
187 | Unless required by applicable law or agreed to in writing, software
188 | distributed under the License is distributed on an "AS IS" BASIS,
189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 | See the License for the specific language governing permissions and
191 | limitations under the License.
192 |
--------------------------------------------------------------------------------
/vendor/github.com/Unknwon/macaron/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction, and
10 | distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
13 | owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all other entities
16 | that control, are controlled by, or are under common control with that entity.
17 | For the purposes of this definition, "control" means (i) the power, direct or
18 | indirect, to cause the direction or management of such entity, whether by
19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 | outstanding shares, or (iii) beneficial ownership of such entity.
21 |
22 | "You" (or "Your") shall mean an individual or Legal Entity exercising
23 | permissions granted by this License.
24 |
25 | "Source" form shall mean the preferred form for making modifications, including
26 | but not limited to software source code, documentation source, and configuration
27 | files.
28 |
29 | "Object" form shall mean any form resulting from mechanical transformation or
30 | translation of a Source form, including but not limited to compiled object code,
31 | generated documentation, and conversions to other media types.
32 |
33 | "Work" shall mean the work of authorship, whether in Source or Object form, made
34 | available under the License, as indicated by a copyright notice that is included
35 | in or attached to the work (an example is provided in the Appendix below).
36 |
37 | "Derivative Works" shall mean any work, whether in Source or Object form, that
38 | is based on (or derived from) the Work and for which the editorial revisions,
39 | annotations, elaborations, or other modifications represent, as a whole, an
40 | original work of authorship. For the purposes of this License, Derivative Works
41 | shall not include works that remain separable from, or merely link (or bind by
42 | name) to the interfaces of, the Work and Derivative Works thereof.
43 |
44 | "Contribution" shall mean any work of authorship, including the original version
45 | of the Work and any modifications or additions to that Work or Derivative Works
46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work
47 | by the copyright owner or by an individual or Legal Entity authorized to submit
48 | on behalf of the copyright owner. For the purposes of this definition,
49 | "submitted" means any form of electronic, verbal, or written communication sent
50 | to the Licensor or its representatives, including but not limited to
51 | communication on electronic mailing lists, source code control systems, and
52 | issue tracking systems that are managed by, or on behalf of, the Licensor for
53 | the purpose of discussing and improving the Work, but excluding communication
54 | that is conspicuously marked or otherwise designated in writing by the copyright
55 | owner as "Not a Contribution."
56 |
57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58 | of whom a Contribution has been received by Licensor and subsequently
59 | incorporated within the Work.
60 |
61 | 2. Grant of Copyright License.
62 |
63 | Subject to the terms and conditions of this License, each Contributor hereby
64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65 | irrevocable copyright license to reproduce, prepare Derivative Works of,
66 | publicly display, publicly perform, sublicense, and distribute the Work and such
67 | Derivative Works in Source or Object form.
68 |
69 | 3. Grant of Patent License.
70 |
71 | Subject to the terms and conditions of this License, each Contributor hereby
72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73 | irrevocable (except as stated in this section) patent license to make, have
74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75 | such license applies only to those patent claims licensable by such Contributor
76 | that are necessarily infringed by their Contribution(s) alone or by combination
77 | of their Contribution(s) with the Work to which such Contribution(s) was
78 | submitted. If You institute patent litigation against any entity (including a
79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80 | Contribution incorporated within the Work constitutes direct or contributory
81 | patent infringement, then any patent licenses granted to You under this License
82 | for that Work shall terminate as of the date such litigation is filed.
83 |
84 | 4. Redistribution.
85 |
86 | You may reproduce and distribute copies of the Work or Derivative Works thereof
87 | in any medium, with or without modifications, and in Source or Object form,
88 | provided that You meet the following conditions:
89 |
90 | You must give any other recipients of the Work or Derivative Works a copy of
91 | this License; and
92 | You must cause any modified files to carry prominent notices stating that You
93 | changed the files; and
94 | You must retain, in the Source form of any Derivative Works that You distribute,
95 | all copyright, patent, trademark, and attribution notices from the Source form
96 | of the Work, excluding those notices that do not pertain to any part of the
97 | Derivative Works; and
98 | If the Work includes a "NOTICE" text file as part of its distribution, then any
99 | Derivative Works that You distribute must include a readable copy of the
100 | attribution notices contained within such NOTICE file, excluding those notices
101 | that do not pertain to any part of the Derivative Works, in at least one of the
102 | following places: within a NOTICE text file distributed as part of the
103 | Derivative Works; within the Source form or documentation, if provided along
104 | with the Derivative Works; or, within a display generated by the Derivative
105 | Works, if and wherever such third-party notices normally appear. The contents of
106 | the NOTICE file are for informational purposes only and do not modify the
107 | License. You may add Your own attribution notices within Derivative Works that
108 | You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 | provided that such additional attribution notices cannot be construed as
110 | modifying the License.
111 | You may add Your own copyright statement to Your modifications and may provide
112 | additional or different license terms and conditions for use, reproduction, or
113 | distribution of Your modifications, or for any such Derivative Works as a whole,
114 | provided Your use, reproduction, and distribution of the Work otherwise complies
115 | with the conditions stated in this License.
116 |
117 | 5. Submission of Contributions.
118 |
119 | Unless You explicitly state otherwise, any Contribution intentionally submitted
120 | for inclusion in the Work by You to the Licensor shall be under the terms and
121 | conditions of this License, without any additional terms or conditions.
122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 | any separate license agreement you may have executed with Licensor regarding
124 | such Contributions.
125 |
126 | 6. Trademarks.
127 |
128 | This License does not grant permission to use the trade names, trademarks,
129 | service marks, or product names of the Licensor, except as required for
130 | reasonable and customary use in describing the origin of the Work and
131 | reproducing the content of the NOTICE file.
132 |
133 | 7. Disclaimer of Warranty.
134 |
135 | Unless required by applicable law or agreed to in writing, Licensor provides the
136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 | including, without limitation, any warranties or conditions of TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 | solely responsible for determining the appropriateness of using or
141 | redistributing the Work and assume any risks associated with Your exercise of
142 | permissions under this License.
143 |
144 | 8. Limitation of Liability.
145 |
146 | In no event and under no legal theory, whether in tort (including negligence),
147 | contract, or otherwise, unless required by applicable law (such as deliberate
148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 | liable to You for damages, including any direct, indirect, special, incidental,
150 | or consequential damages of any character arising as a result of this License or
151 | out of the use or inability to use the Work (including but not limited to
152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 | any and all other commercial damages or losses), even if such Contributor has
154 | been advised of the possibility of such damages.
155 |
156 | 9. Accepting Warranty or Additional Liability.
157 |
158 | While redistributing the Work or Derivative Works thereof, You may choose to
159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 | other liability obligations and/or rights consistent with this License. However,
161 | in accepting such obligations, You may act only on Your own behalf and on Your
162 | sole responsibility, not on behalf of any other Contributor, and only if You
163 | agree to indemnify, defend, and hold each Contributor harmless for any liability
164 | incurred by, or claims asserted against, such Contributor by reason of your
165 | accepting any such warranty or additional liability.
166 |
167 | END OF TERMS AND CONDITIONS
168 |
169 | APPENDIX: How to apply the Apache License to your work
170 |
171 | To apply the Apache License to your work, attach the following boilerplate
172 | notice, with the fields enclosed by brackets "[]" replaced with your own
173 | identifying information. (Don't include the brackets!) The text should be
174 | enclosed in the appropriate comment syntax for the file format. We also
175 | recommend that a file or class name and description of purpose be included on
176 | the same "printed page" as the copyright notice for easier identification within
177 | third-party archives.
178 |
179 | Copyright [yyyy] [name of copyright owner]
180 |
181 | Licensed under the Apache License, Version 2.0 (the "License");
182 | you may not use this file except in compliance with the License.
183 | You may obtain a copy of the License at
184 |
185 | http://www.apache.org/licenses/LICENSE-2.0
186 |
187 | Unless required by applicable law or agreed to in writing, software
188 | distributed under the License is distributed on an "AS IS" BASIS,
189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 | See the License for the specific language governing permissions and
191 | limitations under the License.
192 |
--------------------------------------------------------------------------------
/vendor/github.com/go-macaron/inject/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction, and
10 | distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
13 | owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all other entities
16 | that control, are controlled by, or are under common control with that entity.
17 | For the purposes of this definition, "control" means (i) the power, direct or
18 | indirect, to cause the direction or management of such entity, whether by
19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 | outstanding shares, or (iii) beneficial ownership of such entity.
21 |
22 | "You" (or "Your") shall mean an individual or Legal Entity exercising
23 | permissions granted by this License.
24 |
25 | "Source" form shall mean the preferred form for making modifications, including
26 | but not limited to software source code, documentation source, and configuration
27 | files.
28 |
29 | "Object" form shall mean any form resulting from mechanical transformation or
30 | translation of a Source form, including but not limited to compiled object code,
31 | generated documentation, and conversions to other media types.
32 |
33 | "Work" shall mean the work of authorship, whether in Source or Object form, made
34 | available under the License, as indicated by a copyright notice that is included
35 | in or attached to the work (an example is provided in the Appendix below).
36 |
37 | "Derivative Works" shall mean any work, whether in Source or Object form, that
38 | is based on (or derived from) the Work and for which the editorial revisions,
39 | annotations, elaborations, or other modifications represent, as a whole, an
40 | original work of authorship. For the purposes of this License, Derivative Works
41 | shall not include works that remain separable from, or merely link (or bind by
42 | name) to the interfaces of, the Work and Derivative Works thereof.
43 |
44 | "Contribution" shall mean any work of authorship, including the original version
45 | of the Work and any modifications or additions to that Work or Derivative Works
46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work
47 | by the copyright owner or by an individual or Legal Entity authorized to submit
48 | on behalf of the copyright owner. For the purposes of this definition,
49 | "submitted" means any form of electronic, verbal, or written communication sent
50 | to the Licensor or its representatives, including but not limited to
51 | communication on electronic mailing lists, source code control systems, and
52 | issue tracking systems that are managed by, or on behalf of, the Licensor for
53 | the purpose of discussing and improving the Work, but excluding communication
54 | that is conspicuously marked or otherwise designated in writing by the copyright
55 | owner as "Not a Contribution."
56 |
57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58 | of whom a Contribution has been received by Licensor and subsequently
59 | incorporated within the Work.
60 |
61 | 2. Grant of Copyright License.
62 |
63 | Subject to the terms and conditions of this License, each Contributor hereby
64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65 | irrevocable copyright license to reproduce, prepare Derivative Works of,
66 | publicly display, publicly perform, sublicense, and distribute the Work and such
67 | Derivative Works in Source or Object form.
68 |
69 | 3. Grant of Patent License.
70 |
71 | Subject to the terms and conditions of this License, each Contributor hereby
72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73 | irrevocable (except as stated in this section) patent license to make, have
74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75 | such license applies only to those patent claims licensable by such Contributor
76 | that are necessarily infringed by their Contribution(s) alone or by combination
77 | of their Contribution(s) with the Work to which such Contribution(s) was
78 | submitted. If You institute patent litigation against any entity (including a
79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80 | Contribution incorporated within the Work constitutes direct or contributory
81 | patent infringement, then any patent licenses granted to You under this License
82 | for that Work shall terminate as of the date such litigation is filed.
83 |
84 | 4. Redistribution.
85 |
86 | You may reproduce and distribute copies of the Work or Derivative Works thereof
87 | in any medium, with or without modifications, and in Source or Object form,
88 | provided that You meet the following conditions:
89 |
90 | You must give any other recipients of the Work or Derivative Works a copy of
91 | this License; and
92 | You must cause any modified files to carry prominent notices stating that You
93 | changed the files; and
94 | You must retain, in the Source form of any Derivative Works that You distribute,
95 | all copyright, patent, trademark, and attribution notices from the Source form
96 | of the Work, excluding those notices that do not pertain to any part of the
97 | Derivative Works; and
98 | If the Work includes a "NOTICE" text file as part of its distribution, then any
99 | Derivative Works that You distribute must include a readable copy of the
100 | attribution notices contained within such NOTICE file, excluding those notices
101 | that do not pertain to any part of the Derivative Works, in at least one of the
102 | following places: within a NOTICE text file distributed as part of the
103 | Derivative Works; within the Source form or documentation, if provided along
104 | with the Derivative Works; or, within a display generated by the Derivative
105 | Works, if and wherever such third-party notices normally appear. The contents of
106 | the NOTICE file are for informational purposes only and do not modify the
107 | License. You may add Your own attribution notices within Derivative Works that
108 | You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 | provided that such additional attribution notices cannot be construed as
110 | modifying the License.
111 | You may add Your own copyright statement to Your modifications and may provide
112 | additional or different license terms and conditions for use, reproduction, or
113 | distribution of Your modifications, or for any such Derivative Works as a whole,
114 | provided Your use, reproduction, and distribution of the Work otherwise complies
115 | with the conditions stated in this License.
116 |
117 | 5. Submission of Contributions.
118 |
119 | Unless You explicitly state otherwise, any Contribution intentionally submitted
120 | for inclusion in the Work by You to the Licensor shall be under the terms and
121 | conditions of this License, without any additional terms or conditions.
122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 | any separate license agreement you may have executed with Licensor regarding
124 | such Contributions.
125 |
126 | 6. Trademarks.
127 |
128 | This License does not grant permission to use the trade names, trademarks,
129 | service marks, or product names of the Licensor, except as required for
130 | reasonable and customary use in describing the origin of the Work and
131 | reproducing the content of the NOTICE file.
132 |
133 | 7. Disclaimer of Warranty.
134 |
135 | Unless required by applicable law or agreed to in writing, Licensor provides the
136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 | including, without limitation, any warranties or conditions of TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 | solely responsible for determining the appropriateness of using or
141 | redistributing the Work and assume any risks associated with Your exercise of
142 | permissions under this License.
143 |
144 | 8. Limitation of Liability.
145 |
146 | In no event and under no legal theory, whether in tort (including negligence),
147 | contract, or otherwise, unless required by applicable law (such as deliberate
148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 | liable to You for damages, including any direct, indirect, special, incidental,
150 | or consequential damages of any character arising as a result of this License or
151 | out of the use or inability to use the Work (including but not limited to
152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 | any and all other commercial damages or losses), even if such Contributor has
154 | been advised of the possibility of such damages.
155 |
156 | 9. Accepting Warranty or Additional Liability.
157 |
158 | While redistributing the Work or Derivative Works thereof, You may choose to
159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 | other liability obligations and/or rights consistent with this License. However,
161 | in accepting such obligations, You may act only on Your own behalf and on Your
162 | sole responsibility, not on behalf of any other Contributor, and only if You
163 | agree to indemnify, defend, and hold each Contributor harmless for any liability
164 | incurred by, or claims asserted against, such Contributor by reason of your
165 | accepting any such warranty or additional liability.
166 |
167 | END OF TERMS AND CONDITIONS
168 |
169 | APPENDIX: How to apply the Apache License to your work
170 |
171 | To apply the Apache License to your work, attach the following boilerplate
172 | notice, with the fields enclosed by brackets "[]" replaced with your own
173 | identifying information. (Don't include the brackets!) The text should be
174 | enclosed in the appropriate comment syntax for the file format. We also
175 | recommend that a file or class name and description of purpose be included on
176 | the same "printed page" as the copyright notice for easier identification within
177 | third-party archives.
178 |
179 | Copyright [yyyy] [name of copyright owner]
180 |
181 | Licensed under the Apache License, Version 2.0 (the "License");
182 | you may not use this file except in compliance with the License.
183 | You may obtain a copy of the License at
184 |
185 | http://www.apache.org/licenses/LICENSE-2.0
186 |
187 | Unless required by applicable law or agreed to in writing, software
188 | distributed under the License is distributed on an "AS IS" BASIS,
189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 | See the License for the specific language governing permissions and
191 | limitations under the License.
192 |
--------------------------------------------------------------------------------
/vendor/github.com/go-macaron/macaron/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction, and
10 | distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
13 | owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all other entities
16 | that control, are controlled by, or are under common control with that entity.
17 | For the purposes of this definition, "control" means (i) the power, direct or
18 | indirect, to cause the direction or management of such entity, whether by
19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 | outstanding shares, or (iii) beneficial ownership of such entity.
21 |
22 | "You" (or "Your") shall mean an individual or Legal Entity exercising
23 | permissions granted by this License.
24 |
25 | "Source" form shall mean the preferred form for making modifications, including
26 | but not limited to software source code, documentation source, and configuration
27 | files.
28 |
29 | "Object" form shall mean any form resulting from mechanical transformation or
30 | translation of a Source form, including but not limited to compiled object code,
31 | generated documentation, and conversions to other media types.
32 |
33 | "Work" shall mean the work of authorship, whether in Source or Object form, made
34 | available under the License, as indicated by a copyright notice that is included
35 | in or attached to the work (an example is provided in the Appendix below).
36 |
37 | "Derivative Works" shall mean any work, whether in Source or Object form, that
38 | is based on (or derived from) the Work and for which the editorial revisions,
39 | annotations, elaborations, or other modifications represent, as a whole, an
40 | original work of authorship. For the purposes of this License, Derivative Works
41 | shall not include works that remain separable from, or merely link (or bind by
42 | name) to the interfaces of, the Work and Derivative Works thereof.
43 |
44 | "Contribution" shall mean any work of authorship, including the original version
45 | of the Work and any modifications or additions to that Work or Derivative Works
46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work
47 | by the copyright owner or by an individual or Legal Entity authorized to submit
48 | on behalf of the copyright owner. For the purposes of this definition,
49 | "submitted" means any form of electronic, verbal, or written communication sent
50 | to the Licensor or its representatives, including but not limited to
51 | communication on electronic mailing lists, source code control systems, and
52 | issue tracking systems that are managed by, or on behalf of, the Licensor for
53 | the purpose of discussing and improving the Work, but excluding communication
54 | that is conspicuously marked or otherwise designated in writing by the copyright
55 | owner as "Not a Contribution."
56 |
57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58 | of whom a Contribution has been received by Licensor and subsequently
59 | incorporated within the Work.
60 |
61 | 2. Grant of Copyright License.
62 |
63 | Subject to the terms and conditions of this License, each Contributor hereby
64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65 | irrevocable copyright license to reproduce, prepare Derivative Works of,
66 | publicly display, publicly perform, sublicense, and distribute the Work and such
67 | Derivative Works in Source or Object form.
68 |
69 | 3. Grant of Patent License.
70 |
71 | Subject to the terms and conditions of this License, each Contributor hereby
72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73 | irrevocable (except as stated in this section) patent license to make, have
74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75 | such license applies only to those patent claims licensable by such Contributor
76 | that are necessarily infringed by their Contribution(s) alone or by combination
77 | of their Contribution(s) with the Work to which such Contribution(s) was
78 | submitted. If You institute patent litigation against any entity (including a
79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80 | Contribution incorporated within the Work constitutes direct or contributory
81 | patent infringement, then any patent licenses granted to You under this License
82 | for that Work shall terminate as of the date such litigation is filed.
83 |
84 | 4. Redistribution.
85 |
86 | You may reproduce and distribute copies of the Work or Derivative Works thereof
87 | in any medium, with or without modifications, and in Source or Object form,
88 | provided that You meet the following conditions:
89 |
90 | You must give any other recipients of the Work or Derivative Works a copy of
91 | this License; and
92 | You must cause any modified files to carry prominent notices stating that You
93 | changed the files; and
94 | You must retain, in the Source form of any Derivative Works that You distribute,
95 | all copyright, patent, trademark, and attribution notices from the Source form
96 | of the Work, excluding those notices that do not pertain to any part of the
97 | Derivative Works; and
98 | If the Work includes a "NOTICE" text file as part of its distribution, then any
99 | Derivative Works that You distribute must include a readable copy of the
100 | attribution notices contained within such NOTICE file, excluding those notices
101 | that do not pertain to any part of the Derivative Works, in at least one of the
102 | following places: within a NOTICE text file distributed as part of the
103 | Derivative Works; within the Source form or documentation, if provided along
104 | with the Derivative Works; or, within a display generated by the Derivative
105 | Works, if and wherever such third-party notices normally appear. The contents of
106 | the NOTICE file are for informational purposes only and do not modify the
107 | License. You may add Your own attribution notices within Derivative Works that
108 | You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 | provided that such additional attribution notices cannot be construed as
110 | modifying the License.
111 | You may add Your own copyright statement to Your modifications and may provide
112 | additional or different license terms and conditions for use, reproduction, or
113 | distribution of Your modifications, or for any such Derivative Works as a whole,
114 | provided Your use, reproduction, and distribution of the Work otherwise complies
115 | with the conditions stated in this License.
116 |
117 | 5. Submission of Contributions.
118 |
119 | Unless You explicitly state otherwise, any Contribution intentionally submitted
120 | for inclusion in the Work by You to the Licensor shall be under the terms and
121 | conditions of this License, without any additional terms or conditions.
122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 | any separate license agreement you may have executed with Licensor regarding
124 | such Contributions.
125 |
126 | 6. Trademarks.
127 |
128 | This License does not grant permission to use the trade names, trademarks,
129 | service marks, or product names of the Licensor, except as required for
130 | reasonable and customary use in describing the origin of the Work and
131 | reproducing the content of the NOTICE file.
132 |
133 | 7. Disclaimer of Warranty.
134 |
135 | Unless required by applicable law or agreed to in writing, Licensor provides the
136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 | including, without limitation, any warranties or conditions of TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 | solely responsible for determining the appropriateness of using or
141 | redistributing the Work and assume any risks associated with Your exercise of
142 | permissions under this License.
143 |
144 | 8. Limitation of Liability.
145 |
146 | In no event and under no legal theory, whether in tort (including negligence),
147 | contract, or otherwise, unless required by applicable law (such as deliberate
148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 | liable to You for damages, including any direct, indirect, special, incidental,
150 | or consequential damages of any character arising as a result of this License or
151 | out of the use or inability to use the Work (including but not limited to
152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 | any and all other commercial damages or losses), even if such Contributor has
154 | been advised of the possibility of such damages.
155 |
156 | 9. Accepting Warranty or Additional Liability.
157 |
158 | While redistributing the Work or Derivative Works thereof, You may choose to
159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 | other liability obligations and/or rights consistent with this License. However,
161 | in accepting such obligations, You may act only on Your own behalf and on Your
162 | sole responsibility, not on behalf of any other Contributor, and only if You
163 | agree to indemnify, defend, and hold each Contributor harmless for any liability
164 | incurred by, or claims asserted against, such Contributor by reason of your
165 | accepting any such warranty or additional liability.
166 |
167 | END OF TERMS AND CONDITIONS
168 |
169 | APPENDIX: How to apply the Apache License to your work
170 |
171 | To apply the Apache License to your work, attach the following boilerplate
172 | notice, with the fields enclosed by brackets "[]" replaced with your own
173 | identifying information. (Don't include the brackets!) The text should be
174 | enclosed in the appropriate comment syntax for the file format. We also
175 | recommend that a file or class name and description of purpose be included on
176 | the same "printed page" as the copyright notice for easier identification within
177 | third-party archives.
178 |
179 | Copyright [yyyy] [name of copyright owner]
180 |
181 | Licensed under the Apache License, Version 2.0 (the "License");
182 | you may not use this file except in compliance with the License.
183 | You may obtain a copy of the License at
184 |
185 | http://www.apache.org/licenses/LICENSE-2.0
186 |
187 | Unless required by applicable law or agreed to in writing, software
188 | distributed under the License is distributed on an "AS IS" BASIS,
189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 | See the License for the specific language governing permissions and
191 | limitations under the License.
192 |
--------------------------------------------------------------------------------