This commit is contained in:
Brad Rydzewski 2016-04-19 11:53:52 -07:00
Родитель 00bc4a80fa
Коммит 2809c850e4
26 изменённых файлов: 637 добавлений и 248 удалений

Просмотреть файл

@ -11,7 +11,7 @@ import (
"github.com/lgtmco/lgtm/shared/token"
"github.com/lgtmco/lgtm/store"
log "github.com/Sirupsen/logrus"
"github.com/Sirupsen/logrus"
"github.com/gin-gonic/gin"
)
@ -20,7 +20,7 @@ func GetRepos(c *gin.Context) {
user := session.User(c)
repos, err := cache.GetRepos(c, user)
if err != nil {
log.Errorf("Error getting remote repository list. %s", err)
logrus.Errorf("Error getting remote repository list. %s", err)
c.String(500, "Error getting remote repository list")
return
}
@ -32,7 +32,7 @@ func GetRepos(c *gin.Context) {
repom, err := store.GetRepoIntersectMap(c, repos)
if err != nil {
log.Errorf("Error getting active repository list. %s", err)
logrus.Errorf("Error getting active repository list. %s", err)
c.String(500, "Error getting active repository list")
return
}
@ -45,7 +45,7 @@ func GetRepos(c *gin.Context) {
repoc[i] = repo_
}
}
c.IndentedJSON(200, repoc)
c.JSON(200, repoc)
}
// GetRepo gets the repository by slug.
@ -56,7 +56,7 @@ func GetRepo(c *gin.Context) {
)
repo, err := store.GetRepoOwnerName(c, owner, name)
if err != nil {
log.Errorf("Error getting repository %s. %s", name, err)
logrus.Errorf("Error getting repository %s. %s", name, err)
c.String(404, "Error getting repository %s", name)
return
}
@ -111,7 +111,7 @@ func PostRepo(c *gin.Context) {
c.String(500, "Error activating the repository. %s", err)
return
}
c.IndentedJSON(200, repo)
c.JSON(200, repo)
}
// DeleteRepo deletes a repository configuration.
@ -123,13 +123,13 @@ func DeleteRepo(c *gin.Context) {
)
repo, err := store.GetRepoOwnerName(c, owner, name)
if err != nil {
log.Errorf("Error getting repository %s. %s", name, err)
logrus.Errorf("Error getting repository %s. %s", name, err)
c.AbortWithStatus(404)
return
}
err = store.DeleteRepo(c, repo)
if err != nil {
log.Errorf("Error deleting repository %s. %s", name, err)
logrus.Errorf("Error deleting repository %s. %s", name, err)
c.AbortWithStatus(500)
return
}
@ -139,7 +139,7 @@ func DeleteRepo(c *gin.Context) {
)
err = remote.DelHook(c, user, repo, link)
if err != nil {
log.Errorf("Error deleting repository hook for %s. %s", name, err)
logrus.Errorf("Error deleting repository hook for %s. %s", name, err)
}
c.String(200, "")
}

Просмотреть файл

@ -5,7 +5,7 @@ import (
"github.com/lgtmco/lgtm/model"
"github.com/lgtmco/lgtm/router/middleware/session"
log "github.com/Sirupsen/logrus"
"github.com/Sirupsen/logrus"
"github.com/gin-gonic/gin"
)
@ -14,7 +14,7 @@ func GetTeams(c *gin.Context) {
user := session.User(c)
teams, err := cache.GetTeams(c, user)
if err != nil {
log.Errorf("Error getting team list. %s", err)
logrus.Errorf("Error getting teams for user %s. %s", user.Login, err)
c.String(500, "Error getting team list")
return
}

79
api/teams_test.go Normal file
Просмотреть файл

@ -0,0 +1,79 @@
package api
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/lgtmco/lgtm/model"
cache "github.com/lgtmco/lgtm/cache/mock"
remote "github.com/lgtmco/lgtm/remote/mock"
"github.com/Sirupsen/logrus"
"github.com/franela/goblin"
"github.com/gin-gonic/gin"
)
func TestTeams(t *testing.T) {
gin.SetMode(gin.TestMode)
logrus.SetOutput(ioutil.Discard)
g := goblin.Goblin(t)
g.Describe("Team endpoint", func() {
g.It("Should return the team list", func() {
cache := new(cache.Cache)
cache.On("Get", "teams:octocat").Return(fakeTeams, nil).Once()
e := gin.New()
e.NoRoute(GetTeams)
e.Use(func(c *gin.Context) {
c.Set("user", fakeUser)
c.Set("cache", cache)
})
w := httptest.NewRecorder()
r, _ := http.NewRequest("GET", "/", nil)
e.ServeHTTP(w, r)
// the user is appended to the team list so we retrieve a full list of
// accounts to which the user has access.
teams := append(fakeTeams, &model.Team{
Login: fakeUser.Login,
})
want, _ := json.Marshal(teams)
got := strings.TrimSpace(w.Body.String())
g.Assert(got).Equal(string(want))
g.Assert(w.Code).Equal(200)
})
g.It("Should return a 500 error", func() {
remote := new(remote.Remote)
cache := new(cache.Cache)
cache.On("Get", "teams:octocat").Return(nil, fmt.Errorf("Not Found")).Once()
remote.On("GetTeams", fakeUser).Return(nil, fmt.Errorf("Not Found")).Once()
e := gin.New()
e.NoRoute(GetTeams)
e.Use(func(c *gin.Context) {
c.Set("user", fakeUser)
c.Set("cache", cache)
c.Set("remote", remote)
})
w := httptest.NewRecorder()
r, _ := http.NewRequest("GET", "/", nil)
e.ServeHTTP(w, r)
got := strings.TrimSpace(w.Body.String())
g.Assert(got).Equal("Error getting team list")
g.Assert(w.Code).Equal(500)
})
})
}

51
api/user_test.go Normal file
Просмотреть файл

