├── .editorconfig ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Dockerfile ├── Godeps ├── Godeps.json └── Readme ├── LICENSE ├── Makefile ├── README.md ├── dao ├── spirit-dao-factory.go ├── spirit-dao-mock.go ├── spirit-dao-mongo.go ├── spirit-dao-mongo_test.go └── spirit-dao.go ├── doc └── img │ ├── concurrency.png │ ├── gopath_vendor.png │ ├── main_architecture.png │ └── web_architecture.png ├── docker-compose.yml ├── etc ├── apiquery.sh ├── caroni.json └── clairin.json ├── handsongo.go ├── model └── model.go ├── utils ├── logger.go ├── statistics.go ├── statistics_test.go ├── timetrack.go └── web.go ├── vendor ├── github.com │ ├── Sirupsen │ │ └── logrus │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── doc.go │ │ │ ├── entry.go │ │ │ ├── exported.go │ │ │ ├── formatter.go │ │ │ ├── formatters │ │ │ └── logstash │ │ │ │ └── logstash.go │ │ │ ├── hooks.go │ │ │ ├── json_formatter.go │ │ │ ├── logger.go │ │ │ ├── logrus.go │ │ │ ├── terminal_bsd.go │ │ │ ├── terminal_linux.go │ │ │ ├── terminal_notwindows.go │ │ │ ├── terminal_solaris.go │ │ │ ├── terminal_windows.go │ │ │ ├── text_formatter.go │ │ │ └── writer.go │ ├── gorilla │ │ ├── context │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── context.go │ │ │ └── doc.go │ │ └── mux │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── doc.go │ │ │ ├── mux.go │ │ │ ├── regexp.go │ │ │ └── route.go │ ├── meatballhat │ │ └── negroni-logrus │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ └── middleware.go │ └── urfave │ │ ├── cli │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── app.go │ │ ├── appveyor.yml │ │ ├── category.go │ │ ├── cli.go │ │ ├── command.go │ │ ├── context.go │ │ ├── errors.go │ │ ├── flag.go │ │ ├── funcs.go │ │ ├── help.go │ │ └── runtests │ │ └── negroni │ │ ├── .travis.yml │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── doc.go │ │ ├── logger.go │ │ ├── negroni.go │ │ ├── recovery.go │ │ ├── response_writer.go │ │ └── static.go ├── golang.org │ └── x │ │ └── sys │ │ ├── LICENSE │ │ ├── PATENTS │ │ └── unix │ │ ├── .gitignore │ │ ├── asm.s │ │ ├── asm_darwin_386.s │ │ ├── asm_darwin_amd64.s │ │ ├── asm_darwin_arm.s │ │ ├── asm_darwin_arm64.s │ │ ├── asm_dragonfly_386.s │ │ ├── asm_dragonfly_amd64.s │ │ ├── asm_freebsd_386.s │ │ ├── asm_freebsd_amd64.s │ │ ├── asm_freebsd_arm.s │ │ ├── asm_linux_386.s │ │ ├── asm_linux_amd64.s │ │ ├── asm_linux_arm.s │ │ ├── asm_linux_arm64.s │ │ ├── asm_linux_mips64x.s │ │ ├── asm_linux_ppc64x.s │ │ ├── asm_netbsd_386.s │ │ ├── asm_netbsd_amd64.s │ │ ├── asm_netbsd_arm.s │ │ ├── asm_openbsd_386.s │ │ ├── asm_openbsd_amd64.s │ │ ├── asm_solaris_amd64.s │ │ ├── bluetooth_linux.go │ │ ├── constants.go │ │ ├── env_unix.go │ │ ├── env_unset.go │ │ ├── flock.go │ │ ├── flock_linux_32bit.go │ │ ├── gccgo.go │ │ ├── gccgo_c.c │ │ ├── gccgo_linux_amd64.go │ │ ├── mkall.sh │ │ ├── mkerrors.sh │ │ ├── mksyscall.pl │ │ ├── mksyscall_solaris.pl │ │ ├── mksysctl_openbsd.pl │ │ ├── mksysnum_darwin.pl │ │ ├── mksysnum_dragonfly.pl │ │ ├── mksysnum_freebsd.pl │ │ ├── mksysnum_linux.pl │ │ ├── mksysnum_netbsd.pl │ │ ├── mksysnum_openbsd.pl │ │ ├── race.go │ │ ├── race0.go │ │ ├── sockcmsg_linux.go │ │ ├── sockcmsg_unix.go │ │ ├── str.go │ │ ├── syscall.go │ │ ├── syscall_bsd.go │ │ ├── syscall_darwin.go │ │ ├── syscall_darwin_386.go │ │ ├── syscall_darwin_amd64.go │ │ ├── syscall_darwin_arm.go │ │ ├── syscall_darwin_arm64.go │ │ ├── syscall_dragonfly.go │ │ ├── syscall_dragonfly_386.go │ │ ├── syscall_dragonfly_amd64.go │ │ ├── syscall_freebsd.go │ │ ├── syscall_freebsd_386.go │ │ ├── syscall_freebsd_amd64.go │ │ ├── syscall_freebsd_arm.go │ │ ├── syscall_linux.go │ │ ├── syscall_linux_386.go │ │ ├── syscall_linux_amd64.go │ │ ├── syscall_linux_arm.go │ │ ├── syscall_linux_arm64.go │ │ ├── syscall_linux_mips64x.go │ │ ├── syscall_linux_ppc64x.go │ │ ├── syscall_netbsd.go │ │ ├── syscall_netbsd_386.go │ │ ├── syscall_netbsd_amd64.go │ │ ├── syscall_netbsd_arm.go │ │ ├── syscall_no_getwd.go │ │ ├── syscall_openbsd.go │ │ ├── syscall_openbsd_386.go │ │ ├── syscall_openbsd_amd64.go │ │ ├── syscall_solaris.go │ │ ├── syscall_solaris_amd64.go │ │ ├── syscall_unix.go │ │ ├── types_darwin.go │ │ ├── types_dragonfly.go │ │ ├── types_freebsd.go │ │ ├── types_linux.go │ │ ├── types_netbsd.go │ │ ├── types_openbsd.go │ │ ├── types_solaris.go │ │ ├── zerrors_darwin_386.go │ │ ├── zerrors_darwin_amd64.go │ │ ├── zerrors_darwin_arm.go │ │ ├── zerrors_darwin_arm64.go │ │ ├── zerrors_dragonfly_386.go │ │ ├── zerrors_dragonfly_amd64.go │ │ ├── zerrors_freebsd_386.go │ │ ├── zerrors_freebsd_amd64.go │ │ ├── zerrors_freebsd_arm.go │ │ ├── zerrors_linux_386.go │ │ ├── zerrors_linux_amd64.go │ │ ├── zerrors_linux_arm.go │ │ ├── zerrors_linux_arm64.go │ │ ├── zerrors_linux_mips64.go │ │ ├── zerrors_linux_mips64le.go │ │ ├── zerrors_linux_ppc64.go │ │ ├── zerrors_linux_ppc64le.go │ │ ├── zerrors_netbsd_386.go │ │ ├── zerrors_netbsd_amd64.go │ │ ├── zerrors_netbsd_arm.go │ │ ├── zerrors_openbsd_386.go │ │ ├── zerrors_openbsd_amd64.go │ │ ├── zerrors_solaris_amd64.go │ │ ├── zsyscall_darwin_386.go │ │ ├── zsyscall_darwin_amd64.go │ │ ├── zsyscall_darwin_arm.go │ │ ├── zsyscall_darwin_arm64.go │ │ ├── zsyscall_dragonfly_386.go │ │ ├── zsyscall_dragonfly_amd64.go │ │ ├── zsyscall_freebsd_386.go │ │ ├── zsyscall_freebsd_amd64.go │ │ ├── zsyscall_freebsd_arm.go │ │ ├── zsyscall_linux_386.go │ │ ├── zsyscall_linux_amd64.go │ │ ├── zsyscall_linux_arm.go │ │ ├── zsyscall_linux_arm64.go │ │ ├── zsyscall_linux_mips64.go │ │ ├── zsyscall_linux_mips64le.go │ │ ├── zsyscall_linux_ppc64.go │ │ ├── zsyscall_linux_ppc64le.go │ │ ├── zsyscall_netbsd_386.go │ │ ├── zsyscall_netbsd_amd64.go │ │ ├── zsyscall_netbsd_arm.go │ │ ├── zsyscall_openbsd_386.go │ │ ├── zsyscall_openbsd_amd64.go │ │ ├── zsyscall_solaris_amd64.go │ │ ├── zsysctl_openbsd.go │ │ ├── zsysnum_darwin_386.go │ │ ├── zsysnum_darwin_amd64.go │ │ ├── zsysnum_darwin_arm.go │ │ ├── zsysnum_darwin_arm64.go │ │ ├── zsysnum_dragonfly_386.go │ │ ├── zsysnum_dragonfly_amd64.go │ │ ├── zsysnum_freebsd_386.go │ │ ├── zsysnum_freebsd_amd64.go │ │ ├── zsysnum_freebsd_arm.go │ │ ├── zsysnum_linux_386.go │ │ ├── zsysnum_linux_amd64.go │ │ ├── zsysnum_linux_arm.go │ │ ├── zsysnum_linux_arm64.go │ │ ├── zsysnum_linux_mips64.go │ │ ├── zsysnum_linux_mips64le.go │ │ ├── zsysnum_linux_ppc64.go │ │ ├── zsysnum_linux_ppc64le.go │ │ ├── zsysnum_netbsd_386.go │ │ ├── zsysnum_netbsd_amd64.go │ │ ├── zsysnum_netbsd_arm.go │ │ ├── zsysnum_openbsd_386.go │ │ ├── zsysnum_openbsd_amd64.go │ │ ├── zsysnum_solaris_amd64.go │ │ ├── ztypes_darwin_386.go │ │ ├── ztypes_darwin_amd64.go │ │ ├── ztypes_darwin_arm.go │ │ ├── ztypes_darwin_arm64.go │ │ ├── ztypes_dragonfly_386.go │ │ ├── ztypes_dragonfly_amd64.go │ │ ├── ztypes_freebsd_386.go │ │ ├── ztypes_freebsd_amd64.go │ │ ├── ztypes_freebsd_arm.go │ │ ├── ztypes_linux_386.go │ │ ├── ztypes_linux_amd64.go │ │ ├── ztypes_linux_arm.go │ │ ├── ztypes_linux_arm64.go │ │ ├── ztypes_linux_mips64.go │ │ ├── ztypes_linux_mips64le.go │ │ ├── ztypes_linux_ppc64.go │ │ ├── ztypes_linux_ppc64le.go │ │ ├── ztypes_netbsd_386.go │ │ ├── ztypes_netbsd_amd64.go │ │ ├── ztypes_netbsd_arm.go │ │ ├── ztypes_openbsd_386.go │ │ ├── ztypes_openbsd_amd64.go │ │ └── ztypes_solaris_amd64.go └── gopkg.in │ └── mgo.v2 │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── auth.go │ ├── bson │ ├── LICENSE │ ├── bson.go │ ├── decode.go │ └── encode.go │ ├── bulk.go │ ├── cluster.go │ ├── doc.go │ ├── gridfs.go │ ├── internal │ ├── sasl │ │ ├── sasl.c │ │ ├── sasl.go │ │ ├── sasl_windows.c │ │ ├── sasl_windows.go │ │ ├── sasl_windows.h │ │ ├── sspi_windows.c │ │ └── sspi_windows.h │ └── scram │ │ └── scram.go │ ├── log.go │ ├── queue.go │ ├── raceoff.go │ ├── raceon.go │ ├── saslimpl.go │ ├── saslstub.go │ ├── server.go │ ├── session.go │ ├── socket.go │ └── stats.go └── web ├── handler.go ├── router.go ├── statistics-middleware.go ├── web-server.go └── web_test.go /.editorconfig: -------------------------------------------------------------------------------- 1 | # unifying the coding style for different editors and IDEs => editorconfig.org 2 | 3 | ; indicate this is the root of the project 4 | root = true 5 | 6 | ########################################################### 7 | ; common 8 | ########################################################### 9 | 10 | [*] 11 | charset = utf-8 12 | 13 | end_of_line = LF 14 | insert_final_newline = true 15 | trim_trailing_whitespace = true 16 | 17 | indent_style = space 18 | indent_size = 2 19 | 20 | ########################################################### 21 | ; make 22 | ########################################################### 23 | 24 | [Makefile] 25 | indent_style = tab 26 | 27 | ########################################################### 28 | ; asciidoctor 29 | ########################################################### 30 | 31 | [*.adoc] 32 | trim_trailing_whitespace = false 33 | 34 | ########################################################### 35 | ; golang 36 | ########################################################### 37 | 38 | [*.go] 39 | indent_style = space 40 | indent_size = 2 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### HANDSONGO ### 2 | build/ 3 | *.out 4 | *.log 5 | documentation/*.html 6 | documentation/*.css 7 | !documentation/readthedocs.css 8 | documentation/diag-*.png* 9 | documentation/generated/* 10 | documentation/*.pdf* 11 | *.lock 12 | _* 13 | handsongo 14 | .tmp/ 15 | node_modules/ 16 | tags 17 | firmware 18 | 19 | ### Go ### 20 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 21 | *.o 22 | *.a 23 | *.so 24 | tmp 25 | 26 | # Folders 27 | _obj 28 | _test 29 | 30 | # Architecture specific extensions/prefixes 31 | *.[568vq] 32 | [568vq].out 33 | 34 | *.cgo1.go 35 | *.cgo2.c 36 | _cgo_defun.c 37 | _cgo_gotypes.go 38 | _cgo_export.* 39 | 40 | _testmain.go 41 | 42 | *.exe 43 | *.test 44 | *.prof 45 | 46 | ### OSX ### 47 | .DS_Store 48 | .AppleDouble 49 | .LSOverride 50 | 51 | # Icon must end with two \r 52 | Icon 53 | 54 | 55 | # Thumbnails 56 | ._* 57 | 58 | # Files that might appear in the root of a volume 59 | .DocumentRevisions-V100 60 | .fseventsd 61 | .Spotlight-V100 62 | .TemporaryItems 63 | .Trashes 64 | .VolumeIcon.icns 65 | 66 | # Directories potentially created on remote AFP share 67 | .AppleDB 68 | .AppleDesktop 69 | Network Trash Folder 70 | Temporary Items 71 | .apdisk 72 | 73 | ### INTELLIJ IDEA ### 74 | .idea/ 75 | *.iml 76 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.6 5 | - tip 6 | 7 | script: 8 | - make build 9 | - go get -u github.com/golang/lint/golint 10 | - make lint 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## v0.0.4 [16/08/09] 4 | - 16/08/09 chore(doc): update README (SFR) 5 | chore(deploy): switch to smaller image alpine 6 | refact(all): use anonymous attribute for router 7 | refact(all): main action return errors 8 | 9 | ## v0.0.3 [16/07/13] 10 | - 16/07/07 chore(vendor): update codegansta vendor to urfave (SFR) 11 | chore(docker): update Go version to 1.6 in Docker deployment 12 | chore(build): add travis build support 13 | 14 | ## v0.0.2 [16/06/06] 15 | - 16/06/05 refact(dao): change dao Upsert signature to remove mgo dependency (SFR) 16 | refact(model): fix model JSON annotation for age 17 | fix(test): fix statistics test for expected request count 18 | refact(web): refactor web server in a separate file and main entry point 19 | feat(test): add full web server test 20 | chore(test): add benchmarking target and instruction 21 | - 16/06/01 chore(test): add go routine to statistics test (SFR) 22 | 23 | ## v0.0.1 [16/05/31] 24 | - 16/05/25 chore(test): fix tests to run from all OS (SFR/RLE) 25 | - 16/05/19 feat(all): finalize web server, tests and test script (SFR) 26 | feat(web): add web server, middleware and router and get implementation without range 27 | refact(dao): fix panic on wrong object id format 28 | chore(vendor): update vendors with web dependency 29 | chore(etc): add scripts to query API 30 | - 16/05/11 feat(dao): add model of spirits, mongo dao, factory and update vendors (SFR) 31 | - 16/05/10 feat(all): project start, add command line, vendors, makefile, docker, logger, tests and statistics (SFR) 32 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # minimal linux distribution 2 | FROM golang:1.6-alpine 3 | 4 | # GO and PATH env variables already set in golang image 5 | # to reduce download time 6 | RUN apk add -U make 7 | 8 | # set the go path to import the source project 9 | WORKDIR $GOPATH/src/github.com/sebastienfr/handsongo 10 | ADD . $GOPATH/src/github.com/sebastienfr/handsongo 11 | 12 | # In one command-line (for reduce memory usage purposes), 13 | # we install the required software, 14 | # we build handsongo program 15 | # we clean the system from all build dependencies 16 | RUN make all && apk del make && \ 17 | rm -rf /gopath/pkg && \ 18 | rm -rf /gopath/src && \ 19 | rm -rf /var/cache/apk/* 20 | 21 | # by default, the exposed ports are 8020 (HTTP) 22 | EXPOSE 8020 23 | -------------------------------------------------------------------------------- /Godeps/Godeps.json: -------------------------------------------------------------------------------- 1 | { 2 | "ImportPath": "github.com/sebastienfr/handsongo", 3 | "GoVersion": "go1.6", 4 | "GodepVersion": "v74", 5 | "Packages": [ 6 | "./..." 7 | ], 8 | "Deps": [ 9 | { 10 | "ImportPath": "github.com/Sirupsen/logrus", 11 | "Comment": "v0.10.0-19-gf3cfb45", 12 | "Rev": "f3cfb454f4c209e6668c95216c4744b8fddb2356" 13 | }, 14 | { 15 | "ImportPath": "github.com/Sirupsen/logrus/formatters/logstash", 16 | "Comment": "v0.10.0-19-gf3cfb45", 17 | "Rev": "f3cfb454f4c209e6668c95216c4744b8fddb2356" 18 | }, 19 | { 20 | "ImportPath": "github.com/gorilla/context", 21 | "Rev": "1ea25387ff6f684839d82767c1733ff4d4d15d0a" 22 | }, 23 | { 24 | "ImportPath": "github.com/gorilla/mux", 25 | "Comment": "v1.1", 26 | "Rev": "0eeaf8392f5b04950925b8a69fe70f110fa7cbfc" 27 | }, 28 | { 29 | "ImportPath": "github.com/meatballhat/negroni-logrus", 30 | "Rev": "7c570a907cfc69cdc004ad506c6f5e234815b936" 31 | }, 32 | { 33 | "ImportPath": "github.com/urfave/cli", 34 | "Comment": "v1.17.0-79-g6011f16", 35 | "Rev": "6011f165dc288c72abd8acd7722f837c5c64198d" 36 | }, 37 | { 38 | "ImportPath": "github.com/urfave/negroni", 39 | "Comment": "v0.2.0-48-gdcaac91", 40 | "Rev": "dcaac9107a7a6ba4cf5143afc145e2b70a1c12c2" 41 | }, 42 | { 43 | "ImportPath": "golang.org/x/sys/unix", 44 | "Rev": "9eef40adf05b951699605195b829612bd7b69952" 45 | }, 46 | { 47 | "ImportPath": "gopkg.in/mgo.v2", 48 | "Comment": "r2016.02.04-1-gb6e2fa3", 49 | "Rev": "b6e2fa371e64216a45e61072a96d4e3859f169da" 50 | }, 51 | { 52 | "ImportPath": "gopkg.in/mgo.v2/bson", 53 | "Comment": "r2016.02.04-1-gb6e2fa3", 54 | "Rev": "b6e2fa371e64216a45e61072a96d4e3859f169da" 55 | }, 56 | { 57 | "ImportPath": "gopkg.in/mgo.v2/internal/sasl", 58 | "Comment": "r2016.02.04-1-gb6e2fa3", 59 | "Rev": "b6e2fa371e64216a45e61072a96d4e3859f169da" 60 | }, 61 | { 62 | "ImportPath": "gopkg.in/mgo.v2/internal/scram", 63 | "Comment": "r2016.02.04-1-gb6e2fa3", 64 | "Rev": "b6e2fa371e64216a45e61072a96d4e3859f169da" 65 | } 66 | ] 67 | } 68 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #HANDSONGO 2 | [![Build Status](https://travis-ci.org/sebastienfr/handsongo.svg?branch=master)](https://travis-ci.org/sebastienfr/handsongo) 3 | [![GoDoc](https://godoc.org/github.com/sebastienfr/handsongo?status.svg)](https://godoc.org/github.com/sebastienfr/handsongo) 4 | [![codebeat badge](https://codebeat.co/badges/4c43152a-e6f8-4781-b1b4-9f5c9c040c00)](https://codebeat.co/projects/github-com-sebastienfr-handsongo) 5 | [![Software License](http://img.shields.io/badge/license-APACHE2-blue.svg)](https://github.com/sebastienfr/handsongo/blob/master/LICENSE) 6 | 7 | This project is meant to help learning go. It provides a basic implementation of a REST microservice exposing a CRUD API. 8 | Data are persisted in a MongoDB NoSQL database and the application is deployed in Docker. 9 | 10 | ## Technical stack 11 | 12 | * [Docker](https://www.docker.com) 13 | * [MongoDB NoSQL database](https://www.mongodb.com) 14 | * [Go is the language](https://golang.org) 15 | * [Gorilla Mux the URL router](https://github.com/gorilla/mux) 16 | * [Gorilla Mux the request context manager](https://github.com/gorilla/context) 17 | * [Urfave negroni Web HTTP middleware](https://github.com/urfave/negroni) 18 | * [Urfave cli the command line client parser](https://github.com/urfave/cli) 19 | * [Sirupsen the logger](https://github.com/Sirupsen/logrus) 20 | * [The database driver](https://gopkg.in/mgo.v2) 21 | * [Godep the dependency manager](https://github.com/tools/godep) 22 | * [Golint the source linter](https://github.com/golang/lint/golint) 23 | 24 | ## Architecture 25 | 26 | ![main architecture](doc/img/main_architecture.png "Main architecture") 27 | 28 | ![web architecture](doc/img/web_architecture.png "Web architecture") 29 | 30 | ## Build 31 | 32 | ```shell 33 | make help 34 | ``` 35 | -------------------------------------------------------------------------------- /dao/spirit-dao-factory.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "errors" 5 | "gopkg.in/mgo.v2" 6 | "time" 7 | ) 8 | 9 | const ( 10 | // DAOMongo is used for Mongo implementation of SpiritDAO 11 | DAOMongo int = iota 12 | // DAOMock is used for mocked implementation of SpiritDAO 13 | DAOMock 14 | 15 | // mongo timeout 16 | timeout = 15 * time.Second 17 | // poolSize of mongo connection pool 18 | poolSize = 35 19 | ) 20 | 21 | var ( 22 | // ErrorDAONotFound is used for unknown DAO type 23 | ErrorDAONotFound = errors.New("Unknown DAO type") 24 | ) 25 | 26 | // GetSpiritDAO returns a SpiritDAO according to type and params 27 | func GetSpiritDAO(param string, daoType int) (SpiritDAO, error) { 28 | switch daoType { 29 | case DAOMongo: 30 | // mongo connection 31 | mgoSession, err := mgo.DialWithTimeout(param, timeout) 32 | if err != nil { 33 | return nil, err 34 | } 35 | 36 | // set 30 sec timeout on session 37 | mgoSession.SetSyncTimeout(timeout) 38 | mgoSession.SetSocketTimeout(timeout) 39 | // set mode 40 | mgoSession.SetMode(mgo.Monotonic, true) 41 | mgoSession.SetPoolLimit(poolSize) 42 | 43 | return NewSpiritDAOMongo(mgoSession), nil 44 | case DAOMock: 45 | return NewSpiritDAOMock(), nil 46 | default: 47 | return nil, ErrorDAONotFound 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /dao/spirit-dao-mock.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "github.com/sebastienfr/handsongo/model" 5 | "time" 6 | ) 7 | 8 | // MockedSpirit is the spirit returned by this mocked interface 9 | var MockedSpirit = model.Spirit{ 10 | Name: "Caroni", 11 | Distiller: "Caroni", 12 | Bottler: "Velier", 13 | Country: "Trinidad", 14 | Composition: "Molasse", 15 | SpiritType: model.TypeRhum, 16 | Age: 15, 17 | BottlingDate: time.Date(2015, 01, 01, 0, 0, 0, 0, time.UTC), 18 | Score: 8.5, 19 | Comment: "heavy tire taste", 20 | } 21 | 22 | // SpiritDAOMock is the mocked implementation of the SpiritDAO 23 | type SpiritDAOMock struct { 24 | } 25 | 26 | // NewSpiritDAOMock creates a new SpiritDAO with a mocked implementation 27 | func NewSpiritDAOMock() SpiritDAO { 28 | return &SpiritDAOMock{} 29 | } 30 | 31 | // GetSpiritByID returns a spirit by its ID 32 | func (s *SpiritDAOMock) GetSpiritByID(ID string) (*model.Spirit, error) { 33 | return &MockedSpirit, nil 34 | } 35 | 36 | // GetAllSpirits returns all spirits with paging capability 37 | func (s *SpiritDAOMock) GetAllSpirits(start, end int) ([]model.Spirit, error) { 38 | return []model.Spirit{MockedSpirit}, nil 39 | } 40 | 41 | // GetSpiritsByName returns all spirits by name 42 | func (s *SpiritDAOMock) GetSpiritsByName(name string) ([]model.Spirit, error) { 43 | return []model.Spirit{MockedSpirit}, nil 44 | } 45 | 46 | // GetSpiritsByType returns all spirits by type 47 | func (s *SpiritDAOMock) GetSpiritsByType(spiritType string) ([]model.Spirit, error) { 48 | return []model.Spirit{MockedSpirit}, nil 49 | } 50 | 51 | // GetSpiritsByTypeAndScore returns all spirits by type and score greater than parameter 52 | func (s *SpiritDAOMock) GetSpiritsByTypeAndScore(spiritType string, score uint8) ([]model.Spirit, error) { 53 | return []model.Spirit{MockedSpirit}, nil 54 | } 55 | 56 | // SaveSpirit saves the spirit 57 | func (s *SpiritDAOMock) SaveSpirit(spirit *model.Spirit) error { 58 | return nil 59 | } 60 | 61 | // UpsertSpirit updates or creates a spirit 62 | func (s *SpiritDAOMock) UpsertSpirit(ID string, spirit *model.Spirit) (bool, error) { 63 | return true, nil 64 | } 65 | 66 | // DeleteSpirit deletes a spirits by its ID 67 | func (s *SpiritDAOMock) DeleteSpirit(ID string) error { 68 | return nil 69 | } 70 | -------------------------------------------------------------------------------- /dao/spirit-dao-mongo.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "errors" 5 | logger "github.com/Sirupsen/logrus" 6 | "github.com/sebastienfr/handsongo/model" 7 | "gopkg.in/mgo.v2" 8 | "gopkg.in/mgo.v2/bson" 9 | ) 10 | 11 | const ( 12 | collection = "spirits" 13 | index = "id" 14 | ) 15 | 16 | // SpiritDAOMongo is the mongo implementation of the SpiritDAO 17 | type SpiritDAOMongo struct { 18 | session *mgo.Session 19 | } 20 | 21 | // NewSpiritDAOMongo creates a new SpiritDAO mongo implementation 22 | func NewSpiritDAOMongo(session *mgo.Session) SpiritDAO { 23 | // create index 24 | err := session.DB("").C(collection).EnsureIndex(mgo.Index{ 25 | Key: []string{index}, 26 | Unique: true, 27 | DropDups: true, 28 | Background: true, 29 | Sparse: true, 30 | }) 31 | 32 | if err != nil { 33 | logger.WithField("error", err).Warn("mongo db connection") 34 | } 35 | 36 | return &SpiritDAOMongo{ 37 | session: session, 38 | } 39 | } 40 | 41 | // GetSpiritByID returns a spirit by its ID 42 | func (s *SpiritDAOMongo) GetSpiritByID(ID string) (*model.Spirit, error) { 43 | // check ID 44 | if !bson.IsObjectIdHex(ID) { 45 | return nil, errors.New("Invalid input to ObjectIdHex") 46 | } 47 | 48 | session := s.session.Copy() 49 | defer session.Close() 50 | 51 | spirit := model.Spirit{} 52 | c := session.DB("").C(collection) 53 | err := c.Find(bson.M{"_id": bson.ObjectIdHex(ID)}).One(&spirit) 54 | return &spirit, err 55 | } 56 | 57 | // getAllSpiritsByQuery returns spirits by query and paging capability 58 | func (s *SpiritDAOMongo) getAllSpiritsByQuery(query interface{}, start, end int) ([]model.Spirit, error) { 59 | session := s.session.Copy() 60 | defer session.Close() 61 | c := session.DB("").C(collection) 62 | 63 | // check param 64 | hasPaging := start > -1 && end > -1 && end > start 65 | 66 | // perform request 67 | var err error 68 | spirits := []model.Spirit{} 69 | if hasPaging { 70 | err = c.Find(query).Skip(start).Limit(end - start).All(&spirits) 71 | } else { 72 | err = c.Find(query).All(&spirits) 73 | } 74 | 75 | return spirits, err 76 | } 77 | 78 | // GetAllSpirits returns all spirits with paging capability 79 | func (s *SpiritDAOMongo) GetAllSpirits(start, end int) ([]model.Spirit, error) { 80 | return s.getAllSpiritsByQuery(nil, start, end) 81 | } 82 | 83 | // GetSpiritsByName returns all spirits by name 84 | func (s *SpiritDAOMongo) GetSpiritsByName(name string) ([]model.Spirit, error) { 85 | return s.getAllSpiritsByQuery(bson.M{"name": name}, NoPaging, NoPaging) 86 | } 87 | 88 | // GetSpiritsByType returns all spirits by type 89 | func (s *SpiritDAOMongo) GetSpiritsByType(spiritType string) ([]model.Spirit, error) { 90 | return s.getAllSpiritsByQuery(bson.M{"type": spiritType}, NoPaging, NoPaging) 91 | } 92 | 93 | // GetSpiritsByTypeAndScore returns all spirits by type and score greater than parameter 94 | func (s *SpiritDAOMongo) GetSpiritsByTypeAndScore(spiritType string, score uint8) ([]model.Spirit, error) { 95 | return s.getAllSpiritsByQuery(bson.M{"type": spiritType, "score": bson.M{"$gte": score}}, NoPaging, NoPaging) 96 | } 97 | 98 | // SaveSpirit saves the spirit 99 | func (s *SpiritDAOMongo) SaveSpirit(spirit *model.Spirit) error { 100 | session := s.session.Copy() 101 | defer session.Close() 102 | c := session.DB("").C(collection) 103 | return c.Insert(spirit) 104 | } 105 | 106 | // UpsertSpirit updates or creates a spirit 107 | func (s *SpiritDAOMongo) UpsertSpirit(ID string, spirit *model.Spirit) (bool, error) { 108 | session := s.session.Copy() 109 | defer session.Close() 110 | c := session.DB("").C(collection) 111 | chg, err := c.Upsert(bson.M{"_id": bson.ObjectIdHex(ID)}, spirit) 112 | if err != nil { 113 | return false, err 114 | } 115 | return chg.Updated > 0, err 116 | } 117 | 118 | // DeleteSpirit deletes a spirits by its ID 119 | func (s *SpiritDAOMongo) DeleteSpirit(ID string) error { 120 | session := s.session.Copy() 121 | defer session.Close() 122 | c := session.DB("").C(collection) 123 | err := c.Remove(bson.M{"_id": bson.ObjectIdHex(ID)}) 124 | return err 125 | } 126 | -------------------------------------------------------------------------------- /dao/spirit-dao-mongo_test.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "github.com/sebastienfr/handsongo/model" 5 | "os" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestDAOMongo(t *testing.T) { 11 | // get config 12 | config := os.Getenv("MONGODB_SRV") 13 | 14 | daoMongo, err := GetSpiritDAO(config, DAOMongo) 15 | if err != nil { 16 | t.Error(err) 17 | } 18 | 19 | toSave := model.Spirit{ 20 | Name: "Caroni 2000", 21 | Distiller: "Caroni", 22 | Bottler: "Velier", 23 | Country: "Trinidad", 24 | Composition: "Melasse", 25 | SpiritType: model.TypeRhum, 26 | Age: 15, 27 | BottlingDate: time.Date(2015, 01, 01, 0, 0, 0, 0, time.UTC), 28 | Score: 8.5, 29 | Comment: "heavy tire taste", 30 | } 31 | 32 | err = daoMongo.SaveSpirit(&toSave) 33 | if err != nil { 34 | t.Error(err) 35 | } 36 | 37 | t.Log("initial spirit saved", toSave) 38 | 39 | spirits, err := daoMongo.GetAllSpirits(NoPaging, NoPaging) 40 | if err != nil { 41 | t.Error(err) 42 | } 43 | 44 | t.Log("initial spirit found all", spirits[0]) 45 | 46 | oneSpirit, err := daoMongo.GetSpiritByID(spirits[0].ID.Hex()) 47 | if err != nil { 48 | t.Error(err) 49 | } 50 | 51 | t.Log("initial spirit found one", oneSpirit) 52 | 53 | oneSpirit.Age = 18 54 | oneSpirit.Comment = "soft tarmac smell" 55 | chg, err := daoMongo.UpsertSpirit(oneSpirit.ID.Hex(), oneSpirit) 56 | if err != nil { 57 | t.Error(err) 58 | } 59 | 60 | t.Log("initial spirit modified", chg, oneSpirit) 61 | 62 | oneSpirit, err = daoMongo.GetSpiritByID(oneSpirit.ID.Hex()) 63 | if err != nil { 64 | t.Error(err) 65 | } 66 | 67 | t.Log("initial spirit found one modified", oneSpirit) 68 | 69 | err = daoMongo.DeleteSpirit(oneSpirit.ID.Hex()) 70 | if err != nil { 71 | t.Error(err) 72 | } 73 | 74 | oneSpirit, err = daoMongo.GetSpiritByID(oneSpirit.ID.Hex()) 75 | if err != nil { 76 | t.Log("initial spirit deleted", err, oneSpirit) 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /dao/spirit-dao.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "github.com/sebastienfr/handsongo/model" 5 | ) 6 | 7 | const ( 8 | // NoPaging used with skip, limit parameters 9 | NoPaging = -1 10 | ) 11 | 12 | // SpiritDAO is the DAO interface to work with spirits 13 | type SpiritDAO interface { 14 | 15 | // GetSpiritByID returns a spirit by its ID 16 | GetSpiritByID(ID string) (*model.Spirit, error) 17 | 18 | // GetAllSpirits returns all spirits with paging capability 19 | GetAllSpirits(start, end int) ([]model.Spirit, error) 20 | 21 | // GetSpiritsByName returns all spirits by name 22 | GetSpiritsByName(name string) ([]model.Spirit, error) 23 | 24 | // GetSpiritsByType returns all spirits by type 25 | GetSpiritsByType(spiritType string) ([]model.Spirit, error) 26 | 27 | // GetSpiritsByTypeAndScore returns all spirits by type and score greater than parameter 28 | GetSpiritsByTypeAndScore(spiritType string, score uint8) ([]model.Spirit, error) 29 | 30 | // SaveSpirit saves the spirit 31 | SaveSpirit(spirit *model.Spirit) error 32 | 33 | // UpsertSpirit updates or creates a spirit 34 | UpsertSpirit(ID string, spirit *model.Spirit) (bool, error) 35 | 36 | // DeleteSpirit deletes a spirits by its ID 37 | DeleteSpirit(ID string) error 38 | } 39 | -------------------------------------------------------------------------------- /doc/img/concurrency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastienfr/handsongo/de1cdf56d3491b7645204959b229e40400073dbd/doc/img/concurrency.png -------------------------------------------------------------------------------- /doc/img/gopath_vendor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastienfr/handsongo/de1cdf56d3491b7645204959b229e40400073dbd/doc/img/gopath_vendor.png -------------------------------------------------------------------------------- /doc/img/main_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastienfr/handsongo/de1cdf56d3491b7645204959b229e40400073dbd/doc/img/main_architecture.png -------------------------------------------------------------------------------- /doc/img/web_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastienfr/handsongo/de1cdf56d3491b7645204959b229e40400073dbd/doc/img/web_architecture.png -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | # handsongo micro-service 2 | handsongo: 3 | container_name: handsongo 4 | image: sfeir/handsongo:latest 5 | restart: always 6 | links: 7 | - mongo 8 | ports: 9 | - "8020:8020" 10 | command: /go/bin/handsongo -port 8020 -logl debug -logf text -statd 15s -db mongodb://mongo/spirits 11 | 12 | # bdd mockup 13 | mongo: 14 | container_name: handsongo-mongo 15 | image: mongo:3.2 16 | restart: always 17 | ports: 18 | - "27017:27017" 19 | -------------------------------------------------------------------------------- /etc/apiquery.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #debug 3 | #set -x 4 | 5 | # check if running on osx or linux 6 | IP=127.0.0.1 7 | if [ ! -z "$DOCKER_MACHINE_NAME" ]; then 8 | IP=$(docker-machine ip $DOCKER_MACHINE_NAME) 9 | fi 10 | 11 | echo "Create spirit from file..." 12 | curl -s -X POST -H "Content-Type:application/json" -d @caroni.json ${IP}:8020/spirits | jq 13 | 14 | echo "Query all spirits..." 15 | curl -s ${IP}:8020/spirits | jq 16 | 17 | echo "Retrieve first spirit by ID..." 18 | ID=$(curl -s ${IP}:8020/spirits | jq '.[0]' | jq -r '.id') 19 | 20 | echo "Query one spirit by found ID ${ID}" 21 | curl -s ${IP}:8020/spirits/${ID} | jq 22 | 23 | echo "Update spirit from file..." 24 | curl -s -X PUT -H "Content-Type:application/json" -d @clairin.json ${IP}:8020/spirits/${ID} | jq 25 | 26 | echo "Query one spirit by found ID ${ID} after update" 27 | curl -s ${IP}:8020/spirits/${ID} | jq 28 | 29 | echo "Deleting spirit by ID ${ID}" 30 | curl -X DELETE -H "Content-Type:application/json" ${IP}:8020/spirits/${ID} 31 | -------------------------------------------------------------------------------- /etc/caroni.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Caroni", 3 | "distiller": "Caroni", 4 | "bottler": "Velier", 5 | "country": "Trinidad", 6 | "region": "", 7 | "composition": "Molasse", 8 | "type": "rhum", 9 | "age": 15, 10 | "bottlingDate": "2015-01-01T00:00:00Z", 11 | "score": 8.5, 12 | "comment": "heavy tire taste" 13 | } 14 | -------------------------------------------------------------------------------- /etc/clairin.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Clairin", 3 | "distiller": "Vaval", 4 | "bottler": "Velier", 5 | "country": "Haïti", 6 | "region": "", 7 | "composition": "Cane juice", 8 | "type": "rhum", 9 | "age": 5, 10 | "bottlingDate": "2015-01-01T00:00:00Z", 11 | "score": 8.0, 12 | "comment": "fruity" 13 | } 14 | -------------------------------------------------------------------------------- /model/model.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "gopkg.in/mgo.v2/bson" 5 | "time" 6 | ) 7 | 8 | const ( 9 | // TypeRhum is the constant used for rhum spirits 10 | TypeRhum = "rhum" 11 | // TypeWhine is the constant used for rhum spirits 12 | TypeWhine = "wine" 13 | // TypeBeer is the constant used for rhum spirits 14 | TypeBeer = "beer" 15 | // TypeCalados is the constant used for rhum spirits 16 | TypeCalados = "calvados" 17 | // TypeChampagne is the constant used for rhum spirits 18 | TypeChampagne = "champagne" 19 | // TypeGin is the constant used for rhum spirits 20 | TypeGin = "gin" 21 | ) 22 | 23 | // Spirit is the structure to define a spirit 24 | type Spirit struct { 25 | ID bson.ObjectId `json:"id" bson:"_id,omitempty" ` 26 | Name string `json:"name" bson:"name"` 27 | Distiller string `json:"distiller" bson:"distiller"` 28 | Bottler string `json:"bottler" bson:"bottler"` 29 | Country string `json:"country" bson:"country"` 30 | Region string `json:"region" bson:"region"` 31 | Composition string `json:"composition" bson:"composition"` 32 | SpiritType string `json:"type" bson:"type"` 33 | Age uint8 `json:"age" bson:"age"` 34 | BottlingDate time.Time `json:"bottlingDate" bson:"bottlingDate"` 35 | Score float32 `json:"score" bson:"score"` 36 | Comment string `json:"comment" bson:"comment"` 37 | } 38 | 39 | // GetID returns the ID of an Spirit as a string 40 | func (s *Spirit) GetID() string { 41 | return s.ID.Hex() 42 | } 43 | -------------------------------------------------------------------------------- /utils/logger.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/Sirupsen/logrus" 5 | "github.com/Sirupsen/logrus/formatters/logstash" 6 | "os" 7 | "time" 8 | ) 9 | 10 | const ( 11 | // LogStashFormatter is constant used to format logs as logstash format 12 | LogStashFormatter = "logstash" 13 | // TextFormatter is constant used to format logs as simple text format 14 | TextFormatter = "text" 15 | ) 16 | 17 | // InitLog initializes the logrus logger 18 | func InitLog(logLevel, formatter string) error { 19 | 20 | switch formatter { 21 | case LogStashFormatter: 22 | logrus.SetFormatter(&logstash.LogstashFormatter{ 23 | TimestampFormat: time.RFC3339, 24 | }) 25 | default: 26 | logrus.SetFormatter(&logrus.TextFormatter{ 27 | ForceColors: true, 28 | FullTimestamp: true, 29 | }) 30 | } 31 | 32 | logrus.SetOutput(os.Stdout) 33 | 34 | level, err := logrus.ParseLevel(logLevel) 35 | 36 | if err != nil { 37 | logrus.SetLevel(logrus.DebugLevel) 38 | return err 39 | } 40 | 41 | logrus.SetLevel(level) 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /utils/statistics.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | logger "github.com/Sirupsen/logrus" 6 | "time" 7 | ) 8 | 9 | const ( 10 | statisticsChannelSize = 1000 11 | ) 12 | 13 | // Statistics is the worker to persist the request statistics 14 | type Statistics struct { 15 | statistics chan uint8 16 | counter uint32 17 | start time.Time 18 | loggingPeriod time.Duration 19 | } 20 | 21 | // NewStatistics creates a new statistics structure and launches its worker routine 22 | func NewStatistics(loggingPeriod time.Duration) *Statistics { 23 | sw := Statistics{ 24 | statistics: make(chan uint8, statisticsChannelSize), 25 | counter: 0, 26 | start: time.Now(), 27 | loggingPeriod: loggingPeriod, 28 | } 29 | go sw.run() 30 | return &sw 31 | } 32 | 33 | // PlusOne is used to add one to the counter 34 | func (sw *Statistics) PlusOne() { 35 | sw.statistics <- uint8(1) 36 | } 37 | 38 | func (sw *Statistics) run() { 39 | ticker := time.NewTicker(sw.loggingPeriod) 40 | for { 41 | select { 42 | case stat := <-sw.statistics: 43 | logger.WithField("stat", stat).Debug("new count received") 44 | sw.counter += uint32(stat) 45 | case <-ticker.C: 46 | elapsed := time.Since(sw.start) 47 | logger.WithField("elapsed time", elapsed).WithField("count", sw.counter). 48 | WithField("request per second", fmt.Sprintf("%.2f", float64(sw.counter)/elapsed.Seconds())).Warn("request monitoring") 49 | sw.counter = 0 50 | sw.start = time.Now() 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /utils/statistics_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | const ( 9 | statPeriod = 500 * time.Millisecond 10 | expectedCount = 2 11 | emptyCount = 0 12 | ) 13 | 14 | func TestStatistics(t *testing.T) { 15 | 16 | statistics := NewStatistics(2 * statPeriod) 17 | 18 | // other go routine incrementing the counter 19 | go func() { 20 | statistics.PlusOne() 21 | }() 22 | 23 | // other go routine incrementing the counter 24 | go func() { 25 | statistics.PlusOne() 26 | }() 27 | 28 | time.Sleep(statPeriod) 29 | 30 | if statistics.counter != expectedCount { 31 | t.Errorf("Wrong statictics count %d is different from expected %d", statistics.counter, expectedCount) 32 | } 33 | 34 | time.Sleep(3 * statPeriod) 35 | 36 | if statistics.counter != emptyCount { 37 | t.Errorf("Wrong statictics count %d is different from expected %d", statistics.counter, emptyCount) 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /utils/timetrack.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | log "github.com/Sirupsen/logrus" 5 | "time" 6 | ) 7 | 8 | // TimeTrack is used to log execution times for functions 9 | func TimeTrack(start time.Time, name string) { 10 | elapsed := time.Since(start) 11 | log.WithField("name", name).WithField("elapsed time", elapsed).Debug("time monitoring") 12 | } 13 | -------------------------------------------------------------------------------- /utils/web.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "encoding/json" 5 | logger "github.com/Sirupsen/logrus" 6 | "github.com/gorilla/mux" 7 | "net/http" 8 | ) 9 | 10 | const ( 11 | // ResponseHeaderContentTypeKey is the key used for response content type 12 | ResponseHeaderContentTypeKey = "Content-Type" 13 | // ResponseHeaderContentTypeJSONUTF8 is the key used for UTF8 JSON response 14 | ResponseHeaderContentTypeJSONUTF8 = "application/json; charset=UTF-8" 15 | 16 | resourceNotFound = "Resource not found" 17 | errorMsg = "Error" 18 | ) 19 | 20 | // SendJSONWithHTTPCode outputs JSON with an HTTP code 21 | func SendJSONWithHTTPCode(w http.ResponseWriter, d interface{}, code int) { 22 | w.Header().Set(ResponseHeaderContentTypeKey, ResponseHeaderContentTypeJSONUTF8) 23 | w.WriteHeader(code) 24 | if d != nil { 25 | err := json.NewEncoder(w).Encode(d) 26 | if err != nil { 27 | logger.WithField("body", d).WithField("code", code).Error("error while encoding JSON body of response") 28 | // panic will cause the http.StatusInternalServerError to be send to users 29 | panic(err) 30 | } 31 | } 32 | } 33 | 34 | // SendJSONOk outputs a JSON with http.StatusOK code 35 | func SendJSONOk(w http.ResponseWriter, d interface{}) { 36 | SendJSONWithHTTPCode(w, d, http.StatusOK) 37 | } 38 | 39 | // SendJSONError sends error with a custom message and error code 40 | func SendJSONError(w http.ResponseWriter, error string, code int) { 41 | SendJSONWithHTTPCode(w, map[string]string{errorMsg: error}, code) 42 | } 43 | 44 | // SendJSONNotFound produces a http.StatusNotFound response with the following JSON, '{"Error":"Resource not found"}' 45 | func SendJSONNotFound(w http.ResponseWriter) { 46 | SendJSONError(w, resourceNotFound, http.StatusNotFound) 47 | } 48 | 49 | // NotFoundHandler return a JSON implementation of the not found handler 50 | func NotFoundHandler() http.HandlerFunc { 51 | return func(w http.ResponseWriter, r *http.Request) { 52 | SendJSONNotFound(w) 53 | } 54 | } 55 | 56 | // ParamAsString returns an URL parameter /{name} as a string 57 | func ParamAsString(name string, r *http.Request) string { 58 | vars := mux.Vars(r) 59 | value := vars[name] 60 | return value 61 | } 62 | 63 | // GetJSONContent returns the JSON content of a request 64 | func GetJSONContent(v interface{}, r *http.Request) error { 65 | defer r.Body.Close() 66 | return json.NewDecoder(r.Body).Decode(v) 67 | } 68 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/.gitignore: -------------------------------------------------------------------------------- 1 | logrus 2 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.3 4 | - 1.4 5 | - 1.5 6 | - 1.6 7 | - tip 8 | install: 9 | - go get -t ./... 10 | script: GOMAXPROCS=4 GORACE="halt_on_error=1" go test -race -v ./... 11 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.10.0 2 | 3 | * feature: Add a test hook (#180) 4 | * feature: `ParseLevel` is now case-insensitive (#326) 5 | * feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308) 6 | * performance: avoid re-allocations on `WithFields` (#335) 7 | 8 | # 0.9.0 9 | 10 | * logrus/text_formatter: don't emit empty msg 11 | * logrus/hooks/airbrake: move out of main repository 12 | * logrus/hooks/sentry: move out of main repository 13 | * logrus/hooks/papertrail: move out of main repository 14 | * logrus/hooks/bugsnag: move out of main repository 15 | * logrus/core: run tests with `-race` 16 | * logrus/core: detect TTY based on `stderr` 17 | * logrus/core: support `WithError` on logger 18 | * logrus/core: Solaris support 19 | 20 | # 0.8.7 21 | 22 | * logrus/core: fix possible race (#216) 23 | * logrus/doc: small typo fixes and doc improvements 24 | 25 | 26 | # 0.8.6 27 | 28 | * hooks/raven: allow passing an initialized client 29 | 30 | # 0.8.5 31 | 32 | * logrus/core: revert #208 33 | 34 | # 0.8.4 35 | 36 | * formatter/text: fix data race (#218) 37 | 38 | # 0.8.3 39 | 40 | * logrus/core: fix entry log level (#208) 41 | * logrus/core: improve performance of text formatter by 40% 42 | * logrus/core: expose `LevelHooks` type 43 | * logrus/core: add support for DragonflyBSD and NetBSD 44 | * formatter/text: print structs more verbosely 45 | 46 | # 0.8.2 47 | 48 | * logrus: fix more Fatal family functions 49 | 50 | # 0.8.1 51 | 52 | * logrus: fix not exiting on `Fatalf` and `Fatalln` 53 | 54 | # 0.8.0 55 | 56 | * logrus: defaults to stderr instead of stdout 57 | * hooks/sentry: add special field for `*http.Request` 58 | * formatter/text: ignore Windows for colors 59 | 60 | # 0.7.3 61 | 62 | * formatter/\*: allow configuration of timestamp layout 63 | 64 | # 0.7.2 65 | 66 | * formatter/text: Add configuration option for time format (#158) 67 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Simon Eskildsen 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package logrus is a structured logger for Go, completely API compatible with the standard library logger. 3 | 4 | 5 | The simplest way to use Logrus is simply the package-level exported logger: 6 | 7 | package main 8 | 9 | import ( 10 | log "github.com/Sirupsen/logrus" 11 | ) 12 | 13 | func main() { 14 | log.WithFields(log.Fields{ 15 | "animal": "walrus", 16 | "number": 1, 17 | "size": 10, 18 | }).Info("A walrus appears") 19 | } 20 | 21 | Output: 22 | time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 23 | 24 | For a full guide visit https://github.com/Sirupsen/logrus 25 | */ 26 | package logrus 27 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/formatter.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import "time" 4 | 5 | const DefaultTimestampFormat = time.RFC3339 6 | 7 | // The Formatter interface is used to implement a custom Formatter. It takes an 8 | // `Entry`. It exposes all the fields, including the default ones: 9 | // 10 | // * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. 11 | // * `entry.Data["time"]`. The timestamp. 12 | // * `entry.Data["level"]. The level the entry was logged at. 13 | // 14 | // Any additional fields added with `WithField` or `WithFields` are also in 15 | // `entry.Data`. Format is expected to return an array of bytes which are then 16 | // logged to `logger.Out`. 17 | type Formatter interface { 18 | Format(*Entry) ([]byte, error) 19 | } 20 | 21 | // This is to not silently overwrite `time`, `msg` and `level` fields when 22 | // dumping it. If this code wasn't there doing: 23 | // 24 | // logrus.WithField("level", 1).Info("hello") 25 | // 26 | // Would just silently drop the user provided level. Instead with this code 27 | // it'll logged as: 28 | // 29 | // {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} 30 | // 31 | // It's not exported because it's still using Data in an opinionated way. It's to 32 | // avoid code duplication between the two default formatters. 33 | func prefixFieldClashes(data Fields) { 34 | if t, ok := data["time"]; ok { 35 | data["fields.time"] = t 36 | } 37 | 38 | if m, ok := data["msg"]; ok { 39 | data["fields.msg"] = m 40 | } 41 | 42 | if l, ok := data["level"]; ok { 43 | data["fields.level"] = l 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go: -------------------------------------------------------------------------------- 1 | package logstash 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | 7 | "github.com/Sirupsen/logrus" 8 | ) 9 | 10 | // Formatter generates json in logstash format. 11 | // Logstash site: http://logstash.net/ 12 | type LogstashFormatter struct { 13 | Type string // if not empty use for logstash type field. 14 | 15 | // TimestampFormat sets the format used for timestamps. 16 | TimestampFormat string 17 | } 18 | 19 | func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) { 20 | fields := make(logrus.Fields) 21 | for k, v := range entry.Data { 22 | fields[k] = v 23 | } 24 | 25 | fields["@version"] = 1 26 | 27 | timeStampFormat := f.TimestampFormat 28 | 29 | if timeStampFormat == "" { 30 | timeStampFormat = logrus.DefaultTimestampFormat 31 | } 32 | 33 | fields["@timestamp"] = entry.Time.Format(timeStampFormat) 34 | 35 | // set message field 36 | v, ok := entry.Data["message"] 37 | if ok { 38 | fields["fields.message"] = v 39 | } 40 | fields["message"] = entry.Message 41 | 42 | // set level field 43 | v, ok = entry.Data["level"] 44 | if ok { 45 | fields["fields.level"] = v 46 | } 47 | fields["level"] = entry.Level.String() 48 | 49 | // set type field 50 | if f.Type != "" { 51 | v, ok = entry.Data["type"] 52 | if ok { 53 | fields["fields.type"] = v 54 | } 55 | fields["type"] = f.Type 56 | } 57 | 58 | serialized, err := json.Marshal(fields) 59 | if err != nil { 60 | return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) 61 | } 62 | return append(serialized, '\n'), nil 63 | } 64 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/hooks.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | // A hook to be fired when logging on the logging levels returned from 4 | // `Levels()` on your implementation of the interface. Note that this is not 5 | // fired in a goroutine or a channel with workers, you should handle such 6 | // functionality yourself if your call is non-blocking and you don't wish for 7 | // the logging calls for levels returned from `Levels()` to block. 8 | type Hook interface { 9 | Levels() []Level 10 | Fire(*Entry) error 11 | } 12 | 13 | // Internal type for storing the hooks on a logger instance. 14 | type LevelHooks map[Level][]Hook 15 | 16 | // Add a hook to an instance of logger. This is called with 17 | // `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface. 18 | func (hooks LevelHooks) Add(hook Hook) { 19 | for _, level := range hook.Levels() { 20 | hooks[level] = append(hooks[level], hook) 21 | } 22 | } 23 | 24 | // Fire all the hooks for the passed level. Used by `entry.log` to fire 25 | // appropriate hooks for a log entry. 26 | func (hooks LevelHooks) Fire(level Level, entry *Entry) error { 27 | for _, hook := range hooks[level] { 28 | if err := hook.Fire(entry); err != nil { 29 | return err 30 | } 31 | } 32 | 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/json_formatter.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | type JSONFormatter struct { 9 | // TimestampFormat sets the format used for marshaling timestamps. 10 | TimestampFormat string 11 | } 12 | 13 | func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { 14 | data := make(Fields, len(entry.Data)+3) 15 | for k, v := range entry.Data { 16 | switch v := v.(type) { 17 | case error: 18 | // Otherwise errors are ignored by `encoding/json` 19 | // https://github.com/Sirupsen/logrus/issues/137 20 | data[k] = v.Error() 21 | default: 22 | data[k] = v 23 | } 24 | } 25 | prefixFieldClashes(data) 26 | 27 | timestampFormat := f.TimestampFormat 28 | if timestampFormat == "" { 29 | timestampFormat = DefaultTimestampFormat 30 | } 31 | 32 | data["time"] = entry.Time.Format(timestampFormat) 33 | data["msg"] = entry.Message 34 | data["level"] = entry.Level.String() 35 | 36 | serialized, err := json.Marshal(data) 37 | if err != nil { 38 | return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) 39 | } 40 | return append(serialized, '\n'), nil 41 | } 42 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/logrus.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "strings" 7 | ) 8 | 9 | // Fields type, used to pass to `WithFields`. 10 | type Fields map[string]interface{} 11 | 12 | // Level type 13 | type Level uint8 14 | 15 | // Convert the Level to a string. E.g. PanicLevel becomes "panic". 16 | func (level Level) String() string { 17 | switch level { 18 | case DebugLevel: 19 | return "debug" 20 | case InfoLevel: 21 | return "info" 22 | case WarnLevel: 23 | return "warning" 24 | case ErrorLevel: 25 | return "error" 26 | case FatalLevel: 27 | return "fatal" 28 | case PanicLevel: 29 | return "panic" 30 | } 31 | 32 | return "unknown" 33 | } 34 | 35 | // ParseLevel takes a string level and returns the Logrus log level constant. 36 | func ParseLevel(lvl string) (Level, error) { 37 | switch strings.ToLower(lvl) { 38 | case "panic": 39 | return PanicLevel, nil 40 | case "fatal": 41 | return FatalLevel, nil 42 | case "error": 43 | return ErrorLevel, nil 44 | case "warn", "warning": 45 | return WarnLevel, nil 46 | case "info": 47 | return InfoLevel, nil 48 | case "debug": 49 | return DebugLevel, nil 50 | } 51 | 52 | var l Level 53 | return l, fmt.Errorf("not a valid logrus Level: %q", lvl) 54 | } 55 | 56 | // A constant exposing all logging levels 57 | var AllLevels = []Level{ 58 | PanicLevel, 59 | FatalLevel, 60 | ErrorLevel, 61 | WarnLevel, 62 | InfoLevel, 63 | DebugLevel, 64 | } 65 | 66 | // These are the different logging levels. You can set the logging level to log 67 | // on your instance of logger, obtained with `logrus.New()`. 68 | const ( 69 | // PanicLevel level, highest level of severity. Logs and then calls panic with the 70 | // message passed to Debug, Info, ... 71 | PanicLevel Level = iota 72 | // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the 73 | // logging level is set to Panic. 74 | FatalLevel 75 | // ErrorLevel level. Logs. Used for errors that should definitely be noted. 76 | // Commonly used for hooks to send errors to an error tracking service. 77 | ErrorLevel 78 | // WarnLevel level. Non-critical entries that deserve eyes. 79 | WarnLevel 80 | // InfoLevel level. General operational entries about what's going on inside the 81 | // application. 82 | InfoLevel 83 | // DebugLevel level. Usually only enabled when debugging. Very verbose logging. 84 | DebugLevel 85 | ) 86 | 87 | // Won't compile if StdLogger can't be realized by a log.Logger 88 | var ( 89 | _ StdLogger = &log.Logger{} 90 | _ StdLogger = &Entry{} 91 | _ StdLogger = &Logger{} 92 | ) 93 | 94 | // StdLogger is what your logrus-enabled library should take, that way 95 | // it'll accept a stdlib logger and a logrus logger. There's no standard 96 | // interface, this is the closest we get, unfortunately. 97 | type StdLogger interface { 98 | Print(...interface{}) 99 | Printf(string, ...interface{}) 100 | Println(...interface{}) 101 | 102 | Fatal(...interface{}) 103 | Fatalf(string, ...interface{}) 104 | Fatalln(...interface{}) 105 | 106 | Panic(...interface{}) 107 | Panicf(string, ...interface{}) 108 | Panicln(...interface{}) 109 | } 110 | 111 | // The FieldLogger interface generalizes the Entry and Logger types 112 | type FieldLogger interface { 113 | WithField(key string, value interface{}) *Entry 114 | WithFields(fields Fields) *Entry 115 | WithError(err error) *Entry 116 | 117 | Debugf(format string, args ...interface{}) 118 | Infof(format string, args ...interface{}) 119 | Printf(format string, args ...interface{}) 120 | Warnf(format string, args ...interface{}) 121 | Warningf(format string, args ...interface{}) 122 | Errorf(format string, args ...interface{}) 123 | Fatalf(format string, args ...interface{}) 124 | Panicf(format string, args ...interface{}) 125 | 126 | Debug(args ...interface{}) 127 | Info(args ...interface{}) 128 | Print(args ...interface{}) 129 | Warn(args ...interface{}) 130 | Warning(args ...interface{}) 131 | Error(args ...interface{}) 132 | Fatal(args ...interface{}) 133 | Panic(args ...interface{}) 134 | 135 | Debugln(args ...interface{}) 136 | Infoln(args ...interface{}) 137 | Println(args ...interface{}) 138 | Warnln(args ...interface{}) 139 | Warningln(args ...interface{}) 140 | Errorln(args ...interface{}) 141 | Fatalln(args ...interface{}) 142 | Panicln(args ...interface{}) 143 | } 144 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/terminal_bsd.go: -------------------------------------------------------------------------------- 1 | // +build darwin freebsd openbsd netbsd dragonfly 2 | 3 | package logrus 4 | 5 | import "syscall" 6 | 7 | const ioctlReadTermios = syscall.TIOCGETA 8 | 9 | type Termios syscall.Termios 10 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/terminal_linux.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2013 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package logrus 7 | 8 | import "syscall" 9 | 10 | const ioctlReadTermios = syscall.TCGETS 11 | 12 | type Termios syscall.Termios 13 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/terminal_notwindows.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2011 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // +build linux darwin freebsd openbsd netbsd dragonfly 7 | 8 | package logrus 9 | 10 | import ( 11 | "syscall" 12 | "unsafe" 13 | ) 14 | 15 | // IsTerminal returns true if stderr's file descriptor is a terminal. 16 | func IsTerminal() bool { 17 | fd := syscall.Stderr 18 | var termios Termios 19 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) 20 | return err == 0 21 | } 22 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/terminal_solaris.go: -------------------------------------------------------------------------------- 1 | // +build solaris 2 | 3 | package logrus 4 | 5 | import ( 6 | "os" 7 | 8 | "golang.org/x/sys/unix" 9 | ) 10 | 11 | // IsTerminal returns true if the given file descriptor is a terminal. 12 | func IsTerminal() bool { 13 | _, err := unix.IoctlGetTermios(int(os.Stdout.Fd()), unix.TCGETA) 14 | return err == nil 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/terminal_windows.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2011 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // +build windows 7 | 8 | package logrus 9 | 10 | import ( 11 | "syscall" 12 | "unsafe" 13 | ) 14 | 15 | var kernel32 = syscall.NewLazyDLL("kernel32.dll") 16 | 17 | var ( 18 | procGetConsoleMode = kernel32.NewProc("GetConsoleMode") 19 | ) 20 | 21 | // IsTerminal returns true if stderr's file descriptor is a terminal. 22 | func IsTerminal() bool { 23 | fd := syscall.Stderr 24 | var st uint32 25 | r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) 26 | return r != 0 && e == 0 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/text_formatter.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "runtime" 7 | "sort" 8 | "strings" 9 | "time" 10 | ) 11 | 12 | const ( 13 | nocolor = 0 14 | red = 31 15 | green = 32 16 | yellow = 33 17 | blue = 34 18 | gray = 37 19 | ) 20 | 21 | var ( 22 | baseTimestamp time.Time 23 | isTerminal bool 24 | ) 25 | 26 | func init() { 27 | baseTimestamp = time.Now() 28 | isTerminal = IsTerminal() 29 | } 30 | 31 | func miniTS() int { 32 | return int(time.Since(baseTimestamp) / time.Second) 33 | } 34 | 35 | type TextFormatter struct { 36 | // Set to true to bypass checking for a TTY before outputting colors. 37 | ForceColors bool 38 | 39 | // Force disabling colors. 40 | DisableColors bool 41 | 42 | // Disable timestamp logging. useful when output is redirected to logging 43 | // system that already adds timestamps. 44 | DisableTimestamp bool 45 | 46 | // Enable logging the full timestamp when a TTY is attached instead of just 47 | // the time passed since beginning of execution. 48 | FullTimestamp bool 49 | 50 | // TimestampFormat to use for display when a full timestamp is printed 51 | TimestampFormat string 52 | 53 | // The fields are sorted by default for a consistent output. For applications 54 | // that log extremely frequently and don't use the JSON formatter this may not 55 | // be desired. 56 | DisableSorting bool 57 | } 58 | 59 | func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { 60 | var keys []string = make([]string, 0, len(entry.Data)) 61 | for k := range entry.Data { 62 | keys = append(keys, k) 63 | } 64 | 65 | if !f.DisableSorting { 66 | sort.Strings(keys) 67 | } 68 | 69 | b := &bytes.Buffer{} 70 | 71 | prefixFieldClashes(entry.Data) 72 | 73 | isColorTerminal := isTerminal && (runtime.GOOS != "windows") 74 | isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors 75 | 76 | timestampFormat := f.TimestampFormat 77 | if timestampFormat == "" { 78 | timestampFormat = DefaultTimestampFormat 79 | } 80 | if isColored { 81 | f.printColored(b, entry, keys, timestampFormat) 82 | } else { 83 | if !f.DisableTimestamp { 84 | f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat)) 85 | } 86 | f.appendKeyValue(b, "level", entry.Level.String()) 87 | if entry.Message != "" { 88 | f.appendKeyValue(b, "msg", entry.Message) 89 | } 90 | for _, key := range keys { 91 | f.appendKeyValue(b, key, entry.Data[key]) 92 | } 93 | } 94 | 95 | b.WriteByte('\n') 96 | return b.Bytes(), nil 97 | } 98 | 99 | func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) { 100 | var levelColor int 101 | switch entry.Level { 102 | case DebugLevel: 103 | levelColor = gray 104 | case WarnLevel: 105 | levelColor = yellow 106 | case ErrorLevel, FatalLevel, PanicLevel: 107 | levelColor = red 108 | default: 109 | levelColor = blue 110 | } 111 | 112 | levelText := strings.ToUpper(entry.Level.String())[0:4] 113 | 114 | if !f.FullTimestamp { 115 | fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message) 116 | } else { 117 | fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message) 118 | } 119 | for _, k := range keys { 120 | v := entry.Data[k] 121 | fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%+v", levelColor, k, v) 122 | } 123 | } 124 | 125 | func needsQuoting(text string) bool { 126 | for _, ch := range text { 127 | if !((ch >= 'a' && ch <= 'z') || 128 | (ch >= 'A' && ch <= 'Z') || 129 | (ch >= '0' && ch <= '9') || 130 | ch == '-' || ch == '.') { 131 | return true 132 | } 133 | } 134 | return false 135 | } 136 | 137 | func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { 138 | 139 | b.WriteString(key) 140 | b.WriteByte('=') 141 | 142 | switch value := value.(type) { 143 | case string: 144 | if !needsQuoting(value) { 145 | b.WriteString(value) 146 | } else { 147 | fmt.Fprintf(b, "%q", value) 148 | } 149 | case error: 150 | errmsg := value.Error() 151 | if !needsQuoting(errmsg) { 152 | b.WriteString(errmsg) 153 | } else { 154 | fmt.Fprintf(b, "%q", value) 155 | } 156 | default: 157 | fmt.Fprint(b, value) 158 | } 159 | 160 | b.WriteByte(' ') 161 | } 162 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/writer.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bufio" 5 | "io" 6 | "runtime" 7 | ) 8 | 9 | func (logger *Logger) Writer() *io.PipeWriter { 10 | return logger.WriterLevel(InfoLevel) 11 | } 12 | 13 | func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { 14 | reader, writer := io.Pipe() 15 | 16 | var printFunc func(args ...interface{}) 17 | switch level { 18 | case DebugLevel: 19 | printFunc = logger.Debug 20 | case InfoLevel: 21 | printFunc = logger.Info 22 | case WarnLevel: 23 | printFunc = logger.Warn 24 | case ErrorLevel: 25 | printFunc = logger.Error 26 | case FatalLevel: 27 | printFunc = logger.Fatal 28 | case PanicLevel: 29 | printFunc = logger.Panic 30 | default: 31 | printFunc = logger.Print 32 | } 33 | 34 | go logger.writerScanner(reader, printFunc) 35 | runtime.SetFinalizer(writer, writerFinalizer) 36 | 37 | return writer 38 | } 39 | 40 | func (logger *Logger) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { 41 | scanner := bufio.NewScanner(reader) 42 | for scanner.Scan() { 43 | printFunc(scanner.Text()) 44 | } 45 | if err := scanner.Err(); err != nil { 46 | logger.Errorf("Error while reading from Writer: %s", err) 47 | } 48 | reader.Close() 49 | } 50 | 51 | func writerFinalizer(writer *io.PipeWriter) { 52 | writer.Close() 53 | } 54 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/context/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | 4 | matrix: 5 | include: 6 | - go: 1.3 7 | - go: 1.4 8 | - go: 1.5 9 | - go: 1.6 10 | - go: tip 11 | 12 | install: 13 | - go get golang.org/x/tools/cmd/vet 14 | 15 | script: 16 | - go get -t -v ./... 17 | - diff -u <(echo -n) <(gofmt -d .) 18 | - go tool vet . 19 | - go test -v -race ./... 20 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/context/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Rodrigo Moraes. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/context/README.md: -------------------------------------------------------------------------------- 1 | context 2 | ======= 3 | [![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context) 4 | 5 | gorilla/context is a general purpose registry for global request variables. 6 | 7 | Read the full documentation here: http://www.gorillatoolkit.org/pkg/context 8 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/context/context.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Gorilla Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package context 6 | 7 | import ( 8 | "net/http" 9 | "sync" 10 | "time" 11 | ) 12 | 13 | var ( 14 | mutex sync.RWMutex 15 | data = make(map[*http.Request]map[interface{}]interface{}) 16 | datat = make(map[*http.Request]int64) 17 | ) 18 | 19 | // Set stores a value for a given key in a given request. 20 | func Set(r *http.Request, key, val interface{}) { 21 | mutex.Lock() 22 | if data[r] == nil { 23 | data[r] = make(map[interface{}]interface{}) 24 | datat[r] = time.Now().Unix() 25 | } 26 | data[r][key] = val 27 | mutex.Unlock() 28 | } 29 | 30 | // Get returns a value stored for a given key in a given request. 31 | func Get(r *http.Request, key interface{}) interface{} { 32 | mutex.RLock() 33 | if ctx := data[r]; ctx != nil { 34 | value := ctx[key] 35 | mutex.RUnlock() 36 | return value 37 | } 38 | mutex.RUnlock() 39 | return nil 40 | } 41 | 42 | // GetOk returns stored value and presence state like multi-value return of map access. 43 | func GetOk(r *http.Request, key interface{}) (interface{}, bool) { 44 | mutex.RLock() 45 | if _, ok := data[r]; ok { 46 | value, ok := data[r][key] 47 | mutex.RUnlock() 48 | return value, ok 49 | } 50 | mutex.RUnlock() 51 | return nil, false 52 | } 53 | 54 | // GetAll returns all stored values for the request as a map. Nil is returned for invalid requests. 55 | func GetAll(r *http.Request) map[interface{}]interface{} { 56 | mutex.RLock() 57 | if context, ok := data[r]; ok { 58 | result := make(map[interface{}]interface{}, len(context)) 59 | for k, v := range context { 60 | result[k] = v 61 | } 62 | mutex.RUnlock() 63 | return result 64 | } 65 | mutex.RUnlock() 66 | return nil 67 | } 68 | 69 | // GetAllOk returns all stored values for the request as a map and a boolean value that indicates if 70 | // the request was registered. 71 | func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) { 72 | mutex.RLock() 73 | context, ok := data[r] 74 | result := make(map[interface{}]interface{}, len(context)) 75 | for k, v := range context { 76 | result[k] = v 77 | } 78 | mutex.RUnlock() 79 | return result, ok 80 | } 81 | 82 | // Delete removes a value stored for a given key in a given request. 83 | func Delete(r *http.Request, key interface{}) { 84 | mutex.Lock() 85 | if data[r] != nil { 86 | delete(data[r], key) 87 | } 88 | mutex.Unlock() 89 | } 90 | 91 | // Clear removes all values stored for a given request. 92 | // 93 | // This is usually called by a handler wrapper to clean up request 94 | // variables at the end of a request lifetime. See ClearHandler(). 95 | func Clear(r *http.Request) { 96 | mutex.Lock() 97 | clear(r) 98 | mutex.Unlock() 99 | } 100 | 101 | // clear is Clear without the lock. 102 | func clear(r *http.Request) { 103 | delete(data, r) 104 | delete(datat, r) 105 | } 106 | 107 | // Purge removes request data stored for longer than maxAge, in seconds. 108 | // It returns the amount of requests removed. 109 | // 110 | // If maxAge <= 0, all request data is removed. 111 | // 112 | // This is only used for sanity check: in case context cleaning was not 113 | // properly set some request data can be kept forever, consuming an increasing 114 | // amount of memory. In case this is detected, Purge() must be called 115 | // periodically until the problem is fixed. 116 | func Purge(maxAge int) int { 117 | mutex.Lock() 118 | count := 0 119 | if maxAge <= 0 { 120 | count = len(data) 121 | data = make(map[*http.Request]map[interface{}]interface{}) 122 | datat = make(map[*http.Request]int64) 123 | } else { 124 | min := time.Now().Unix() - int64(maxAge) 125 | for r := range data { 126 | if datat[r] < min { 127 | clear(r) 128 | count++ 129 | } 130 | } 131 | } 132 | mutex.Unlock() 133 | return count 134 | } 135 | 136 | // ClearHandler wraps an http.Handler and clears request values at the end 137 | // of a request lifetime. 138 | func ClearHandler(h http.Handler) http.Handler { 139 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 140 | defer Clear(r) 141 | h.ServeHTTP(w, r) 142 | }) 143 | } 144 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/context/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Gorilla Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package context stores values shared during a request lifetime. 7 | 8 | For example, a router can set variables extracted from the URL and later 9 | application handlers can access those values, or it can be used to store 10 | sessions values to be saved at the end of a request. There are several 11 | others common uses. 12 | 13 | The idea was posted by Brad Fitzpatrick to the go-nuts mailing list: 14 | 15 | http://groups.google.com/group/golang-nuts/msg/e2d679d303aa5d53 16 | 17 | Here's the basic usage: first define the keys that you will need. The key 18 | type is interface{} so a key can be of any type that supports equality. 19 | Here we define a key using a custom int type to avoid name collisions: 20 | 21 | package foo 22 | 23 | import ( 24 | "github.com/gorilla/context" 25 | ) 26 | 27 | type key int 28 | 29 | const MyKey key = 0 30 | 31 | Then set a variable. Variables are bound to an http.Request object, so you 32 | need a request instance to set a value: 33 | 34 | context.Set(r, MyKey, "bar") 35 | 36 | The application can later access the variable using the same key you provided: 37 | 38 | func MyHandler(w http.ResponseWriter, r *http.Request) { 39 | // val is "bar". 40 | val := context.Get(r, foo.MyKey) 41 | 42 | // returns ("bar", true) 43 | val, ok := context.GetOk(r, foo.MyKey) 44 | // ... 45 | } 46 | 47 | And that's all about the basic usage. We discuss some other ideas below. 48 | 49 | Any type can be stored in the context. To enforce a given type, make the key 50 | private and wrap Get() and Set() to accept and return values of a specific 51 | type: 52 | 53 | type key int 54 | 55 | const mykey key = 0 56 | 57 | // GetMyKey returns a value for this package from the request values. 58 | func GetMyKey(r *http.Request) SomeType { 59 | if rv := context.Get(r, mykey); rv != nil { 60 | return rv.(SomeType) 61 | } 62 | return nil 63 | } 64 | 65 | // SetMyKey sets a value for this package in the request values. 66 | func SetMyKey(r *http.Request, val SomeType) { 67 | context.Set(r, mykey, val) 68 | } 69 | 70 | Variables must be cleared at the end of a request, to remove all values 71 | that were stored. This can be done in an http.Handler, after a request was 72 | served. Just call Clear() passing the request: 73 | 74 | context.Clear(r) 75 | 76 | ...or use ClearHandler(), which conveniently wraps an http.Handler to clear 77 | variables at the end of a request lifetime. 78 | 79 | The Routers from the packages gorilla/mux and gorilla/pat call Clear() 80 | so if you are using either of them you don't need to clear the context manually. 81 | */ 82 | package context 83 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/mux/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | 4 | matrix: 5 | include: 6 | - go: 1.2 7 | - go: 1.3 8 | - go: 1.4 9 | - go: 1.5 10 | - go: 1.6 11 | - go: tip 12 | 13 | install: 14 | - go get golang.org/x/tools/cmd/vet 15 | 16 | script: 17 | - go get -t -v ./... 18 | - diff -u <(echo -n) <(gofmt -d .) 19 | - go tool vet . 20 | - go test -v -race ./... 21 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/mux/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Rodrigo Moraes. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/meatballhat/negroni-logrus/.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 | *coverprofile 25 | -------------------------------------------------------------------------------- /vendor/github.com/meatballhat/negroni-logrus/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | go: 4 | - 1.5 5 | - 1.6 6 | - tip 7 | before_install: 8 | - go get -u golang.org/x/tools/cmd/cover 9 | - go get -u github.com/alecthomas/gometalinter 10 | - gometalinter --install --update 11 | script: 12 | - gometalinter --deadline=1m . 13 | - go test -v -coverprofile=package.coverprofile 14 | - go tool cover -func=package.coverprofile 15 | -------------------------------------------------------------------------------- /vendor/github.com/meatballhat/negroni-logrus/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Dan Buch 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. -------------------------------------------------------------------------------- /vendor/github.com/meatballhat/negroni-logrus/README.md: -------------------------------------------------------------------------------- 1 | negroni-logrus 2 | ============== 3 | 4 | [![GoDoc](https://godoc.org/github.com/meatballhat/negroni-logrus?status.svg)](https://godoc.org/github.com/meatballhat/negroni-logrus) 5 | [![Build Status](https://travis-ci.org/meatballhat/negroni-logrus.svg?branch=master)](https://travis-ci.org/meatballhat/negroni-logrus) 6 | 7 | logrus middleware for negroni 8 | 9 | ## Usage 10 | 11 | Take a peek at the [basic example](./examples/basic/example.go) or the [custom 12 | example](./examples/custom/example.go), the latter of which includes setting a 13 | custom log level on the logger with `NewCustomMiddleware`. 14 | 15 | If you want to reuse an already initialized `logrus.Logger`, you should be using 16 | `NewMiddlewareFromLogger` (see [existinglogrus](./examples/existinglogrus/example.go)). 17 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/cli/.gitignore: -------------------------------------------------------------------------------- 1 | *.coverprofile 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/cli/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | sudo: false 4 | 5 | cache: 6 | directories: 7 | - node_modules 8 | 9 | go: 10 | - 1.2.2 11 | - 1.3.3 12 | - 1.4 13 | - 1.5.4 14 | - 1.6.2 15 | - master 16 | 17 | matrix: 18 | allow_failures: 19 | - go: master 20 | include: 21 | - go: 1.6.2 22 | os: osx 23 | - go: 1.1.2 24 | install: go get -v . 25 | before_script: echo skipping gfmxr on $TRAVIS_GO_VERSION 26 | script: 27 | - ./runtests vet 28 | - ./runtests test 29 | 30 | before_script: 31 | - go get github.com/urfave/gfmxr/... 32 | - if [ ! -f node_modules/.bin/markdown-toc ] ; then 33 | npm install markdown-toc ; 34 | fi 35 | 36 | script: 37 | - ./runtests vet 38 | - ./runtests test 39 | - ./runtests gfmxr 40 | - ./runtests toc 41 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/cli/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 Jeremy Saenz 2 | All Rights Reserved. 3 | 4 | MIT LICENSE 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/cli/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: "{build}" 2 | 3 | os: Windows Server 2012 R2 4 | 5 | clone_folder: c:\gopath\src\github.com\urfave\cli 6 | 7 | environment: 8 | GOPATH: C:\gopath 9 | GOVERSION: 1.6 10 | PYTHON: C:\Python27-x64 11 | PYTHON_VERSION: 2.7.x 12 | PYTHON_ARCH: 64 13 | GFMXR_DEBUG: 1 14 | 15 | install: 16 | - set PATH=%GOPATH%\bin;C:\go\bin;%PATH% 17 | - go version 18 | - go env 19 | - go get github.com/urfave/gfmxr/... 20 | - go get -v -t ./... 21 | 22 | build_script: 23 | - python runtests vet 24 | - python runtests test 25 | - python runtests gfmxr 26 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/cli/category.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | // CommandCategories is a slice of *CommandCategory. 4 | type CommandCategories []*CommandCategory 5 | 6 | // CommandCategory is a category containing commands. 7 | type CommandCategory struct { 8 | Name string 9 | Commands Commands 10 | } 11 | 12 | func (c CommandCategories) Less(i, j int) bool { 13 | return c[i].Name < c[j].Name 14 | } 15 | 16 | func (c CommandCategories) Len() int { 17 | return len(c) 18 | } 19 | 20 | func (c CommandCategories) Swap(i, j int) { 21 | c[i], c[j] = c[j], c[i] 22 | } 23 | 24 | // AddCommand adds a command to a category. 25 | func (c CommandCategories) AddCommand(category string, command Command) CommandCategories { 26 | for _, commandCategory := range c { 27 | if commandCategory.Name == category { 28 | commandCategory.Commands = append(commandCategory.Commands, command) 29 | return c 30 | } 31 | } 32 | return append(c, &CommandCategory{Name: category, Commands: []Command{command}}) 33 | } 34 | 35 | // VisibleCommands returns a slice of the Commands with Hidden=false 36 | func (c *CommandCategory) VisibleCommands() []Command { 37 | ret := []Command{} 38 | for _, command := range c.Commands { 39 | if !command.Hidden { 40 | ret = append(ret, command) 41 | } 42 | } 43 | return ret 44 | } 45 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/cli/cli.go: -------------------------------------------------------------------------------- 1 | // Package cli provides a minimal framework for creating and organizing command line 2 | // Go applications. cli is designed to be easy to understand and write, the most simple 3 | // cli application can be written as follows: 4 | // func main() { 5 | // cli.NewApp().Run(os.Args) 6 | // } 7 | // 8 | // Of course this application does not do much, so let's make this an actual application: 9 | // func main() { 10 | // app := cli.NewApp() 11 | // app.Name = "greet" 12 | // app.Usage = "say a greeting" 13 | // app.Action = func(c *cli.Context) error { 14 | // println("Greetings") 15 | // } 16 | // 17 | // app.Run(os.Args) 18 | // } 19 | package cli 20 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/cli/errors.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | // OsExiter is the function used when the app exits. If not set defaults to os.Exit. 11 | var OsExiter = os.Exit 12 | 13 | // ErrWriter is used to write errors to the user. This can be anything 14 | // implementing the io.Writer interface and defaults to os.Stderr. 15 | var ErrWriter io.Writer = os.Stderr 16 | 17 | // MultiError is an error that wraps multiple errors. 18 | type MultiError struct { 19 | Errors []error 20 | } 21 | 22 | // NewMultiError creates a new MultiError. Pass in one or more errors. 23 | func NewMultiError(err ...error) MultiError { 24 | return MultiError{Errors: err} 25 | } 26 | 27 | // Error implents the error interface. 28 | func (m MultiError) Error() string { 29 | errs := make([]string, len(m.Errors)) 30 | for i, err := range m.Errors { 31 | errs[i] = err.Error() 32 | } 33 | 34 | return strings.Join(errs, "\n") 35 | } 36 | 37 | // ExitCoder is the interface checked by `App` and `Command` for a custom exit 38 | // code 39 | type ExitCoder interface { 40 | error 41 | ExitCode() int 42 | } 43 | 44 | // ExitError fulfills both the builtin `error` interface and `ExitCoder` 45 | type ExitError struct { 46 | exitCode int 47 | message string 48 | } 49 | 50 | // NewExitError makes a new *ExitError 51 | func NewExitError(message string, exitCode int) *ExitError { 52 | return &ExitError{ 53 | exitCode: exitCode, 54 | message: message, 55 | } 56 | } 57 | 58 | // Error returns the string message, fulfilling the interface required by 59 | // `error` 60 | func (ee *ExitError) Error() string { 61 | return ee.message 62 | } 63 | 64 | // ExitCode returns the exit code, fulfilling the interface required by 65 | // `ExitCoder` 66 | func (ee *ExitError) ExitCode() int { 67 | return ee.exitCode 68 | } 69 | 70 | // HandleExitCoder checks if the error fulfills the ExitCoder interface, and if 71 | // so prints the error to stderr (if it is non-empty) and calls OsExiter with the 72 | // given exit code. If the given error is a MultiError, then this func is 73 | // called on all members of the Errors slice. 74 | func HandleExitCoder(err error) { 75 | if err == nil { 76 | return 77 | } 78 | 79 | if exitErr, ok := err.(ExitCoder); ok { 80 | if err.Error() != "" { 81 | fmt.Fprintln(ErrWriter, err) 82 | } 83 | OsExiter(exitErr.ExitCode()) 84 | return 85 | } 86 | 87 | if multiErr, ok := err.(MultiError); ok { 88 | for _, merr := range multiErr.Errors { 89 | HandleExitCoder(merr) 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/cli/funcs.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | // BashCompleteFunc is an action to execute when the bash-completion flag is set 4 | type BashCompleteFunc func(*Context) 5 | 6 | // BeforeFunc is an action to execute before any subcommands are run, but after 7 | // the context is ready if a non-nil error is returned, no subcommands are run 8 | type BeforeFunc func(*Context) error 9 | 10 | // AfterFunc is an action to execute after any subcommands are run, but after the 11 | // subcommand has finished it is run even if Action() panics 12 | type AfterFunc func(*Context) error 13 | 14 | // ActionFunc is the action to execute when no subcommands are specified 15 | type ActionFunc func(*Context) error 16 | 17 | // CommandNotFoundFunc is executed if the proper command cannot be found 18 | type CommandNotFoundFunc func(*Context, string) 19 | 20 | // OnUsageErrorFunc is executed if an usage error occurs. This is useful for displaying 21 | // customized usage error messages. This function is able to replace the 22 | // original error messages. If this function is not set, the "Incorrect usage" 23 | // is displayed and the execution is interrupted. 24 | type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error 25 | 26 | // FlagStringFunc is used by the help generation to display a flag, which is 27 | // expected to be a single line. 28 | type FlagStringFunc func(Flag) string 29 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/cli/runtests: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | 4 | import argparse 5 | import os 6 | import sys 7 | import tempfile 8 | 9 | from subprocess import check_call, check_output 10 | 11 | 12 | PACKAGE_NAME = os.environ.get( 13 | 'CLI_PACKAGE_NAME', 'github.com/urfave/cli' 14 | ) 15 | 16 | 17 | def main(sysargs=sys.argv[:]): 18 | targets = { 19 | 'vet': _vet, 20 | 'test': _test, 21 | 'gfmxr': _gfmxr, 22 | 'toc': _toc, 23 | } 24 | 25 | parser = argparse.ArgumentParser() 26 | parser.add_argument( 27 | 'target', nargs='?', choices=tuple(targets.keys()), default='test' 28 | ) 29 | args = parser.parse_args(sysargs[1:]) 30 | 31 | targets[args.target]() 32 | return 0 33 | 34 | 35 | def _test(): 36 | if check_output('go version'.split()).split()[2] < 'go1.2': 37 | _run('go test -v .'.split()) 38 | return 39 | 40 | coverprofiles = [] 41 | for subpackage in ['', 'altsrc']: 42 | coverprofile = 'cli.coverprofile' 43 | if subpackage != '': 44 | coverprofile = '{}.coverprofile'.format(subpackage) 45 | 46 | coverprofiles.append(coverprofile) 47 | 48 | _run('go test -v'.split() + [ 49 | '-coverprofile={}'.format(coverprofile), 50 | ('{}/{}'.format(PACKAGE_NAME, subpackage)).rstrip('/') 51 | ]) 52 | 53 | combined_name = _combine_coverprofiles(coverprofiles) 54 | _run('go tool cover -func={}'.format(combined_name).split()) 55 | os.remove(combined_name) 56 | 57 | 58 | def _gfmxr(): 59 | _run(['gfmxr', '-c', str(_gfmxr_count()), '-s', 'README.md']) 60 | 61 | 62 | def _vet(): 63 | _run('go vet ./...'.split()) 64 | 65 | 66 | def _toc(): 67 | _run(['node_modules/.bin/markdown-toc', '-i', 'README.md']) 68 | _run(['git', 'diff', '--quiet']) 69 | 70 | 71 | def _run(command): 72 | print('runtests: {}'.format(' '.join(command)), file=sys.stderr) 73 | check_call(command) 74 | 75 | 76 | def _gfmxr_count(): 77 | with open('README.md') as infile: 78 | lines = infile.read().splitlines() 79 | return len(filter(_is_go_runnable, lines)) 80 | 81 | 82 | def _is_go_runnable(line): 83 | return line.startswith('package main') 84 | 85 | 86 | def _combine_coverprofiles(coverprofiles): 87 | combined = tempfile.NamedTemporaryFile( 88 | suffix='.coverprofile', delete=False 89 | ) 90 | combined.write('mode: set\n') 91 | 92 | for coverprofile in coverprofiles: 93 | with open(coverprofile, 'r') as infile: 94 | for line in infile.readlines(): 95 | if not line.startswith('mode: '): 96 | combined.write(line) 97 | 98 | combined.flush() 99 | name = combined.name 100 | combined.close() 101 | return name 102 | 103 | 104 | if __name__ == '__main__': 105 | sys.exit(main()) 106 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/negroni/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | sudo: false 4 | 5 | go: 6 | - 1.2.2 7 | - 1.3.3 8 | - 1.4 9 | - 1.5.4 10 | - 1.6.2 11 | - master 12 | 13 | matrix: 14 | allow_failures: 15 | - go: master 16 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/negroni/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | **ATTN**: This project uses [semantic versioning](http://semver.org/). 4 | 5 | ## [Unreleased] 6 | ### Added 7 | - `Recovery.ErrorHandlerFunc` for custom error handling during recovery 8 | 9 | ### Fixed 10 | - `Written()` correct returns `false` if no response header has been written 11 | - 12 | ### Changed 13 | 14 | - Set default status to `0` in the case that no handler writes status -- was 15 | previously `200` (in 0.2.0, before that it was `0` so this reestablishes that 16 | behavior) 17 | 18 | ## [0.2.0] - 2016-05-10 19 | ### Added 20 | - Support for variadic handlers in `New()` 21 | - Added `Negroni.Handlers()` to fetch all of the handlers for a given chain 22 | - Allowed size in `Recovery` handler was bumped to 8k 23 | - `Negroni.UseFunc` to push another handler onto the chain 24 | 25 | ### Changed 26 | - Set the status before calling `beforeFuncs` so the information is available to them 27 | - Set default status to `200` in the case that no handler writes status -- was previously `0` 28 | - Panic if `nil` handler is given to `negroni.Use` 29 | 30 | ## 0.1.0 - 2013-07-22 31 | ### Added 32 | - Initial implementation. 33 | 34 | [Unreleased]: https://github.com/urfave/negroni/compare/v0.2.0...HEAD 35 | [0.2.0]: https://github.com/urfave/negroni/compare/v0.1.0...v0.2.0 36 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/negroni/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Jeremy Saenz 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 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/negroni/doc.go: -------------------------------------------------------------------------------- 1 | // Package negroni is an idiomatic approach to web middleware in Go. It is tiny, non-intrusive, and encourages use of net/http Handlers. 2 | // 3 | // If you like the idea of Martini, but you think it contains too much magic, then Negroni is a great fit. 4 | // 5 | // For a full guide visit http://github.com/urfave/negroni 6 | // 7 | // package main 8 | // 9 | // import ( 10 | // "github.com/urfave/negroni" 11 | // "net/http" 12 | // "fmt" 13 | // ) 14 | // 15 | // func main() { 16 | // mux := http.NewServeMux() 17 | // mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { 18 | // fmt.Fprintf(w, "Welcome to the home page!") 19 | // }) 20 | // 21 | // n := negroni.Classic() 22 | // n.UseHandler(mux) 23 | // n.Run(":3000") 24 | // } 25 | package negroni 26 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/negroni/logger.go: -------------------------------------------------------------------------------- 1 | package negroni 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "os" 7 | "time" 8 | ) 9 | 10 | // Logger is a middleware handler that logs the request as it goes in and the response as it goes out. 11 | type Logger struct { 12 | // Logger inherits from log.Logger used to log messages with the Logger middleware 13 | *log.Logger 14 | } 15 | 16 | // NewLogger returns a new Logger instance 17 | func NewLogger() *Logger { 18 | return &Logger{log.New(os.Stdout, "[negroni] ", 0)} 19 | } 20 | 21 | func (l *Logger) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 22 | start := time.Now() 23 | l.Printf("Started %s %s", r.Method, r.URL.Path) 24 | 25 | next(rw, r) 26 | 27 | res := rw.(ResponseWriter) 28 | l.Printf("Completed %v %s in %v", res.Status(), http.StatusText(res.Status()), time.Since(start)) 29 | } 30 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/negroni/recovery.go: -------------------------------------------------------------------------------- 1 | package negroni 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | "os" 8 | "runtime" 9 | ) 10 | 11 | // Recovery is a Negroni middleware that recovers from any panics and writes a 500 if there was one. 12 | type Recovery struct { 13 | Logger *log.Logger 14 | PrintStack bool 15 | ErrorHandlerFunc func(interface{}) 16 | StackAll bool 17 | StackSize int 18 | } 19 | 20 | // NewRecovery returns a new instance of Recovery 21 | func NewRecovery() *Recovery { 22 | return &Recovery{ 23 | Logger: log.New(os.Stdout, "[negroni] ", 0), 24 | PrintStack: true, 25 | StackAll: false, 26 | StackSize: 1024 * 8, 27 | } 28 | } 29 | 30 | func (rec *Recovery) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 31 | defer func() { 32 | if err := recover(); err != nil { 33 | if rw.Header().Get("Content-Type") == "" { 34 | rw.Header().Set("Content-Type", "text/plain; charset=utf-8") 35 | } 36 | 37 | rw.WriteHeader(http.StatusInternalServerError) 38 | stack := make([]byte, rec.StackSize) 39 | stack = stack[:runtime.Stack(stack, rec.StackAll)] 40 | 41 | f := "PANIC: %s\n%s" 42 | rec.Logger.Printf(f, err, stack) 43 | 44 | if rec.PrintStack { 45 | fmt.Fprintf(rw, f, err, stack) 46 | } 47 | 48 | if rec.ErrorHandlerFunc != nil { 49 | rec.ErrorHandlerFunc(err) 50 | } 51 | } 52 | }() 53 | 54 | next(rw, r) 55 | } 56 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/negroni/response_writer.go: -------------------------------------------------------------------------------- 1 | package negroni 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "net/http" 8 | ) 9 | 10 | // ResponseWriter is a wrapper around http.ResponseWriter that provides extra information about 11 | // the response. It is recommended that middleware handlers use this construct to wrap a responsewriter 12 | // if the functionality calls for it. 13 | type ResponseWriter interface { 14 | http.ResponseWriter 15 | http.Flusher 16 | // Status returns the status code of the response or 200 if the response has 17 | // not been written (as this is the default response code in net/http) 18 | Status() int 19 | // Written returns whether or not the ResponseWriter has been written. 20 | Written() bool 21 | // Size returns the size of the response body. 22 | Size() int 23 | // Before allows for a function to be called before the ResponseWriter has been written to. This is 24 | // useful for setting headers or any other operations that must happen before a response has been written. 25 | Before(func(ResponseWriter)) 26 | } 27 | 28 | type beforeFunc func(ResponseWriter) 29 | 30 | // NewResponseWriter creates a ResponseWriter that wraps an http.ResponseWriter 31 | func NewResponseWriter(rw http.ResponseWriter) ResponseWriter { 32 | return &responseWriter{ 33 | ResponseWriter: rw, 34 | } 35 | } 36 | 37 | type responseWriter struct { 38 | http.ResponseWriter 39 | status int 40 | size int 41 | beforeFuncs []beforeFunc 42 | } 43 | 44 | func (rw *responseWriter) WriteHeader(s int) { 45 | rw.status = s 46 | rw.callBefore() 47 | rw.ResponseWriter.WriteHeader(s) 48 | } 49 | 50 | func (rw *responseWriter) Write(b []byte) (int, error) { 51 | if !rw.Written() { 52 | // The status will be StatusOK if WriteHeader has not been called yet 53 | rw.WriteHeader(http.StatusOK) 54 | } 55 | size, err := rw.ResponseWriter.Write(b) 56 | rw.size += size 57 | return size, err 58 | } 59 | 60 | func (rw *responseWriter) Status() int { 61 | return rw.status 62 | } 63 | 64 | func (rw *responseWriter) Size() int { 65 | return rw.size 66 | } 67 | 68 | func (rw *responseWriter) Written() bool { 69 | return rw.status != 0 70 | } 71 | 72 | func (rw *responseWriter) Before(before func(ResponseWriter)) { 73 | rw.beforeFuncs = append(rw.beforeFuncs, before) 74 | } 75 | 76 | func (rw *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { 77 | hijacker, ok := rw.ResponseWriter.(http.Hijacker) 78 | if !ok { 79 | return nil, nil, fmt.Errorf("the ResponseWriter doesn't support the Hijacker interface") 80 | } 81 | return hijacker.Hijack() 82 | } 83 | 84 | func (rw *responseWriter) CloseNotify() <-chan bool { 85 | return rw.ResponseWriter.(http.CloseNotifier).CloseNotify() 86 | } 87 | 88 | func (rw *responseWriter) callBefore() { 89 | for i := len(rw.beforeFuncs) - 1; i >= 0; i-- { 90 | rw.beforeFuncs[i](rw) 91 | } 92 | } 93 | 94 | func (rw *responseWriter) Flush() { 95 | flusher, ok := rw.ResponseWriter.(http.Flusher) 96 | if ok { 97 | flusher.Flush() 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /vendor/github.com/urfave/negroni/static.go: -------------------------------------------------------------------------------- 1 | package negroni 2 | 3 | import ( 4 | "net/http" 5 | "path" 6 | "strings" 7 | ) 8 | 9 | // Static is a middleware handler that serves static files in the given 10 | // directory/filesystem. If the file does not exist on the filesystem, it 11 | // passes along to the next middleware in the chain. If you desire "fileserver" 12 | // type behavior where it returns a 404 for unfound files, you should consider 13 | // using http.FileServer from the Go stdlib. 14 | type Static struct { 15 | // Dir is the directory to serve static files from 16 | Dir http.FileSystem 17 | // Prefix is the optional prefix used to serve the static directory content 18 | Prefix string 19 | // IndexFile defines which file to serve as index if it exists. 20 | IndexFile string 21 | } 22 | 23 | // NewStatic returns a new instance of Static 24 | func NewStatic(directory http.FileSystem) *Static { 25 | return &Static{ 26 | Dir: directory, 27 | Prefix: "", 28 | IndexFile: "index.html", 29 | } 30 | } 31 | 32 | func (s *Static) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 33 | if r.Method != "GET" && r.Method != "HEAD" { 34 | next(rw, r) 35 | return 36 | } 37 | file := r.URL.Path 38 | // if we have a prefix, filter requests by stripping the prefix 39 | if s.Prefix != "" { 40 | if !strings.HasPrefix(file, s.Prefix) { 41 | next(rw, r) 42 | return 43 | } 44 | file = file[len(s.Prefix):] 45 | if file != "" && file[0] != '/' { 46 | next(rw, r) 47 | return 48 | } 49 | } 50 | f, err := s.Dir.Open(file) 51 | if err != nil { 52 | // discard the error? 53 | next(rw, r) 54 | return 55 | } 56 | defer f.Close() 57 | 58 | fi, err := f.Stat() 59 | if err != nil { 60 | next(rw, r) 61 | return 62 | } 63 | 64 | // try to serve index file 65 | if fi.IsDir() { 66 | // redirect if missing trailing slash 67 | if !strings.HasSuffix(r.URL.Path, "/") { 68 | http.Redirect(rw, r, r.URL.Path+"/", http.StatusFound) 69 | return 70 | } 71 | 72 | file = path.Join(file, s.IndexFile) 73 | f, err = s.Dir.Open(file) 74 | if err != nil { 75 | next(rw, r) 76 | return 77 | } 78 | defer f.Close() 79 | 80 | fi, err = f.Stat() 81 | if err != nil || fi.IsDir() { 82 | next(rw, r) 83 | return 84 | } 85 | } 86 | 87 | http.ServeContent(rw, r, file, fi.ModTime(), f) 88 | } 89 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/.gitignore: -------------------------------------------------------------------------------- 1 | _obj/ 2 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm.s: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | TEXT ·use(SB),NOSPLIT,$0 10 | RET 11 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_darwin_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for 386, Darwin 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_darwin_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for AMD64, Darwin 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-56 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-104 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_darwin_arm.s: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | // +build arm,darwin 7 | 8 | #include "textflag.h" 9 | 10 | // 11 | // System call support for ARM, Darwin 12 | // 13 | 14 | // Just jump to package syscall's implementation for all these functions. 15 | // The runtime may know about them. 16 | 17 | TEXT ·Syscall(SB),NOSPLIT,$0-28 18 | B syscall·Syscall(SB) 19 | 20 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 21 | B syscall·Syscall6(SB) 22 | 23 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 24 | B syscall·Syscall9(SB) 25 | 26 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 27 | B syscall·RawSyscall(SB) 28 | 29 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 30 | B syscall·RawSyscall6(SB) 31 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_darwin_arm64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | // +build arm64,darwin 7 | 8 | #include "textflag.h" 9 | 10 | // 11 | // System call support for AMD64, Darwin 12 | // 13 | 14 | // Just jump to package syscall's implementation for all these functions. 15 | // The runtime may know about them. 16 | 17 | TEXT ·Syscall(SB),NOSPLIT,$0-56 18 | B syscall·Syscall(SB) 19 | 20 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 21 | B syscall·Syscall6(SB) 22 | 23 | TEXT ·Syscall9(SB),NOSPLIT,$0-104 24 | B syscall·Syscall9(SB) 25 | 26 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 27 | B syscall·RawSyscall(SB) 28 | 29 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 30 | B syscall·RawSyscall6(SB) 31 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_dragonfly_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for 386, FreeBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-32 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-44 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-56 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-32 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-44 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for AMD64, DragonFly 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-64 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-88 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-112 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-64 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-88 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_freebsd_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for 386, FreeBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for AMD64, FreeBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-56 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-104 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_freebsd_arm.s: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for ARM, FreeBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | B syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | B syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | B syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | B syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | B syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_linux_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System calls for 386, Linux 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 23 | JMP syscall·RawSyscall(SB) 24 | 25 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 26 | JMP syscall·RawSyscall6(SB) 27 | 28 | TEXT ·socketcall(SB),NOSPLIT,$0-36 29 | JMP syscall·socketcall(SB) 30 | 31 | TEXT ·rawsocketcall(SB),NOSPLIT,$0-36 32 | JMP syscall·rawsocketcall(SB) 33 | 34 | TEXT ·seek(SB),NOSPLIT,$0-28 35 | JMP syscall·seek(SB) 36 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_linux_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System calls for AMD64, Linux 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-56 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 23 | JMP syscall·RawSyscall(SB) 24 | 25 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 26 | JMP syscall·RawSyscall6(SB) 27 | 28 | TEXT ·gettimeofday(SB),NOSPLIT,$0-16 29 | JMP syscall·gettimeofday(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_linux_arm.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System calls for arm, Linux 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | B syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | B syscall·Syscall6(SB) 21 | 22 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 23 | B syscall·RawSyscall(SB) 24 | 25 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 26 | B syscall·RawSyscall6(SB) 27 | 28 | TEXT ·seek(SB),NOSPLIT,$0-32 29 | B syscall·seek(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_linux_arm64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build linux 6 | // +build arm64 7 | // +build !gccgo 8 | 9 | #include "textflag.h" 10 | 11 | // Just jump to package syscall's implementation for all these functions. 12 | // The runtime may know about them. 13 | 14 | TEXT ·Syscall(SB),NOSPLIT,$0-56 15 | B syscall·Syscall(SB) 16 | 17 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 18 | B syscall·Syscall6(SB) 19 | 20 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 21 | B syscall·RawSyscall(SB) 22 | 23 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 24 | B syscall·RawSyscall6(SB) 25 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_linux_mips64x.s: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build linux 6 | // +build mips64 mips64le 7 | // +build !gccgo 8 | 9 | #include "textflag.h" 10 | 11 | // 12 | // System calls for mips64, Linux 13 | // 14 | 15 | // Just jump to package syscall's implementation for all these functions. 16 | // The runtime may know about them. 17 | 18 | TEXT ·Syscall(SB),NOSPLIT,$0-56 19 | JMP syscall·Syscall(SB) 20 | 21 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 22 | JMP syscall·Syscall6(SB) 23 | 24 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 25 | JMP syscall·RawSyscall(SB) 26 | 27 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 28 | JMP syscall·RawSyscall6(SB) 29 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build linux 6 | // +build ppc64 ppc64le 7 | // +build !gccgo 8 | 9 | #include "textflag.h" 10 | 11 | // 12 | // System calls for ppc64, Linux 13 | // 14 | 15 | // Just jump to package syscall's implementation for all these functions. 16 | // The runtime may know about them. 17 | 18 | TEXT ·Syscall(SB),NOSPLIT,$0-56 19 | BR syscall·Syscall(SB) 20 | 21 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 22 | BR syscall·Syscall6(SB) 23 | 24 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 25 | BR syscall·RawSyscall(SB) 26 | 27 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 28 | BR syscall·RawSyscall6(SB) 29 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_netbsd_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for 386, NetBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for AMD64, NetBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-56 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-104 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_netbsd_arm.s: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for ARM, NetBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | B syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | B syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | B syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | B syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | B syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_openbsd_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for 386, OpenBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for AMD64, OpenBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-56 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-104 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/asm_solaris_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go 11 | // 12 | 13 | TEXT ·sysvicall6(SB),NOSPLIT,$0-64 14 | JMP syscall·sysvicall6(SB) 15 | 16 | TEXT ·rawSysvicall6(SB),NOSPLIT,$0-64 17 | JMP syscall·rawSysvicall6(SB) 18 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/bluetooth_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Bluetooth sockets and messages 6 | 7 | package unix 8 | 9 | // Bluetooth Protocols 10 | const ( 11 | BTPROTO_L2CAP = 0 12 | BTPROTO_HCI = 1 13 | BTPROTO_SCO = 2 14 | BTPROTO_RFCOMM = 3 15 | BTPROTO_BNEP = 4 16 | BTPROTO_CMTP = 5 17 | BTPROTO_HIDP = 6 18 | BTPROTO_AVDTP = 7 19 | ) 20 | 21 | const ( 22 | HCI_CHANNEL_RAW = 0 23 | HCI_CHANNEL_USER = 1 24 | HCI_CHANNEL_MONITOR = 2 25 | HCI_CHANNEL_CONTROL = 3 26 | ) 27 | 28 | // Socketoption Level 29 | const ( 30 | SOL_BLUETOOTH = 0x112 31 | SOL_HCI = 0x0 32 | SOL_L2CAP = 0x6 33 | SOL_RFCOMM = 0x12 34 | SOL_SCO = 0x11 35 | ) 36 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 | 7 | package unix 8 | 9 | const ( 10 | R_OK = 0x4 11 | W_OK = 0x2 12 | X_OK = 0x1 13 | ) 14 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/env_unix.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 | 7 | // Unix environment variables. 8 | 9 | package unix 10 | 11 | import "syscall" 12 | 13 | func Getenv(key string) (value string, found bool) { 14 | return syscall.Getenv(key) 15 | } 16 | 17 | func Setenv(key, value string) error { 18 | return syscall.Setenv(key, value) 19 | } 20 | 21 | func Clearenv() { 22 | syscall.Clearenv() 23 | } 24 | 25 | func Environ() []string { 26 | return syscall.Environ() 27 | } 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/env_unset.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.4 6 | 7 | package unix 8 | 9 | import "syscall" 10 | 11 | func Unsetenv(key string) error { 12 | // This was added in Go 1.4. 13 | return syscall.Unsetenv(key) 14 | } 15 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/flock.go: -------------------------------------------------------------------------------- 1 | // +build linux darwin freebsd openbsd netbsd dragonfly 2 | 3 | // Copyright 2014 The Go Authors. All rights reserved. 4 | // Use of this source code is governed by a BSD-style 5 | // license that can be found in the LICENSE file. 6 | 7 | // +build darwin dragonfly freebsd linux netbsd openbsd 8 | 9 | package unix 10 | 11 | import "unsafe" 12 | 13 | // fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux 14 | // systems by flock_linux_32bit.go to be SYS_FCNTL64. 15 | var fcntl64Syscall uintptr = SYS_FCNTL 16 | 17 | // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. 18 | func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { 19 | _, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk))) 20 | if errno == 0 { 21 | return nil 22 | } 23 | return errno 24 | } 25 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/flock_linux_32bit.go: -------------------------------------------------------------------------------- 1 | // +build linux,386 linux,arm 2 | 3 | // Copyright 2014 The Go Authors. All rights reserved. 4 | // Use of this source code is governed by a BSD-style 5 | // license that can be found in the LICENSE file. 6 | 7 | package unix 8 | 9 | func init() { 10 | // On 32-bit Linux systems, the fcntl syscall that matches Go's 11 | // Flock_t type is SYS_FCNTL64, not SYS_FCNTL. 12 | fcntl64Syscall = SYS_FCNTL64 13 | } 14 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/gccgo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gccgo 6 | 7 | package unix 8 | 9 | import "syscall" 10 | 11 | // We can't use the gc-syntax .s files for gccgo. On the plus side 12 | // much of the functionality can be written directly in Go. 13 | 14 | //extern gccgoRealSyscall 15 | func realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr) 16 | 17 | func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { 18 | syscall.Entersyscall() 19 | r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0) 20 | syscall.Exitsyscall() 21 | return r, 0, syscall.Errno(errno) 22 | } 23 | 24 | func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) { 25 | syscall.Entersyscall() 26 | r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0) 27 | syscall.Exitsyscall() 28 | return r, 0, syscall.Errno(errno) 29 | } 30 | 31 | func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) { 32 | syscall.Entersyscall() 33 | r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9) 34 | syscall.Exitsyscall() 35 | return r, 0, syscall.Errno(errno) 36 | } 37 | 38 | func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { 39 | r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0) 40 | return r, 0, syscall.Errno(errno) 41 | } 42 | 43 | func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) { 44 | r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0) 45 | return r, 0, syscall.Errno(errno) 46 | } 47 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/gccgo_c.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gccgo 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define _STRINGIFY2_(x) #x 12 | #define _STRINGIFY_(x) _STRINGIFY2_(x) 13 | #define GOSYM_PREFIX _STRINGIFY_(__USER_LABEL_PREFIX__) 14 | 15 | // Call syscall from C code because the gccgo support for calling from 16 | // Go to C does not support varargs functions. 17 | 18 | struct ret { 19 | uintptr_t r; 20 | uintptr_t err; 21 | }; 22 | 23 | struct ret 24 | gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9) 25 | { 26 | struct ret r; 27 | 28 | errno = 0; 29 | r.r = syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9); 30 | r.err = errno; 31 | return r; 32 | } 33 | 34 | // Define the use function in C so that it is not inlined. 35 | 36 | extern void use(void *) __asm__ (GOSYM_PREFIX GOPKGPATH ".use") __attribute__((noinline)); 37 | 38 | void 39 | use(void *p __attribute__ ((unused))) 40 | { 41 | } 42 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gccgo,linux,amd64 6 | 7 | package unix 8 | 9 | import "syscall" 10 | 11 | //extern gettimeofday 12 | func realGettimeofday(*Timeval, *byte) int32 13 | 14 | func gettimeofday(tv *Timeval) (err syscall.Errno) { 15 | r := realGettimeofday(tv, nil) 16 | if r < 0 { 17 | return syscall.GetErrno() 18 | } 19 | return 0 20 | } 21 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/mksysnum_darwin.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # Copyright 2009 The Go Authors. All rights reserved. 3 | # Use of this source code is governed by a BSD-style 4 | # license that can be found in the LICENSE file. 5 | # 6 | # Generate system call table for Darwin from sys/syscall.h 7 | 8 | use strict; 9 | 10 | if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { 11 | print STDERR "GOARCH or GOOS not defined in environment\n"; 12 | exit 1; 13 | } 14 | 15 | my $command = "mksysnum_darwin.pl " . join(' ', @ARGV); 16 | 17 | print <){ 29 | if(/^#define\s+SYS_(\w+)\s+([0-9]+)/){ 30 | my $name = $1; 31 | my $num = $2; 32 | $name =~ y/a-z/A-Z/; 33 | print " SYS_$name = $num;" 34 | } 35 | } 36 | 37 | print <){ 30 | if(/^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$/){ 31 | my $num = $1; 32 | my $proto = $2; 33 | my $name = "SYS_$3"; 34 | $name =~ y/a-z/A-Z/; 35 | 36 | # There are multiple entries for enosys and nosys, so comment them out. 37 | if($name =~ /^SYS_E?NOSYS$/){ 38 | $name = "// $name"; 39 | } 40 | if($name eq 'SYS_SYS_EXIT'){ 41 | $name = 'SYS_EXIT'; 42 | } 43 | 44 | print " $name = $num; // $proto\n"; 45 | } 46 | } 47 | 48 | print <){ 30 | if(/^([0-9]+)\s+\S+\s+STD\s+({ \S+\s+(\w+).*)$/){ 31 | my $num = $1; 32 | my $proto = $2; 33 | my $name = "SYS_$3"; 34 | $name =~ y/a-z/A-Z/; 35 | 36 | # There are multiple entries for enosys and nosys, so comment them out. 37 | if($name =~ /^SYS_E?NOSYS$/){ 38 | $name = "// $name"; 39 | } 40 | if($name eq 'SYS_SYS_EXIT'){ 41 | $name = 'SYS_EXIT'; 42 | } 43 | if($name =~ /^SYS_CAP_+/ || $name =~ /^SYS___CAP_+/){ 44 | next 45 | } 46 | 47 | print " $name = $num; // $proto\n"; 48 | 49 | # We keep Capsicum syscall numbers for FreeBSD 50 | # 9-STABLE here because we are not sure whether they 51 | # are mature and stable. 52 | if($num == 513){ 53 | print " SYS_CAP_NEW = 514 // { int cap_new(int fd, uint64_t rights); }\n"; 54 | print " SYS_CAP_GETRIGHTS = 515 // { int cap_getrights(int fd, \\\n"; 55 | print " SYS_CAP_ENTER = 516 // { int cap_enter(void); }\n"; 56 | print " SYS_CAP_GETMODE = 517 // { int cap_getmode(u_int *modep); }\n"; 57 | } 58 | } 59 | } 60 | 61 | print < 999){ 29 | # ignore deprecated syscalls that are no longer implemented 30 | # https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/asm-generic/unistd.h?id=refs/heads/master#n716 31 | return; 32 | } 33 | $name =~ y/a-z/A-Z/; 34 | print " SYS_$name = $num;\n"; 35 | } 36 | 37 | my $prev; 38 | open(GCC, "gcc -E -dD $ARGV[0] |") || die "can't run gcc"; 39 | while(){ 40 | if(/^#define __NR_syscalls\s+/) { 41 | # ignore redefinitions of __NR_syscalls 42 | } 43 | elsif(/^#define __NR_(\w+)\s+([0-9]+)/){ 44 | $prev = $2; 45 | fmt($1, $2); 46 | } 47 | elsif(/^#define __NR3264_(\w+)\s+([0-9]+)/){ 48 | $prev = $2; 49 | fmt($1, $2); 50 | } 51 | elsif(/^#define __NR_(\w+)\s+\(\w+\+\s*([0-9]+)\)/){ 52 | fmt($1, $prev+$2) 53 | } 54 | } 55 | 56 | print <){ 31 | if($line =~ /^(.*)\\$/) { 32 | # Handle continuation 33 | $line = $1; 34 | $_ =~ s/^\s+//; 35 | $line .= $_; 36 | } else { 37 | # New line 38 | $line = $_; 39 | } 40 | next if $line =~ /\\$/; 41 | if($line =~ /^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$/) { 42 | my $num = $1; 43 | my $proto = $6; 44 | my $compat = $8; 45 | my $name = "$7_$9"; 46 | 47 | $name = "$7_$11" if $11 ne ''; 48 | $name =~ y/a-z/A-Z/; 49 | 50 | if($compat eq '' || $compat eq '30' || $compat eq '50') { 51 | print " $name = $num; // $proto\n"; 52 | } 53 | } 54 | } 55 | 56 | print <){ 30 | if(/^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$/){ 31 | my $num = $1; 32 | my $proto = $3; 33 | my $name = $4; 34 | $name =~ y/a-z/A-Z/; 35 | 36 | # There are multiple entries for enosys and nosys, so comment them out. 37 | if($name =~ /^SYS_E?NOSYS$/){ 38 | $name = "// $name"; 39 | } 40 | if($name eq 'SYS_SYS_EXIT'){ 41 | $name = 'SYS_EXIT'; 42 | } 43 | 44 | print " $name = $num; // $proto\n"; 45 | } 46 | } 47 | 48 | print < len(b) { 66 | return nil, nil, EINVAL 67 | } 68 | return h, b[cmsgAlignOf(SizeofCmsghdr):h.Len], nil 69 | } 70 | 71 | // UnixRights encodes a set of open file descriptors into a socket 72 | // control message for sending to another process. 73 | func UnixRights(fds ...int) []byte { 74 | datalen := len(fds) * 4 75 | b := make([]byte, CmsgSpace(datalen)) 76 | h := (*Cmsghdr)(unsafe.Pointer(&b[0])) 77 | h.Level = SOL_SOCKET 78 | h.Type = SCM_RIGHTS 79 | h.SetLen(CmsgLen(datalen)) 80 | data := cmsgData(h) 81 | for _, fd := range fds { 82 | *(*int32)(data) = int32(fd) 83 | data = unsafe.Pointer(uintptr(data) + 4) 84 | } 85 | return b 86 | } 87 | 88 | // ParseUnixRights decodes a socket control message that contains an 89 | // integer array of open file descriptors from another process. 90 | func ParseUnixRights(m *SocketControlMessage) ([]int, error) { 91 | if m.Header.Level != SOL_SOCKET { 92 | return nil, EINVAL 93 | } 94 | if m.Header.Type != SCM_RIGHTS { 95 | return nil, EINVAL 96 | } 97 | fds := make([]int, len(m.Data)>>2) 98 | for i, j := 0, 0; i < len(m.Data); i += 4 { 99 | fds[j] = int(*(*int32)(unsafe.Pointer(&m.Data[i]))) 100 | j++ 101 | } 102 | return fds, nil 103 | } 104 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/str.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 | 7 | package unix 8 | 9 | func itoa(val int) string { // do it here rather than with fmt to avoid dependency 10 | if val < 0 { 11 | return "-" + uitoa(uint(-val)) 12 | } 13 | return uitoa(uint(val)) 14 | } 15 | 16 | func uitoa(val uint) string { 17 | var buf [32]byte // big enough for int64 18 | i := len(buf) - 1 19 | for val >= 10 { 20 | buf[i] = byte(val%10 + '0') 21 | i-- 22 | val /= 10 23 | } 24 | buf[i] = byte(val + '0') 25 | return string(buf[i:]) 26 | } 27 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 | 7 | // Package unix contains an interface to the low-level operating system 8 | // primitives. OS details vary depending on the underlying system, and 9 | // by default, godoc will display OS-specific documentation for the current 10 | // system. If you want godoc to display OS documentation for another 11 | // system, set $GOOS and $GOARCH to the desired system. For example, if 12 | // you want to view documentation for freebsd/arm on linux/amd64, set $GOOS 13 | // to freebsd and $GOARCH to arm. 14 | // The primary use of this package is inside other packages that provide a more 15 | // portable interface to the system, such as "os", "time" and "net". Use 16 | // those packages rather than this one if you can. 17 | // For details of the functions and data types in this package consult 18 | // the manuals for the appropriate operating system. 19 | // These calls return err == nil to indicate success; otherwise 20 | // err represents an operating system error describing the failure and 21 | // holds a value of type syscall.Errno. 22 | package unix 23 | 24 | import "unsafe" 25 | 26 | // ByteSliceFromString returns a NUL-terminated slice of bytes 27 | // containing the text of s. If s contains a NUL byte at any 28 | // location, it returns (nil, EINVAL). 29 | func ByteSliceFromString(s string) ([]byte, error) { 30 | for i := 0; i < len(s); i++ { 31 | if s[i] == 0 { 32 | return nil, EINVAL 33 | } 34 | } 35 | a := make([]byte, len(s)+1) 36 | copy(a, s) 37 | return a, nil 38 | } 39 | 40 | // BytePtrFromString returns a pointer to a NUL-terminated array of 41 | // bytes containing the text of s. If s contains a NUL byte at any 42 | // location, it returns (nil, EINVAL). 43 | func BytePtrFromString(s string) (*byte, error) { 44 | a, err := ByteSliceFromString(s) 45 | if err != nil { 46 | return nil, err 47 | } 48 | return &a[0], nil 49 | } 50 | 51 | // Single-word zero for use when we need a valid pointer to 0 bytes. 52 | // See mkunix.pl. 53 | var _zero uintptr 54 | 55 | func (ts *Timespec) Unix() (sec int64, nsec int64) { 56 | return int64(ts.Sec), int64(ts.Nsec) 57 | } 58 | 59 | func (tv *Timeval) Unix() (sec int64, nsec int64) { 60 | return int64(tv.Sec), int64(tv.Usec) * 1000 61 | } 62 | 63 | func (ts *Timespec) Nano() int64 { 64 | return int64(ts.Sec)*1e9 + int64(ts.Nsec) 65 | } 66 | 67 | func (tv *Timeval) Nano() int64 { 68 | return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 69 | } 70 | 71 | func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } 72 | 73 | // use is a no-op, but the compiler cannot see that it is. 74 | // Calling use(p) ensures that p is kept live until that point. 75 | //go:noescape 76 | func use(p unsafe.Pointer) 77 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_darwin_386.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386,darwin 6 | 7 | package unix 8 | 9 | import ( 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | func Getpagesize() int { return 4096 } 15 | 16 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 17 | 18 | func NsecToTimespec(nsec int64) (ts Timespec) { 19 | ts.Sec = int32(nsec / 1e9) 20 | ts.Nsec = int32(nsec % 1e9) 21 | return 22 | } 23 | 24 | func NsecToTimeval(nsec int64) (tv Timeval) { 25 | nsec += 999 // round up to microsecond 26 | tv.Usec = int32(nsec % 1e9 / 1e3) 27 | tv.Sec = int32(nsec / 1e9) 28 | return 29 | } 30 | 31 | //sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) 32 | func Gettimeofday(tv *Timeval) (err error) { 33 | // The tv passed to gettimeofday must be non-nil 34 | // but is otherwise unused. The answers come back 35 | // in the two registers. 36 | sec, usec, err := gettimeofday(tv) 37 | tv.Sec = int32(sec) 38 | tv.Usec = int32(usec) 39 | return err 40 | } 41 | 42 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 43 | k.Ident = uint32(fd) 44 | k.Filter = int16(mode) 45 | k.Flags = uint16(flags) 46 | } 47 | 48 | func (iov *Iovec) SetLen(length int) { 49 | iov.Len = uint32(length) 50 | } 51 | 52 | func (msghdr *Msghdr) SetControllen(length int) { 53 | msghdr.Controllen = uint32(length) 54 | } 55 | 56 | func (cmsg *Cmsghdr) SetLen(length int) { 57 | cmsg.Len = uint32(length) 58 | } 59 | 60 | func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 61 | var length = uint64(count) 62 | 63 | _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(*offset>>32), uintptr(unsafe.Pointer(&length)), 0, 0, 0, 0) 64 | 65 | written = int(length) 66 | 67 | if e1 != 0 { 68 | err = e1 69 | } 70 | return 71 | } 72 | 73 | func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) 74 | 75 | // SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions 76 | // of darwin/386 the syscall is called sysctl instead of __sysctl. 77 | const SYS___SYSCTL = SYS_SYSCTL 78 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,darwin 6 | 7 | package unix 8 | 9 | import ( 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) 15 | 16 | func Getpagesize() int { return 4096 } 17 | 18 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 19 | 20 | func NsecToTimespec(nsec int64) (ts Timespec) { 21 | ts.Sec = nsec / 1e9 22 | ts.Nsec = nsec % 1e9 23 | return 24 | } 25 | 26 | func NsecToTimeval(nsec int64) (tv Timeval) { 27 | nsec += 999 // round up to microsecond 28 | tv.Usec = int32(nsec % 1e9 / 1e3) 29 | tv.Sec = int64(nsec / 1e9) 30 | return 31 | } 32 | 33 | //sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) 34 | func Gettimeofday(tv *Timeval) (err error) { 35 | // The tv passed to gettimeofday must be non-nil 36 | // but is otherwise unused. The answers come back 37 | // in the two registers. 38 | sec, usec, err := gettimeofday(tv) 39 | tv.Sec = sec 40 | tv.Usec = usec 41 | return err 42 | } 43 | 44 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 45 | k.Ident = uint64(fd) 46 | k.Filter = int16(mode) 47 | k.Flags = uint16(flags) 48 | } 49 | 50 | func (iov *Iovec) SetLen(length int) { 51 | iov.Len = uint64(length) 52 | } 53 | 54 | func (msghdr *Msghdr) SetControllen(length int) { 55 | msghdr.Controllen = uint32(length) 56 | } 57 | 58 | func (cmsg *Cmsghdr) SetLen(length int) { 59 | cmsg.Len = uint32(length) 60 | } 61 | 62 | func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 63 | var length = uint64(count) 64 | 65 | _, _, e1 := Syscall6(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0) 66 | 67 | written = int(length) 68 | 69 | if e1 != 0 { 70 | err = e1 71 | } 72 | return 73 | } 74 | 75 | func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) 76 | 77 | // SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions 78 | // of darwin/amd64 the syscall is called sysctl instead of __sysctl. 79 | const SYS___SYSCTL = SYS_SYSCTL 80 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_darwin_arm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package unix 6 | 7 | import ( 8 | "syscall" 9 | "unsafe" 10 | ) 11 | 12 | func Getpagesize() int { return 4096 } 13 | 14 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 15 | 16 | func NsecToTimespec(nsec int64) (ts Timespec) { 17 | ts.Sec = int32(nsec / 1e9) 18 | ts.Nsec = int32(nsec % 1e9) 19 | return 20 | } 21 | 22 | func NsecToTimeval(nsec int64) (tv Timeval) { 23 | nsec += 999 // round up to microsecond 24 | tv.Usec = int32(nsec % 1e9 / 1e3) 25 | tv.Sec = int32(nsec / 1e9) 26 | return 27 | } 28 | 29 | //sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) 30 | func Gettimeofday(tv *Timeval) (err error) { 31 | // The tv passed to gettimeofday must be non-nil 32 | // but is otherwise unused. The answers come back 33 | // in the two registers. 34 | sec, usec, err := gettimeofday(tv) 35 | tv.Sec = int32(sec) 36 | tv.Usec = int32(usec) 37 | return err 38 | } 39 | 40 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 41 | k.Ident = uint32(fd) 42 | k.Filter = int16(mode) 43 | k.Flags = uint16(flags) 44 | } 45 | 46 | func (iov *Iovec) SetLen(length int) { 47 | iov.Len = uint32(length) 48 | } 49 | 50 | func (msghdr *Msghdr) SetControllen(length int) { 51 | msghdr.Controllen = uint32(length) 52 | } 53 | 54 | func (cmsg *Cmsghdr) SetLen(length int) { 55 | cmsg.Len = uint32(length) 56 | } 57 | 58 | func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 59 | var length = uint64(count) 60 | 61 | _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(*offset>>32), uintptr(unsafe.Pointer(&length)), 0, 0, 0, 0) 62 | 63 | written = int(length) 64 | 65 | if e1 != 0 { 66 | err = e1 67 | } 68 | return 69 | } 70 | 71 | func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic 72 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build arm64,darwin 6 | 7 | package unix 8 | 9 | import ( 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | func Getpagesize() int { return 16384 } 15 | 16 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 17 | 18 | func NsecToTimespec(nsec int64) (ts Timespec) { 19 | ts.Sec = nsec / 1e9 20 | ts.Nsec = nsec % 1e9 21 | return 22 | } 23 | 24 | func NsecToTimeval(nsec int64) (tv Timeval) { 25 | nsec += 999 // round up to microsecond 26 | tv.Usec = int32(nsec % 1e9 / 1e3) 27 | tv.Sec = int64(nsec / 1e9) 28 | return 29 | } 30 | 31 | //sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) 32 | func Gettimeofday(tv *Timeval) (err error) { 33 | // The tv passed to gettimeofday must be non-nil 34 | // but is otherwise unused. The answers come back 35 | // in the two registers. 36 | sec, usec, err := gettimeofday(tv) 37 | tv.Sec = sec 38 | tv.Usec = usec 39 | return err 40 | } 41 | 42 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 43 | k.Ident = uint64(fd) 44 | k.Filter = int16(mode) 45 | k.Flags = uint16(flags) 46 | } 47 | 48 | func (iov *Iovec) SetLen(length int) { 49 | iov.Len = uint64(length) 50 | } 51 | 52 | func (msghdr *Msghdr) SetControllen(length int) { 53 | msghdr.Controllen = uint32(length) 54 | } 55 | 56 | func (cmsg *Cmsghdr) SetLen(length int) { 57 | cmsg.Len = uint32(length) 58 | } 59 | 60 | func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 61 | var length = uint64(count) 62 | 63 | _, _, e1 := Syscall6(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0) 64 | 65 | written = int(length) 66 | 67 | if e1 != 0 { 68 | err = e1 69 | } 70 | return 71 | } 72 | 73 | func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic 74 | 75 | // SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions 76 | // of darwin/arm64 the syscall is called sysctl instead of __sysctl. 77 | const SYS___SYSCTL = SYS_SYSCTL 78 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_dragonfly_386.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386,dragonfly 6 | 7 | package unix 8 | 9 | import ( 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | func Getpagesize() int { return 4096 } 15 | 16 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 17 | 18 | func NsecToTimespec(nsec int64) (ts Timespec) { 19 | ts.Sec = int32(nsec / 1e9) 20 | ts.Nsec = int32(nsec % 1e9) 21 | return 22 | } 23 | 24 | func NsecToTimeval(nsec int64) (tv Timeval) { 25 | nsec += 999 // round up to microsecond 26 | tv.Usec = int32(nsec % 1e9 / 1e3) 27 | tv.Sec = int32(nsec / 1e9) 28 | return 29 | } 30 | 31 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 32 | k.Ident = uint32(fd) 33 | k.Filter = int16(mode) 34 | k.Flags = uint16(flags) 35 | } 36 | 37 | func (iov *Iovec) SetLen(length int) { 38 | iov.Len = uint32(length) 39 | } 40 | 41 | func (msghdr *Msghdr) SetControllen(length int) { 42 | msghdr.Controllen = uint32(length) 43 | } 44 | 45 | func (cmsg *Cmsghdr) SetLen(length int) { 46 | cmsg.Len = uint32(length) 47 | } 48 | 49 | func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 50 | var writtenOut uint64 = 0 51 | _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0) 52 | 53 | written = int(writtenOut) 54 | 55 | if e1 != 0 { 56 | err = e1 57 | } 58 | return 59 | } 60 | 61 | func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) 62 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,dragonfly 6 | 7 | package unix 8 | 9 | import ( 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | func Getpagesize() int { return 4096 } 15 | 16 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 17 | 18 | func NsecToTimespec(nsec int64) (ts Timespec) { 19 | ts.Sec = nsec / 1e9 20 | ts.Nsec = nsec % 1e9 21 | return 22 | } 23 | 24 | func NsecToTimeval(nsec int64) (tv Timeval) { 25 | nsec += 999 // round up to microsecond 26 | tv.Usec = nsec % 1e9 / 1e3 27 | tv.Sec = int64(nsec / 1e9) 28 | return 29 | } 30 | 31 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 32 | k.Ident = uint64(fd) 33 | k.Filter = int16(mode) 34 | k.Flags = uint16(flags) 35 | } 36 | 37 | func (iov *Iovec) SetLen(length int) { 38 | iov.Len = uint64(length) 39 | } 40 | 41 | func (msghdr *Msghdr) SetControllen(length int) { 42 | msghdr.Controllen = uint32(length) 43 | } 44 | 45 | func (cmsg *Cmsghdr) SetLen(length int) { 46 | cmsg.Len = uint32(length) 47 | } 48 | 49 | func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 50 | var writtenOut uint64 = 0 51 | _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0) 52 | 53 | written = int(writtenOut) 54 | 55 | if e1 != 0 { 56 | err = e1 57 | } 58 | return 59 | } 60 | 61 | func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) 62 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_freebsd_386.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386,freebsd 6 | 7 | package unix 8 | 9 | import ( 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | func Getpagesize() int { return 4096 } 15 | 16 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 17 | 18 | func NsecToTimespec(nsec int64) (ts Timespec) { 19 | ts.Sec = int32(nsec / 1e9) 20 | ts.Nsec = int32(nsec % 1e9) 21 | return 22 | } 23 | 24 | func NsecToTimeval(nsec int64) (tv Timeval) { 25 | nsec += 999 // round up to microsecond 26 | tv.Usec = int32(nsec % 1e9 / 1e3) 27 | tv.Sec = int32(nsec / 1e9) 28 | return 29 | } 30 | 31 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 32 | k.Ident = uint32(fd) 33 | k.Filter = int16(mode) 34 | k.Flags = uint16(flags) 35 | } 36 | 37 | func (iov *Iovec) SetLen(length int) { 38 | iov.Len = uint32(length) 39 | } 40 | 41 | func (msghdr *Msghdr) SetControllen(length int) { 42 | msghdr.Controllen = uint32(length) 43 | } 44 | 45 | func (cmsg *Cmsghdr) SetLen(length int) { 46 | cmsg.Len = uint32(length) 47 | } 48 | 49 | func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 50 | var writtenOut uint64 = 0 51 | _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0) 52 | 53 | written = int(writtenOut) 54 | 55 | if e1 != 0 { 56 | err = e1 57 | } 58 | return 59 | } 60 | 61 | func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) 62 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,freebsd 6 | 7 | package unix 8 | 9 | import ( 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | func Getpagesize() int { return 4096 } 15 | 16 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 17 | 18 | func NsecToTimespec(nsec int64) (ts Timespec) { 19 | ts.Sec = nsec / 1e9 20 | ts.Nsec = nsec % 1e9 21 | return 22 | } 23 | 24 | func NsecToTimeval(nsec int64) (tv Timeval) { 25 | nsec += 999 // round up to microsecond 26 | tv.Usec = nsec % 1e9 / 1e3 27 | tv.Sec = int64(nsec / 1e9) 28 | return 29 | } 30 | 31 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 32 | k.Ident = uint64(fd) 33 | k.Filter = int16(mode) 34 | k.Flags = uint16(flags) 35 | } 36 | 37 | func (iov *Iovec) SetLen(length int) { 38 | iov.Len = uint64(length) 39 | } 40 | 41 | func (msghdr *Msghdr) SetControllen(length int) { 42 | msghdr.Controllen = uint32(length) 43 | } 44 | 45 | func (cmsg *Cmsghdr) SetLen(length int) { 46 | cmsg.Len = uint32(length) 47 | } 48 | 49 | func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 50 | var writtenOut uint64 = 0 51 | _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0) 52 | 53 | written = int(writtenOut) 54 | 55 | if e1 != 0 { 56 | err = e1 57 | } 58 | return 59 | } 60 | 61 | func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) 62 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build arm,freebsd 6 | 7 | package unix 8 | 9 | import ( 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | func Getpagesize() int { return 4096 } 15 | 16 | func TimespecToNsec(ts Timespec) int64 { return ts.Sec*1e9 + int64(ts.Nsec) } 17 | 18 | func NsecToTimespec(nsec int64) (ts Timespec) { 19 | ts.Sec = nsec / 1e9 20 | ts.Nsec = int32(nsec % 1e9) 21 | return 22 | } 23 | 24 | func NsecToTimeval(nsec int64) (tv Timeval) { 25 | nsec += 999 // round up to microsecond 26 | tv.Usec = int32(nsec % 1e9 / 1e3) 27 | tv.Sec = nsec / 1e9 28 | return 29 | } 30 | 31 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 32 | k.Ident = uint32(fd) 33 | k.Filter = int16(mode) 34 | k.Flags = uint16(flags) 35 | } 36 | 37 | func (iov *Iovec) SetLen(length int) { 38 | iov.Len = uint32(length) 39 | } 40 | 41 | func (msghdr *Msghdr) SetControllen(length int) { 42 | msghdr.Controllen = uint32(length) 43 | } 44 | 45 | func (cmsg *Cmsghdr) SetLen(length int) { 46 | cmsg.Len = uint32(length) 47 | } 48 | 49 | func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 50 | var writtenOut uint64 = 0 51 | _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0) 52 | 53 | written = int(writtenOut) 54 | 55 | if e1 != 0 { 56 | err = e1 57 | } 58 | return 59 | } 60 | 61 | func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) 62 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build linux 6 | // +build ppc64 ppc64le 7 | 8 | package unix 9 | 10 | //sys Dup2(oldfd int, newfd int) (err error) 11 | //sys Fchown(fd int, uid int, gid int) (err error) 12 | //sys Fstat(fd int, stat *Stat_t) (err error) 13 | //sys Fstatfs(fd int, buf *Statfs_t) (err error) 14 | //sys Ftruncate(fd int, length int64) (err error) 15 | //sysnb Getegid() (egid int) 16 | //sysnb Geteuid() (euid int) 17 | //sysnb Getgid() (gid int) 18 | //sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_UGETRLIMIT 19 | //sysnb Getuid() (uid int) 20 | //sys Ioperm(from int, num int, on int) (err error) 21 | //sys Iopl(level int) (err error) 22 | //sys Lchown(path string, uid int, gid int) (err error) 23 | //sys Listen(s int, n int) (err error) 24 | //sys Lstat(path string, stat *Stat_t) (err error) 25 | //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 26 | //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 27 | //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK 28 | //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) 29 | //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) 30 | //sys Setfsgid(gid int) (err error) 31 | //sys Setfsuid(uid int) (err error) 32 | //sysnb Setregid(rgid int, egid int) (err error) 33 | //sysnb Setresgid(rgid int, egid int, sgid int) (err error) 34 | //sysnb Setresuid(ruid int, euid int, suid int) (err error) 35 | //sysnb Setrlimit(resource int, rlim *Rlimit) (err error) 36 | //sysnb Setreuid(ruid int, euid int) (err error) 37 | //sys Shutdown(fd int, how int) (err error) 38 | //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) 39 | //sys Stat(path string, stat *Stat_t) (err error) 40 | //sys Statfs(path string, buf *Statfs_t) (err error) 41 | //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) = SYS_SYNC_FILE_RANGE2 42 | //sys Truncate(path string, length int64) (err error) 43 | //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) 44 | //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) 45 | //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) 46 | //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) 47 | //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) 48 | //sysnb setgroups(n int, list *_Gid_t) (err error) 49 | //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) 50 | //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) 51 | //sysnb socket(domain int, typ int, proto int) (fd int, err error) 52 | //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) 53 | //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) 54 | //sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) 55 | //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) 56 | //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) 57 | //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) 58 | //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) 59 | //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) 60 | 61 | func Getpagesize() int { return 65536 } 62 | 63 | //sysnb Gettimeofday(tv *Timeval) (err error) 64 | //sysnb Time(t *Time_t) (tt Time_t, err error) 65 | 66 | //sys Utime(path string, buf *Utimbuf) (err error) 67 | 68 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 69 | 70 | func NsecToTimespec(nsec int64) (ts Timespec) { 71 | ts.Sec = nsec / 1e9 72 | ts.Nsec = nsec % 1e9 73 | return 74 | } 75 | 76 | func NsecToTimeval(nsec int64) (tv Timeval) { 77 | nsec += 999 // round up to microsecond 78 | tv.Sec = nsec / 1e9 79 | tv.Usec = nsec % 1e9 / 1e3 80 | return 81 | } 82 | 83 | func (r *PtraceRegs) PC() uint64 { return r.Nip } 84 | 85 | func (r *PtraceRegs) SetPC(pc uint64) { r.Nip = pc } 86 | 87 | func (iov *Iovec) SetLen(length int) { 88 | iov.Len = uint64(length) 89 | } 90 | 91 | func (msghdr *Msghdr) SetControllen(length int) { 92 | msghdr.Controllen = uint64(length) 93 | } 94 | 95 | func (cmsg *Cmsghdr) SetLen(length int) { 96 | cmsg.Len = uint64(length) 97 | } 98 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_netbsd_386.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386,netbsd 6 | 7 | package unix 8 | 9 | func Getpagesize() int { return 4096 } 10 | 11 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 12 | 13 | func NsecToTimespec(nsec int64) (ts Timespec) { 14 | ts.Sec = int64(nsec / 1e9) 15 | ts.Nsec = int32(nsec % 1e9) 16 | return 17 | } 18 | 19 | func NsecToTimeval(nsec int64) (tv Timeval) { 20 | nsec += 999 // round up to microsecond 21 | tv.Usec = int32(nsec % 1e9 / 1e3) 22 | tv.Sec = int64(nsec / 1e9) 23 | return 24 | } 25 | 26 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 27 | k.Ident = uint32(fd) 28 | k.Filter = uint32(mode) 29 | k.Flags = uint32(flags) 30 | } 31 | 32 | func (iov *Iovec) SetLen(length int) { 33 | iov.Len = uint32(length) 34 | } 35 | 36 | func (msghdr *Msghdr) SetControllen(length int) { 37 | msghdr.Controllen = uint32(length) 38 | } 39 | 40 | func (cmsg *Cmsghdr) SetLen(length int) { 41 | cmsg.Len = uint32(length) 42 | } 43 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,netbsd 6 | 7 | package unix 8 | 9 | func Getpagesize() int { return 4096 } 10 | 11 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 12 | 13 | func NsecToTimespec(nsec int64) (ts Timespec) { 14 | ts.Sec = int64(nsec / 1e9) 15 | ts.Nsec = int64(nsec % 1e9) 16 | return 17 | } 18 | 19 | func NsecToTimeval(nsec int64) (tv Timeval) { 20 | nsec += 999 // round up to microsecond 21 | tv.Usec = int32(nsec % 1e9 / 1e3) 22 | tv.Sec = int64(nsec / 1e9) 23 | return 24 | } 25 | 26 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 27 | k.Ident = uint64(fd) 28 | k.Filter = uint32(mode) 29 | k.Flags = uint32(flags) 30 | } 31 | 32 | func (iov *Iovec) SetLen(length int) { 33 | iov.Len = uint64(length) 34 | } 35 | 36 | func (msghdr *Msghdr) SetControllen(length int) { 37 | msghdr.Controllen = uint32(length) 38 | } 39 | 40 | func (cmsg *Cmsghdr) SetLen(length int) { 41 | cmsg.Len = uint32(length) 42 | } 43 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build arm,netbsd 6 | 7 | package unix 8 | 9 | func Getpagesize() int { return 4096 } 10 | 11 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 12 | 13 | func NsecToTimespec(nsec int64) (ts Timespec) { 14 | ts.Sec = int64(nsec / 1e9) 15 | ts.Nsec = int32(nsec % 1e9) 16 | return 17 | } 18 | 19 | func NsecToTimeval(nsec int64) (tv Timeval) { 20 | nsec += 999 // round up to microsecond 21 | tv.Usec = int32(nsec % 1e9 / 1e3) 22 | tv.Sec = int64(nsec / 1e9) 23 | return 24 | } 25 | 26 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 27 | k.Ident = uint32(fd) 28 | k.Filter = uint32(mode) 29 | k.Flags = uint32(flags) 30 | } 31 | 32 | func (iov *Iovec) SetLen(length int) { 33 | iov.Len = uint32(length) 34 | } 35 | 36 | func (msghdr *Msghdr) SetControllen(length int) { 37 | msghdr.Controllen = uint32(length) 38 | } 39 | 40 | func (cmsg *Cmsghdr) SetLen(length int) { 41 | cmsg.Len = uint32(length) 42 | } 43 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_no_getwd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build dragonfly freebsd netbsd openbsd 6 | 7 | package unix 8 | 9 | const ImplementsGetwd = false 10 | 11 | func Getwd() (string, error) { return "", ENOTSUP } 12 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_openbsd_386.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386,openbsd 6 | 7 | package unix 8 | 9 | func Getpagesize() int { return 4096 } 10 | 11 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 12 | 13 | func NsecToTimespec(nsec int64) (ts Timespec) { 14 | ts.Sec = int64(nsec / 1e9) 15 | ts.Nsec = int32(nsec % 1e9) 16 | return 17 | } 18 | 19 | func NsecToTimeval(nsec int64) (tv Timeval) { 20 | nsec += 999 // round up to microsecond 21 | tv.Usec = int32(nsec % 1e9 / 1e3) 22 | tv.Sec = int64(nsec / 1e9) 23 | return 24 | } 25 | 26 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 27 | k.Ident = uint32(fd) 28 | k.Filter = int16(mode) 29 | k.Flags = uint16(flags) 30 | } 31 | 32 | func (iov *Iovec) SetLen(length int) { 33 | iov.Len = uint32(length) 34 | } 35 | 36 | func (msghdr *Msghdr) SetControllen(length int) { 37 | msghdr.Controllen = uint32(length) 38 | } 39 | 40 | func (cmsg *Cmsghdr) SetLen(length int) { 41 | cmsg.Len = uint32(length) 42 | } 43 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,openbsd 6 | 7 | package unix 8 | 9 | func Getpagesize() int { return 4096 } 10 | 11 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 12 | 13 | func NsecToTimespec(nsec int64) (ts Timespec) { 14 | ts.Sec = nsec / 1e9 15 | ts.Nsec = nsec % 1e9 16 | return 17 | } 18 | 19 | func NsecToTimeval(nsec int64) (tv Timeval) { 20 | nsec += 999 // round up to microsecond 21 | tv.Usec = nsec % 1e9 / 1e3 22 | tv.Sec = nsec / 1e9 23 | return 24 | } 25 | 26 | func SetKevent(k *Kevent_t, fd, mode, flags int) { 27 | k.Ident = uint64(fd) 28 | k.Filter = int16(mode) 29 | k.Flags = uint16(flags) 30 | } 31 | 32 | func (iov *Iovec) SetLen(length int) { 33 | iov.Len = uint64(length) 34 | } 35 | 36 | func (msghdr *Msghdr) SetControllen(length int) { 37 | msghdr.Controllen = uint32(length) 38 | } 39 | 40 | func (cmsg *Cmsghdr) SetLen(length int) { 41 | cmsg.Len = uint32(length) 42 | } 43 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,solaris 6 | 7 | package unix 8 | 9 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 10 | 11 | func NsecToTimespec(nsec int64) (ts Timespec) { 12 | ts.Sec = nsec / 1e9 13 | ts.Nsec = nsec % 1e9 14 | return 15 | } 16 | 17 | func NsecToTimeval(nsec int64) (tv Timeval) { 18 | nsec += 999 // round up to microsecond 19 | tv.Usec = nsec % 1e9 / 1e3 20 | tv.Sec = int64(nsec / 1e9) 21 | return 22 | } 23 | 24 | func (iov *Iovec) SetLen(length int) { 25 | iov.Len = uint64(length) 26 | } 27 | 28 | func (cmsg *Cmsghdr) SetLen(length int) { 29 | cmsg.Len = uint32(length) 30 | } 31 | 32 | func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 33 | // TODO(aram): implement this, see issue 5847. 34 | panic("unimplemented") 35 | } 36 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/unix/zsysnum_solaris_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,solaris 6 | 7 | package unix 8 | 9 | // TODO(aram): remove these before Go 1.3. 10 | const ( 11 | SYS_EXECVE = 59 12 | SYS_FCNTL = 62 13 | ) 14 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/LICENSE: -------------------------------------------------------------------------------- 1 | mgo - MongoDB driver for Go 2 | 3 | Copyright (c) 2010-2013 - Gustavo Niemeyer 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/Makefile: -------------------------------------------------------------------------------- 1 | startdb: 2 | @testdb/setup.sh start 3 | 4 | stopdb: 5 | @testdb/setup.sh stop 6 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/README.md: -------------------------------------------------------------------------------- 1 | The MongoDB driver for Go 2 | ------------------------- 3 | 4 | Please go to [http://labix.org/mgo](http://labix.org/mgo) for all project details. 5 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/bson/LICENSE: -------------------------------------------------------------------------------- 1 | BSON library for Go 2 | 3 | Copyright (c) 2010-2012 - Gustavo Niemeyer 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/doc.go: -------------------------------------------------------------------------------- 1 | // Package mgo offers a rich MongoDB driver for Go. 2 | // 3 | // Details about the mgo project (pronounced as "mango") are found 4 | // in its web page: 5 | // 6 | // http://labix.org/mgo 7 | // 8 | // Usage of the driver revolves around the concept of sessions. To 9 | // get started, obtain a session using the Dial function: 10 | // 11 | // session, err := mgo.Dial(url) 12 | // 13 | // This will establish one or more connections with the cluster of 14 | // servers defined by the url parameter. From then on, the cluster 15 | // may be queried with multiple consistency rules (see SetMode) and 16 | // documents retrieved with statements such as: 17 | // 18 | // c := session.DB(database).C(collection) 19 | // err := c.Find(query).One(&result) 20 | // 21 | // New sessions are typically created by calling session.Copy on the 22 | // initial session obtained at dial time. These new sessions will share 23 | // the same cluster information and connection pool, and may be easily 24 | // handed into other methods and functions for organizing logic. 25 | // Every session created must have its Close method called at the end 26 | // of its life time, so its resources may be put back in the pool or 27 | // collected, depending on the case. 28 | // 29 | // For more details, see the documentation for the types and methods. 30 | // 31 | package mgo 32 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/internal/sasl/sasl.c: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | static int mgo_sasl_simple(void *context, int id, const char **result, unsigned int *len) 9 | { 10 | if (!result) { 11 | return SASL_BADPARAM; 12 | } 13 | switch (id) { 14 | case SASL_CB_USER: 15 | *result = (char *)context; 16 | break; 17 | case SASL_CB_AUTHNAME: 18 | *result = (char *)context; 19 | break; 20 | case SASL_CB_LANGUAGE: 21 | *result = NULL; 22 | break; 23 | default: 24 | return SASL_BADPARAM; 25 | } 26 | if (len) { 27 | *len = *result ? strlen(*result) : 0; 28 | } 29 | return SASL_OK; 30 | } 31 | 32 | typedef int (*callback)(void); 33 | 34 | static int mgo_sasl_secret(sasl_conn_t *conn, void *context, int id, sasl_secret_t **result) 35 | { 36 | if (!conn || !result || id != SASL_CB_PASS) { 37 | return SASL_BADPARAM; 38 | } 39 | *result = (sasl_secret_t *)context; 40 | return SASL_OK; 41 | } 42 | 43 | sasl_callback_t *mgo_sasl_callbacks(const char *username, const char *password) 44 | { 45 | sasl_callback_t *cb = malloc(4 * sizeof(sasl_callback_t)); 46 | int n = 0; 47 | 48 | size_t len = strlen(password); 49 | sasl_secret_t *secret = (sasl_secret_t*)malloc(sizeof(sasl_secret_t) + len); 50 | if (!secret) { 51 | free(cb); 52 | return NULL; 53 | } 54 | strcpy((char *)secret->data, password); 55 | secret->len = len; 56 | 57 | cb[n].id = SASL_CB_PASS; 58 | cb[n].proc = (callback)&mgo_sasl_secret; 59 | cb[n].context = secret; 60 | n++; 61 | 62 | cb[n].id = SASL_CB_USER; 63 | cb[n].proc = (callback)&mgo_sasl_simple; 64 | cb[n].context = (char*)username; 65 | n++; 66 | 67 | cb[n].id = SASL_CB_AUTHNAME; 68 | cb[n].proc = (callback)&mgo_sasl_simple; 69 | cb[n].context = (char*)username; 70 | n++; 71 | 72 | cb[n].id = SASL_CB_LIST_END; 73 | cb[n].proc = NULL; 74 | cb[n].context = NULL; 75 | 76 | return cb; 77 | } 78 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/internal/sasl/sasl.go: -------------------------------------------------------------------------------- 1 | // Package sasl is an implementation detail of the mgo package. 2 | // 3 | // This package is not meant to be used by itself. 4 | // 5 | 6 | // +build !windows 7 | 8 | package sasl 9 | 10 | // #cgo LDFLAGS: -lsasl2 11 | // 12 | // struct sasl_conn {}; 13 | // 14 | // #include 15 | // #include 16 | // 17 | // sasl_callback_t *mgo_sasl_callbacks(const char *username, const char *password); 18 | // 19 | import "C" 20 | 21 | import ( 22 | "fmt" 23 | "strings" 24 | "sync" 25 | "unsafe" 26 | ) 27 | 28 | type saslStepper interface { 29 | Step(serverData []byte) (clientData []byte, done bool, err error) 30 | Close() 31 | } 32 | 33 | type saslSession struct { 34 | conn *C.sasl_conn_t 35 | step int 36 | mech string 37 | 38 | cstrings []*C.char 39 | callbacks *C.sasl_callback_t 40 | } 41 | 42 | var initError error 43 | var initOnce sync.Once 44 | 45 | func initSASL() { 46 | rc := C.sasl_client_init(nil) 47 | if rc != C.SASL_OK { 48 | initError = saslError(rc, nil, "cannot initialize SASL library") 49 | } 50 | } 51 | 52 | func New(username, password, mechanism, service, host string) (saslStepper, error) { 53 | initOnce.Do(initSASL) 54 | if initError != nil { 55 | return nil, initError 56 | } 57 | 58 | ss := &saslSession{mech: mechanism} 59 | if service == "" { 60 | service = "mongodb" 61 | } 62 | if i := strings.Index(host, ":"); i >= 0 { 63 | host = host[:i] 64 | } 65 | ss.callbacks = C.mgo_sasl_callbacks(ss.cstr(username), ss.cstr(password)) 66 | rc := C.sasl_client_new(ss.cstr(service), ss.cstr(host), nil, nil, ss.callbacks, 0, &ss.conn) 67 | if rc != C.SASL_OK { 68 | ss.Close() 69 | return nil, saslError(rc, nil, "cannot create new SASL client") 70 | } 71 | return ss, nil 72 | } 73 | 74 | func (ss *saslSession) cstr(s string) *C.char { 75 | cstr := C.CString(s) 76 | ss.cstrings = append(ss.cstrings, cstr) 77 | return cstr 78 | } 79 | 80 | func (ss *saslSession) Close() { 81 | for _, cstr := range ss.cstrings { 82 | C.free(unsafe.Pointer(cstr)) 83 | } 84 | ss.cstrings = nil 85 | 86 | if ss.callbacks != nil { 87 | C.free(unsafe.Pointer(ss.callbacks)) 88 | } 89 | 90 | // The documentation of SASL dispose makes it clear that this should only 91 | // be done when the connection is done, not when the authentication phase 92 | // is done, because an encryption layer may have been negotiated. 93 | // Even then, we'll do this for now, because it's simpler and prevents 94 | // keeping track of this state for every socket. If it breaks, we'll fix it. 95 | C.sasl_dispose(&ss.conn) 96 | } 97 | 98 | func (ss *saslSession) Step(serverData []byte) (clientData []byte, done bool, err error) { 99 | ss.step++ 100 | if ss.step > 10 { 101 | return nil, false, fmt.Errorf("too many SASL steps without authentication") 102 | } 103 | var cclientData *C.char 104 | var cclientDataLen C.uint 105 | var rc C.int 106 | if ss.step == 1 { 107 | var mechanism *C.char // ignored - must match cred 108 | rc = C.sasl_client_start(ss.conn, ss.cstr(ss.mech), nil, &cclientData, &cclientDataLen, &mechanism) 109 | } else { 110 | var cserverData *C.char 111 | var cserverDataLen C.uint 112 | if len(serverData) > 0 { 113 | cserverData = (*C.char)(unsafe.Pointer(&serverData[0])) 114 | cserverDataLen = C.uint(len(serverData)) 115 | } 116 | rc = C.sasl_client_step(ss.conn, cserverData, cserverDataLen, nil, &cclientData, &cclientDataLen) 117 | } 118 | if cclientData != nil && cclientDataLen > 0 { 119 | clientData = C.GoBytes(unsafe.Pointer(cclientData), C.int(cclientDataLen)) 120 | } 121 | if rc == C.SASL_OK { 122 | return clientData, true, nil 123 | } 124 | if rc == C.SASL_CONTINUE { 125 | return clientData, false, nil 126 | } 127 | return nil, false, saslError(rc, ss.conn, "cannot establish SASL session") 128 | } 129 | 130 | func saslError(rc C.int, conn *C.sasl_conn_t, msg string) error { 131 | var detail string 132 | if conn == nil { 133 | detail = C.GoString(C.sasl_errstring(rc, nil, nil)) 134 | } else { 135 | detail = C.GoString(C.sasl_errdetail(conn)) 136 | } 137 | return fmt.Errorf(msg + ": " + detail) 138 | } 139 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/internal/sasl/sasl_windows.c: -------------------------------------------------------------------------------- 1 | #include "sasl_windows.h" 2 | 3 | static const LPSTR SSPI_PACKAGE_NAME = "kerberos"; 4 | 5 | SECURITY_STATUS SEC_ENTRY sspi_acquire_credentials_handle(CredHandle *cred_handle, char *username, char *password, char *domain) 6 | { 7 | SEC_WINNT_AUTH_IDENTITY auth_identity; 8 | SECURITY_INTEGER ignored; 9 | 10 | auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; 11 | auth_identity.User = (LPSTR) username; 12 | auth_identity.UserLength = strlen(username); 13 | auth_identity.Password = (LPSTR) password; 14 | auth_identity.PasswordLength = strlen(password); 15 | auth_identity.Domain = (LPSTR) domain; 16 | auth_identity.DomainLength = strlen(domain); 17 | return call_sspi_acquire_credentials_handle(NULL, SSPI_PACKAGE_NAME, SECPKG_CRED_OUTBOUND, NULL, &auth_identity, NULL, NULL, cred_handle, &ignored); 18 | } 19 | 20 | int sspi_step(CredHandle *cred_handle, int has_context, CtxtHandle *context, PVOID *buffer, ULONG *buffer_length, char *target) 21 | { 22 | SecBufferDesc inbuf; 23 | SecBuffer in_bufs[1]; 24 | SecBufferDesc outbuf; 25 | SecBuffer out_bufs[1]; 26 | 27 | if (has_context > 0) { 28 | // If we already have a context, we now have data to send. 29 | // Put this data in an inbuf. 30 | inbuf.ulVersion = SECBUFFER_VERSION; 31 | inbuf.cBuffers = 1; 32 | inbuf.pBuffers = in_bufs; 33 | in_bufs[0].pvBuffer = *buffer; 34 | in_bufs[0].cbBuffer = *buffer_length; 35 | in_bufs[0].BufferType = SECBUFFER_TOKEN; 36 | } 37 | 38 | outbuf.ulVersion = SECBUFFER_VERSION; 39 | outbuf.cBuffers = 1; 40 | outbuf.pBuffers = out_bufs; 41 | out_bufs[0].pvBuffer = NULL; 42 | out_bufs[0].cbBuffer = 0; 43 | out_bufs[0].BufferType = SECBUFFER_TOKEN; 44 | 45 | ULONG context_attr = 0; 46 | 47 | int ret = call_sspi_initialize_security_context(cred_handle, 48 | has_context > 0 ? context : NULL, 49 | (LPSTR) target, 50 | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_MUTUAL_AUTH, 51 | 0, 52 | SECURITY_NETWORK_DREP, 53 | has_context > 0 ? &inbuf : NULL, 54 | 0, 55 | context, 56 | &outbuf, 57 | &context_attr, 58 | NULL); 59 | 60 | *buffer = malloc(out_bufs[0].cbBuffer); 61 | *buffer_length = out_bufs[0].cbBuffer; 62 | memcpy(*buffer, out_bufs[0].pvBuffer, *buffer_length); 63 | 64 | return ret; 65 | } 66 | 67 | int sspi_send_client_authz_id(CtxtHandle *context, PVOID *buffer, ULONG *buffer_length, char *user_plus_realm) 68 | { 69 | SecPkgContext_Sizes sizes; 70 | SECURITY_STATUS status = call_sspi_query_context_attributes(context, SECPKG_ATTR_SIZES, &sizes); 71 | 72 | if (status != SEC_E_OK) { 73 | return status; 74 | } 75 | 76 | size_t user_plus_realm_length = strlen(user_plus_realm); 77 | int msgSize = 4 + user_plus_realm_length; 78 | char *msg = malloc((sizes.cbSecurityTrailer + msgSize + sizes.cbBlockSize) * sizeof(char)); 79 | msg[sizes.cbSecurityTrailer + 0] = 1; 80 | msg[sizes.cbSecurityTrailer + 1] = 0; 81 | msg[sizes.cbSecurityTrailer + 2] = 0; 82 | msg[sizes.cbSecurityTrailer + 3] = 0; 83 | memcpy(&msg[sizes.cbSecurityTrailer + 4], user_plus_realm, user_plus_realm_length); 84 | 85 | SecBuffer wrapBufs[3]; 86 | SecBufferDesc wrapBufDesc; 87 | wrapBufDesc.cBuffers = 3; 88 | wrapBufDesc.pBuffers = wrapBufs; 89 | wrapBufDesc.ulVersion = SECBUFFER_VERSION; 90 | 91 | wrapBufs[0].cbBuffer = sizes.cbSecurityTrailer; 92 | wrapBufs[0].BufferType = SECBUFFER_TOKEN; 93 | wrapBufs[0].pvBuffer = msg; 94 | 95 | wrapBufs[1].cbBuffer = msgSize; 96 | wrapBufs[1].BufferType = SECBUFFER_DATA; 97 | wrapBufs[1].pvBuffer = msg + sizes.cbSecurityTrailer; 98 | 99 | wrapBufs[2].cbBuffer = sizes.cbBlockSize; 100 | wrapBufs[2].BufferType = SECBUFFER_PADDING; 101 | wrapBufs[2].pvBuffer = msg + sizes.cbSecurityTrailer + msgSize; 102 | 103 | status = call_sspi_encrypt_message(context, SECQOP_WRAP_NO_ENCRYPT, &wrapBufDesc, 0); 104 | if (status != SEC_E_OK) { 105 | free(msg); 106 | return status; 107 | } 108 | 109 | *buffer_length = wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer + wrapBufs[2].cbBuffer; 110 | *buffer = malloc(*buffer_length); 111 | 112 | memcpy(*buffer, wrapBufs[0].pvBuffer, wrapBufs[0].cbBuffer); 113 | memcpy(*buffer + wrapBufs[0].cbBuffer, wrapBufs[1].pvBuffer, wrapBufs[1].cbBuffer); 114 | memcpy(*buffer + wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer, wrapBufs[2].pvBuffer, wrapBufs[2].cbBuffer); 115 | 116 | free(msg); 117 | return SEC_E_OK; 118 | } 119 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/internal/sasl/sasl_windows.go: -------------------------------------------------------------------------------- 1 | package sasl 2 | 3 | // #include "sasl_windows.h" 4 | import "C" 5 | 6 | import ( 7 | "fmt" 8 | "strings" 9 | "sync" 10 | "unsafe" 11 | ) 12 | 13 | type saslStepper interface { 14 | Step(serverData []byte) (clientData []byte, done bool, err error) 15 | Close() 16 | } 17 | 18 | type saslSession struct { 19 | // Credentials 20 | mech string 21 | service string 22 | host string 23 | userPlusRealm string 24 | target string 25 | domain string 26 | 27 | // Internal state 28 | authComplete bool 29 | errored bool 30 | step int 31 | 32 | // C internal state 33 | credHandle C.CredHandle 34 | context C.CtxtHandle 35 | hasContext C.int 36 | 37 | // Keep track of pointers we need to explicitly free 38 | stringsToFree []*C.char 39 | } 40 | 41 | var initError error 42 | var initOnce sync.Once 43 | 44 | func initSSPI() { 45 | rc := C.load_secur32_dll() 46 | if rc != 0 { 47 | initError = fmt.Errorf("Error loading libraries: %v", rc) 48 | } 49 | } 50 | 51 | func New(username, password, mechanism, service, host string) (saslStepper, error) { 52 | initOnce.Do(initSSPI) 53 | ss := &saslSession{mech: mechanism, hasContext: 0, userPlusRealm: username} 54 | if service == "" { 55 | service = "mongodb" 56 | } 57 | if i := strings.Index(host, ":"); i >= 0 { 58 | host = host[:i] 59 | } 60 | ss.service = service 61 | ss.host = host 62 | 63 | usernameComponents := strings.Split(username, "@") 64 | if len(usernameComponents) < 2 { 65 | return nil, fmt.Errorf("Username '%v' doesn't contain a realm!", username) 66 | } 67 | user := usernameComponents[0] 68 | ss.domain = usernameComponents[1] 69 | ss.target = fmt.Sprintf("%s/%s", ss.service, ss.host) 70 | 71 | var status C.SECURITY_STATUS 72 | // Step 0: call AcquireCredentialsHandle to get a nice SSPI CredHandle 73 | if len(password) > 0 { 74 | status = C.sspi_acquire_credentials_handle(&ss.credHandle, ss.cstr(user), ss.cstr(password), ss.cstr(ss.domain)) 75 | } else { 76 | status = C.sspi_acquire_credentials_handle(&ss.credHandle, ss.cstr(user), nil, ss.cstr(ss.domain)) 77 | } 78 | if status != C.SEC_E_OK { 79 | ss.errored = true 80 | return nil, fmt.Errorf("Couldn't create new SSPI client, error code %v", status) 81 | } 82 | return ss, nil 83 | } 84 | 85 | func (ss *saslSession) cstr(s string) *C.char { 86 | cstr := C.CString(s) 87 | ss.stringsToFree = append(ss.stringsToFree, cstr) 88 | return cstr 89 | } 90 | 91 | func (ss *saslSession) Close() { 92 | for _, cstr := range ss.stringsToFree { 93 | C.free(unsafe.Pointer(cstr)) 94 | } 95 | } 96 | 97 | func (ss *saslSession) Step(serverData []byte) (clientData []byte, done bool, err error) { 98 | ss.step++ 99 | if ss.step > 10 { 100 | return nil, false, fmt.Errorf("too many SSPI steps without authentication") 101 | } 102 | var buffer C.PVOID 103 | var bufferLength C.ULONG 104 | if len(serverData) > 0 { 105 | buffer = (C.PVOID)(unsafe.Pointer(&serverData[0])) 106 | bufferLength = C.ULONG(len(serverData)) 107 | } 108 | var status C.int 109 | if ss.authComplete { 110 | // Step 3: last bit of magic to use the correct server credentials 111 | status = C.sspi_send_client_authz_id(&ss.context, &buffer, &bufferLength, ss.cstr(ss.userPlusRealm)) 112 | } else { 113 | // Step 1 + Step 2: set up security context with the server and TGT 114 | status = C.sspi_step(&ss.credHandle, ss.hasContext, &ss.context, &buffer, &bufferLength, ss.cstr(ss.target)) 115 | } 116 | if buffer != C.PVOID(nil) { 117 | defer C.free(unsafe.Pointer(buffer)) 118 | } 119 | if status != C.SEC_E_OK && status != C.SEC_I_CONTINUE_NEEDED { 120 | ss.errored = true 121 | return nil, false, ss.handleSSPIErrorCode(status) 122 | } 123 | 124 | clientData = C.GoBytes(unsafe.Pointer(buffer), C.int(bufferLength)) 125 | if status == C.SEC_E_OK { 126 | ss.authComplete = true 127 | return clientData, true, nil 128 | } else { 129 | ss.hasContext = 1 130 | return clientData, false, nil 131 | } 132 | } 133 | 134 | func (ss *saslSession) handleSSPIErrorCode(code C.int) error { 135 | switch { 136 | case code == C.SEC_E_TARGET_UNKNOWN: 137 | return fmt.Errorf("Target %v@%v not found", ss.target, ss.domain) 138 | } 139 | return fmt.Errorf("Unknown error doing step %v, error code %v", ss.step, code) 140 | } 141 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/internal/sasl/sasl_windows.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "sspi_windows.h" 4 | 5 | SECURITY_STATUS SEC_ENTRY sspi_acquire_credentials_handle(CredHandle* cred_handle, char* username, char* password, char* domain); 6 | int sspi_step(CredHandle* cred_handle, int has_context, CtxtHandle* context, PVOID* buffer, ULONG* buffer_length, char* target); 7 | int sspi_send_client_authz_id(CtxtHandle* context, PVOID* buffer, ULONG* buffer_length, char* user_plus_realm); 8 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/internal/sasl/sspi_windows.c: -------------------------------------------------------------------------------- 1 | // Code adapted from the NodeJS kerberos library: 2 | // 3 | // https://github.com/christkv/kerberos/tree/master/lib/win32/kerberos_sspi.c 4 | // 5 | // Under the terms of the Apache License, Version 2.0: 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | #include 10 | 11 | #include "sspi_windows.h" 12 | 13 | static HINSTANCE sspi_secur32_dll = NULL; 14 | 15 | int load_secur32_dll() 16 | { 17 | sspi_secur32_dll = LoadLibrary("secur32.dll"); 18 | if (sspi_secur32_dll == NULL) { 19 | return GetLastError(); 20 | } 21 | return 0; 22 | } 23 | 24 | SECURITY_STATUS SEC_ENTRY call_sspi_encrypt_message(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo) 25 | { 26 | if (sspi_secur32_dll == NULL) { 27 | return -1; 28 | } 29 | encryptMessage_fn pfn_encryptMessage = (encryptMessage_fn) GetProcAddress(sspi_secur32_dll, "EncryptMessage"); 30 | if (!pfn_encryptMessage) { 31 | return -2; 32 | } 33 | return (*pfn_encryptMessage)(phContext, fQOP, pMessage, MessageSeqNo); 34 | } 35 | 36 | SECURITY_STATUS SEC_ENTRY call_sspi_acquire_credentials_handle( 37 | LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse, 38 | void *pvLogonId, void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, 39 | PCredHandle phCredential, PTimeStamp ptsExpiry) 40 | { 41 | if (sspi_secur32_dll == NULL) { 42 | return -1; 43 | } 44 | acquireCredentialsHandle_fn pfn_acquireCredentialsHandle; 45 | #ifdef _UNICODE 46 | pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn) GetProcAddress(sspi_secur32_dll, "AcquireCredentialsHandleW"); 47 | #else 48 | pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn) GetProcAddress(sspi_secur32_dll, "AcquireCredentialsHandleA"); 49 | #endif 50 | if (!pfn_acquireCredentialsHandle) { 51 | return -2; 52 | } 53 | return (*pfn_acquireCredentialsHandle)( 54 | pszPrincipal, pszPackage, fCredentialUse, pvLogonId, pAuthData, 55 | pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry); 56 | } 57 | 58 | SECURITY_STATUS SEC_ENTRY call_sspi_initialize_security_context( 59 | PCredHandle phCredential, PCtxtHandle phContext, LPSTR pszTargetName, 60 | unsigned long fContextReq, unsigned long Reserved1, unsigned long TargetDataRep, 61 | PSecBufferDesc pInput, unsigned long Reserved2, PCtxtHandle phNewContext, 62 | PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry) 63 | { 64 | if (sspi_secur32_dll == NULL) { 65 | return -1; 66 | } 67 | initializeSecurityContext_fn pfn_initializeSecurityContext; 68 | #ifdef _UNICODE 69 | pfn_initializeSecurityContext = (initializeSecurityContext_fn) GetProcAddress(sspi_secur32_dll, "InitializeSecurityContextW"); 70 | #else 71 | pfn_initializeSecurityContext = (initializeSecurityContext_fn) GetProcAddress(sspi_secur32_dll, "InitializeSecurityContextA"); 72 | #endif 73 | if (!pfn_initializeSecurityContext) { 74 | return -2; 75 | } 76 | return (*pfn_initializeSecurityContext)( 77 | phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, 78 | pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); 79 | } 80 | 81 | SECURITY_STATUS SEC_ENTRY call_sspi_query_context_attributes(PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer) 82 | { 83 | if (sspi_secur32_dll == NULL) { 84 | return -1; 85 | } 86 | queryContextAttributes_fn pfn_queryContextAttributes; 87 | #ifdef _UNICODE 88 | pfn_queryContextAttributes = (queryContextAttributes_fn) GetProcAddress(sspi_secur32_dll, "QueryContextAttributesW"); 89 | #else 90 | pfn_queryContextAttributes = (queryContextAttributes_fn) GetProcAddress(sspi_secur32_dll, "QueryContextAttributesA"); 91 | #endif 92 | if (!pfn_queryContextAttributes) { 93 | return -2; 94 | } 95 | return (*pfn_queryContextAttributes)(phContext, ulAttribute, pBuffer); 96 | } 97 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/internal/sasl/sspi_windows.h: -------------------------------------------------------------------------------- 1 | // Code adapted from the NodeJS kerberos library: 2 | // 3 | // https://github.com/christkv/kerberos/tree/master/lib/win32/kerberos_sspi.h 4 | // 5 | // Under the terms of the Apache License, Version 2.0: 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | #ifndef SSPI_WINDOWS_H 10 | #define SSPI_WINDOWS_H 11 | 12 | #define SECURITY_WIN32 1 13 | 14 | #include 15 | #include 16 | 17 | int load_secur32_dll(); 18 | 19 | SECURITY_STATUS SEC_ENTRY call_sspi_encrypt_message(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo); 20 | 21 | typedef DWORD (WINAPI *encryptMessage_fn)(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo); 22 | 23 | SECURITY_STATUS SEC_ENTRY call_sspi_acquire_credentials_handle( 24 | LPSTR pszPrincipal, // Name of principal 25 | LPSTR pszPackage, // Name of package 26 | unsigned long fCredentialUse, // Flags indicating use 27 | void *pvLogonId, // Pointer to logon ID 28 | void *pAuthData, // Package specific data 29 | SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func 30 | void *pvGetKeyArgument, // Value to pass to GetKey() 31 | PCredHandle phCredential, // (out) Cred Handle 32 | PTimeStamp ptsExpiry // (out) Lifetime (optional) 33 | ); 34 | 35 | typedef DWORD (WINAPI *acquireCredentialsHandle_fn)( 36 | LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse, 37 | void *pvLogonId, void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, 38 | PCredHandle phCredential, PTimeStamp ptsExpiry 39 | ); 40 | 41 | SECURITY_STATUS SEC_ENTRY call_sspi_initialize_security_context( 42 | PCredHandle phCredential, // Cred to base context 43 | PCtxtHandle phContext, // Existing context (OPT) 44 | LPSTR pszTargetName, // Name of target 45 | unsigned long fContextReq, // Context Requirements 46 | unsigned long Reserved1, // Reserved, MBZ 47 | unsigned long TargetDataRep, // Data rep of target 48 | PSecBufferDesc pInput, // Input Buffers 49 | unsigned long Reserved2, // Reserved, MBZ 50 | PCtxtHandle phNewContext, // (out) New Context handle 51 | PSecBufferDesc pOutput, // (inout) Output Buffers 52 | unsigned long *pfContextAttr, // (out) Context attrs 53 | PTimeStamp ptsExpiry // (out) Life span (OPT) 54 | ); 55 | 56 | typedef DWORD (WINAPI *initializeSecurityContext_fn)( 57 | PCredHandle phCredential, PCtxtHandle phContext, LPSTR pszTargetName, unsigned long fContextReq, 58 | unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput, unsigned long Reserved2, 59 | PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry); 60 | 61 | SECURITY_STATUS SEC_ENTRY call_sspi_query_context_attributes( 62 | PCtxtHandle phContext, // Context to query 63 | unsigned long ulAttribute, // Attribute to query 64 | void *pBuffer // Buffer for attributes 65 | ); 66 | 67 | typedef DWORD (WINAPI *queryContextAttributes_fn)( 68 | PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer); 69 | 70 | #endif // SSPI_WINDOWS_H 71 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/log.go: -------------------------------------------------------------------------------- 1 | // mgo - MongoDB driver for Go 2 | // 3 | // Copyright (c) 2010-2012 - Gustavo Niemeyer 4 | // 5 | // All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without 8 | // modification, are permitted provided that the following conditions are met: 9 | // 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | package mgo 28 | 29 | import ( 30 | "fmt" 31 | "sync" 32 | ) 33 | 34 | // --------------------------------------------------------------------------- 35 | // Logging integration. 36 | 37 | // Avoid importing the log type information unnecessarily. There's a small cost 38 | // associated with using an interface rather than the type. Depending on how 39 | // often the logger is plugged in, it would be worth using the type instead. 40 | type log_Logger interface { 41 | Output(calldepth int, s string) error 42 | } 43 | 44 | var ( 45 | globalLogger log_Logger 46 | globalDebug bool 47 | globalMutex sync.Mutex 48 | ) 49 | 50 | // RACE WARNING: There are known data races when logging, which are manually 51 | // silenced when the race detector is in use. These data races won't be 52 | // observed in typical use, because logging is supposed to be set up once when 53 | // the application starts. Having raceDetector as a constant, the compiler 54 | // should elide the locks altogether in actual use. 55 | 56 | // Specify the *log.Logger object where log messages should be sent to. 57 | func SetLogger(logger log_Logger) { 58 | if raceDetector { 59 | globalMutex.Lock() 60 | defer globalMutex.Unlock() 61 | } 62 | globalLogger = logger 63 | } 64 | 65 | // Enable the delivery of debug messages to the logger. Only meaningful 66 | // if a logger is also set. 67 | func SetDebug(debug bool) { 68 | if raceDetector { 69 | globalMutex.Lock() 70 | defer globalMutex.Unlock() 71 | } 72 | globalDebug = debug 73 | } 74 | 75 | func log(v ...interface{}) { 76 | if raceDetector { 77 | globalMutex.Lock() 78 | defer globalMutex.Unlock() 79 | } 80 | if globalLogger != nil { 81 | globalLogger.Output(2, fmt.Sprint(v...)) 82 | } 83 | } 84 | 85 | func logln(v ...interface{}) { 86 | if raceDetector { 87 | globalMutex.Lock() 88 | defer globalMutex.Unlock() 89 | } 90 | if globalLogger != nil { 91 | globalLogger.Output(2, fmt.Sprintln(v...)) 92 | } 93 | } 94 | 95 | func logf(format string, v ...interface{}) { 96 | if raceDetector { 97 | globalMutex.Lock() 98 | defer globalMutex.Unlock() 99 | } 100 | if globalLogger != nil { 101 | globalLogger.Output(2, fmt.Sprintf(format, v...)) 102 | } 103 | } 104 | 105 | func debug(v ...interface{}) { 106 | if raceDetector { 107 | globalMutex.Lock() 108 | defer globalMutex.Unlock() 109 | } 110 | if globalDebug && globalLogger != nil { 111 | globalLogger.Output(2, fmt.Sprint(v...)) 112 | } 113 | } 114 | 115 | func debugln(v ...interface{}) { 116 | if raceDetector { 117 | globalMutex.Lock() 118 | defer globalMutex.Unlock() 119 | } 120 | if globalDebug && globalLogger != nil { 121 | globalLogger.Output(2, fmt.Sprintln(v...)) 122 | } 123 | } 124 | 125 | func debugf(format string, v ...interface{}) { 126 | if raceDetector { 127 | globalMutex.Lock() 128 | defer globalMutex.Unlock() 129 | } 130 | if globalDebug && globalLogger != nil { 131 | globalLogger.Output(2, fmt.Sprintf(format, v...)) 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/queue.go: -------------------------------------------------------------------------------- 1 | // mgo - MongoDB driver for Go 2 | // 3 | // Copyright (c) 2010-2012 - Gustavo Niemeyer 4 | // 5 | // All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without 8 | // modification, are permitted provided that the following conditions are met: 9 | // 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | package mgo 28 | 29 | type queue struct { 30 | elems []interface{} 31 | nelems, popi, pushi int 32 | } 33 | 34 | func (q *queue) Len() int { 35 | return q.nelems 36 | } 37 | 38 | func (q *queue) Push(elem interface{}) { 39 | //debugf("Pushing(pushi=%d popi=%d cap=%d): %#v\n", 40 | // q.pushi, q.popi, len(q.elems), elem) 41 | if q.nelems == len(q.elems) { 42 | q.expand() 43 | } 44 | q.elems[q.pushi] = elem 45 | q.nelems++ 46 | q.pushi = (q.pushi + 1) % len(q.elems) 47 | //debugf(" Pushed(pushi=%d popi=%d cap=%d): %#v\n", 48 | // q.pushi, q.popi, len(q.elems), elem) 49 | } 50 | 51 | func (q *queue) Pop() (elem interface{}) { 52 | //debugf("Popping(pushi=%d popi=%d cap=%d)\n", 53 | // q.pushi, q.popi, len(q.elems)) 54 | if q.nelems == 0 { 55 | return nil 56 | } 57 | elem = q.elems[q.popi] 58 | q.elems[q.popi] = nil // Help GC. 59 | q.nelems-- 60 | q.popi = (q.popi + 1) % len(q.elems) 61 | //debugf(" Popped(pushi=%d popi=%d cap=%d): %#v\n", 62 | // q.pushi, q.popi, len(q.elems), elem) 63 | return elem 64 | } 65 | 66 | func (q *queue) expand() { 67 | curcap := len(q.elems) 68 | var newcap int 69 | if curcap == 0 { 70 | newcap = 8 71 | } else if curcap < 1024 { 72 | newcap = curcap * 2 73 | } else { 74 | newcap = curcap + (curcap / 4) 75 | } 76 | elems := make([]interface{}, newcap) 77 | 78 | if q.popi == 0 { 79 | copy(elems, q.elems) 80 | q.pushi = curcap 81 | } else { 82 | newpopi := newcap - (curcap - q.popi) 83 | copy(elems, q.elems[:q.popi]) 84 | copy(elems[newpopi:], q.elems[q.popi:]) 85 | q.popi = newpopi 86 | } 87 | for i := range q.elems { 88 | q.elems[i] = nil // Help GC. 89 | } 90 | q.elems = elems 91 | } 92 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/raceoff.go: -------------------------------------------------------------------------------- 1 | // +build !race 2 | 3 | package mgo 4 | 5 | const raceDetector = false 6 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/raceon.go: -------------------------------------------------------------------------------- 1 | // +build race 2 | 3 | package mgo 4 | 5 | const raceDetector = true 6 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/saslimpl.go: -------------------------------------------------------------------------------- 1 | //+build sasl 2 | 3 | package mgo 4 | 5 | import ( 6 | "gopkg.in/mgo.v2/internal/sasl" 7 | ) 8 | 9 | func saslNew(cred Credential, host string) (saslStepper, error) { 10 | return sasl.New(cred.Username, cred.Password, cred.Mechanism, cred.Service, host) 11 | } 12 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/saslstub.go: -------------------------------------------------------------------------------- 1 | //+build !sasl 2 | 3 | package mgo 4 | 5 | import ( 6 | "fmt" 7 | ) 8 | 9 | func saslNew(cred Credential, host string) (saslStepper, error) { 10 | return nil, fmt.Errorf("SASL support not enabled during build (-tags sasl)") 11 | } 12 | -------------------------------------------------------------------------------- /vendor/gopkg.in/mgo.v2/stats.go: -------------------------------------------------------------------------------- 1 | // mgo - MongoDB driver for Go 2 | // 3 | // Copyright (c) 2010-2012 - Gustavo Niemeyer 4 | // 5 | // All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without 8 | // modification, are permitted provided that the following conditions are met: 9 | // 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | package mgo 28 | 29 | import ( 30 | "sync" 31 | ) 32 | 33 | var stats *Stats 34 | var statsMutex sync.Mutex 35 | 36 | func SetStats(enabled bool) { 37 | statsMutex.Lock() 38 | if enabled { 39 | if stats == nil { 40 | stats = &Stats{} 41 | } 42 | } else { 43 | stats = nil 44 | } 45 | statsMutex.Unlock() 46 | } 47 | 48 | func GetStats() (snapshot Stats) { 49 | statsMutex.Lock() 50 | snapshot = *stats 51 | statsMutex.Unlock() 52 | return 53 | } 54 | 55 | func ResetStats() { 56 | statsMutex.Lock() 57 | debug("Resetting stats") 58 | old := stats 59 | stats = &Stats{} 60 | // These are absolute values: 61 | stats.Clusters = old.Clusters 62 | stats.SocketsInUse = old.SocketsInUse 63 | stats.SocketsAlive = old.SocketsAlive 64 | stats.SocketRefs = old.SocketRefs 65 | statsMutex.Unlock() 66 | return 67 | } 68 | 69 | type Stats struct { 70 | Clusters int 71 | MasterConns int 72 | SlaveConns int 73 | SentOps int 74 | ReceivedOps int 75 | ReceivedDocs int 76 | SocketsAlive int 77 | SocketsInUse int 78 | SocketRefs int 79 | } 80 | 81 | func (stats *Stats) cluster(delta int) { 82 | if stats != nil { 83 | statsMutex.Lock() 84 | stats.Clusters += delta 85 | statsMutex.Unlock() 86 | } 87 | } 88 | 89 | func (stats *Stats) conn(delta int, master bool) { 90 | if stats != nil { 91 | statsMutex.Lock() 92 | if master { 93 | stats.MasterConns += delta 94 | } else { 95 | stats.SlaveConns += delta 96 | } 97 | statsMutex.Unlock() 98 | } 99 | } 100 | 101 | func (stats *Stats) sentOps(delta int) { 102 | if stats != nil { 103 | statsMutex.Lock() 104 | stats.SentOps += delta 105 | statsMutex.Unlock() 106 | } 107 | } 108 | 109 | func (stats *Stats) receivedOps(delta int) { 110 | if stats != nil { 111 | statsMutex.Lock() 112 | stats.ReceivedOps += delta 113 | statsMutex.Unlock() 114 | } 115 | } 116 | 117 | func (stats *Stats) receivedDocs(delta int) { 118 | if stats != nil { 119 | statsMutex.Lock() 120 | stats.ReceivedDocs += delta 121 | statsMutex.Unlock() 122 | } 123 | } 124 | 125 | func (stats *Stats) socketsInUse(delta int) { 126 | if stats != nil { 127 | statsMutex.Lock() 128 | stats.SocketsInUse += delta 129 | statsMutex.Unlock() 130 | } 131 | } 132 | 133 | func (stats *Stats) socketsAlive(delta int) { 134 | if stats != nil { 135 | statsMutex.Lock() 136 | stats.SocketsAlive += delta 137 | statsMutex.Unlock() 138 | } 139 | } 140 | 141 | func (stats *Stats) socketRefs(delta int) { 142 | if stats != nil { 143 | statsMutex.Lock() 144 | stats.SocketRefs += delta 145 | statsMutex.Unlock() 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /web/router.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | logger "github.com/Sirupsen/logrus" 5 | "github.com/gorilla/mux" 6 | "github.com/sebastienfr/handsongo/utils" 7 | "net/http" 8 | ) 9 | 10 | // Router is the struct use for routing 11 | type Router struct { 12 | *mux.Router 13 | } 14 | 15 | // Route is a structure of Route 16 | type Route struct { 17 | Name string 18 | Method string 19 | Pattern string 20 | HandlerFunc http.HandlerFunc 21 | } 22 | 23 | // NewRouter creates a new router instance 24 | func NewRouter(handler *SpiritHandler) *Router { 25 | // new router 26 | router := Router{mux.NewRouter()} 27 | 28 | // default JSON not found handler 29 | router.NotFoundHandler = utils.NotFoundHandler() 30 | 31 | // no strict slash 32 | router.StrictSlash(false) 33 | 34 | // add routes of handler 35 | for _, route := range handler.Routes { 36 | logger.WithField("route", route).Debug("adding route to mux") 37 | router. 38 | Methods(route.Method). 39 | Path(handler.Prefix + route.Pattern). 40 | Name(route.Name). 41 | Handler(route.HandlerFunc) 42 | } 43 | 44 | return &router 45 | } 46 | -------------------------------------------------------------------------------- /web/statistics-middleware.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | "github.com/sebastienfr/handsongo/utils" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | // StatisticsMiddleware is the middleware to record request statistics 10 | type StatisticsMiddleware struct { 11 | Stat *utils.Statistics 12 | } 13 | 14 | // NewStatisticsMiddleware creates a new statistics middleware 15 | func NewStatisticsMiddleware(duration time.Duration) *StatisticsMiddleware { 16 | return &StatisticsMiddleware{ 17 | Stat: utils.NewStatistics(duration), 18 | } 19 | } 20 | 21 | func (sm *StatisticsMiddleware) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 22 | sm.Stat.PlusOne() 23 | next(rw, r) 24 | } 25 | -------------------------------------------------------------------------------- /web/web-server.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | logger "github.com/Sirupsen/logrus" 5 | "github.com/meatballhat/negroni-logrus" 6 | "github.com/sebastienfr/handsongo/dao" 7 | "github.com/urfave/negroni" 8 | "time" 9 | ) 10 | 11 | // BuildWebServer constructs a new web server with the right DAO and spirits handler 12 | func BuildWebServer(db string, daoType int, statisticsDuration time.Duration) (*negroni.Negroni, error) { 13 | 14 | // spirit dao 15 | dao, err := dao.GetSpiritDAO(db, daoType) 16 | if err != nil { 17 | logger.WithField("error", err).WithField("connection string", db).Fatal("unable to connect to mongo db") 18 | return nil, err 19 | } 20 | 21 | // web server 22 | n := negroni.New() 23 | 24 | // new handler 25 | handler := NewSpiritHandler(dao) 26 | 27 | // new router 28 | router := NewRouter(handler) 29 | 30 | // add middleware for logging 31 | n.Use(negronilogrus.NewMiddlewareFromLogger(logger.StandardLogger(), "spirit")) 32 | 33 | // add recovery middleware in case of panic in handler func 34 | recovery := negroni.NewRecovery() 35 | recovery.PrintStack = false 36 | n.Use(recovery) 37 | 38 | // add statistics middleware 39 | n.Use(NewStatisticsMiddleware(statisticsDuration)) 40 | 41 | // add as many middleware as you like 42 | 43 | // handler goes last 44 | n.UseHandler(router) 45 | 46 | return n, nil 47 | } 48 | -------------------------------------------------------------------------------- /web/web_test.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/sebastienfr/handsongo/dao" 6 | "github.com/sebastienfr/handsongo/model" 7 | "net/http" 8 | "net/http/httptest" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | func TestSpiritHandlerGet(t *testing.T) { 14 | 15 | // get mock dao 16 | daoMock, _ := dao.GetSpiritDAO("", dao.DAOMock) 17 | handler := NewSpiritHandler(daoMock) 18 | 19 | // build a request 20 | req, err := http.NewRequest("GET", "localhost/spirits", nil) 21 | if err != nil { 22 | t.Fatal(err) 23 | } 24 | 25 | // build the recorder 26 | res := httptest.NewRecorder() 27 | 28 | // execute the query 29 | handler.GetAll(res, req) 30 | 31 | var spiritOut []model.Spirit 32 | json.NewDecoder(res.Body).Decode(&spiritOut) 33 | 34 | if err != nil { 35 | t.Errorf("Unable to get JSON content %v", err) 36 | } 37 | 38 | if res.Code != http.StatusOK { 39 | t.Error("Wrong response code") 40 | } 41 | 42 | if dao.MockedSpirit != spiritOut[0] { 43 | t.Errorf("Expected different from %v output %v", dao.MockedSpirit, spiritOut[0]) 44 | } 45 | } 46 | 47 | func TestSpiritHandlerGetServer(t *testing.T) { 48 | 49 | srv, err := BuildWebServer("", dao.DAOMock, 250*time.Millisecond) 50 | 51 | if err != nil { 52 | t.Error(err) 53 | } 54 | 55 | ts := httptest.NewServer(srv) 56 | defer ts.Close() 57 | 58 | res, err := http.Get(ts.URL + "/spirits") 59 | 60 | if err != nil { 61 | t.Error(err) 62 | } 63 | 64 | var resSpirit []model.Spirit 65 | err = json.NewDecoder(res.Body).Decode(&resSpirit) 66 | 67 | if err != nil { 68 | t.Errorf("Unable to get JSON content %v", err) 69 | } 70 | 71 | res.Body.Close() 72 | 73 | if res.StatusCode != http.StatusOK { 74 | t.Error("Wrong response code") 75 | } 76 | 77 | if resSpirit[0] != dao.MockedSpirit { 78 | t.Error("Wrong response body") 79 | } 80 | } 81 | 82 | func BenchmarkSpiritHandlerGet(t *testing.B) { 83 | 84 | // tooling purpose 85 | _ = new([45000]int) 86 | 87 | // get mock dao 88 | daoMock, _ := dao.GetSpiritDAO("", dao.DAOMock) 89 | handler := NewSpiritHandler(daoMock) 90 | 91 | // build a request 92 | req, err := http.NewRequest("GET", "localhost/spirits", nil) 93 | if err != nil { 94 | t.Fatal(err) 95 | } 96 | 97 | // build the recorder 98 | res := httptest.NewRecorder() 99 | 100 | // execute the query 101 | handler.GetAll(res, req) 102 | 103 | var spiritOut []model.Spirit 104 | err = json.NewDecoder(res.Body).Decode(&spiritOut) 105 | 106 | if err != nil { 107 | t.Errorf("Unable to get JSON content %v", err) 108 | } 109 | 110 | expected := model.Spirit{ 111 | Name: "Caroni", 112 | Distiller: "Caroni", 113 | Bottler: "Velier", 114 | Country: "Trinidad", 115 | Composition: "Molasse", 116 | SpiritType: model.TypeRhum, 117 | Age: 15, 118 | BottlingDate: time.Date(2015, 01, 01, 0, 0, 0, 0, time.UTC), 119 | Score: 8.5, 120 | Comment: "heavy tire taste", 121 | } 122 | 123 | if expected != spiritOut[0] { 124 | t.Errorf("Expected different from %v output %v", expected, spiritOut) 125 | } 126 | } 127 | --------------------------------------------------------------------------------