├── vendor ├── github.com │ ├── Unknwon │ │ ├── macaron │ │ │ ├── inject │ │ │ │ ├── inject.goconvey │ │ │ │ ├── README.md │ │ │ │ └── inject.go │ │ │ ├── .gitignore │ │ │ ├── macaronlogo.png │ │ │ ├── logger.go │ │ │ ├── return_handler.go │ │ │ ├── response_writer.go │ │ │ ├── gzip.go │ │ │ ├── README.md │ │ │ ├── recovery.go │ │ │ ├── static.go │ │ │ ├── macaron.go │ │ │ └── LICENSE │ │ └── com │ │ │ ├── .travis.yml │ │ │ ├── .gitignore │ │ │ ├── math.go │ │ │ ├── README.md │ │ │ ├── url.go │ │ │ ├── html.go │ │ │ ├── regex.go │ │ │ ├── slice.go │ │ │ ├── path.go │ │ │ ├── file.go │ │ │ ├── convert.go │ │ │ ├── time.go │ │ │ ├── dir.go │ │ │ ├── cmd.go │ │ │ ├── http.go │ │ │ ├── string.go │ │ │ └── LICENSE │ ├── go-macaron │ │ ├── macaron │ │ │ ├── .gitignore │ │ │ ├── macaronlogo.png │ │ │ ├── .travis.yml │ │ │ ├── logger.go │ │ │ ├── return_handler.go │ │ │ ├── response_writer.go │ │ │ ├── README.md │ │ │ ├── recovery.go │ │ │ ├── static.go │ │ │ ├── macaron.go │ │ │ └── LICENSE │ │ └── inject │ │ │ ├── .travis.yml │ │ │ ├── README.md │ │ │ ├── inject.go │ │ │ └── LICENSE │ ├── elazarl │ │ └── go-bindata-assetfs │ │ │ ├── doc.go │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ └── assetfs.go │ └── macaron-contrib │ │ └── bindata │ │ └── README.md └── gopkg.in │ └── ini.v1 │ ├── .gitignore │ ├── struct.go │ └── LICENSE ├── public ├── css │ └── style.css ├── entry.js ├── favicon.ico ├── Main.jsx ├── HelloWorld.jsx └── js │ └── HelloWorld.jsx ├── Godeps ├── Readme └── Godeps.json ├── modules ├── assets.go └── assets_bindata.go ├── .gitignore ├── server.js ├── package.json ├── templates └── homepage.tmpl ├── webpack.config.prod.js ├── Makefile ├── webpack.config.js ├── README.md ├── LICENSE └── main.go /vendor/github.com/Unknwon/macaron/inject/inject.goconvey: -------------------------------------------------------------------------------- 1 | ignore -------------------------------------------------------------------------------- /public/css/style.css: -------------------------------------------------------------------------------- 1 | /* css */ 2 | body { 3 | font-family: "Courier New" 4 | } 5 | 6 | -------------------------------------------------------------------------------- /vendor/github.com/Unknwon/macaron/.gitignore: -------------------------------------------------------------------------------- 1 | macaron.sublime-project 2 | macaron.sublime-workspace -------------------------------------------------------------------------------- /public/entry.js: -------------------------------------------------------------------------------- 1 | /* entry for webpack */ 2 | 3 | require('./css/style.css') 4 | require('./Main.jsx') -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeskyblue/go-reactjs-example/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /vendor/github.com/go-macaron/macaron/.gitignore: -------------------------------------------------------------------------------- 1 | macaron.sublime-project 2 | macaron.sublime-workspace -------------------------------------------------------------------------------- /vendor/github.com/Unknwon/macaron/inject/README.md: -------------------------------------------------------------------------------- 1 | inject 2 | ====== 3 | 4 | Dependency injection for go 5 | -------------------------------------------------------------------------------- /vendor/gopkg.in/ini.v1/.gitignore: -------------------------------------------------------------------------------- 1 | testdata/conf_out.ini 2 | ini.sublime-project 3 | ini.sublime-workspace 4 | testdata/conf_reflect.ini 5 | -------------------------------------------------------------------------------- /vendor/github.com/Unknwon/macaron/macaronlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeskyblue/go-reactjs-example/HEAD/vendor/github.com/Unknwon/macaron/macaronlogo.png -------------------------------------------------------------------------------- /Godeps/Readme: -------------------------------------------------------------------------------- 1 | This directory tree is generated automatically by godep. 2 | 3 | Please do not edit. 4 | 5 | See https://github.com/tools/godep for more information. 6 | -------------------------------------------------------------------------------- /vendor/github.com/go-macaron/macaron/macaronlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeskyblue/go-reactjs-example/HEAD/vendor/github.com/go-macaron/macaron/macaronlogo.png -------------------------------------------------------------------------------- /vendor/github.com/Unknwon/com/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.2 5 | - 1.3 6 | - 1.4 7 | - tip 8 | 9 | install: go get -v -t 10 | 11 | notifications: 12 | email: 13 | - u@gogs.io -------------------------------------------------------------------------------- /vendor/github.com/go-macaron/macaron/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | 4 | go: 5 | - 1.3 6 | - 1.4 7 | - 1.5 8 | 9 | script: go test -v -cover -race 10 | 11 | notifications: 12 | email: 13 | - u@gogs.io 14 | -------------------------------------------------------------------------------- /public/Main.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDOM = require('react-dom'); 3 | 4 | var HelloWorld = require('./HelloWorld.jsx'); 5 | 6 | 7 | ReactDOM.render( 8 | , 9 | document.getElementById('content') 10 | ) 11 | -------------------------------------------------------------------------------- /public/HelloWorld.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | 4 | var HelloWorld = React.createClass({ 5 | 6 | render: function() { 7 | return ( 8 |