@ -0,0 +1,51 @@
package api
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/Sirupsen/logrus"
"github.com/lgtmco/lgtm/model"
"github.com/franela/goblin"
"github.com/gin-gonic/gin"
)
func TestUsers(t *testing.T) {
gin.SetMode(gin.TestMode)
logrus.SetOutput(ioutil.Discard)
g := goblin.Goblin(t)
g.Describe("User endpoint", func() {
g.It("Should return the authenticated user", func() {
e := gin.New()
e.NoRoute(GetUser)
e.Use(func(c *gin.Context) {
c.Set("user", fakeUser)
})
w := httptest.NewRecorder()
r, _ := http.NewRequest("GET", "/", nil)
e.ServeHTTP(w, r)
want, _ := json.Marshal(fakeUser)
got := strings.TrimSpace(w.Body.String())
g.Assert(got).Equal(string(want))
g.Assert(w.Code).Equal(200)
})
})
}
var (
fakeUser = &model.User{Login: "octocat"}
fakeTeams = []*model.Team{
{Login: "drone"},
{Login: "docker"},
}
)

2
vendor/github.com/gin-gonic/gin/CHANGELOG.md сгенерированный поставляемый
Просмотреть файл

@ -2,7 +2,7 @@
###Gin 1.0rc2 (...)
- [PERFORMANCE] Fast path for writting Content-Type.
- [PERFORMANCE] Fast path for writing Content-Type.
- [PERFORMANCE] Much faster 404 routing
- [PERFORMANCE] Allocation optimizations
- [PERFORMANCE] Faster root tree lookup

261
vendor/github.com/gin-gonic/gin/README.md сгенерированный поставляемый
Просмотреть файл

@ -1,18 +1,19 @@
#Gin Web Framework
<img align="right" src="https://s3.amazonaws.com/uploads.hipchat.com/36744/1498287/JVR32LgyEGCiy01/path4201%20copy%202.png">
<img align="right" src="https://raw.githubusercontent.com/gin-gonic/gin/master/logo.jpg">
[![Build Status](https://travis-ci.org/gin-gonic/gin.svg)](https://travis-ci.org/gin-gonic/gin)
[![Coverage Status](https://coveralls.io/repos/gin-gonic/gin/badge.svg?branch=master)](https://coveralls.io/r/gin-gonic/gin?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/gin-gonic/gin)](https://goreportcard.com/report/github.com/gin-gonic/gin)
[![GoDoc](https://godoc.org/github.com/gin-gonic/gin?status.svg)](https://godoc.org/github.com/gin-gonic/gin)
[![Join the chat at https://gitter.im/gin-gonic/gin](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gin-gonic/gin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Gin is a web framework written in Golang. It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin.
Gin is a web framework written in Go (Golang). It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin.
![Gin console logger](https://gin-gonic.github.io/gin/other/console.png)
```
```sh
$ cat test.go
```
```go
@ -23,9 +24,11 @@ import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run(":8080") // listen and serve on 0.0.0.0:8080
r.Run() // listen and server on 0.0.0.0:8080
}
```
@ -83,14 +86,21 @@ BenchmarkZeus_GithubAll | 2000 | 944234 | 300688 | 2648
## Start using it
1. Download and install it:
```sh
go get github.com/gin-gonic/gin
```
```sh
$ go get github.com/gin-gonic/gin
```
2. Import it in your code:
```go
import "github.com/gin-gonic/gin"
```
```go
import "github.com/gin-gonic/gin"
```
3. (Optional) Import `net/http`. This is required for example if using constants such as `http.StatusOK`.
```go
import "net/http"
```
##API Examples
@ -110,8 +120,10 @@ func main() {
router.HEAD("/someHead", head)
router.OPTIONS("/someOptions", options)
// Listen and server on 0.0.0.0:8080
router.Run(":8080")
// By default it serves on :8080 unless a
// PORT environment variable was defined.
router.Run()
// router.Run(":3000") for a hard coded port
}
```
@ -128,7 +140,7 @@ func main() {
})
// However, this one will match /user/john/ and also /user/john/send
// If no other routers match /user/john, it will redirect to /user/join/
// If no other routers match /user/john, it will redirect to /user/john/
router.GET("/user/:name/*action", func(c *gin.Context) {
name := c.Param("name")
action := c.Param("action")
@ -143,17 +155,17 @@ func main() {
#### Querystring parameters
```go
func main() {
router := gin.Default()
router := gin.Default()
// Query string parameters are parsed using the existing underlying request object.
// The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
router.GET("/welcome", func(c *gin.Context) {
firstname := c.DefaultQuery("firstname", "Guest")
lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
// Query string parameters are parsed using the existing underlying request object.
// The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
router.GET("/welcome", func(c *gin.Context) {
firstname := c.DefaultQuery("firstname", "Guest")
lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
})
router.Run(":8080")
c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
})
router.Run(":8080")
}
```
@ -161,18 +173,19 @@ func main() {
```go
func main() {
router := gin.Default()
router := gin.Default()
router.POST("/form_post", func(c *gin.Context) {
message := c.PostForm("message")
nick := c.DefaultPostForm("nick", "anonymous")
router.POST("/form_post", func(c *gin.Context) {
message := c.PostForm("message")
nick := c.DefaultPostForm("nick", "anonymous")
c.JSON(200, gin.H{
"status": "posted",
"message": message,
})
})
router.Run(":8080")
c.JSON(200, gin.H{
"status": "posted",
"message": message,
"nick": nick,
})
})
router.Run(":8080")
}
```
@ -190,21 +203,48 @@ func main() {
router := gin.Default()
router.POST("/post", func(c *gin.Context) {
id := c.Query("id")
page := c.DefaultQuery("id", "0")
name := c.PostForm("name")
message := c.PostForm("message")
fmt.Println("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
id := c.Query("id")
page := c.DefaultQuery("page", "0")
name := c.PostForm("name")
message := c.PostForm("message")
fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
})
router.Run(":8080")
}
```
```
id: 1234; page: 0; name: manu; message: this_is_great
id: 1234; page: 1; name: manu; message: this_is_great
```
### Another example: upload file
References issue [#548](https://github.com/gin-gonic/gin/issues/548).
```go
func main() {
router := gin.Default()
router.POST("/upload", func(c *gin.Context) {
file, header , err := c.Request.FormFile("upload")
filename := header.Filename
fmt.Println(header.Filename)
out, err := os.Create("./tmp/"+filename+".png")
if err != nil {
log.Fatal(err)
}
defer out.Close()
_, err = io.Copy(out, file)
if err != nil {
log.Fatal(err)
}
})
router.Run(":8080")
}
```
#### Grouping routes
```go
@ -261,7 +301,7 @@ func main() {
// Authorization group
// authorized := r.Group("/", AuthRequired())
// exactly the same than:
// exactly the same as:
authorized := r.Group("/")
// per group middleware! in this case we use the custom created
// AuthRequired() middleware just in the "authorized" group.
@ -301,30 +341,30 @@ type Login struct {
func main() {
router := gin.Default()
// Example for binding JSON ({"user": "manu", "password": "123"})
// Example for binding JSON ({"user": "manu", "password": "123"})
router.POST("/loginJSON", func(c *gin.Context) {
var json Login
if c.BindJSON(&json) == nil {
if json.User == "manu" && json.Password == "123" {
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
} else {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
}
}
if c.BindJSON(&json) == nil {
if json.User == "manu" && json.Password == "123" {
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
} else {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
}
}
})
// Example for binding a HTML form (user=manu&password=123)
router.POST("/loginForm", func(c *gin.Context) {
var form Login
// This will infer what binder to use depending on the content-type header.
if c.Bind(&form) == nil {
if form.User == "manu" && form.Password == "123" {
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
} else {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
}
}
})
// Example for binding a HTML form (user=manu&password=123)
router.POST("/loginForm", func(c *gin.Context) {
var form Login
// This will infer what binder to use depending on the content-type header.
if c.Bind(&form) == nil {
if form.User == "manu" && form.Password == "123" {
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
} else {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
}
}
})
// Listen and server on 0.0.0.0:8080
router.Run(":8080")
@ -353,21 +393,21 @@ func main() {
// c.BindWith(&form, binding.Form)
// or you can simply use autobinding with Bind method:
var form LoginForm
// in this case proper binding will be automatically selected
// in this case proper binding will be automatically selected
if c.Bind(&form) == nil {
if form.User == "user" && form.Password == "password" {
c.JSON(200, gin.H{"status": "you are logged in"})
} else {
c.JSON(401, gin.H{"status": "unauthorized"})
}
}
if form.User == "user" && form.Password == "password" {
c.JSON(200, gin.H{"status": "you are logged in"})
} else {
c.JSON(401, gin.H{"status": "unauthorized"})
}
}
})
router.Run(":8080")
}
```
Test it with:
```bash
```sh
$ curl -v --form user=user --form password=password http://localhost:8080/login
```
@ -411,13 +451,13 @@ func main() {
```go
func main() {
router := gin.Default()
router.Static("/assets", "./assets")
router.StaticFS("/more_static", http.Dir("my_file_system"))
router.StaticFile("/favicon.ico", "./resources/favicon.ico")
router := gin.Default()
router.Static("/assets", "./assets")
router.StaticFS("/more_static", http.Dir("my_file_system"))
router.StaticFile("/favicon.ico", "./resources/favicon.ico")
// Listen and server on 0.0.0.0:8080
router.Run(":8080")
// Listen and server on 0.0.0.0:8080
router.Run(":8080")
}
```
@ -438,11 +478,53 @@ func main() {
router.Run(":8080")
}
```
templates/index.tmpl
```html
<html>
<h1>
{{ .title }}
</h1>
</html>
```
Using templates with same name in different directories
```go
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/**/*")
router.GET("/posts/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
"title": "Posts",
})
})
router.GET("/users/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
"title": "Users",
})
})
router.Run(":8080")
}
```
templates/posts/index.tmpl
```html
{{ define "posts/index.tmpl" }}
<html><h1>
{{ .title }}
</h1>
<p>Using posts/index.tmpl</p>
</html>
{{ end }}
```
templates/users/index.tmpl
```html
{{ define "users/index.tmpl" }}
<html><h1>
{{ .title }}
</h1>
<p>Using users/index.tmpl</p>
</html>
{{ end }}
```
You can also use your own html template render
@ -535,7 +617,7 @@ func main() {
// /admin/secrets endpoint
// hit "localhost:8080/admin/secrets
authorized.GET("/secrets", func(c *gin.Context) {
// get user, it was setted by the BasicAuth middleware
// get user, it was set by the BasicAuth middleware
user := c.MustGet(gin.AuthUserKey).(string)
if secret, ok := secrets[user]; ok {
c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
@ -559,17 +641,16 @@ func main() {
r.GET("/long_async", func(c *gin.Context) {
// create copy to be used inside the goroutine
c_cp := c.Copy()
cCp := c.Copy()
go func() {
// simulate a long task with time.Sleep(). 5 seconds
time.Sleep(5 * time.Second)
// note than you are using the copied context "c_cp", IMPORTANT
log.Println("Done! in path " + c_cp.Request.URL.Path)
// note that you are using the copied context "cCp", IMPORTANT
log.Println("Done! in path " + cCp.Request.URL.Path)
}()
})
r.GET("/long_sync", func(c *gin.Context) {
// simulate a long task with time.Sleep(). 5 seconds
time.Sleep(5 * time.Second)
@ -578,8 +659,8 @@ func main() {
log.Println("Done! in path " + c.Request.URL.Path)
})
// Listen and server on 0.0.0.0:8080
r.Run(":8080")
// Listen and server on 0.0.0.0:8080
r.Run(":8080")
}
```
@ -609,3 +690,21 @@ func main() {
s.ListenAndServe()
}
```
#### Graceful restart or stop
Do you want to graceful restart or stop your web server?
There are some ways this can be done.
We can use [fvbock/endless](https://github.com/fvbock/endless) to replace the default `ListenAndServe`. Refer issue [#296](https://github.com/gin-gonic/gin/issues/296) for more details.
```go
router := gin.Default()
router.GET("/", handler)
// [...]
endless.ListenAndServe(":4242", router)
```
An alternative to endless:
* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.

8
vendor/github.com/gin-gonic/gin/auth.go сгенерированный поставляемый
Просмотреть файл

@ -65,14 +65,10 @@ func BasicAuth(accounts Accounts) HandlerFunc {
}
func processAccounts(accounts Accounts) authPairs {
if len(accounts) == 0 {
panic("Empty list of authorized credentials")
}
assert1(len(accounts) > 0, "Empty list of authorized credentials")
pairs := make(authPairs, 0, len(accounts))
for user, password := range accounts {
if len(user) == 0 {
panic("User can not be empty")
}
assert1(len(user) > 0, "User can not be empty")
value := authorizationHeader(user, password)
pairs = append(pairs, authPair{
Value: value,

4
vendor/github.com/gin-gonic/gin/binding/binding.go сгенерированный поставляемый
Просмотреть файл

@ -14,6 +14,7 @@ const (
MIMEPlain = "text/plain"
MIMEPOSTForm = "application/x-www-form-urlencoded"
MIMEMultipartPOSTForm = "multipart/form-data"
MIMEPROTOBUF = "application/x-protobuf"
)
type Binding interface {
@ -38,6 +39,7 @@ var (
Form = formBinding{}
FormPost = formPostBinding{}
FormMultipart = formMultipartBinding{}
ProtoBuf = protobufBinding{}
)
func Default(method, contentType string) Binding {
@ -49,6 +51,8 @@ func Default(method, contentType string) Binding {
return JSON
case MIMEXML, MIMEXML2:
return XML
case MIMEPROTOBUF:
return ProtoBuf
default: //case MIMEPOSTForm, MIMEMultipartPOSTForm:
return Form
}

5
vendor/github.com/gin-gonic/gin/binding/default_validator.go сгенерированный поставляемый
Просмотреть файл

@ -4,7 +4,7 @@ import (
"reflect"
"sync"
"gopkg.in/bluesuncorp/validator.v5"
"gopkg.in/go-playground/validator.v8"
)
type defaultValidator struct {
@ -26,7 +26,8 @@ func (v *defaultValidator) ValidateStruct(obj interface{}) error {
func (v *defaultValidator) lazyinit() {
v.once.Do(func() {
v.validate = validator.New("binding", validator.BakedInValidators)
config := &validator.Config{TagName: "binding"}
v.validate = validator.New(config)
})
}

35
vendor/github.com/gin-gonic/gin/binding/protobuf.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,35 @@
// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package binding
import (
"github.com/golang/protobuf/proto"
"io/ioutil"
"net/http"
)
type protobufBinding struct{}
func (protobufBinding) Name() string {
return "protobuf"
}
func (protobufBinding) Bind(req *http.Request, obj interface{}) error {
buf, err := ioutil.ReadAll(req.Body)
if err != nil {
return err
}
if err = proto.Unmarshal(buf, obj.(proto.Message)); err != nil {
return err
}
//Here it's same to return validate(obj), but util now we cann't add `binding:""` to the struct
//which automatically generate by gen-proto
return nil
//return validate(obj)
}

191
vendor/github.com/gin-gonic/gin/context.go сгенерированный поставляемый
Просмотреть файл

@ -8,7 +8,9 @@ import (
"errors"
"io"
"math"
"net"
"net/http"
"net/url"
"strings"
"time"
@ -67,7 +69,7 @@ func (c *Context) reset() {
// Copy returns a copy of the current context that can be safely used outside the request's scope.
// This have to be used then the context has to be passed to a goroutine.
func (c *Context) Copy() *Context {
var cp Context = *c
var cp = *c
cp.writermem.ResponseWriter = nil
cp.Writer = &cp.writermem
cp.index = abortIndex
@ -75,7 +77,7 @@ func (c *Context) Copy() *Context {
return &cp
}
// HandlerName returns the main handle's name. For example if the handler is "handleGetUsers()", this
// HandlerName returns the main handler's name. For example if the handler is "handleGetUsers()", this
// function will return "main.handleGetUsers"
func (c *Context) HandlerName() string {
return nameOfFunction(c.handlers.Last())
@ -96,15 +98,15 @@ func (c *Context) Next() {
}
}
// IsAborted returns true if the currect context was aborted.
// IsAborted returns true if the current context was aborted.
func (c *Context) IsAborted() bool {
return c.index >= abortIndex
}
// Abort stops the system to continue calling the pending handlers in the chain.
// Let's say you have an authorization middleware that validates if the request is authorized
// if the authorization fails (the password does not match). This method (Abort()) should be called
// in order to stop the execution of the actual handler.
// Abort prevents pending handlers from being called. Note that this will not stop the current handler.
// Let's say you have an authorization middleware that validates that the current request is authorized. If the
// authorization fails (ex: the password does not match), call Abort to ensure the remaining handlers
// for this request are not called.
func (c *Context) Abort() {
c.index = abortIndex
}
@ -112,7 +114,8 @@ func (c *Context) Abort() {
// AbortWithStatus calls `Abort()` and writes the headers with the specified status code.
// For example, a failed attempt to authentificate a request could use: context.AbortWithStatus(401).
func (c *Context) AbortWithStatus(code int) {
c.Writer.WriteHeader(code)
c.Status(code)
c.Writer.WriteHeaderNow()
c.Abort()
}
@ -169,7 +172,7 @@ func (c *Context) Get(key string) (value interface{}, exists bool) {
return
}
// Returns the value for the given key if it exists, otherwise it panics.
// MustGet returns the value for the given key if it exists, otherwise it panics.
func (c *Context) MustGet(key string) interface{} {
if value, exists := c.Get(key); exists {
return value
@ -181,50 +184,52 @@ func (c *Context) MustGet(key string) interface{} {
/************ INPUT DATA ************/
/************************************/
// Query is a shortcut for c.Request.URL.Query().Get(key)
// It is used to return the url query values.
// ?id=1234&name=Manu
// c.Query("id") == "1234"
// c.Query("name") == "Manu"
// c.Query("wtf") == ""
func (c *Context) Query(key string) (va string) {
va, _ = c.query(key)
return
}
// PostForm is a shortcut for c.Request.PostFormValue(key)
func (c *Context) PostForm(key string) (va string) {
va, _ = c.postForm(key)
return
}
// Param is a shortcut for c.Params.ByName(key)
// Param returns the value of the URL param.
// It is a shortcut for c.Params.ByName(key)
// router.GET("/user/:id", func(c *gin.Context) {
// // a GET request to /user/john
// id := c.Param("id") // id == "john"
// })
func (c *Context) Param(key string) string {
return c.Params.ByName(key)
}
func (c *Context) DefaultPostForm(key, defaultValue string) string {
if va, ok := c.postForm(key); ok {
return va
}
return defaultValue
// Query returns the keyed url query value if it exists,
// othewise it returns an empty string `("")`.
// It is shortcut for `c.Request.URL.Query().Get(key)`
// GET /path?id=1234&name=Manu&value=
// c.Query("id") == "1234"
// c.Query("name") == "Manu"
// c.Query("value") == ""
// c.Query("wtf") == ""
func (c *Context) Query(key string) string {
value, _ := c.GetQuery(key)
return value
}
// DefaultQuery returns the keyed url query value if it exists, othewise it returns the
// specified defaultValue.
// ```
// /?name=Manu
// c.DefaultQuery("name", "unknown") == "Manu"
// c.DefaultQuery("id", "none") == "none"
// ```
// DefaultQuery returns the keyed url query value if it exists,
// othewise it returns the specified defaultValue string.
// See: Query() and GetQuery() for further information.
// GET /?name=Manu&lastname=
// c.DefaultQuery("name", "unknown") == "Manu"
// c.DefaultQuery("id", "none") == "none"
// c.DefaultQuery("lastname", "none") == ""
func (c *Context) DefaultQuery(key, defaultValue string) string {
if va, ok := c.query(key); ok {
return va
if value, ok := c.GetQuery(key); ok {
return value
}
return defaultValue
}
func (c *Context) query(key string) (string, bool) {
// GetQuery is like Query(), it returns the keyed url query value
// if it exists `(value, true)` (even when the value is an empty string),
// othewise it returns `("", false)`.
// It is shortcut for `c.Request.URL.Query().Get(key)`
// GET /?name=Manu&lastname=
// ("Manu", true) == c.GetQuery("name")
// ("", false) == c.GetQuery("id")
// ("", true) == c.GetQuery("lastname")
func (c *Context) GetQuery(key string) (string, bool) {
req := c.Request
if values, ok := req.URL.Query()[key]; ok && len(values) > 0 {
return values[0], true
@ -232,7 +237,31 @@ func (c *Context) query(key string) (string, bool) {
return "", false
}
func (c *Context) postForm(key string) (string, bool) {
// PostForm returns the specified key from a POST urlencoded form or multipart form
// when it exists, otherwise it returns an empty string `("")`.
func (c *Context) PostForm(key string) string {
value, _ := c.GetPostForm(key)
return value
}
// DefaultPostForm returns the specified key from a POST urlencoded form or multipart form
// when it exists, otherwise it returns the specified defaultValue string.
// See: PostForm() and GetPostForm() for further information.
func (c *Context) DefaultPostForm(key, defaultValue string) string {
if value, ok := c.GetPostForm(key); ok {
return value
}
return defaultValue
}
// GetPostForm is like PostForm(key). It returns the specified key from a POST urlencoded
// form or multipart form when it exists `(value, true)` (even when the value is an empty string),
// otherwise it returns ("", false).
// For example, during a PATCH request to update the user's email:
// email=mail@example.com --> ("mail@example.com", true) := GetPostForm("email") // set email to "mail@example.com"
// email= --> ("", true) := GetPostForm("email") // set email to ""
// --> ("", false) := GetPostForm("email") // do nothing with email
func (c *Context) GetPostForm(key string) (string, bool) {
req := c.Request
req.ParseMultipartForm(32 << 20) // 32 MB
if values := req.PostForm[key]; len(values) > 0 {
@ -248,10 +277,10 @@ func (c *Context) postForm(key string) (string, bool) {
// Bind checks the Content-Type to select a binding engine automatically,
// Depending the "Content-Type" header different bindings are used:
// "application/json" --> JSON binding
// "application/xml" --> XML binding
// "application/json" --> JSON binding
// "application/xml" --> XML binding
// otherwise --> returns an error
// If Parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input.
// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input.
// It decodes the json payload into the struct specified as a pointer.
// Like ParseBody() but this method also writes a 400 error if the json is not valid.
func (c *Context) Bind(obj interface{}) error {
@ -291,7 +320,10 @@ func (c *Context) ClientIP() string {
return clientIP
}
}
return strings.TrimSpace(c.Request.RemoteAddr)
if ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr)); err == nil {
return ip
}
return ""
}
// ContentType returns the Content-Type header of the request.
@ -310,6 +342,10 @@ func (c *Context) requestHeader(key string) string {
/******** RESPONSE RENDERING ********/
/************************************/
func (c *Context) Status(code int) {
c.writermem.WriteHeader(code)
}
// Header is a intelligent shortcut for c.Writer.Header().Set(key, value)
// It writes a header in the response.
// If value == "", this method removes the header `c.Writer.Header().Del(key)`
@ -321,16 +357,43 @@ func (c *Context) Header(key, value string) {
}
}
func (c *Context) Render(code int, r render.Render) {
c.writermem.WriteHeader(code)
if err := r.Render(c.Writer); err != nil {
c.renderError(err)
func (c *Context) SetCookie(
name string,
value string,
maxAge int,
path string,
domain string,
secure bool,
httpOnly bool,
) {
if path == "" {
path = "/"
}
http.SetCookie(c.Writer, &http.Cookie{
Name: name,
Value: url.QueryEscape(value),
MaxAge: maxAge,
Path: path,
Domain: domain,
Secure: secure,
HttpOnly: httpOnly,
})
}
func (c *Context) renderError(err error) {
debugPrintError(err)
c.AbortWithError(500, err).SetType(ErrorTypeRender)
func (c *Context) Cookie(name string) (string, error) {
cookie, err := c.Request.Cookie(name)
if err != nil {
return "", err
}
val, _ := url.QueryUnescape(cookie.Value)
return val, nil
}
func (c *Context) Render(code int, r render.Render) {
c.Status(code)
if err := r.Render(c.Writer); err != nil {
panic(err)
}
}
// HTML renders the HTTP template specified by its file name.
@ -352,9 +415,9 @@ func (c *Context) IndentedJSON(code int, obj interface{}) {
// JSON serializes the given struct as JSON into the response body.
// It also sets the Content-Type as "application/json".
func (c *Context) JSON(code int, obj interface{}) {
c.writermem.WriteHeader(code)
c.Status(code)
if err := render.WriteJSON(c.Writer, obj); err != nil {
c.renderError(err)
panic(err)
}
}
@ -364,9 +427,14 @@ func (c *Context) XML(code int, obj interface{}) {
c.Render(code, render.XML{Data: obj})
}
// YAML serializes the given struct as YAML into the response body.
func (c *Context) YAML(code int, obj interface{}) {
c.Render(code, render.YAML{Data: obj})
}
// String writes the given string into the response body.
func (c *Context) String(code int, format string, values ...interface{}) {
c.writermem.WriteHeader(code)
c.Status(code)
render.WriteString(c.Writer, format, values)
}
@ -408,9 +476,9 @@ func (c *Context) Stream(step func(w io.Writer) bool) {
case <-clientGone:
return
default:
keepopen := step(w)
keepOpen := step(w)
w.Flush()
if !keepopen {
if !keepOpen {
return
}
}
@ -450,9 +518,8 @@ func (c *Context) Negotiate(code int, config Negotiate) {
}
func (c *Context) NegotiateFormat(offered ...string) string {
if len(offered) == 0 {
panic("you must provide at least one offer")
}
assert1(len(offered) > 0, "you must provide at least one offer")
if c.Accepted == nil {
c.Accepted = parseAccept(c.requestHeader("Accept"))
}

2
vendor/github.com/gin-gonic/gin/debug.go сгенерированный поставляемый
Просмотреть файл

@ -24,7 +24,7 @@ func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) {
if IsDebugging() {
nuHandlers := len(handlers)
handlerName := nameOfFunction(handlers.Last())
debugPrint("%-5s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers)
debugPrint("%-6s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers)
}
}

7
vendor/github.com/gin-gonic/gin/deprecated.go сгенерированный поставляемый
Просмотреть файл

@ -3,3 +3,10 @@
// license that can be found in the LICENSE file.
package gin
import "log"
func (c *Context) GetCookie(name string) (string, error) {
log.Println("GetCookie() method is deprecated. Use Cookie() instead.")
return c.Cookie(name)
}

16
vendor/github.com/gin-gonic/gin/errors.go сгенерированный поставляемый
Просмотреть файл

@ -66,7 +66,7 @@ func (msg *Error) JSON() interface{} {
return json
}
// Implements the json.Marshaller interface
// MarshalJSON implements the json.Marshaller interface
func (msg *Error) MarshalJSON() ([]byte, error) {
return json.Marshal(msg.JSON())
}
@ -89,7 +89,7 @@ func (a errorMsgs) ByType(typ ErrorType) errorMsgs {
if typ == ErrorTypeAny {
return a
}
var result errorMsgs = nil
var result errorMsgs
for _, msg := range a {
if msg.IsType(typ) {
result = append(result, msg)
@ -109,13 +109,11 @@ func (a errorMsgs) Last() *Error {
}
// Returns an array will all the error messages.
// Example
// ```
// c.Error(errors.New("first"))
// c.Error(errors.New("second"))
// c.Error(errors.New("third"))
// c.Errors.Errors() // == []string{"first", "second", "third"}
// ``
// Example:
// c.Error(errors.New("first"))
// c.Error(errors.New("second"))
// c.Error(errors.New("third"))
// c.Errors.Errors() // == []string{"first", "second", "third"}
func (a errorMsgs) Errors() []string {
if len(a) == 0 {
return nil

36
vendor/github.com/gin-gonic/gin/gin.go сгенерированный поставляемый
Просмотреть файл

@ -14,7 +14,7 @@ import (
"github.com/gin-gonic/gin/render"
)
// Framework's version
// Version is Framework's version
const Version = "v1.0rc2"
var default404Body = []byte("404 page not found")
@ -113,7 +113,7 @@ func New() *Engine {
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *Engine {
engine := New()
engine.Use(Recovery(), Logger())
engine.Use(Logger(), Recovery())
return engine
}
@ -147,19 +147,19 @@ func (engine *Engine) SetHTMLTemplate(templ *template.Template) {
engine.HTMLRender = render.HTMLProduction{Template: templ}
}
// Adds handlers for NoRoute. It return a 404 code by default.
// NoRoute adds handlers for NoRoute. It return a 404 code by default.
func (engine *Engine) NoRoute(handlers ...HandlerFunc) {
engine.noRoute = handlers
engine.rebuild404Handlers()
}
// Sets the handlers called when... TODO
// NoMethod sets the handlers called when... TODO
func (engine *Engine) NoMethod(handlers ...HandlerFunc) {
engine.noMethod = handlers
engine.rebuild405Handlers()
}
// Attachs a global middleware to the router. ie. the middleware attached though Use() will be
// Use attachs a global middleware to the router. ie. the middleware attached though Use() will be
// included in the handlers chain for every single request. Even 404, 405, static files...
// For example, this is the right place for a logger or error management middleware.
func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {
@ -178,25 +178,15 @@ func (engine *Engine) rebuild405Handlers() {
}
func (engine *Engine) addRoute(method, path string, handlers HandlersChain) {
assert1(path[0] == '/', "path must begin with '/'")
assert1(len(method) > 0, "HTTP method can not be empty")
assert1(len(handlers) > 0, "there must be at least one handler")
debugPrintRoute(method, path, handlers)
if path[0] != '/' {
panic("path must begin with '/'")
}
if method == "" {
panic("HTTP method can not be empty")
}
if len(handlers) == 0 {
panic("there must be at least one handler")
}
root := engine.trees.get(method)
if root == nil {
root = new(node)
engine.trees = append(engine.trees, methodTree{
method: method,
root: root,
})
engine.trees = append(engine.trees, methodTree{method: method, root: root})
}
root.addRoute(path, handlers)
}
@ -227,7 +217,7 @@ func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo {
// Run attaches the router to a http.Server and starts listening and serving HTTP requests.
// It is a shortcut for http.ListenAndServe(addr, router)
// Note: this method will block the calling goroutine undefinitelly unless an error happens.
// Note: this method will block the calling goroutine indefinitely unless an error happens.
func (engine *Engine) Run(addr ...string) (err error) {
defer func() { debugPrintError(err) }()
@ -239,7 +229,7 @@ func (engine *Engine) Run(addr ...string) (err error) {
// RunTLS attaches the router to a http.Server and starts listening and serving HTTPS (secure) requests.
// It is a shortcut for http.ListenAndServeTLS(addr, certFile, keyFile, router)
// Note: this method will block the calling goroutine undefinitelly unless an error happens.
// Note: this method will block the calling goroutine indefinitely unless an error happens.
func (engine *Engine) RunTLS(addr string, certFile string, keyFile string) (err error) {
debugPrint("Listening and serving HTTPS on %s\n", addr)
defer func() { debugPrintError(err) }()
@ -250,7 +240,7 @@ func (engine *Engine) RunTLS(addr string, certFile string, keyFile string) (err
// RunUnix attaches the router to a http.Server and starts listening and serving HTTP requests
// through the specified unix socket (ie. a file).
// Note: this method will block the calling goroutine undefinitelly unless an error happens.
// Note: this method will block the calling goroutine indefinitely unless an error happens.
func (engine *Engine) RunUnix(file string) (err error) {
debugPrint("Listening and serving HTTP on unix:/%s", file)
defer func() { debugPrintError(err) }()

64
vendor/github.com/gin-gonic/gin/logger.go сгенерированный поставляемый
Просмотреть файл

@ -28,25 +28,32 @@ func ErrorLogger() HandlerFunc {
func ErrorLoggerT(typ ErrorType) HandlerFunc {
return func(c *Context) {
c.Next()
// avoid writting if we already wrote into the response body
if !c.Writer.Written() {
errors := c.Errors.ByType(typ)
if len(errors) > 0 {
c.JSON(-1, errors)
}
errors := c.Errors.ByType(typ)
if len(errors) > 0 {
c.JSON(-1, errors)
}
}
}
// Instances a Logger middleware that will write the logs to gin.DefaultWriter
// Logger instances a Logger middleware that will write the logs to gin.DefaultWriter
// By default gin.DefaultWriter = os.Stdout
func Logger() HandlerFunc {
return LoggerWithWriter(DefaultWriter)
}
// Instance a Logger middleware with the specified writter buffer.
// LoggerWithWriter instance a Logger middleware with the specified writter buffer.
// Example: os.Stdout, a file opened in write mode, a socket...
func LoggerWithWriter(out io.Writer) HandlerFunc {
func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
var skip map[string]struct{}
if length := len(notlogged); length > 0 {
skip = make(map[string]struct{}, length)
for _, path := range notlogged {
skip[path] = struct{}{}
}
}
return func(c *Context) {
// Start timer
start := time.Now()
@ -55,26 +62,29 @@ func LoggerWithWriter(out io.Writer) HandlerFunc {
// Process request
c.Next()
// Stop timer
end := time.Now()
latency := end.Sub(start)
// Log only when path is not being skipped
if _, ok := skip[path]; !ok {
// Stop timer
end := time.Now()
latency := end.Sub(start)
clientIP := c.ClientIP()
method := c.Request.Method
statusCode := c.Writer.Status()
statusColor := colorForStatus(statusCode)
methodColor := colorForMethod(method)
comment := c.Errors.ByType(ErrorTypePrivate).String()
clientIP := c.ClientIP()
method := c.Request.Method
statusCode := c.Writer.Status()
statusColor := colorForStatus(statusCode)
methodColor := colorForMethod(method)
comment := c.Errors.ByType(ErrorTypePrivate).String()
fmt.Fprintf(out, "[GIN] %v |%s %3d %s| %13v | %s |%s %s %-7s %s\n%s",
end.Format("2006/01/02 - 15:04:05"),
statusColor, statusCode, reset,
latency,
clientIP,
methodColor, reset, method,
path,
comment,
)
fmt.Fprintf(out, "[GIN] %v |%s %3d %s| %13v | %s |%s %s %-7s %s\n%s",
end.Format("2006/01/02 - 15:04:05"),
statusColor, statusCode, reset,
latency,
clientIP,
methodColor, reset, method,
path,
comment,
)
}
}
}

Двоичные данные
vendor/github.com/gin-gonic/gin/logo.jpg сгенерированный поставляемый Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 12 KiB

17
vendor/github.com/gin-gonic/gin/mode.go сгенерированный поставляемый
Просмотреть файл

@ -5,11 +5,9 @@
package gin
import (
"io"
"os"
"github.com/gin-gonic/gin/binding"
"github.com/mattn/go-colorable"
)
const ENV_GIN_MODE = "GIN_MODE"
@ -25,9 +23,18 @@ const (
testCode = iota
)
var DefaultWriter io.Writer = colorable.NewColorableStdout()
var ginMode int = debugCode
var modeName string = DebugMode
// DefaultWriter is the default io.Writer used the Gin for debug output and
// middleware output like Logger() or Recovery().
// Note that both Logger and Recovery provides custom ways to configure their
// output io.Writer.
// To support coloring in Windows use:
// import "github.com/mattn/go-colorable"
// gin.DefaultWriter = colorable.NewColorableStdout()
var DefaultWriter = os.Stdout
var DefaultErrorWriter = os.Stderr
var ginMode = debugCode
var modeName = DebugMode
func init() {
mode := os.Getenv(ENV_GIN_MODE)

8
vendor/github.com/gin-gonic/gin/recovery.go сгенерированный поставляемый
Просмотреть файл

@ -10,6 +10,7 @@ import (
"io"
"io/ioutil"
"log"
"net/http/httputil"
"runtime"
)
@ -22,20 +23,21 @@ var (
// Recovery returns a middleware that recovers from any panics and writes a 500 if there was one.
func Recovery() HandlerFunc {
return RecoveryWithWriter(DefaultWriter)
return RecoveryWithWriter(DefaultErrorWriter)
}
func RecoveryWithWriter(out io.Writer) HandlerFunc {
var logger *log.Logger
if out != nil {
logger = log.New(out, "", log.LstdFlags)
logger = log.New(out, "\n\n\x1b[31m", log.LstdFlags)
}
return func(c *Context) {
defer func() {
if err := recover(); err != nil {
if logger != nil {
stack := stack(3)
logger.Printf("Panic recovery -> %s\n%s\n", err, stack)
httprequest, _ := httputil.DumpRequest(c.Request, false)
logger.Printf("[Recovery] panic recovered:\n%s\n%s\n%s%s", string(httprequest), err, stack, reset)
}
c.AbortWithStatus(500)
}

3
vendor/github.com/gin-gonic/gin/render/html.go сгенерированный поставляемый
Просмотреть файл

@ -61,7 +61,6 @@ func (r HTML) Render(w http.ResponseWriter) error {
writeContentType(w, htmlContentType)
if len(r.Name) == 0 {
return r.Template.Execute(w, r.Data)
} else {
return r.Template.ExecuteTemplate(w, r.Name, r.Data)
}
return r.Template.ExecuteTemplate(w, r.Name, r.Data)
}

2
vendor/github.com/gin-gonic/gin/render/redirect.go сгенерированный поставляемый
Просмотреть файл

@ -16,7 +16,7 @@ type Redirect struct {
}
func (r Redirect) Render(w http.ResponseWriter) error {
if r.Code < 300 || r.Code > 308 {
if (r.Code < 300 || r.Code > 308) && r.Code != 201 {
panic(fmt.Sprintf("Cannot redirect with status code %d", r.Code))
}
http.Redirect(w, r.Request, r.Location, r.Code)

1
vendor/github.com/gin-gonic/gin/render/render.go сгенерированный поставляемый
Просмотреть файл

@ -20,6 +20,7 @@ var (
_ Render = HTML{}
_ HTMLRender = HTMLDebug{}
_ HTMLRender = HTMLProduction{}
_ Render = YAML{}
)
func writeContentType(w http.ResponseWriter, value []string) {

29
vendor/github.com/gin-gonic/gin/render/yaml.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,29 @@
// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package render
import (
"net/http"
"gopkg.in/yaml.v2"
)
type YAML struct {
Data interface{}
}
var yamlContentType = []string{"application/x-yaml; charset=utf-8"}
func (r YAML) Render(w http.ResponseWriter) error {
writeContentType(w, yamlContentType)
bytes, err := yaml.Marshal(r.Data)
if err != nil {
return err
}
w.Write(bytes)
return nil
}

17
vendor/github.com/gin-gonic/gin/tree.go сгенерированный поставляемый
Просмотреть файл

@ -20,7 +20,7 @@ type Param struct {
// It is therefore safe to read values by the index.
type Params []Param
// ByName returns the value of the first Param which key matches the given name.
// Get returns the value of the first Param which key matches the given name.
// If no matching Param is found, an empty string is returned.
func (ps Params) Get(name string) (string, bool) {
for _, entry := range ps {
@ -31,6 +31,8 @@ func (ps Params) Get(name string) (string, bool) {
return "", false
}
// ByName returns the value of the first Param which key matches the given name.
// If no matching Param is found, an empty string is returned.
func (ps Params) ByName(name string) (va string) {
va, _ = ps.Get(name)
return
@ -76,9 +78,10 @@ func countParams(path string) uint8 {
type nodeType uint8
const (
static nodeType = 0
param nodeType = 1
catchAll nodeType = 2
static nodeType = iota // default
root
param
catchAll
)
type node struct {
@ -238,6 +241,7 @@ func (n *node) addRoute(path string, handlers HandlersChain) {
}
} else { // Empty tree
n.insertChild(numParams, path, fullPath, handlers)
n.nType = root
}
}
@ -452,6 +456,11 @@ walk: // Outer loop for walking the tree
return
}
if path == "/" && n.wildChild && n.nType != root {
tsr = true
return
}
// No handle found. Check if a handle for this path + a
// trailing slash exists for trailing slash recommendation
for i := 0; i < len(n.indices); i++ {

13
vendor/github.com/gin-gonic/gin/utils.go сгенерированный поставляемый
Просмотреть файл

@ -47,7 +47,7 @@ func WrapH(h http.Handler) HandlerFunc {
type H map[string]interface{}
// Allows type H to be used with xml.Marshal
// MarshalXML allows type H to be used with xml.Marshal
func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
start.Name = xml.Name{
Space: "",
@ -71,6 +71,12 @@ func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
return nil
}
func assert1(guard bool, text string) {
if !guard {
panic(text)
}
}
func filterFlags(content string) string {
for i, char := range content {
if char == ' ' || char == ';' {
@ -137,10 +143,9 @@ func resolveAddress(addr []string) string {
if port := os.Getenv("PORT"); len(port) > 0 {
debugPrint("Environment variable PORT=\"%s\"", port)
return ":" + port
} else {
debugPrint("Environment variable PORT is undefined. Using port :8080 by default")
return ":8080"
}
debugPrint("Environment variable PORT is undefined. Using port :8080 by default")
return ":8080"
case 1:
return addr[0]
default:

12
vendor/vendor.json поставляемый
Просмотреть файл

@ -34,18 +34,18 @@
},
{
"path": "github.com/gin-gonic/gin",
"revision": "52fcc5dbf6e94df33ad313858fb94b713e9d1b4a",
"revisionTime": "2015-09-25T12:14:45+02:00"
"revision": "5caaac4c5c712a9e7a7de29e6c24ef46c753017f",
"revisionTime": "2016-04-15T01:39:28+02:00"
},
{
"path": "github.com/gin-gonic/gin/binding",
"revision": "52fcc5dbf6e94df33ad313858fb94b713e9d1b4a",
"revisionTime": "2015-09-25T12:14:45+02:00"
"revision": "5caaac4c5c712a9e7a7de29e6c24ef46c753017f",
"revisionTime": "2016-04-15T01:39:28+02:00"
},
{
"path": "github.com/gin-gonic/gin/render",
"revision": "52fcc5dbf6e94df33ad313858fb94b713e9d1b4a",
"revisionTime": "2015-09-25T12:14:45+02:00"
"revision": "5caaac4c5c712a9e7a7de29e6c24ef46c753017f",
"revisionTime": "2016-04-15T01:39:28+02:00"
},
{
"path": "github.com/go-sql-driver/mysql",