Hello world

9 | ); 10 | } 11 | 12 | }); 13 | 14 | module.exports = HelloWorld; -------------------------------------------------------------------------------- /vendor/github.com/go-macaron/inject/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | 4 | go: 5 | - 1.3 6 | - 1.4 7 | - 1.5 8 | - tip 9 | 10 | script: go test -v -cover -race 11 | 12 | notifications: 13 | email: 14 | - u@gogs.io 15 | -------------------------------------------------------------------------------- /public/js/HelloWorld.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | 4 | var HelloWorld = React.createClass({ 5 | 6 | render: function() { 7 | return ( 8 |

Hello world

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 [![Build Status](https://travis-ci.org/go-macaron/inject.svg?branch=master)](https://travis-ci.org/go-macaron/inject) [![](http://gocover.io/_badge/github.com/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 [![Build Status](https://drone.io/github.com/macaron-contrib/bindata/status.png)](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 | [![Build Status](https://travis-ci.org/Unknwon/com.svg)](https://travis-ci.org/Unknwon/com) [![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/Unknwon/com) 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)[^<>]*>.*?|]*>|`) 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 [![Build Status](https://travis-ci.org/go-macaron/macaron.svg?branch=v1)](https://travis-ci.org/go-macaron/macaron) [![](http://gocover.io/_badge/github.com/go-macaron/macaron)](http://gocover.io/github.com/go-macaron/macaron) 2 | ======================= 3 | 4 | ![Macaron Logo](https://raw.githubusercontent.com/go-macaron/macaron/v1/macaronlogo.png) 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 | - [![Join the chat at https://gitter.im/Unknwon/macaron](https://badges.gitter.im/Join%20Chat.svg)](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 [![Build Status](https://drone.io/github.com/Unknwon/macaron/status.png)](https://drone.io/github.com/Unknwon/macaron/latest) [![](http://gocover.io/_badge/github.com/Unknwon/macaron)](http://gocover.io/github.com/Unknwon/macaron) 2 | ======================= 3 | 4 | ![Macaron Logo](https://raw.githubusercontent.com/Unknwon/macaron/master/macaronlogo.png) 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 | - [![Join the chat at https://gitter.im/Unknwon/macaron](https://badges.gitter.im/Join%20Chat.svg)](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 | --------------------------------------------------------------------------------