change dep to go module
This commit is contained in:
parent
c21d43a691
commit
ac1dcb7827
276
Gopkg.lock
generated
276
Gopkg.lock
generated
@ -1,276 +0,0 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:b763ac7907021d7c87885dd299ae8b57015243f179493b274b3b9af808ecbdcc"
|
||||
name = "github.com/DeanThompson/ginpprof"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "8c0e31bfeaa87bd40412ee8a8ba383f5f700ff72"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a62f6ed230a8cd138a9efbe718e7d0b0294f139266f5f55cd942769a9aac8de2"
|
||||
name = "github.com/PuerkitoBio/goquery"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "dc2ec5c7ca4d9aae063b79b9f581dd3ea6afd2b2"
|
||||
version = "v1.4.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:66b3310cf22cdc96c35ef84ede4f7b9b370971c4025f394c89a2638729653b11"
|
||||
name = "github.com/andybalholm/cascadia"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "901648c87902174f774fac311d7f176f8647bdaa"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:db932d4696ed23e244a69a60d258a23816aceb012a95e4c3871c711d4fc120e7"
|
||||
name = "github.com/boj/redistore"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "fc113767cd6b051980f260d6dbe84b2740c46ab0"
|
||||
version = "v1.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0594af97b2f4cec6554086eeace6597e20a4b69466eb4ada25adf9f4300dddd2"
|
||||
name = "github.com/garyburd/redigo"
|
||||
packages = [
|
||||
"internal",
|
||||
"redis",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "a69d19351219b6dd56f274f96d85a7014a2ec34e"
|
||||
version = "v1.6.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2b59aca2665ff804f6606c8829eaee133ddd3aefbc841014660d961b0034f888"
|
||||
name = "github.com/gin-contrib/cors"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "cf4846e6a636a76237a28d9286f163c132e841bc"
|
||||
version = "v1.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:36fe9527deed01d2a317617e59304eb2c4ce9f8a24115bcc5c2e37b3aee5bae4"
|
||||
name = "github.com/gin-contrib/sse"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "22d885f9ecc78bf4ee5d72b937e4bbcdc58e8cae"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:a9fc00ef112bb3d3f057c7f41c00e5a5dd56ce36381103d753938458b2356ca1"
|
||||
name = "github.com/gin-gonic/contrib"
|
||||
packages = ["sessions"]
|
||||
pruneopts = "UT"
|
||||
revision = "39cfb9727134fef3120d2458fce5fab14265a46c"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:489e108f21464371ebf9cb5c30b1eceb07c6dd772dff073919267493dd9d04ea"
|
||||
name = "github.com/gin-gonic/gin"
|
||||
packages = [
|
||||
".",
|
||||
"binding",
|
||||
"render",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "d459835d2b077e44f7c9b453505ee29881d5d12d"
|
||||
version = "v1.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:15042ad3498153684d09f393bbaec6b216c8eec6d61f63dff711de7d64ed8861"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto"]
|
||||
pruneopts = "UT"
|
||||
revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c79fb010be38a59d657c48c6ba1d003a8aa651fa56b579d959d74573b7dff8e1"
|
||||
name = "github.com/gorilla/context"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e72d1ebb8d395cf9f346fd9cbc652e5ae222dd85e0ac842dc57f175abed6d195"
|
||||
name = "github.com/gorilla/securecookie"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "e59506cc896acb7f7bf732d4fdf5e25f7ccd8983"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0fe783ea0c04c7d13f7c55d8f74b01b17e18a8320e7deecf578b41ef99b27205"
|
||||
name = "github.com/gorilla/sessions"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "03b6f63cc43ef9c7240a635a5e22b13180e822b8"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:7654989089e5bd5b6734ec3be8b695e87d3f1f8d95620b343fd7d3995a5b60d7"
|
||||
name = "github.com/jmoiron/sqlx"
|
||||
packages = [
|
||||
".",
|
||||
"reflectx",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "0dae4fefe7c0e190f7b5a78dac28a1c82cc8d849"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:37ce7d7d80531b227023331002c0d42b4b4b291a96798c82a049d03a54ba79e4"
|
||||
name = "github.com/lib/pq"
|
||||
packages = [
|
||||
".",
|
||||
"oid",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "90697d60dd844d5ef6ff15135d0203f65d2f53b8"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:aa3d8d42865c42626b5c1add193692d045b3188b1479f0a0a88690d21fe20083"
|
||||
name = "github.com/mailru/easyjson"
|
||||
packages = [
|
||||
".",
|
||||
"buffer",
|
||||
"jlexer",
|
||||
"jwriter",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "60711f1a8329503b04e1c88535f419d0bb440bff"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d4d17353dbd05cb52a2a52b7fe1771883b682806f68db442b436294926bbfafb"
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:34534b73e925d20cc72cf202f8b482fdcbe3a1b113e19375f31aadabd0f0f97d"
|
||||
name = "github.com/nfnt/resize"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "83c6a9932646f83e3267f353373d47347b6036b2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e01edb58fc507572461d56a8d24632c99af04686005dd5b411ec4b0029a24151"
|
||||
name = "github.com/olivere/elastic"
|
||||
packages = [
|
||||
".",
|
||||
"config",
|
||||
"uritemplates",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "bd115a1132ece51519151c33b5d74e1387d3265a"
|
||||
version = "v6.2.8"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747"
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ed615c5430ecabbb0fb7629a182da65ecee6523900ac1ac932520860878ffcad"
|
||||
name = "github.com/robfig/cron"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "b41be1df696709bb6395fe435af20370037c0b4c"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:03aa6e485e528acb119fb32901cf99582c380225fc7d5a02758e08b180cb56c3"
|
||||
name = "github.com/ugorji/go"
|
||||
packages = ["codec"]
|
||||
pruneopts = "UT"
|
||||
revision = "b4c50a2b199d93b13dc15e78929cfb23bfdf21ab"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:1ecf2a49df33be51e757d0033d5d51d5f784f35f68e5a38f797b2d3f03357d71"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = [
|
||||
"bcrypt",
|
||||
"blowfish",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "614d502a4dac94afa3a6ce146bd1736da82514c6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:a5ae8f624991c4156ab2610befdbc78ea3a961473ce4846cc34342649cb81878"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"html",
|
||||
"html/atom",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "161cd47e91fd58ac17490ef4d742dc98bb4cf60e"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:33a43cb31975899cfcd81600d1390467db1778ae87102f80668a753fed8c663e"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
pruneopts = "UT"
|
||||
revision = "98c5dad5d1a0e8a73845ecc8897d0bd56586511d"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:cbc72c4c4886a918d6ab4b95e347ffe259846260f99ebdd8a198c2331cf2b2e9"
|
||||
name = "gopkg.in/go-playground/validator.v8"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "5f1438d3fca68893a817e4a66806cea46a9e4ebf"
|
||||
version = "v8.18.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:54c3b474a0e4a8e65c74e0dbb272bcf30a4bab48883d34f958cbb9d8e8ef387a"
|
||||
name = "gopkg.in/irc.v2"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "4901bf6be124ba1558d3657e91286393c97fb47f"
|
||||
version = "v2.1.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"github.com/DeanThompson/ginpprof",
|
||||
"github.com/PuerkitoBio/goquery",
|
||||
"github.com/gin-contrib/cors",
|
||||
"github.com/gin-gonic/contrib/sessions",
|
||||
"github.com/gin-gonic/gin",
|
||||
"github.com/gin-gonic/gin/binding",
|
||||
"github.com/jmoiron/sqlx",
|
||||
"github.com/lib/pq",
|
||||
"github.com/nfnt/resize",
|
||||
"github.com/olivere/elastic",
|
||||
"github.com/robfig/cron",
|
||||
"golang.org/x/crypto/bcrypt",
|
||||
"gopkg.in/irc.v2",
|
||||
"gopkg.in/yaml.v2",
|
||||
]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
36
go.mod
Normal file
36
go.mod
Normal file
@ -0,0 +1,36 @@
|
||||
module git.trj.tw/golang/mtfosbot
|
||||
|
||||
require (
|
||||
github.com/DeanThompson/ginpprof v0.0.0-20170218162546-8c0e31bfeaa8
|
||||
github.com/PuerkitoBio/goquery v1.5.0
|
||||
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fortytw2/leaktest v1.3.0 // indirect
|
||||
github.com/gin-contrib/cors v0.0.0-20181008113111-488de3ec974f
|
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 // indirect
|
||||
github.com/gin-gonic/contrib v0.0.0-20181101072842-54170a7b0b4b
|
||||
github.com/gin-gonic/gin v1.3.0
|
||||
github.com/go-irc/irc v2.1.0+incompatible
|
||||
github.com/gorilla/sessions v1.1.3 // indirect
|
||||
github.com/jmoiron/sqlx v1.2.0
|
||||
github.com/json-iterator/go v1.1.5 // indirect
|
||||
github.com/lib/pq v1.0.0
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect
|
||||
github.com/mattn/go-isatty v0.0.4 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/olivere/elastic v6.2.12+incompatible
|
||||
github.com/pkg/errors v0.8.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/robfig/cron v0.0.0-20180505203441-b41be1df6967
|
||||
github.com/stretchr/testify v1.2.2 // indirect
|
||||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f // indirect
|
||||
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f // indirect
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8 // indirect
|
||||
google.golang.org/appengine v1.3.0 // indirect
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.1
|
||||
)
|
86
go.sum
Normal file
86
go.sum
Normal file
@ -0,0 +1,86 @@
|
||||
github.com/DeanThompson/ginpprof v0.0.0-20170218162546-8c0e31bfeaa8 h1:ciyrUaonhkfoqjGNUKzRVvpkugE+afQ7HKU2umHvANo=
|
||||
github.com/DeanThompson/ginpprof v0.0.0-20170218162546-8c0e31bfeaa8/go.mod h1:kMi/fSDAgvjo9TYfYwYeQ2vkyj+VTR/tB6u/Tjh39t0=
|
||||
github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk=
|
||||
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
|
||||
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
|
||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff h1:RmdPFa+slIr4SCBg4st/l/vZWVe9QJKMXGO60Bxbe04=
|
||||
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff/go.mod h1:+RTT1BOk5P97fT2CiHkbFQwkK3mjsFAP6zCYV2aXtjw=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/gin-contrib/cors v0.0.0-20181008113111-488de3ec974f h1:7kBk9VE4vAlHGsHqIXuhkrFuL5xTimW4ElJ9tkrnlXk=
|
||||
github.com/gin-contrib/cors v0.0.0-20181008113111-488de3ec974f/go.mod h1:cw+u9IsAkC16e42NtYYVCLsHYXE98nB3M7Dr9mLSeH4=
|
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 h1:AzN37oI0cOS+cougNAV9szl6CVoj2RYwzS3DpUQNtlY=
|
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-gonic/contrib v0.0.0-20181101072842-54170a7b0b4b h1:uJjmSEX74D3EyhBeht+spHAvS+aFRinOZOXjVXqb2cY=
|
||||
github.com/gin-gonic/contrib v0.0.0-20181101072842-54170a7b0b4b/go.mod h1:iqneQ2Df3omzIVTkIfn7c1acsVnMGiSLn4XF5Blh3Yg=
|
||||
github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs=
|
||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
||||
github.com/go-irc/irc v2.1.0+incompatible h1:pg7pMVq5OYQbqTxceByD/EN8VIsba7DtKn49rsCnG8Y=
|
||||
github.com/go-irc/irc v2.1.0+incompatible/go.mod h1:jJILTRy8s/qOvusiKifAEfhQMVwft1ZwQaVJnnzmyX4=
|
||||
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
|
||||
github.com/gorilla/sessions v1.1.3 h1:uXoZdcdA5XdXF3QzuSlheVRUvjl+1rKY7zBXL68L9RU=
|
||||
github.com/gorilla/sessions v1.1.3/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
|
||||
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE=
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/olivere/elastic v6.2.12+incompatible h1:JJ9FxBH/CkfeAXQbyUI8FqzC2vPivNiAXseD2ClQv5Y=
|
||||
github.com/olivere/elastic v6.2.12+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
|
||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/robfig/cron v0.0.0-20180505203441-b41be1df6967 h1:x7xEyJDP7Hv3LVgvWhzioQqbC/KtuUhTigKlH/8ehhE=
|
||||
github.com/robfig/cron v0.0.0-20180505203441-b41be1df6967/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f h1:y3Vj7GoDdcBkxFa2RUUFKM25TrBbWVDnjRDI0u975zQ=
|
||||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869 h1:kkXA53yGe04D0adEYJwEVQjeBppL01Exg+fnMjfUraU=
|
||||
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8 h1:YoY1wS6JYVRpIfFngRf2HHo9R9dAne3xbkGOQ5rJXjU=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
@ -6,8 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"git.trj.tw/golang/mtfosbot/model"
|
||||
|
||||
"gopkg.in/irc.v2"
|
||||
"github.com/go-irc/irc"
|
||||
|
||||
"git.trj.tw/golang/mtfosbot/module/config"
|
||||
)
|
||||
|
1
vendor/github.com/PuerkitoBio/goquery/.travis.yml
generated
vendored
1
vendor/github.com/PuerkitoBio/goquery/.travis.yml
generated
vendored
@ -11,5 +11,6 @@ go:
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- "1.10.x"
|
||||
- 1.11.x
|
||||
- tip
|
||||
|
||||
|
2
vendor/github.com/PuerkitoBio/goquery/README.md
generated
vendored
2
vendor/github.com/PuerkitoBio/goquery/README.md
generated
vendored
@ -37,6 +37,7 @@ Please note that because of the net/html dependency, goquery requires Go1.1+.
|
||||
|
||||
**Note that goquery's API is now stable, and will not break.**
|
||||
|
||||
* **2018-11-15 (v1.5.0)** : Go module support (thanks @Zaba505).
|
||||
* **2018-06-07 (v1.4.1)** : Add `NewDocumentFromReader` examples.
|
||||
* **2018-03-24 (v1.4.0)** : Deprecate `NewDocument(url)` and `NewDocumentFromResponse(response)`.
|
||||
* **2018-01-28 (v1.3.0)** : Add `ToEnd` constant to `Slice` until the end of the selection (thanks to @davidjwilkins for raising the issue).
|
||||
@ -139,6 +140,7 @@ func main() {
|
||||
- [suntong/cascadia][cascadiacli], a command-line interface to the cascadia CSS selector library, useful to test selectors.
|
||||
- [asciimoo/colly](https://github.com/asciimoo/colly), a lightning fast and elegant Scraping Framework
|
||||
- [gnulnx/goperf](https://github.com/gnulnx/goperf), a website performance test tool that also fetches static assets.
|
||||
- [MontFerret/ferret](https://github.com/MontFerret/ferret), declarative web scraping.
|
||||
|
||||
## Support
|
||||
|
||||
|
6
vendor/github.com/PuerkitoBio/goquery/go.mod
generated
vendored
Normal file
6
vendor/github.com/PuerkitoBio/goquery/go.mod
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
module github.com/PuerkitoBio/goquery
|
||||
|
||||
require (
|
||||
github.com/andybalholm/cascadia v1.0.0
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a
|
||||
)
|
5
vendor/github.com/PuerkitoBio/goquery/go.sum
generated
vendored
Normal file
5
vendor/github.com/PuerkitoBio/goquery/go.sum
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
|
||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
0
vendor/github.com/andybalholm/cascadia/LICENSE
generated
vendored
Executable file → Normal file
0
vendor/github.com/andybalholm/cascadia/LICENSE
generated
vendored
Executable file → Normal file
25
vendor/github.com/boj/redistore/.travis.yml
generated
vendored
Normal file
25
vendor/github.com/boj/redistore/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
language: go
|
||||
sudo: false
|
||||
|
||||
services:
|
||||
- redis-server
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- go: 1.5
|
||||
- go: 1.6
|
||||
- go: 1.7
|
||||
- go: 1.8
|
||||
- go: 1.9
|
||||
- go: tip
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
install:
|
||||
- # skip
|
||||
|
||||
script:
|
||||
- go get -t -v ./...
|
||||
- diff -u <(echo -n) <(gofmt -d .)
|
||||
- go tool vet .
|
||||
- go test -v -race ./...
|
57
vendor/github.com/boj/redistore/README.md
generated
vendored
57
vendor/github.com/boj/redistore/README.md
generated
vendored
@ -1,12 +1,13 @@
|
||||
# redistore
|
||||
|
||||
[![Build Status](https://drone.io/github.com/boj/redistore/status.png)](https://drone.io/github.com/boj/redistore/latest)
|
||||
[![GoDoc](https://godoc.org/github.com/boj/redistore?status.svg)](https://godoc.org/github.com/boj/redistore)
|
||||
[![Build Status](https://travis-ci.org/boj/redistore.svg?branch=master)](https://travis-ci.org/boj/redistore)
|
||||
|
||||
A session store backend for [gorilla/sessions](http://www.gorillatoolkit.org/pkg/sessions) - [src](https://github.com/gorilla/sessions).
|
||||
|
||||
## Requirements
|
||||
|
||||
Depends on the [Redigo](https://github.com/garyburd/redigo) Redis library.
|
||||
Depends on the [Redigo](https://github.com/gomodule/redigo) Redis library.
|
||||
|
||||
## Installation
|
||||
|
||||
@ -19,34 +20,34 @@ Available on [godoc.org](http://www.godoc.org/gopkg.in/boj/redistore.v1).
|
||||
See http://www.gorillatoolkit.org/pkg/sessions for full documentation on underlying interface.
|
||||
|
||||
### Example
|
||||
``` go
|
||||
// Fetch new store.
|
||||
store, err := NewRediStore(10, "tcp", ":6379", "", []byte("secret-key"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer store.Close()
|
||||
|
||||
// Fetch new store.
|
||||
store, err := NewRediStore(10, "tcp", ":6379", "", []byte("secret-key"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer store.Close()
|
||||
// Get a session.
|
||||
session, err = store.Get(req, "session-key")
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
}
|
||||
|
||||
// Get a session.
|
||||
session, err = store.Get(req, "session-key")
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
}
|
||||
// Add a value.
|
||||
session.Values["foo"] = "bar"
|
||||
|
||||
// Add a value.
|
||||
session.Values["foo"] = "bar"
|
||||
// Save.
|
||||
if err = sessions.Save(req, rsp); err != nil {
|
||||
t.Fatalf("Error saving session: %v", err)
|
||||
}
|
||||
|
||||
// Save.
|
||||
if err = sessions.Save(req, rsp); err != nil {
|
||||
t.Fatalf("Error saving session: %v", err)
|
||||
}
|
||||
|
||||
// Delete session.
|
||||
session.Options.MaxAge = -1
|
||||
if err = sessions.Save(req, rsp); err != nil {
|
||||
t.Fatalf("Error saving session: %v", err)
|
||||
}
|
||||
|
||||
// Change session storage configuration for MaxAge = 10 days.
|
||||
store.SetMaxAge(10*24*3600)
|
||||
// Delete session.
|
||||
session.Options.MaxAge = -1
|
||||
if err = sessions.Save(req, rsp); err != nil {
|
||||
t.Fatalf("Error saving session: %v", err)
|
||||
}
|
||||
|
||||
// Change session storage configuration for MaxAge = 10 days.
|
||||
store.SetMaxAge(10 * 24 * 3600)
|
||||
```
|
||||
|
7
vendor/github.com/boj/redistore/go.mod
generated
vendored
Normal file
7
vendor/github.com/boj/redistore/go.mod
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
module github.com/boj/redistore
|
||||
|
||||
require (
|
||||
github.com/gomodule/redigo v2.0.0+incompatible
|
||||
github.com/gorilla/securecookie v1.1.1
|
||||
github.com/gorilla/sessions v1.1.1
|
||||
)
|
13
vendor/github.com/boj/redistore/redistore.go
generated
vendored
13
vendor/github.com/boj/redistore/redistore.go
generated
vendored
@ -15,7 +15,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/garyburd/redigo/redis"
|
||||
"github.com/gomodule/redigo/redis"
|
||||
"github.com/gorilla/securecookie"
|
||||
"github.com/gorilla/sessions"
|
||||
)
|
||||
@ -198,7 +198,7 @@ func NewRediStoreWithDB(size int, network, address, password, DB string, keyPair
|
||||
// NewRediStoreWithPool instantiates a RediStore with a *redis.Pool passed in.
|
||||
func NewRediStoreWithPool(pool *redis.Pool, keyPairs ...[]byte) (*RediStore, error) {
|
||||
rs := &RediStore{
|
||||
// http://godoc.org/github.com/garyburd/redigo/redis#Pool
|
||||
// http://godoc.org/github.com/gomodule/redigo/redis#Pool
|
||||
Pool: pool,
|
||||
Codecs: securecookie.CodecsFromPairs(keyPairs...),
|
||||
Options: &sessions.Options{
|
||||
@ -230,7 +230,10 @@ func (s *RediStore) Get(r *http.Request, name string) (*sessions.Session, error)
|
||||
//
|
||||
// See gorilla/sessions FilesystemStore.New().
|
||||
func (s *RediStore) New(r *http.Request, name string) (*sessions.Session, error) {
|
||||
var err error
|
||||
var (
|
||||
err error
|
||||
ok bool
|
||||
)
|
||||
session := sessions.NewSession(s, name)
|
||||
// make a copy
|
||||
options := *s.Options
|
||||
@ -239,7 +242,7 @@ func (s *RediStore) New(r *http.Request, name string) (*sessions.Session, error)
|
||||
if c, errCookie := r.Cookie(name); errCookie == nil {
|
||||
err = securecookie.DecodeMulti(name, c.Value, &session.ID, s.Codecs...)
|
||||
if err == nil {
|
||||
ok, err := s.load(session)
|
||||
ok, err = s.load(session)
|
||||
session.IsNew = !(err == nil && ok) // not new if no error and data available
|
||||
}
|
||||
}
|
||||
@ -249,7 +252,7 @@ func (s *RediStore) New(r *http.Request, name string) (*sessions.Session, error)
|
||||
// Save adds a single session to the response.
|
||||
func (s *RediStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error {
|
||||
// Marked for deletion.
|
||||
if session.Options.MaxAge < 0 {
|
||||
if session.Options.MaxAge <= 0 {
|
||||
if err := s.delete(session); err != nil {
|
||||
return err
|
||||
}
|
||||
|
3
vendor/github.com/gin-contrib/cors/.travis.yml
generated
vendored
3
vendor/github.com/gin-contrib/cors/.travis.yml
generated
vendored
@ -5,6 +5,9 @@ go:
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- tip
|
||||
|
||||
script:
|
||||
|
7
vendor/github.com/gin-contrib/cors/README.md
generated
vendored
7
vendor/github.com/gin-contrib/cors/README.md
generated
vendored
@ -15,13 +15,13 @@ Gin middleware/handler to enable CORS support.
|
||||
Download and install it:
|
||||
|
||||
```sh
|
||||
$ go get gopkg.in/gin-contrib/cors.v1
|
||||
$ go get github.com/gin-contrib/cors
|
||||
```
|
||||
|
||||
Import it in your code:
|
||||
|
||||
```go
|
||||
import "gopkg.in/gin-contrib/cors.v1"
|
||||
import "github.com/gin-contrib/cors"
|
||||
```
|
||||
|
||||
### Canonical example:
|
||||
@ -32,7 +32,7 @@ package main
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gopkg.in/gin-contrib/cors.v1"
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@ -69,7 +69,6 @@ func main() {
|
||||
// - Preflight requests cached for 12 hours
|
||||
config := cors.DefaultConfig()
|
||||
config.AllowOrigins = []string{"http://google.com"}
|
||||
config.AddAllowOrigins("http://facebook.com")
|
||||
// config.AllowOrigins == []string{"http://google.com", "http://facebook.com"}
|
||||
|
||||
router.Use(cors.New(config))
|
||||
|
53
vendor/github.com/gin-contrib/cors/config.go
generated
vendored
53
vendor/github.com/gin-contrib/cors/config.go
generated
vendored
@ -2,6 +2,7 @@ package cors
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@ -14,12 +15,34 @@ type cors struct {
|
||||
exposeHeaders []string
|
||||
normalHeaders http.Header
|
||||
preflightHeaders http.Header
|
||||
wildcardOrigins [][]string
|
||||
}
|
||||
|
||||
var (
|
||||
DefaultSchemas = []string{
|
||||
"http://",
|
||||
"https://",
|
||||
}
|
||||
ExtensionSchemas = []string{
|
||||
"chrome-extension://",
|
||||
"safari-extension://",
|
||||
"moz-extension://",
|
||||
"ms-browser-extension://",
|
||||
}
|
||||
FileSchemas = []string{
|
||||
"file://",
|
||||
}
|
||||
WebSocketSchemas = []string{
|
||||
"ws://",
|
||||
"wss://",
|
||||
}
|
||||
)
|
||||
|
||||
func newCors(config Config) *cors {
|
||||
if err := config.Validate(); err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
return &cors{
|
||||
allowOriginFunc: config.AllowOriginFunc,
|
||||
allowAllOrigins: config.AllowAllOrigins,
|
||||
@ -27,6 +50,7 @@ func newCors(config Config) *cors {
|
||||
allowOrigins: normalize(config.AllowOrigins),
|
||||
normalHeaders: generateNormalHeaders(config),
|
||||
preflightHeaders: generatePreflightHeaders(config),
|
||||
wildcardOrigins: config.parseWildcardRules(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +60,14 @@ func (cors *cors) applyCors(c *gin.Context) {
|
||||
// request is not a CORS request
|
||||
return
|
||||
}
|
||||
host := c.Request.Header.Get("Host")
|
||||
|
||||
if origin == "http://"+host || origin == "https://"+host {
|
||||
// request is not a CORS request but have origin header.
|
||||
// for example, use fetch api
|
||||
return
|
||||
}
|
||||
|
||||
if !cors.validateOrigin(origin) {
|
||||
c.AbortWithStatus(http.StatusForbidden)
|
||||
return
|
||||
@ -43,7 +75,7 @@ func (cors *cors) applyCors(c *gin.Context) {
|
||||
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
cors.handlePreflight(c)
|
||||
defer c.AbortWithStatus(200)
|
||||
defer c.AbortWithStatus(http.StatusNoContent) // Using 204 is better than 200 when the request status is OPTIONS
|
||||
} else {
|
||||
cors.handleNormal(c)
|
||||
}
|
||||
@ -53,6 +85,22 @@ func (cors *cors) applyCors(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (cors *cors) validateWildcardOrigin(origin string) bool {
|
||||
for _, w := range cors.wildcardOrigins {
|
||||
if w[0] == "*" && strings.HasSuffix(origin, w[1]) {
|
||||
return true
|
||||
}
|
||||
if w[1] == "*" && strings.HasPrefix(origin, w[0]) {
|
||||
return true
|
||||
}
|
||||
if strings.HasPrefix(origin, w[0]) && strings.HasSuffix(origin, w[1]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (cors *cors) validateOrigin(origin string) bool {
|
||||
if cors.allowAllOrigins {
|
||||
return true
|
||||
@ -62,6 +110,9 @@ func (cors *cors) validateOrigin(origin string) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if len(cors.wildcardOrigins) > 0 && cors.validateWildcardOrigin(origin) {
|
||||
return true
|
||||
}
|
||||
if cors.allowOriginFunc != nil {
|
||||
return cors.allowOriginFunc(origin)
|
||||
}
|
||||
|
78
vendor/github.com/gin-contrib/cors/cors.go
generated
vendored
78
vendor/github.com/gin-contrib/cors/cors.go
generated
vendored
@ -14,7 +14,7 @@ type Config struct {
|
||||
|
||||
// AllowedOrigins is a list of origins a cross-domain request can be executed from.
|
||||
// If the special "*" value is present in the list, all origins will be allowed.
|
||||
// Default value is ["*"]
|
||||
// Default value is []
|
||||
AllowOrigins []string
|
||||
|
||||
// AllowOriginFunc is a custom function to validate the origin. It take the origin
|
||||
@ -28,8 +28,6 @@ type Config struct {
|
||||
|
||||
// AllowedHeaders is list of non simple headers the client is allowed to use with
|
||||
// cross-domain requests.
|
||||
// If the special "*" value is present in the list, all headers will be allowed.
|
||||
// Default value is [] but "Origin" is always appended to the list.
|
||||
AllowHeaders []string
|
||||
|
||||
// AllowCredentials indicates whether the request can include user credentials like
|
||||
@ -43,6 +41,18 @@ type Config struct {
|
||||
// MaxAge indicates how long (in seconds) the results of a preflight request
|
||||
// can be cached
|
||||
MaxAge time.Duration
|
||||
|
||||
// Allows to add origins like http://some-domain/*, https://api.* or http://some.*.subdomain.com
|
||||
AllowWildcard bool
|
||||
|
||||
// Allows usage of popular browser extensions schemas
|
||||
AllowBrowserExtensions bool
|
||||
|
||||
// Allows usage of WebSocket protocol
|
||||
AllowWebSockets bool
|
||||
|
||||
// Allows usage of file:// schema (dangerous!) use it only when you 100% sure it's needed
|
||||
AllowFiles bool
|
||||
}
|
||||
|
||||
// AddAllowMethods is allowed to add custom methods
|
||||
@ -60,6 +70,30 @@ func (c *Config) AddExposeHeaders(headers ...string) {
|
||||
c.ExposeHeaders = append(c.ExposeHeaders, headers...)
|
||||
}
|
||||
|
||||
func (c Config) getAllowedSchemas() []string {
|
||||
allowedSchemas := DefaultSchemas
|
||||
if c.AllowBrowserExtensions {
|
||||
allowedSchemas = append(allowedSchemas, ExtensionSchemas...)
|
||||
}
|
||||
if c.AllowWebSockets {
|
||||
allowedSchemas = append(allowedSchemas, WebSocketSchemas...)
|
||||
}
|
||||
if c.AllowFiles {
|
||||
allowedSchemas = append(allowedSchemas, FileSchemas...)
|
||||
}
|
||||
return allowedSchemas
|
||||
}
|
||||
|
||||
func (c Config) validateAllowedSchemas(origin string) bool {
|
||||
allowedSchemas := c.getAllowedSchemas()
|
||||
for _, schema := range allowedSchemas {
|
||||
if strings.HasPrefix(origin, schema) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate is check configuration of user defined.
|
||||
func (c Config) Validate() error {
|
||||
if c.AllowAllOrigins && (c.AllowOriginFunc != nil || len(c.AllowOrigins) > 0) {
|
||||
@ -69,17 +103,49 @@ func (c Config) Validate() error {
|
||||
return errors.New("conflict settings: all origins disabled")
|
||||
}
|
||||
for _, origin := range c.AllowOrigins {
|
||||
if !strings.HasPrefix(origin, "http://") && !strings.HasPrefix(origin, "https://") {
|
||||
return errors.New("bad origin: origins must include http:// or https://")
|
||||
if !strings.Contains(origin, "*") && !c.validateAllowedSchemas(origin) {
|
||||
return errors.New("bad origin: origins must contain '*' or include " + strings.Join(c.getAllowedSchemas(), ","))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Config) parseWildcardRules() [][]string {
|
||||
var wRules [][]string
|
||||
|
||||
if !c.AllowWildcard {
|
||||
return wRules
|
||||
}
|
||||
|
||||
for _, o := range c.AllowOrigins {
|
||||
if !strings.Contains(o, "*") {
|
||||
continue
|
||||
}
|
||||
|
||||
if c := strings.Count(o, "*"); c > 1 {
|
||||
panic(errors.New("only one * is allowed").Error())
|
||||
}
|
||||
|
||||
i := strings.Index(o, "*")
|
||||
if i == 0 {
|
||||
wRules = append(wRules, []string{"*", o[1:]})
|
||||
continue
|
||||
}
|
||||
if i == (len(o) - 1) {
|
||||
wRules = append(wRules, []string{o[:i-1], "*"})
|
||||
continue
|
||||
}
|
||||
|
||||
wRules = append(wRules, []string{o[:i], o[i+1:]})
|
||||
}
|
||||
|
||||
return wRules
|
||||
}
|
||||
|
||||
// DefaultConfig returns a generic default configuration mapped to localhost.
|
||||
func DefaultConfig() Config {
|
||||
return Config{
|
||||
AllowMethods: []string{"GET", "POST", "PUT", "HEAD"},
|
||||
AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"},
|
||||
AllowHeaders: []string{"Origin", "Content-Length", "Content-Type"},
|
||||
AllowCredentials: false,
|
||||
MaxAge: 12 * time.Hour,
|
||||
|
1
vendor/github.com/gin-gonic/gin/.gitignore
generated
vendored
1
vendor/github.com/gin-gonic/gin/.gitignore
generated
vendored
@ -2,3 +2,4 @@ vendor/*
|
||||
!vendor/vendor.json
|
||||
coverage.out
|
||||
count.out
|
||||
test
|
||||
|
6
vendor/github.com/gin-gonic/gin/.travis.yml
generated
vendored
6
vendor/github.com/gin-gonic/gin/.travis.yml
generated
vendored
@ -4,14 +4,18 @@ go:
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- master
|
||||
|
||||
git:
|
||||
depth: 3
|
||||
depth: 10
|
||||
|
||||
install:
|
||||
- make install
|
||||
|
||||
go_import_path: github.com/gin-gonic/gin
|
||||
|
||||
script:
|
||||
- make vet
|
||||
- make fmt-check
|
||||
|
6
vendor/github.com/gin-gonic/gin/AUTHORS.md
generated
vendored
6
vendor/github.com/gin-gonic/gin/AUTHORS.md
generated
vendored
@ -1,8 +1,12 @@
|
||||
List of all the awesome people working to make Gin the best Web Framework in Go.
|
||||
|
||||
## gin 1.x series authors
|
||||
|
||||
**Gin Core Team:** Bo-Yi Wu (@appleboy), 田欧 (@thinkerou), Javier Provecho (@javierprovecho)
|
||||
|
||||
## gin 0.x series authors
|
||||
|
||||
**Maintainer:** Manu Martinez-Almeida (@manucorporat), Javier Provecho (@javierprovecho)
|
||||
**Maintainers:** Manu Martinez-Almeida (@manucorporat), Javier Provecho (@javierprovecho)
|
||||
|
||||
People and companies, who have contributed, in alphabetical order.
|
||||
|
||||
|
896
vendor/github.com/gin-gonic/gin/BENCHMARKS.md
generated
vendored
896
vendor/github.com/gin-gonic/gin/BENCHMARKS.md
generated
vendored
@ -1,298 +1,604 @@
|
||||
**Machine:** intel i7 ivy bridge quad-core. 8GB RAM.
|
||||
**Date:** June 4th, 2015
|
||||
[https://github.com/gin-gonic/go-http-routing-benchmark](https://github.com/gin-gonic/go-http-routing-benchmark)
|
||||
|
||||
## Benchmark System
|
||||
|
||||
**VM HOST:** DigitalOcean
|
||||
**Machine:** 4 CPU, 8 GB RAM. Ubuntu 16.04.2 x64
|
||||
**Date:** July 19th, 2017
|
||||
**Go Version:** 1.8.3 linux/amd64
|
||||
**Source:** [Go HTTP Router Benchmark](https://github.com/julienschmidt/go-http-routing-benchmark)
|
||||
|
||||
## Static Routes: 157
|
||||
|
||||
```
|
||||
BenchmarkAce_Param 5000000 372 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkBear_Param 1000000 1165 ns/op 424 B/op 5 allocs/op
|
||||
BenchmarkBeego_Param 1000000 2440 ns/op 720 B/op 10 allocs/op
|
||||
BenchmarkBone_Param 1000000 1067 ns/op 384 B/op 3 allocs/op
|
||||
BenchmarkDenco_Param 5000000 240 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkEcho_Param 10000000 130 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGin_Param 10000000 133 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_Param 1000000 1826 ns/op 656 B/op 9 allocs/op
|
||||
BenchmarkGoji_Param 2000000 957 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGoJsonRest_Param 1000000 2021 ns/op 657 B/op 14 allocs/op
|
||||
BenchmarkGoRestful_Param 200000 8825 ns/op 2496 B/op 31 allocs/op
|
||||
BenchmarkGorillaMux_Param 500000 3340 ns/op 784 B/op 9 allocs/op
|
||||
BenchmarkHttpRouter_Param 10000000 152 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_Param 2000000 717 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkKocha_Param 3000000 423 ns/op 56 B/op 3 allocs/op
|
||||
BenchmarkMacaron_Param 1000000 3410 ns/op 1104 B/op 11 allocs/op
|
||||
BenchmarkMartini_Param 200000 7101 ns/op 1152 B/op 12 allocs/op
|
||||
BenchmarkPat_Param 1000000 2040 ns/op 656 B/op 14 allocs/op
|
||||
BenchmarkPossum_Param 1000000 2048 ns/op 624 B/op 7 allocs/op
|
||||
BenchmarkR2router_Param 1000000 1144 ns/op 432 B/op 6 allocs/op
|
||||
BenchmarkRevel_Param 200000 6725 ns/op 1672 B/op 28 allocs/op
|
||||
BenchmarkRivet_Param 1000000 1121 ns/op 464 B/op 5 allocs/op
|
||||
BenchmarkTango_Param 1000000 1479 ns/op 256 B/op 10 allocs/op
|
||||
BenchmarkTigerTonic_Param 1000000 3393 ns/op 992 B/op 19 allocs/op
|
||||
BenchmarkTraffic_Param 300000 5525 ns/op 1984 B/op 23 allocs/op
|
||||
BenchmarkVulcan_Param 2000000 924 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkZeus_Param 1000000 1084 ns/op 368 B/op 3 allocs/op
|
||||
BenchmarkAce_Param5 3000000 614 ns/op 160 B/op 1 allocs/op
|
||||
BenchmarkBear_Param5 1000000 1617 ns/op 469 B/op 5 allocs/op
|
||||
BenchmarkBeego_Param5 1000000 3373 ns/op 992 B/op 13 allocs/op
|
||||
BenchmarkBone_Param5 1000000 1478 ns/op 432 B/op 3 allocs/op
|
||||
BenchmarkDenco_Param5 3000000 570 ns/op 160 B/op 1 allocs/op
|
||||
BenchmarkEcho_Param5 5000000 256 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGin_Param5 10000000 222 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_Param5 1000000 2789 ns/op 928 B/op 12 allocs/op
|
||||
BenchmarkGoji_Param5 1000000 1287 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGoJsonRest_Param5 1000000 3670 ns/op 1105 B/op 17 allocs/op
|
||||
BenchmarkGoRestful_Param5 200000 10756 ns/op 2672 B/op 31 allocs/op
|
||||
BenchmarkGorillaMux_Param5 300000 5543 ns/op 912 B/op 9 allocs/op
|
||||
BenchmarkHttpRouter_Param5 5000000 403 ns/op 160 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_Param5 1000000 1089 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkKocha_Param5 1000000 1682 ns/op 440 B/op 10 allocs/op
|
||||
BenchmarkMacaron_Param5 300000 4596 ns/op 1376 B/op 14 allocs/op
|
||||
BenchmarkMartini_Param5 100000 15703 ns/op 1280 B/op 12 allocs/op
|
||||
BenchmarkPat_Param5 300000 5320 ns/op 1008 B/op 42 allocs/op
|
||||
BenchmarkPossum_Param5 1000000 2155 ns/op 624 B/op 7 allocs/op
|
||||
BenchmarkR2router_Param5 1000000 1559 ns/op 432 B/op 6 allocs/op
|
||||
BenchmarkRevel_Param5 200000 8184 ns/op 2024 B/op 35 allocs/op
|
||||
BenchmarkRivet_Param5 1000000 1914 ns/op 528 B/op 9 allocs/op
|
||||
BenchmarkTango_Param5 1000000 3280 ns/op 944 B/op 18 allocs/op
|
||||
BenchmarkTigerTonic_Param5 200000 11638 ns/op 2519 B/op 53 allocs/op
|
||||
BenchmarkTraffic_Param5 200000 8941 ns/op 2280 B/op 31 allocs/op
|
||||
BenchmarkVulcan_Param5 1000000 1279 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkZeus_Param5 1000000 1574 ns/op 416 B/op 3 allocs/op
|
||||
BenchmarkAce_Param20 1000000 1528 ns/op 640 B/op 1 allocs/op
|
||||
BenchmarkBear_Param20 300000 4906 ns/op 1633 B/op 5 allocs/op
|
||||
BenchmarkBeego_Param20 200000 10529 ns/op 3868 B/op 17 allocs/op
|
||||
BenchmarkBone_Param20 300000 7362 ns/op 2539 B/op 5 allocs/op
|
||||
BenchmarkDenco_Param20 1000000 1884 ns/op 640 B/op 1 allocs/op
|
||||
BenchmarkEcho_Param20 2000000 689 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGin_Param20 3000000 545 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_Param20 200000 9437 ns/op 3804 B/op 16 allocs/op
|
||||
BenchmarkGoji_Param20 500000 3987 ns/op 1246 B/op 2 allocs/op
|
||||
BenchmarkGoJsonRest_Param20 100000 12799 ns/op 4492 B/op 21 allocs/op
|
||||
BenchmarkGoRestful_Param20 100000 19451 ns/op 5244 B/op 33 allocs/op
|
||||
BenchmarkGorillaMux_Param20 100000 12456 ns/op 3275 B/op 11 allocs/op
|
||||
BenchmarkHttpRouter_Param20 1000000 1333 ns/op 640 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_Param20 300000 6490 ns/op 2187 B/op 4 allocs/op
|
||||
BenchmarkKocha_Param20 300000 5335 ns/op 1808 B/op 27 allocs/op
|
||||
BenchmarkMacaron_Param20 200000 11325 ns/op 4252 B/op 18 allocs/op
|
||||
BenchmarkMartini_Param20 20000 64419 ns/op 3644 B/op 14 allocs/op
|
||||
BenchmarkPat_Param20 50000 24672 ns/op 4888 B/op 151 allocs/op
|
||||
BenchmarkPossum_Param20 1000000 2085 ns/op 624 B/op 7 allocs/op
|
||||
BenchmarkR2router_Param20 300000 6809 ns/op 2283 B/op 8 allocs/op
|
||||
BenchmarkRevel_Param20 100000 16600 ns/op 5551 B/op 54 allocs/op
|
||||
BenchmarkRivet_Param20 200000 8428 ns/op 2620 B/op 26 allocs/op
|
||||
BenchmarkTango_Param20 100000 16302 ns/op 8224 B/op 48 allocs/op
|
||||
BenchmarkTigerTonic_Param20 30000 46828 ns/op 10538 B/op 178 allocs/op
|
||||
BenchmarkTraffic_Param20 50000 28871 ns/op 7998 B/op 66 allocs/op
|
||||
BenchmarkVulcan_Param20 1000000 2267 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkZeus_Param20 300000 6828 ns/op 2507 B/op 5 allocs/op
|
||||
BenchmarkAce_ParamWrite 3000000 502 ns/op 40 B/op 2 allocs/op
|
||||
BenchmarkBear_ParamWrite 1000000 1303 ns/op 424 B/op 5 allocs/op
|
||||
BenchmarkBeego_ParamWrite 1000000 2489 ns/op 728 B/op 11 allocs/op
|
||||
BenchmarkBone_ParamWrite 1000000 1181 ns/op 384 B/op 3 allocs/op
|
||||
BenchmarkDenco_ParamWrite 5000000 315 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkEcho_ParamWrite 10000000 237 ns/op 8 B/op 1 allocs/op
|
||||
BenchmarkGin_ParamWrite 5000000 336 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_ParamWrite 1000000 2079 ns/op 664 B/op 10 allocs/op
|
||||
BenchmarkGoji_ParamWrite 1000000 1092 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGoJsonRest_ParamWrite 1000000 3329 ns/op 1136 B/op 19 allocs/op
|
||||
BenchmarkGoRestful_ParamWrite 200000 9273 ns/op 2504 B/op 32 allocs/op
|
||||
BenchmarkGorillaMux_ParamWrite 500000 3919 ns/op 792 B/op 10 allocs/op
|
||||
BenchmarkHttpRouter_ParamWrite 10000000 223 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_ParamWrite 2000000 788 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkKocha_ParamWrite 3000000 549 ns/op 56 B/op 3 allocs/op
|
||||
BenchmarkMacaron_ParamWrite 500000 4558 ns/op 1216 B/op 16 allocs/op
|
||||
BenchmarkMartini_ParamWrite 200000 8850 ns/op 1256 B/op 16 allocs/op
|
||||
BenchmarkPat_ParamWrite 500000 3679 ns/op 1088 B/op 19 allocs/op
|
||||
BenchmarkPossum_ParamWrite 1000000 2114 ns/op 624 B/op 7 allocs/op
|
||||
BenchmarkR2router_ParamWrite 1000000 1320 ns/op 432 B/op 6 allocs/op
|
||||
BenchmarkRevel_ParamWrite 200000 8048 ns/op 2128 B/op 33 allocs/op
|
||||
BenchmarkRivet_ParamWrite 1000000 1393 ns/op 472 B/op 6 allocs/op
|
||||
BenchmarkTango_ParamWrite 2000000 819 ns/op 136 B/op 5 allocs/op
|
||||
BenchmarkTigerTonic_ParamWrite 300000 5860 ns/op 1440 B/op 25 allocs/op
|
||||
BenchmarkTraffic_ParamWrite 200000 7429 ns/op 2400 B/op 27 allocs/op
|
||||
BenchmarkVulcan_ParamWrite 2000000 972 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkZeus_ParamWrite 1000000 1226 ns/op 368 B/op 3 allocs/op
|
||||
BenchmarkAce_GithubStatic 5000000 294 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkBear_GithubStatic 3000000 575 ns/op 88 B/op 3 allocs/op
|
||||
BenchmarkBeego_GithubStatic 1000000 1561 ns/op 368 B/op 7 allocs/op
|
||||
BenchmarkBone_GithubStatic 200000 12301 ns/op 2880 B/op 60 allocs/op
|
||||
BenchmarkDenco_GithubStatic 20000000 74.6 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkEcho_GithubStatic 10000000 176 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGin_GithubStatic 10000000 159 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GithubStatic 1000000 1116 ns/op 304 B/op 6 allocs/op
|
||||
BenchmarkGoji_GithubStatic 5000000 413 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGoRestful_GithubStatic 30000 55200 ns/op 3520 B/op 36 allocs/op
|
||||
BenchmarkGoJsonRest_GithubStatic 1000000 1504 ns/op 337 B/op 12 allocs/op
|
||||
BenchmarkGorillaMux_GithubStatic 100000 23620 ns/op 464 B/op 8 allocs/op
|
||||
BenchmarkHttpRouter_GithubStatic 20000000 78.3 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkHttpTreeMux_GithubStatic 20000000 84.9 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkKocha_GithubStatic 20000000 111 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_GithubStatic 1000000 2686 ns/op 752 B/op 8 allocs/op
|
||||
BenchmarkMartini_GithubStatic 100000 22244 ns/op 832 B/op 11 allocs/op
|
||||
BenchmarkPat_GithubStatic 100000 13278 ns/op 3648 B/op 76 allocs/op
|
||||
BenchmarkPossum_GithubStatic 1000000 1429 ns/op 480 B/op 4 allocs/op
|
||||
BenchmarkR2router_GithubStatic 2000000 726 ns/op 144 B/op 5 allocs/op
|
||||
BenchmarkRevel_GithubStatic 300000 6271 ns/op 1288 B/op 25 allocs/op
|
||||
BenchmarkRivet_GithubStatic 3000000 474 ns/op 112 B/op 2 allocs/op
|
||||
BenchmarkTango_GithubStatic 1000000 1842 ns/op 256 B/op 10 allocs/op
|
||||
BenchmarkTigerTonic_GithubStatic 5000000 361 ns/op 48 B/op 1 allocs/op
|
||||
BenchmarkTraffic_GithubStatic 30000 47197 ns/op 18920 B/op 149 allocs/op
|
||||
BenchmarkVulcan_GithubStatic 1000000 1415 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkZeus_GithubStatic 1000000 2522 ns/op 512 B/op 11 allocs/op
|
||||
BenchmarkAce_GithubParam 3000000 578 ns/op 96 B/op 1 allocs/op
|
||||
BenchmarkBear_GithubParam 1000000 1592 ns/op 464 B/op 5 allocs/op
|
||||
BenchmarkBeego_GithubParam 1000000 2891 ns/op 784 B/op 11 allocs/op
|
||||
BenchmarkBone_GithubParam 300000 6440 ns/op 1456 B/op 16 allocs/op
|
||||
BenchmarkDenco_GithubParam 3000000 514 ns/op 128 B/op 1 allocs/op
|
||||
BenchmarkEcho_GithubParam 5000000 292 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGin_GithubParam 10000000 242 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GithubParam 1000000 2343 ns/op 720 B/op 10 allocs/op
|
||||
BenchmarkGoji_GithubParam 1000000 1566 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGoJsonRest_GithubParam 1000000 2828 ns/op 721 B/op 15 allocs/op
|
||||
BenchmarkGoRestful_GithubParam 10000 177711 ns/op 2816 B/op 35 allocs/op
|
||||
BenchmarkGorillaMux_GithubParam 100000 13591 ns/op 816 B/op 9 allocs/op
|
||||
BenchmarkHttpRouter_GithubParam 5000000 352 ns/op 96 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_GithubParam 2000000 973 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkKocha_GithubParam 2000000 889 ns/op 128 B/op 5 allocs/op
|
||||
BenchmarkMacaron_GithubParam 500000 4047 ns/op 1168 B/op 12 allocs/op
|
||||
BenchmarkMartini_GithubParam 50000 28982 ns/op 1184 B/op 12 allocs/op
|
||||
BenchmarkPat_GithubParam 200000 8747 ns/op 2480 B/op 56 allocs/op
|
||||
BenchmarkPossum_GithubParam 1000000 2158 ns/op 624 B/op 7 allocs/op
|
||||
BenchmarkR2router_GithubParam 1000000 1352 ns/op 432 B/op 6 allocs/op
|
||||
BenchmarkRevel_GithubParam 200000 7673 ns/op 1784 B/op 30 allocs/op
|
||||
BenchmarkRivet_GithubParam 1000000 1573 ns/op 480 B/op 6 allocs/op
|
||||
BenchmarkTango_GithubParam 1000000 2418 ns/op 480 B/op 13 allocs/op
|
||||
BenchmarkTigerTonic_GithubParam 300000 6048 ns/op 1440 B/op 28 allocs/op
|
||||
BenchmarkTraffic_GithubParam 100000 20143 ns/op 6024 B/op 55 allocs/op
|
||||
BenchmarkVulcan_GithubParam 1000000 2224 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkZeus_GithubParam 500000 4156 ns/op 1312 B/op 12 allocs/op
|
||||
BenchmarkAce_GithubAll 10000 109482 ns/op 13792 B/op 167 allocs/op
|
||||
BenchmarkBear_GithubAll 10000 287490 ns/op 79952 B/op 943 allocs/op
|
||||
BenchmarkBeego_GithubAll 3000 562184 ns/op 146272 B/op 2092 allocs/op
|
||||
BenchmarkBone_GithubAll 500 2578716 ns/op 648016 B/op 8119 allocs/op
|
||||
BenchmarkDenco_GithubAll 20000 94955 ns/op 20224 B/op 167 allocs/op
|
||||
BenchmarkEcho_GithubAll 30000 58705 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGin_GithubAll 30000 50991 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GithubAll 5000 449648 ns/op 133280 B/op 1889 allocs/op
|
||||
BenchmarkGoji_GithubAll 2000 689748 ns/op 56113 B/op 334 allocs/op
|
||||
BenchmarkGoJsonRest_GithubAll 5000 537769 ns/op 135995 B/op 2940 allocs/op
|
||||
BenchmarkGoRestful_GithubAll 100 18410628 ns/op 797236 B/op 7725 allocs/op
|
||||
BenchmarkGorillaMux_GithubAll 200 8036360 ns/op 153137 B/op 1791 allocs/op
|
||||
BenchmarkHttpRouter_GithubAll 20000 63506 ns/op 13792 B/op 167 allocs/op
|
||||
BenchmarkHttpTreeMux_GithubAll 10000 165927 ns/op 56112 B/op 334 allocs/op
|
||||
BenchmarkKocha_GithubAll 10000 171362 ns/op 23304 B/op 843 allocs/op
|
||||
BenchmarkMacaron_GithubAll 2000 817008 ns/op 224960 B/op 2315 allocs/op
|
||||
BenchmarkMartini_GithubAll 100 12609209 ns/op 237952 B/op 2686 allocs/op
|
||||
BenchmarkPat_GithubAll 300 4830398 ns/op 1504101 B/op 32222 allocs/op
|
||||
BenchmarkPossum_GithubAll 10000 301716 ns/op 97440 B/op 812 allocs/op
|
||||
BenchmarkR2router_GithubAll 10000 270691 ns/op 77328 B/op 1182 allocs/op
|
||||
BenchmarkRevel_GithubAll 1000 1491919 ns/op 345553 B/op 5918 allocs/op
|
||||
BenchmarkRivet_GithubAll 10000 283860 ns/op 84272 B/op 1079 allocs/op
|
||||
BenchmarkTango_GithubAll 5000 473821 ns/op 87078 B/op 2470 allocs/op
|
||||
BenchmarkTigerTonic_GithubAll 2000 1120131 ns/op 241088 B/op 6052 allocs/op
|
||||
BenchmarkTraffic_GithubAll 200 8708979 ns/op 2664762 B/op 22390 allocs/op
|
||||
BenchmarkVulcan_GithubAll 5000 353392 ns/op 19894 B/op 609 allocs/op
|
||||
BenchmarkZeus_GithubAll 2000 944234 ns/op 300688 B/op 2648 allocs/op
|
||||
BenchmarkAce_GPlusStatic 5000000 251 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkBear_GPlusStatic 3000000 415 ns/op 72 B/op 3 allocs/op
|
||||
BenchmarkBeego_GPlusStatic 1000000 1416 ns/op 352 B/op 7 allocs/op
|
||||
BenchmarkBone_GPlusStatic 10000000 192 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkDenco_GPlusStatic 30000000 47.6 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkEcho_GPlusStatic 10000000 131 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGin_GPlusStatic 10000000 131 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GPlusStatic 1000000 1035 ns/op 288 B/op 6 allocs/op
|
||||
BenchmarkGoji_GPlusStatic 5000000 304 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGoJsonRest_GPlusStatic 1000000 1286 ns/op 337 B/op 12 allocs/op
|
||||
BenchmarkGoRestful_GPlusStatic 200000 9649 ns/op 2160 B/op 30 allocs/op
|
||||
BenchmarkGorillaMux_GPlusStatic 1000000 2346 ns/op 464 B/op 8 allocs/op
|
||||
BenchmarkHttpRouter_GPlusStatic 30000000 42.7 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkHttpTreeMux_GPlusStatic 30000000 49.5 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkKocha_GPlusStatic 20000000 74.8 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_GPlusStatic 1000000 2520 ns/op 736 B/op 8 allocs/op
|
||||
BenchmarkMartini_GPlusStatic 300000 5310 ns/op 832 B/op 11 allocs/op
|
||||
BenchmarkPat_GPlusStatic 5000000 398 ns/op 96 B/op 2 allocs/op
|
||||
BenchmarkPossum_GPlusStatic 1000000 1434 ns/op 480 B/op 4 allocs/op
|
||||
BenchmarkR2router_GPlusStatic 2000000 646 ns/op 144 B/op 5 allocs/op
|
||||
BenchmarkRevel_GPlusStatic 300000 6172 ns/op 1272 B/op 25 allocs/op
|
||||
BenchmarkRivet_GPlusStatic 3000000 444 ns/op 112 B/op 2 allocs/op
|
||||
BenchmarkTango_GPlusStatic 1000000 1400 ns/op 208 B/op 10 allocs/op
|
||||
BenchmarkTigerTonic_GPlusStatic 10000000 213 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkTraffic_GPlusStatic 1000000 3091 ns/op 1208 B/op 16 allocs/op
|
||||
BenchmarkVulcan_GPlusStatic 2000000 863 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkZeus_GPlusStatic 10000000 237 ns/op 16 B/op 1 allocs/op
|
||||
BenchmarkAce_GPlusParam 3000000 435 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkBear_GPlusParam 1000000 1205 ns/op 448 B/op 5 allocs/op
|
||||
BenchmarkBeego_GPlusParam 1000000 2494 ns/op 720 B/op 10 allocs/op
|
||||
BenchmarkBone_GPlusParam 1000000 1126 ns/op 384 B/op 3 allocs/op
|
||||
BenchmarkDenco_GPlusParam 5000000 325 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkEcho_GPlusParam 10000000 168 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGin_GPlusParam 10000000 170 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GPlusParam 1000000 1895 ns/op 656 B/op 9 allocs/op
|
||||
BenchmarkGoji_GPlusParam 1000000 1071 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGoJsonRest_GPlusParam 1000000 2282 ns/op 657 B/op 14 allocs/op
|
||||
BenchmarkGoRestful_GPlusParam 100000 19400 ns/op 2560 B/op 33 allocs/op
|
||||
BenchmarkGorillaMux_GPlusParam 500000 5001 ns/op 784 B/op 9 allocs/op
|
||||
BenchmarkHttpRouter_GPlusParam 10000000 240 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_GPlusParam 2000000 797 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkKocha_GPlusParam 3000000 505 ns/op 56 B/op 3 allocs/op
|
||||
BenchmarkMacaron_GPlusParam 1000000 3668 ns/op 1104 B/op 11 allocs/op
|
||||
BenchmarkMartini_GPlusParam 200000 10672 ns/op 1152 B/op 12 allocs/op
|
||||
BenchmarkPat_GPlusParam 1000000 2376 ns/op 704 B/op 14 allocs/op
|
||||
BenchmarkPossum_GPlusParam 1000000 2090 ns/op 624 B/op 7 allocs/op
|
||||
BenchmarkR2router_GPlusParam 1000000 1233 ns/op 432 B/op 6 allocs/op
|
||||
BenchmarkRevel_GPlusParam 200000 6778 ns/op 1704 B/op 28 allocs/op
|
||||
BenchmarkRivet_GPlusParam 1000000 1279 ns/op 464 B/op 5 allocs/op
|
||||
BenchmarkTango_GPlusParam 1000000 1981 ns/op 272 B/op 10 allocs/op
|
||||
BenchmarkTigerTonic_GPlusParam 500000 3893 ns/op 1064 B/op 19 allocs/op
|
||||
BenchmarkTraffic_GPlusParam 200000 6585 ns/op 2000 B/op 23 allocs/op
|
||||
BenchmarkVulcan_GPlusParam 1000000 1233 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkZeus_GPlusParam 1000000 1350 ns/op 368 B/op 3 allocs/op
|
||||
BenchmarkAce_GPlus2Params 3000000 512 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkBear_GPlus2Params 1000000 1564 ns/op 464 B/op 5 allocs/op
|
||||
BenchmarkBeego_GPlus2Params 1000000 3043 ns/op 784 B/op 11 allocs/op
|
||||
BenchmarkBone_GPlus2Params 1000000 3152 ns/op 736 B/op 7 allocs/op
|
||||
BenchmarkDenco_GPlus2Params 3000000 431 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkEcho_GPlus2Params 5000000 247 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGin_GPlus2Params 10000000 219 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GPlus2Params 1000000 2363 ns/op 720 B/op 10 allocs/op
|
||||
BenchmarkGoji_GPlus2Params 1000000 1540 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGoJsonRest_GPlus2Params 1000000 2872 ns/op 721 B/op 15 allocs/op
|
||||
BenchmarkGoRestful_GPlus2Params 100000 23030 ns/op 2720 B/op 35 allocs/op
|
||||
BenchmarkGorillaMux_GPlus2Params 200000 10516 ns/op 816 B/op 9 allocs/op
|
||||
BenchmarkHttpRouter_GPlus2Params 5000000 273 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_GPlus2Params 2000000 939 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkKocha_GPlus2Params 2000000 844 ns/op 128 B/op 5 allocs/op
|
||||
BenchmarkMacaron_GPlus2Params 500000 3914 ns/op 1168 B/op 12 allocs/op
|
||||
BenchmarkMartini_GPlus2Params 50000 35759 ns/op 1280 B/op 16 allocs/op
|
||||
BenchmarkPat_GPlus2Params 200000 7089 ns/op 2304 B/op 41 allocs/op
|
||||
BenchmarkPossum_GPlus2Params 1000000 2093 ns/op 624 B/op 7 allocs/op
|
||||
BenchmarkR2router_GPlus2Params 1000000 1320 ns/op 432 B/op 6 allocs/op
|
||||
BenchmarkRevel_GPlus2Params 200000 7351 ns/op 1800 B/op 30 allocs/op
|
||||
BenchmarkRivet_GPlus2Params 1000000 1485 ns/op 480 B/op 6 allocs/op
|
||||
BenchmarkTango_GPlus2Params 1000000 2111 ns/op 448 B/op 12 allocs/op
|
||||
BenchmarkTigerTonic_GPlus2Params 300000 6271 ns/op 1528 B/op 28 allocs/op
|
||||
BenchmarkTraffic_GPlus2Params 100000 14886 ns/op 3312 B/op 34 allocs/op
|
||||
BenchmarkVulcan_GPlus2Params 1000000 1883 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkZeus_GPlus2Params 1000000 2686 ns/op 784 B/op 6 allocs/op
|
||||
BenchmarkAce_GPlusAll 300000 5912 ns/op 640 B/op 11 allocs/op
|
||||
BenchmarkBear_GPlusAll 100000 16448 ns/op 5072 B/op 61 allocs/op
|
||||
BenchmarkBeego_GPlusAll 50000 32916 ns/op 8976 B/op 129 allocs/op
|
||||
BenchmarkBone_GPlusAll 50000 25836 ns/op 6992 B/op 76 allocs/op
|
||||
BenchmarkDenco_GPlusAll 500000 4462 ns/op 672 B/op 11 allocs/op
|
||||
BenchmarkEcho_GPlusAll 500000 2806 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGin_GPlusAll 500000 2579 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GPlusAll 50000 25223 ns/op 8144 B/op 116 allocs/op
|
||||
BenchmarkGoji_GPlusAll 100000 14237 ns/op 3696 B/op 22 allocs/op
|
||||
BenchmarkGoJsonRest_GPlusAll 50000 29227 ns/op 8221 B/op 183 allocs/op
|
||||
BenchmarkGoRestful_GPlusAll 10000 203144 ns/op 36064 B/op 441 allocs/op
|
||||
BenchmarkGorillaMux_GPlusAll 20000 80906 ns/op 9712 B/op 115 allocs/op
|
||||
BenchmarkHttpRouter_GPlusAll 500000 3040 ns/op 640 B/op 11 allocs/op
|
||||
BenchmarkHttpTreeMux_GPlusAll 200000 9627 ns/op 3696 B/op 22 allocs/op
|
||||
BenchmarkKocha_GPlusAll 200000 8108 ns/op 976 B/op 43 allocs/op
|
||||
BenchmarkMacaron_GPlusAll 30000 48083 ns/op 13968 B/op 142 allocs/op
|
||||
BenchmarkMartini_GPlusAll 10000 196978 ns/op 15072 B/op 178 allocs/op
|
||||
BenchmarkPat_GPlusAll 30000 58865 ns/op 16880 B/op 343 allocs/op
|
||||
BenchmarkPossum_GPlusAll 100000 19685 ns/op 6240 B/op 52 allocs/op
|
||||
BenchmarkR2router_GPlusAll 100000 16251 ns/op 5040 B/op 76 allocs/op
|
||||
BenchmarkRevel_GPlusAll 20000 93489 ns/op 21656 B/op 368 allocs/op
|
||||
BenchmarkRivet_GPlusAll 100000 16907 ns/op 5408 B/op 64 allocs/op
|
||||
Gin: 30512 Bytes
|
||||
|
||||
HttpServeMux: 17344 Bytes
|
||||
Ace: 30080 Bytes
|
||||
Bear: 30472 Bytes
|
||||
Beego: 96408 Bytes
|
||||
Bone: 37904 Bytes
|
||||
Denco: 10464 Bytes
|
||||
Echo: 73680 Bytes
|
||||
GocraftWeb: 55720 Bytes
|
||||
Goji: 27200 Bytes
|
||||
Gojiv2: 104464 Bytes
|
||||
GoJsonRest: 136472 Bytes
|
||||
GoRestful: 914904 Bytes
|
||||
GorillaMux: 675568 Bytes
|
||||
HttpRouter: 21128 Bytes
|
||||
HttpTreeMux: 73448 Bytes
|
||||
Kocha: 115072 Bytes
|
||||
LARS: 30120 Bytes
|
||||
Macaron: 37984 Bytes
|
||||
Martini: 310832 Bytes
|
||||
Pat: 20464 Bytes
|
||||
Possum: 91328 Bytes
|
||||
R2router: 23712 Bytes
|
||||
Rivet: 23880 Bytes
|
||||
Tango: 28008 Bytes
|
||||
TigerTonic: 80368 Bytes
|
||||
Traffic: 626480 Bytes
|
||||
Vulcan: 369064 Bytes
|
||||
```
|
||||
|
||||
## GithubAPI Routes: 203
|
||||
|
||||
```
|
||||
Gin: 52672 Bytes
|
||||
|
||||
Ace: 48992 Bytes
|
||||
Bear: 161592 Bytes
|
||||
Beego: 147992 Bytes
|
||||
Bone: 97728 Bytes
|
||||
Denco: 36440 Bytes
|
||||
Echo: 95672 Bytes
|
||||
GocraftWeb: 95640 Bytes
|
||||
Goji: 86088 Bytes
|
||||
Gojiv2: 144392 Bytes
|
||||
GoJsonRest: 134648 Bytes
|
||||
GoRestful: 1410760 Bytes
|
||||
GorillaMux: 1509488 Bytes
|
||||
HttpRouter: 37464 Bytes
|
||||
HttpTreeMux: 78800 Bytes
|
||||
Kocha: 785408 Bytes
|
||||
LARS: 49032 Bytes
|
||||
Macaron: 132712 Bytes
|
||||
Martini: 564352 Bytes
|
||||
Pat: 21200 Bytes
|
||||
Possum: 83888 Bytes
|
||||
R2router: 47104 Bytes
|
||||
Rivet: 42840 Bytes
|
||||
Tango: 54584 Bytes
|
||||
TigerTonic: 96384 Bytes
|
||||
Traffic: 1061920 Bytes
|
||||
Vulcan: 465296 Bytes
|
||||
```
|
||||
|
||||
## GPlusAPI Routes: 13
|
||||
|
||||
```
|
||||
Gin: 3968 Bytes
|
||||
|
||||
Ace: 3600 Bytes
|
||||
Bear: 7112 Bytes
|
||||
Beego: 10048 Bytes
|
||||
Bone: 6480 Bytes
|
||||
Denco: 3256 Bytes
|
||||
Echo: 9000 Bytes
|
||||
GocraftWeb: 7496 Bytes
|
||||
Goji: 2912 Bytes
|
||||
Gojiv2: 7376 Bytes
|
||||
GoJsonRest: 11544 Bytes
|
||||
GoRestful: 88776 Bytes
|
||||
GorillaMux: 71488 Bytes
|
||||
HttpRouter: 2712 Bytes
|
||||
HttpTreeMux: 7440 Bytes
|
||||
Kocha: 128880 Bytes
|
||||
LARS: 3640 Bytes
|
||||
Macaron: 8656 Bytes
|
||||
Martini: 23936 Bytes
|
||||
Pat: 1856 Bytes
|
||||
Possum: 7248 Bytes
|
||||
R2router: 3928 Bytes
|
||||
Rivet: 3064 Bytes
|
||||
Tango: 4912 Bytes
|
||||
TigerTonic: 9408 Bytes
|
||||
Traffic: 49472 Bytes
|
||||
Vulcan: 25496 Bytes
|
||||
```
|
||||
|
||||
## ParseAPI Routes: 26
|
||||
|
||||
```
|
||||
Gin: 6928 Bytes
|
||||
|
||||
Ace: 6592 Bytes
|
||||
Bear: 12320 Bytes
|
||||
Beego: 18960 Bytes
|
||||
Bone: 11024 Bytes
|
||||
Denco: 4184 Bytes
|
||||
Echo: 11168 Bytes
|
||||
GocraftWeb: 12800 Bytes
|
||||
Goji: 5232 Bytes
|
||||
Gojiv2: 14464 Bytes
|
||||
GoJsonRest: 14216 Bytes
|
||||
GoRestful: 127368 Bytes
|
||||
GorillaMux: 123016 Bytes
|
||||
HttpRouter: 4976 Bytes
|
||||
HttpTreeMux: 7848 Bytes
|
||||
Kocha: 181712 Bytes
|
||||
LARS: 6632 Bytes
|
||||
Macaron: 13648 Bytes
|
||||
Martini: 45952 Bytes
|
||||
Pat: 2560 Bytes
|
||||
Possum: 9200 Bytes
|
||||
R2router: 7056 Bytes
|
||||
Rivet: 5680 Bytes
|
||||
Tango: 8664 Bytes
|
||||
TigerTonic: 9840 Bytes
|
||||
Traffic: 93480 Bytes
|
||||
Vulcan: 44504 Bytes
|
||||
```
|
||||
|
||||
## Static Routes
|
||||
|
||||
```
|
||||
BenchmarkGin_StaticAll 50000 34506 ns/op 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkAce_StaticAll 30000 49657 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkHttpServeMux_StaticAll 2000 1183737 ns/op 96 B/op 8 allocs/op
|
||||
BenchmarkBeego_StaticAll 5000 412621 ns/op 57776 B/op 628 allocs/op
|
||||
BenchmarkBear_StaticAll 10000 149242 ns/op 20336 B/op 461 allocs/op
|
||||
BenchmarkBone_StaticAll 10000 118583 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkDenco_StaticAll 100000 13247 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkEcho_StaticAll 20000 79914 ns/op 5024 B/op 157 allocs/op
|
||||
BenchmarkGocraftWeb_StaticAll 10000 211823 ns/op 46440 B/op 785 allocs/op
|
||||
BenchmarkGoji_StaticAll 10000 109390 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGojiv2_StaticAll 3000 415533 ns/op 145696 B/op 1099 allocs/op
|
||||
BenchmarkGoJsonRest_StaticAll 5000 364403 ns/op 51653 B/op 1727 allocs/op
|
||||
BenchmarkGoRestful_StaticAll 500 2578579 ns/op 314936 B/op 3144 allocs/op
|
||||
BenchmarkGorillaMux_StaticAll 500 2704856 ns/op 115648 B/op 1578 allocs/op
|
||||
BenchmarkHttpRouter_StaticAll 100000 18541 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkHttpTreeMux_StaticAll 100000 22332 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkKocha_StaticAll 50000 31176 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkLARS_StaticAll 50000 40840 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_StaticAll 5000 517656 ns/op 120576 B/op 1413 allocs/op
|
||||
BenchmarkMartini_StaticAll 300 4462289 ns/op 125442 B/op 1717 allocs/op
|
||||
BenchmarkPat_StaticAll 500 2157275 ns/op 533904 B/op 11123 allocs/op
|
||||
BenchmarkPossum_StaticAll 10000 254701 ns/op 65312 B/op 471 allocs/op
|
||||
BenchmarkR2router_StaticAll 10000 133956 ns/op 22608 B/op 628 allocs/op
|
||||
BenchmarkRivet_StaticAll 30000 46812 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkTango_StaticAll 5000 390613 ns/op 39225 B/op 1256 allocs/op
|
||||
BenchmarkTigerTonic_StaticAll 20000 88060 ns/op 7504 B/op 157 allocs/op
|
||||
BenchmarkTraffic_StaticAll 500 2910236 ns/op 729736 B/op 14287 allocs/op
|
||||
BenchmarkVulcan_StaticAll 5000 277366 ns/op 15386 B/op 471 allocs/op
|
||||
```
|
||||
|
||||
## Micro Benchmarks
|
||||
|
||||
```
|
||||
BenchmarkGin_Param 20000000 113 ns/op 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkAce_Param 5000000 375 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkBear_Param 1000000 1709 ns/op 456 B/op 5 allocs/op
|
||||
BenchmarkBeego_Param 1000000 2484 ns/op 368 B/op 4 allocs/op
|
||||
BenchmarkBone_Param 1000000 2391 ns/op 688 B/op 5 allocs/op
|
||||
BenchmarkDenco_Param 10000000 240 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkEcho_Param 5000000 366 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkGocraftWeb_Param 1000000 2343 ns/op 648 B/op 8 allocs/op
|
||||
BenchmarkGoji_Param 1000000 1197 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGojiv2_Param 1000000 2771 ns/op 944 B/op 8 allocs/op
|
||||
BenchmarkGoJsonRest_Param 1000000 2993 ns/op 649 B/op 13 allocs/op
|
||||
BenchmarkGoRestful_Param 200000 8860 ns/op 2296 B/op 21 allocs/op
|
||||
BenchmarkGorillaMux_Param 500000 4461 ns/op 1056 B/op 11 allocs/op
|
||||
BenchmarkHttpRouter_Param 10000000 175 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_Param 1000000 1167 ns/op 352 B/op 3 allocs/op
|
||||
BenchmarkKocha_Param 3000000 429 ns/op 56 B/op 3 allocs/op
|
||||
BenchmarkLARS_Param 10000000 134 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_Param 500000 4635 ns/op 1056 B/op 10 allocs/op
|
||||
BenchmarkMartini_Param 200000 9933 ns/op 1072 B/op 10 allocs/op
|
||||
BenchmarkPat_Param 1000000 2929 ns/op 648 B/op 12 allocs/op
|
||||
BenchmarkPossum_Param 1000000 2503 ns/op 560 B/op 6 allocs/op
|
||||
BenchmarkR2router_Param 1000000 1507 ns/op 432 B/op 5 allocs/op
|
||||
BenchmarkRivet_Param 5000000 297 ns/op 48 B/op 1 allocs/op
|
||||
BenchmarkTango_Param 1000000 1862 ns/op 248 B/op 8 allocs/op
|
||||
BenchmarkTigerTonic_Param 500000 5660 ns/op 992 B/op 17 allocs/op
|
||||
BenchmarkTraffic_Param 200000 8408 ns/op 1960 B/op 21 allocs/op
|
||||
BenchmarkVulcan_Param 2000000 963 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkAce_Param5 2000000 740 ns/op 160 B/op 1 allocs/op
|
||||
BenchmarkBear_Param5 1000000 2777 ns/op 501 B/op 5 allocs/op
|
||||
BenchmarkBeego_Param5 1000000 3740 ns/op 368 B/op 4 allocs/op
|
||||
BenchmarkBone_Param5 1000000 2950 ns/op 736 B/op 5 allocs/op
|
||||
BenchmarkDenco_Param5 2000000 644 ns/op 160 B/op 1 allocs/op
|
||||
BenchmarkEcho_Param5 3000000 558 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkGin_Param5 10000000 198 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_Param5 500000 3870 ns/op 920 B/op 11 allocs/op
|
||||
BenchmarkGoji_Param5 1000000 1746 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGojiv2_Param5 1000000 3214 ns/op 1008 B/op 8 allocs/op
|
||||
BenchmarkGoJsonRest_Param5 500000 5509 ns/op 1097 B/op 16 allocs/op
|
||||
BenchmarkGoRestful_Param5 200000 11232 ns/op 2392 B/op 21 allocs/op
|
||||
BenchmarkGorillaMux_Param5 300000 7777 ns/op 1184 B/op 11 allocs/op
|
||||
BenchmarkHttpRouter_Param5 3000000 631 ns/op 160 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_Param5 1000000 2800 ns/op 576 B/op 6 allocs/op
|
||||
BenchmarkKocha_Param5 1000000 2053 ns/op 440 B/op 10 allocs/op
|
||||
BenchmarkLARS_Param5 10000000 232 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_Param5 500000 5888 ns/op 1056 B/op 10 allocs/op
|
||||
BenchmarkMartini_Param5 200000 12807 ns/op 1232 B/op 11 allocs/op
|
||||
BenchmarkPat_Param5 300000 7320 ns/op 964 B/op 32 allocs/op
|
||||
BenchmarkPossum_Param5 1000000 2495 ns/op 560 B/op 6 allocs/op
|
||||
BenchmarkR2router_Param5 1000000 1844 ns/op 432 B/op 5 allocs/op
|
||||
BenchmarkRivet_Param5 2000000 935 ns/op 240 B/op 1 allocs/op
|
||||
BenchmarkTango_Param5 1000000 2327 ns/op 360 B/op 8 allocs/op
|
||||
BenchmarkTigerTonic_Param5 100000 18514 ns/op 2551 B/op 43 allocs/op
|
||||
BenchmarkTraffic_Param5 200000 11997 ns/op 2248 B/op 25 allocs/op
|
||||
BenchmarkVulcan_Param5 1000000 1333 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkAce_Param20 1000000 2031 ns/op 640 B/op 1 allocs/op
|
||||
BenchmarkBear_Param20 200000 7285 ns/op 1664 B/op 5 allocs/op
|
||||
BenchmarkBeego_Param20 300000 6224 ns/op 368 B/op 4 allocs/op
|
||||
BenchmarkBone_Param20 200000 8023 ns/op 1903 B/op 5 allocs/op
|
||||
BenchmarkDenco_Param20 1000000 2262 ns/op 640 B/op 1 allocs/op
|
||||
BenchmarkEcho_Param20 1000000 1387 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkGin_Param20 3000000 503 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_Param20 100000 14408 ns/op 3795 B/op 15 allocs/op
|
||||
BenchmarkGoji_Param20 500000 5272 ns/op 1247 B/op 2 allocs/op
|
||||
BenchmarkGojiv2_Param20 1000000 4163 ns/op 1248 B/op 8 allocs/op
|
||||
BenchmarkGoJsonRest_Param20 100000 17866 ns/op 4485 B/op 20 allocs/op
|
||||
BenchmarkGoRestful_Param20 100000 21022 ns/op 4724 B/op 23 allocs/op
|
||||
BenchmarkGorillaMux_Param20 100000 17055 ns/op 3547 B/op 13 allocs/op
|
||||
BenchmarkHttpRouter_Param20 1000000 1748 ns/op 640 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_Param20 200000 12246 ns/op 3196 B/op 10 allocs/op
|
||||
BenchmarkKocha_Param20 300000 6861 ns/op 1808 B/op 27 allocs/op
|
||||
BenchmarkLARS_Param20 3000000 526 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_Param20 100000 13069 ns/op 2906 B/op 12 allocs/op
|
||||
BenchmarkMartini_Param20 100000 23602 ns/op 3597 B/op 13 allocs/op
|
||||
BenchmarkPat_Param20 50000 32143 ns/op 4688 B/op 111 allocs/op
|
||||
BenchmarkPossum_Param20 1000000 2396 ns/op 560 B/op 6 allocs/op
|
||||
BenchmarkR2router_Param20 200000 8907 ns/op 2283 B/op 7 allocs/op
|
||||
BenchmarkRivet_Param20 1000000 3280 ns/op 1024 B/op 1 allocs/op
|
||||
BenchmarkTango_Param20 500000 4640 ns/op 856 B/op 8 allocs/op
|
||||
BenchmarkTigerTonic_Param20 20000 67581 ns/op 10532 B/op 138 allocs/op
|
||||
BenchmarkTraffic_Param20 50000 40313 ns/op 7941 B/op 45 allocs/op
|
||||
BenchmarkVulcan_Param20 1000000 2264 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkAce_ParamWrite 3000000 532 ns/op 40 B/op 2 allocs/op
|
||||
BenchmarkBear_ParamWrite 1000000 1778 ns/op 456 B/op 5 allocs/op
|
||||
BenchmarkBeego_ParamWrite 1000000 2596 ns/op 376 B/op 5 allocs/op
|
||||
BenchmarkBone_ParamWrite 1000000 2519 ns/op 688 B/op 5 allocs/op
|
||||
BenchmarkDenco_ParamWrite 5000000 411 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkEcho_ParamWrite 2000000 718 ns/op 40 B/op 2 allocs/op
|
||||
BenchmarkGin_ParamWrite 5000000 283 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_ParamWrite 1000000 2561 ns/op 656 B/op 9 allocs/op
|
||||
BenchmarkGoji_ParamWrite 1000000 1378 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGojiv2_ParamWrite 1000000 3128 ns/op 976 B/op 10 allocs/op
|
||||
BenchmarkGoJsonRest_ParamWrite 500000 4446 ns/op 1128 B/op 18 allocs/op
|
||||
BenchmarkGoRestful_ParamWrite 200000 10291 ns/op 2304 B/op 22 allocs/op
|
||||
BenchmarkGorillaMux_ParamWrite 500000 5153 ns/op 1064 B/op 12 allocs/op
|
||||
BenchmarkHttpRouter_ParamWrite 5000000 263 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_ParamWrite 1000000 1351 ns/op 352 B/op 3 allocs/op
|
||||
BenchmarkKocha_ParamWrite 3000000 538 ns/op 56 B/op 3 allocs/op
|
||||
BenchmarkLARS_ParamWrite 5000000 316 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_ParamWrite 500000 5756 ns/op 1160 B/op 14 allocs/op
|
||||
BenchmarkMartini_ParamWrite 200000 13097 ns/op 1176 B/op 14 allocs/op
|
||||
BenchmarkPat_ParamWrite 500000 4954 ns/op 1072 B/op 17 allocs/op
|
||||
BenchmarkPossum_ParamWrite 1000000 2499 ns/op 560 B/op 6 allocs/op
|
||||
BenchmarkR2router_ParamWrite 1000000 1531 ns/op 432 B/op 5 allocs/op
|
||||
BenchmarkRivet_ParamWrite 3000000 570 ns/op 112 B/op 2 allocs/op
|
||||
BenchmarkTango_ParamWrite 2000000 957 ns/op 136 B/op 4 allocs/op
|
||||
BenchmarkTigerTonic_ParamWrite 200000 7025 ns/op 1424 B/op 23 allocs/op
|
||||
BenchmarkTraffic_ParamWrite 200000 10112 ns/op 2384 B/op 25 allocs/op
|
||||
BenchmarkVulcan_ParamWrite 1000000 1006 ns/op 98 B/op 3 allocs/op
|
||||
```
|
||||
|
||||
## GitHub
|
||||
|
||||
```
|
||||
BenchmarkGin_GithubStatic 10000000 156 ns/op 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkAce_GithubStatic 5000000 294 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkBear_GithubStatic 2000000 893 ns/op 120 B/op 3 allocs/op
|
||||
BenchmarkBeego_GithubStatic 1000000 2491 ns/op 368 B/op 4 allocs/op
|
||||
BenchmarkBone_GithubStatic 50000 25300 ns/op 2880 B/op 60 allocs/op
|
||||
BenchmarkDenco_GithubStatic 20000000 76.0 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkEcho_GithubStatic 2000000 516 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkGocraftWeb_GithubStatic 1000000 1448 ns/op 296 B/op 5 allocs/op
|
||||
BenchmarkGoji_GithubStatic 3000000 496 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGojiv2_GithubStatic 1000000 2941 ns/op 928 B/op 7 allocs/op
|
||||
BenchmarkGoRestful_GithubStatic 100000 27256 ns/op 3224 B/op 22 allocs/op
|
||||
BenchmarkGoJsonRest_GithubStatic 1000000 2196 ns/op 329 B/op 11 allocs/op
|
||||
BenchmarkGorillaMux_GithubStatic 50000 31617 ns/op 736 B/op 10 allocs/op
|
||||
BenchmarkHttpRouter_GithubStatic 20000000 88.4 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkHttpTreeMux_GithubStatic 10000000 134 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkKocha_GithubStatic 20000000 113 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkLARS_GithubStatic 10000000 195 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_GithubStatic 500000 3740 ns/op 768 B/op 9 allocs/op
|
||||
BenchmarkMartini_GithubStatic 50000 27673 ns/op 768 B/op 9 allocs/op
|
||||
BenchmarkPat_GithubStatic 100000 19470 ns/op 3648 B/op 76 allocs/op
|
||||
BenchmarkPossum_GithubStatic 1000000 1729 ns/op 416 B/op 3 allocs/op
|
||||
BenchmarkR2router_GithubStatic 2000000 879 ns/op 144 B/op 4 allocs/op
|
||||
BenchmarkRivet_GithubStatic 10000000 231 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkTango_GithubStatic 1000000 2325 ns/op 248 B/op 8 allocs/op
|
||||
BenchmarkTigerTonic_GithubStatic 3000000 610 ns/op 48 B/op 1 allocs/op
|
||||
BenchmarkTraffic_GithubStatic 20000 62973 ns/op 18904 B/op 148 allocs/op
|
||||
BenchmarkVulcan_GithubStatic 1000000 1447 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkAce_GithubParam 2000000 686 ns/op 96 B/op 1 allocs/op
|
||||
BenchmarkBear_GithubParam 1000000 2155 ns/op 496 B/op 5 allocs/op
|
||||
BenchmarkBeego_GithubParam 1000000 2713 ns/op 368 B/op 4 allocs/op
|
||||
BenchmarkBone_GithubParam 100000 15088 ns/op 1760 B/op 18 allocs/op
|
||||
BenchmarkDenco_GithubParam 2000000 629 ns/op 128 B/op 1 allocs/op
|
||||
BenchmarkEcho_GithubParam 2000000 653 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkGin_GithubParam 5000000 255 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GithubParam 1000000 3145 ns/op 712 B/op 9 allocs/op
|
||||
BenchmarkGoji_GithubParam 1000000 1916 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGojiv2_GithubParam 1000000 3975 ns/op 1024 B/op 10 allocs/op
|
||||
BenchmarkGoJsonRest_GithubParam 300000 4134 ns/op 713 B/op 14 allocs/op
|
||||
BenchmarkGoRestful_GithubParam 50000 30782 ns/op 2360 B/op 21 allocs/op
|
||||
BenchmarkGorillaMux_GithubParam 100000 17148 ns/op 1088 B/op 11 allocs/op
|
||||
BenchmarkHttpRouter_GithubParam 3000000 523 ns/op 96 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_GithubParam 1000000 1671 ns/op 384 B/op 4 allocs/op
|
||||
BenchmarkKocha_GithubParam 1000000 1021 ns/op 128 B/op 5 allocs/op
|
||||
BenchmarkLARS_GithubParam 5000000 283 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_GithubParam 500000 4270 ns/op 1056 B/op 10 allocs/op
|
||||
BenchmarkMartini_GithubParam 100000 21728 ns/op 1152 B/op 11 allocs/op
|
||||
BenchmarkPat_GithubParam 200000 11208 ns/op 2464 B/op 48 allocs/op
|
||||
BenchmarkPossum_GithubParam 1000000 2334 ns/op 560 B/op 6 allocs/op
|
||||
BenchmarkR2router_GithubParam 1000000 1487 ns/op 432 B/op 5 allocs/op
|
||||
BenchmarkRivet_GithubParam 2000000 782 ns/op 96 B/op 1 allocs/op
|
||||
BenchmarkTango_GithubParam 1000000 2653 ns/op 344 B/op 8 allocs/op
|
||||
BenchmarkTigerTonic_GithubParam 300000 14073 ns/op 1440 B/op 24 allocs/op
|
||||
BenchmarkTraffic_GithubParam 50000 29164 ns/op 5992 B/op 52 allocs/op
|
||||
BenchmarkVulcan_GithubParam 1000000 2529 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkAce_GithubAll 10000 134059 ns/op 13792 B/op 167 allocs/op
|
||||
BenchmarkBear_GithubAll 5000 534445 ns/op 86448 B/op 943 allocs/op
|
||||
BenchmarkBeego_GithubAll 3000 592444 ns/op 74705 B/op 812 allocs/op
|
||||
BenchmarkBone_GithubAll 200 6957308 ns/op 698784 B/op 8453 allocs/op
|
||||
BenchmarkDenco_GithubAll 10000 158819 ns/op 20224 B/op 167 allocs/op
|
||||
BenchmarkEcho_GithubAll 10000 154700 ns/op 6496 B/op 203 allocs/op
|
||||
BenchmarkGin_GithubAll 30000 48375 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GithubAll 3000 570806 ns/op 131656 B/op 1686 allocs/op
|
||||
BenchmarkGoji_GithubAll 2000 818034 ns/op 56112 B/op 334 allocs/op
|
||||
BenchmarkGojiv2_GithubAll 2000 1213973 ns/op 274768 B/op 3712 allocs/op
|
||||
BenchmarkGoJsonRest_GithubAll 2000 785796 ns/op 134371 B/op 2737 allocs/op
|
||||
BenchmarkGoRestful_GithubAll 300 5238188 ns/op 689672 B/op 4519 allocs/op
|
||||
BenchmarkGorillaMux_GithubAll 100 10257726 ns/op 211840 B/op 2272 allocs/op
|
||||
BenchmarkHttpRouter_GithubAll 20000 105414 ns/op 13792 B/op 167 allocs/op
|
||||
BenchmarkHttpTreeMux_GithubAll 10000 319934 ns/op 65856 B/op 671 allocs/op
|
||||
BenchmarkKocha_GithubAll 10000 209442 ns/op 23304 B/op 843 allocs/op
|
||||
BenchmarkLARS_GithubAll 20000 62565 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_GithubAll 2000 1161270 ns/op 204194 B/op 2000 allocs/op
|
||||
BenchmarkMartini_GithubAll 200 9991713 ns/op 226549 B/op 2325 allocs/op
|
||||
BenchmarkPat_GithubAll 200 5590793 ns/op 1499568 B/op 27435 allocs/op
|
||||
BenchmarkPossum_GithubAll 10000 319768 ns/op 84448 B/op 609 allocs/op
|
||||
BenchmarkR2router_GithubAll 10000 305134 ns/op 77328 B/op 979 allocs/op
|
||||
BenchmarkRivet_GithubAll 10000 132134 ns/op 16272 B/op 167 allocs/op
|
||||
BenchmarkTango_GithubAll 3000 552754 ns/op 63826 B/op 1618 allocs/op
|
||||
BenchmarkTigerTonic_GithubAll 1000 1439483 ns/op 239104 B/op 5374 allocs/op
|
||||
BenchmarkTraffic_GithubAll 100 11383067 ns/op 2659329 B/op 21848 allocs/op
|
||||
BenchmarkVulcan_GithubAll 5000 394253 ns/op 19894 B/op 609 allocs/op
|
||||
```
|
||||
|
||||
## Google+
|
||||
|
||||
```
|
||||
BenchmarkGin_GPlusStatic 10000000 183 ns/op 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkAce_GPlusStatic 5000000 276 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkBear_GPlusStatic 2000000 652 ns/op 104 B/op 3 allocs/op
|
||||
BenchmarkBeego_GPlusStatic 1000000 2239 ns/op 368 B/op 4 allocs/op
|
||||
BenchmarkBone_GPlusStatic 5000000 380 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkDenco_GPlusStatic 30000000 45.8 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkEcho_GPlusStatic 5000000 338 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkGocraftWeb_GPlusStatic 1000000 1158 ns/op 280 B/op 5 allocs/op
|
||||
BenchmarkGoji_GPlusStatic 5000000 331 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGojiv2_GPlusStatic 1000000 2106 ns/op 928 B/op 7 allocs/op
|
||||
BenchmarkGoJsonRest_GPlusStatic 1000000 1626 ns/op 329 B/op 11 allocs/op
|
||||
BenchmarkGoRestful_GPlusStatic 300000 7598 ns/op 1976 B/op 20 allocs/op
|
||||
BenchmarkGorillaMux_GPlusStatic 1000000 2629 ns/op 736 B/op 10 allocs/op
|
||||
BenchmarkHttpRouter_GPlusStatic 30000000 52.5 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkHttpTreeMux_GPlusStatic 20000000 85.8 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkKocha_GPlusStatic 20000000 89.2 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkLARS_GPlusStatic 10000000 162 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_GPlusStatic 500000 3479 ns/op 768 B/op 9 allocs/op
|
||||
BenchmarkMartini_GPlusStatic 200000 9092 ns/op 768 B/op 9 allocs/op
|
||||
BenchmarkPat_GPlusStatic 3000000 493 ns/op 96 B/op 2 allocs/op
|
||||
BenchmarkPossum_GPlusStatic 1000000 1467 ns/op 416 B/op 3 allocs/op
|
||||
BenchmarkR2router_GPlusStatic 2000000 788 ns/op 144 B/op 4 allocs/op
|
||||
BenchmarkRivet_GPlusStatic 20000000 114 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkTango_GPlusStatic 1000000 1534 ns/op 200 B/op 8 allocs/op
|
||||
BenchmarkTigerTonic_GPlusStatic 5000000 282 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkTraffic_GPlusStatic 500000 3798 ns/op 1192 B/op 15 allocs/op
|
||||
BenchmarkVulcan_GPlusStatic 2000000 1125 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkAce_GPlusParam 3000000 528 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkBear_GPlusParam 1000000 1570 ns/op 480 B/op 5 allocs/op
|
||||
BenchmarkBeego_GPlusParam 1000000 2369 ns/op 368 B/op 4 allocs/op
|
||||
BenchmarkBone_GPlusParam 1000000 2028 ns/op 688 B/op 5 allocs/op
|
||||
BenchmarkDenco_GPlusParam 5000000 385 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkEcho_GPlusParam 3000000 441 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkGin_GPlusParam 10000000 174 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GPlusParam 1000000 2033 ns/op 648 B/op 8 allocs/op
|
||||
BenchmarkGoji_GPlusParam 1000000 1399 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGojiv2_GPlusParam 1000000 2641 ns/op 944 B/op 8 allocs/op
|
||||
BenchmarkGoJsonRest_GPlusParam 1000000 2824 ns/op 649 B/op 13 allocs/op
|
||||
BenchmarkGoRestful_GPlusParam 200000 8875 ns/op 2296 B/op 21 allocs/op
|
||||
BenchmarkGorillaMux_GPlusParam 200000 6291 ns/op 1056 B/op 11 allocs/op
|
||||
BenchmarkHttpRouter_GPlusParam 5000000 316 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_GPlusParam 1000000 1129 ns/op 352 B/op 3 allocs/op
|
||||
BenchmarkKocha_GPlusParam 3000000 538 ns/op 56 B/op 3 allocs/op
|
||||
BenchmarkLARS_GPlusParam 10000000 198 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_GPlusParam 500000 3554 ns/op 1056 B/op 10 allocs/op
|
||||
BenchmarkMartini_GPlusParam 200000 9831 ns/op 1072 B/op 10 allocs/op
|
||||
BenchmarkPat_GPlusParam 1000000 2706 ns/op 688 B/op 12 allocs/op
|
||||
BenchmarkPossum_GPlusParam 1000000 2297 ns/op 560 B/op 6 allocs/op
|
||||
BenchmarkR2router_GPlusParam 1000000 1318 ns/op 432 B/op 5 allocs/op
|
||||
BenchmarkRivet_GPlusParam 5000000 399 ns/op 48 B/op 1 allocs/op
|
||||
BenchmarkTango_GPlusParam 1000000 2070 ns/op 264 B/op 8 allocs/op
|
||||
BenchmarkTigerTonic_GPlusParam 500000 4853 ns/op 1056 B/op 17 allocs/op
|
||||
BenchmarkTraffic_GPlusParam 200000 8278 ns/op 1976 B/op 21 allocs/op
|
||||
BenchmarkVulcan_GPlusParam 1000000 1243 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkAce_GPlus2Params 3000000 549 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkBear_GPlus2Params 1000000 2112 ns/op 496 B/op 5 allocs/op
|
||||
BenchmarkBeego_GPlus2Params 500000 2750 ns/op 368 B/op 4 allocs/op
|
||||
BenchmarkBone_GPlus2Params 300000 7032 ns/op 1040 B/op 9 allocs/op
|
||||
BenchmarkDenco_GPlus2Params 3000000 502 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkEcho_GPlus2Params 3000000 641 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkGin_GPlus2Params 5000000 250 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GPlus2Params 1000000 2681 ns/op 712 B/op 9 allocs/op
|
||||
BenchmarkGoji_GPlus2Params 1000000 1926 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGojiv2_GPlus2Params 500000 3996 ns/op 1024 B/op 11 allocs/op
|
||||
BenchmarkGoJsonRest_GPlus2Params 500000 3886 ns/op 713 B/op 14 allocs/op
|
||||
BenchmarkGoRestful_GPlus2Params 200000 10376 ns/op 2360 B/op 21 allocs/op
|
||||
BenchmarkGorillaMux_GPlus2Params 100000 14162 ns/op 1088 B/op 11 allocs/op
|
||||
BenchmarkHttpRouter_GPlus2Params 5000000 336 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_GPlus2Params 1000000 1523 ns/op 384 B/op 4 allocs/op
|
||||
BenchmarkKocha_GPlus2Params 2000000 970 ns/op 128 B/op 5 allocs/op
|
||||
BenchmarkLARS_GPlus2Params 5000000 238 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_GPlus2Params 500000 4016 ns/op 1056 B/op 10 allocs/op
|
||||
BenchmarkMartini_GPlus2Params 100000 21253 ns/op 1200 B/op 13 allocs/op
|
||||
BenchmarkPat_GPlus2Params 200000 8632 ns/op 2256 B/op 34 allocs/op
|
||||
BenchmarkPossum_GPlus2Params 1000000 2171 ns/op 560 B/op 6 allocs/op
|
||||
BenchmarkR2router_GPlus2Params 1000000 1340 ns/op 432 B/op 5 allocs/op
|
||||
BenchmarkRivet_GPlus2Params 3000000 557 ns/op 96 B/op 1 allocs/op
|
||||
BenchmarkTango_GPlus2Params 1000000 2186 ns/op 344 B/op 8 allocs/op
|
||||
BenchmarkTigerTonic_GPlus2Params 200000 9060 ns/op 1488 B/op 24 allocs/op
|
||||
BenchmarkTraffic_GPlus2Params 100000 20324 ns/op 3272 B/op 31 allocs/op
|
||||
BenchmarkVulcan_GPlus2Params 1000000 2039 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkAce_GPlusAll 300000 6603 ns/op 640 B/op 11 allocs/op
|
||||
BenchmarkBear_GPlusAll 100000 22363 ns/op 5488 B/op 61 allocs/op
|
||||
BenchmarkBeego_GPlusAll 50000 38757 ns/op 4784 B/op 52 allocs/op
|
||||
BenchmarkBone_GPlusAll 20000 54916 ns/op 10336 B/op 98 allocs/op
|
||||
BenchmarkDenco_GPlusAll 300000 4959 ns/op 672 B/op 11 allocs/op
|
||||
BenchmarkEcho_GPlusAll 200000 6558 ns/op 416 B/op 13 allocs/op
|
||||
BenchmarkGin_GPlusAll 500000 2757 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_GPlusAll 50000 34615 ns/op 8040 B/op 103 allocs/op
|
||||
BenchmarkGoji_GPlusAll 100000 16002 ns/op 3696 B/op 22 allocs/op
|
||||
BenchmarkGojiv2_GPlusAll 50000 35060 ns/op 12624 B/op 115 allocs/op
|
||||
BenchmarkGoJsonRest_GPlusAll 50000 41479 ns/op 8117 B/op 170 allocs/op
|
||||
BenchmarkGoRestful_GPlusAll 10000 131653 ns/op 32024 B/op 275 allocs/op
|
||||
BenchmarkGorillaMux_GPlusAll 10000 101380 ns/op 13296 B/op 142 allocs/op
|
||||
BenchmarkHttpRouter_GPlusAll 500000 3711 ns/op 640 B/op 11 allocs/op
|
||||
BenchmarkHttpTreeMux_GPlusAll 100000 14438 ns/op 4032 B/op 38 allocs/op
|
||||
BenchmarkKocha_GPlusAll 200000 8039 ns/op 976 B/op 43 allocs/op
|
||||
BenchmarkLARS_GPlusAll 500000 2630 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_GPlusAll 30000 51123 ns/op 13152 B/op 128 allocs/op
|
||||
BenchmarkMartini_GPlusAll 10000 176157 ns/op 14016 B/op 145 allocs/op
|
||||
BenchmarkPat_GPlusAll 20000 69911 ns/op 16576 B/op 298 allocs/op
|
||||
BenchmarkPossum_GPlusAll 100000 20716 ns/op 5408 B/op 39 allocs/op
|
||||
BenchmarkR2router_GPlusAll 100000 17463 ns/op 5040 B/op 63 allocs/op
|
||||
BenchmarkRivet_GPlusAll 300000 5142 ns/op 768 B/op 11 allocs/op
|
||||
BenchmarkTango_GPlusAll 50000 27321 ns/op 3656 B/op 104 allocs/op
|
||||
BenchmarkTigerTonic_GPlusAll 20000 77597 ns/op 14512 B/op 288 allocs/op
|
||||
BenchmarkTraffic_GPlusAll 10000 151406 ns/op 37360 B/op 392 allocs/op
|
||||
BenchmarkVulcan_GPlusAll 100000 18555 ns/op 1274 B/op 39 allocs/op
|
||||
```
|
||||
|
||||
## Parse.com
|
||||
|
||||
```
|
||||
BenchmarkGin_ParseStatic 10000000 133 ns/op 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkAce_ParseStatic 5000000 241 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkBear_ParseStatic 2000000 728 ns/op 120 B/op 3 allocs/op
|
||||
BenchmarkBeego_ParseStatic 1000000 2623 ns/op 368 B/op 4 allocs/op
|
||||
BenchmarkBone_ParseStatic 1000000 1285 ns/op 144 B/op 3 allocs/op
|
||||
BenchmarkDenco_ParseStatic 30000000 57.8 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkEcho_ParseStatic 5000000 342 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkGocraftWeb_ParseStatic 1000000 1478 ns/op 296 B/op 5 allocs/op
|
||||
BenchmarkGoji_ParseStatic 3000000 415 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGojiv2_ParseStatic 1000000 2087 ns/op 928 B/op 7 allocs/op
|
||||
BenchmarkGoJsonRest_ParseStatic 1000000 1712 ns/op 329 B/op 11 allocs/op
|
||||
BenchmarkGoRestful_ParseStatic 200000 11072 ns/op 3224 B/op 22 allocs/op
|
||||
BenchmarkGorillaMux_ParseStatic 500000 4129 ns/op 752 B/op 11 allocs/op
|
||||
BenchmarkHttpRouter_ParseStatic 30000000 52.4 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkHttpTreeMux_ParseStatic 20000000 109 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkKocha_ParseStatic 20000000 81.8 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkLARS_ParseStatic 10000000 150 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_ParseStatic 1000000 3288 ns/op 768 B/op 9 allocs/op
|
||||
BenchmarkMartini_ParseStatic 200000 9110 ns/op 768 B/op 9 allocs/op
|
||||
BenchmarkPat_ParseStatic 1000000 1135 ns/op 240 B/op 5 allocs/op
|
||||
BenchmarkPossum_ParseStatic 1000000 1557 ns/op 416 B/op 3 allocs/op
|
||||
BenchmarkR2router_ParseStatic 2000000 730 ns/op 144 B/op 4 allocs/op
|
||||
BenchmarkRivet_ParseStatic 10000000 121 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkTango_ParseStatic 1000000 1688 ns/op 248 B/op 8 allocs/op
|
||||
BenchmarkTigerTonic_ParseStatic 3000000 427 ns/op 48 B/op 1 allocs/op
|
||||
BenchmarkTraffic_ParseStatic 500000 5962 ns/op 1816 B/op 20 allocs/op
|
||||
BenchmarkVulcan_ParseStatic 2000000 969 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkAce_ParseParam 3000000 497 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkBear_ParseParam 1000000 1473 ns/op 467 B/op 5 allocs/op
|
||||
BenchmarkBeego_ParseParam 1000000 2384 ns/op 368 B/op 4 allocs/op
|
||||
BenchmarkBone_ParseParam 1000000 2513 ns/op 768 B/op 6 allocs/op
|
||||
BenchmarkDenco_ParseParam 5000000 364 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkEcho_ParseParam 5000000 418 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkGin_ParseParam 10000000 163 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_ParseParam 1000000 2361 ns/op 664 B/op 8 allocs/op
|
||||
BenchmarkGoji_ParseParam 1000000 1590 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGojiv2_ParseParam 1000000 2851 ns/op 976 B/op 9 allocs/op
|
||||
BenchmarkGoJsonRest_ParseParam 1000000 2965 ns/op 649 B/op 13 allocs/op
|
||||
BenchmarkGoRestful_ParseParam 200000 12207 ns/op 3544 B/op 23 allocs/op
|
||||
BenchmarkGorillaMux_ParseParam 500000 5187 ns/op 1088 B/op 12 allocs/op
|
||||
BenchmarkHttpRouter_ParseParam 5000000 275 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_ParseParam 1000000 1108 ns/op 352 B/op 3 allocs/op
|
||||
BenchmarkKocha_ParseParam 3000000 495 ns/op 56 B/op 3 allocs/op
|
||||
BenchmarkLARS_ParseParam 10000000 192 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_ParseParam 500000 4103 ns/op 1056 B/op 10 allocs/op
|
||||
BenchmarkMartini_ParseParam 200000 9878 ns/op 1072 B/op 10 allocs/op
|
||||
BenchmarkPat_ParseParam 500000 3657 ns/op 1120 B/op 17 allocs/op
|
||||
BenchmarkPossum_ParseParam 1000000 2084 ns/op 560 B/op 6 allocs/op
|
||||
BenchmarkR2router_ParseParam 1000000 1251 ns/op 432 B/op 5 allocs/op
|
||||
BenchmarkRivet_ParseParam 5000000 335 ns/op 48 B/op 1 allocs/op
|
||||
BenchmarkTango_ParseParam 1000000 1854 ns/op 280 B/op 8 allocs/op
|
||||
BenchmarkTigerTonic_ParseParam 500000 4582 ns/op 1008 B/op 17 allocs/op
|
||||
BenchmarkTraffic_ParseParam 200000 8125 ns/op 2248 B/op 23 allocs/op
|
||||
BenchmarkVulcan_ParseParam 1000000 1148 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkAce_Parse2Params 3000000 539 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkBear_Parse2Params 1000000 1778 ns/op 496 B/op 5 allocs/op
|
||||
BenchmarkBeego_Parse2Params 1000000 2519 ns/op 368 B/op 4 allocs/op
|
||||
BenchmarkBone_Parse2Params 1000000 2596 ns/op 720 B/op 5 allocs/op
|
||||
BenchmarkDenco_Parse2Params 3000000 492 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkEcho_Parse2Params 3000000 484 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkGin_Parse2Params 10000000 193 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_Parse2Params 1000000 2575 ns/op 712 B/op 9 allocs/op
|
||||
BenchmarkGoji_Parse2Params 1000000 1373 ns/op 336 B/op 2 allocs/op
|
||||
BenchmarkGojiv2_Parse2Params 500000 2416 ns/op 960 B/op 8 allocs/op
|
||||
BenchmarkGoJsonRest_Parse2Params 300000 3452 ns/op 713 B/op 14 allocs/op
|
||||
BenchmarkGoRestful_Parse2Params 100000 17719 ns/op 6008 B/op 25 allocs/op
|
||||
BenchmarkGorillaMux_Parse2Params 300000 5102 ns/op 1088 B/op 11 allocs/op
|
||||
BenchmarkHttpRouter_Parse2Params 5000000 303 ns/op 64 B/op 1 allocs/op
|
||||
BenchmarkHttpTreeMux_Parse2Params 1000000 1372 ns/op 384 B/op 4 allocs/op
|
||||
BenchmarkKocha_Parse2Params 2000000 874 ns/op 128 B/op 5 allocs/op
|
||||
BenchmarkLARS_Parse2Params 10000000 192 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_Parse2Params 500000 3871 ns/op 1056 B/op 10 allocs/op
|
||||
BenchmarkMartini_Parse2Params 200000 9954 ns/op 1152 B/op 11 allocs/op
|
||||
BenchmarkPat_Parse2Params 500000 4194 ns/op 832 B/op 17 allocs/op
|
||||
BenchmarkPossum_Parse2Params 1000000 2121 ns/op 560 B/op 6 allocs/op
|
||||
BenchmarkR2router_Parse2Params 1000000 1415 ns/op 432 B/op 5 allocs/op
|
||||
BenchmarkRivet_Parse2Params 3000000 457 ns/op 96 B/op 1 allocs/op
|
||||
BenchmarkTango_Parse2Params 1000000 1914 ns/op 312 B/op 8 allocs/op
|
||||
BenchmarkTigerTonic_Parse2Params 300000 6895 ns/op 1408 B/op 24 allocs/op
|
||||
BenchmarkTraffic_Parse2Params 200000 8317 ns/op 2040 B/op 22 allocs/op
|
||||
BenchmarkVulcan_Parse2Params 1000000 1274 ns/op 98 B/op 3 allocs/op
|
||||
BenchmarkAce_ParseAll 200000 10401 ns/op 640 B/op 16 allocs/op
|
||||
BenchmarkBear_ParseAll 50000 37743 ns/op 8928 B/op 110 allocs/op
|
||||
BenchmarkBeego_ParseAll 20000 63193 ns/op 9568 B/op 104 allocs/op
|
||||
BenchmarkBone_ParseAll 20000 61767 ns/op 14160 B/op 131 allocs/op
|
||||
BenchmarkDenco_ParseAll 300000 7036 ns/op 928 B/op 16 allocs/op
|
||||
BenchmarkEcho_ParseAll 200000 11824 ns/op 832 B/op 26 allocs/op
|
||||
BenchmarkGin_ParseAll 300000 4199 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkGocraftWeb_ParseAll 30000 51758 ns/op 13728 B/op 181 allocs/op
|
||||
BenchmarkGoji_ParseAll 50000 29614 ns/op 5376 B/op 32 allocs/op
|
||||
BenchmarkGojiv2_ParseAll 20000 68676 ns/op 24464 B/op 199 allocs/op
|
||||
BenchmarkGoJsonRest_ParseAll 20000 76135 ns/op 13866 B/op 321 allocs/op
|
||||
BenchmarkGoRestful_ParseAll 5000 389487 ns/op 110928 B/op 600 allocs/op
|
||||
BenchmarkGorillaMux_ParseAll 10000 221250 ns/op 24864 B/op 292 allocs/op
|
||||
BenchmarkHttpRouter_ParseAll 200000 6444 ns/op 640 B/op 16 allocs/op
|
||||
BenchmarkHttpTreeMux_ParseAll 50000 30702 ns/op 5728 B/op 51 allocs/op
|
||||
BenchmarkKocha_ParseAll 200000 13712 ns/op 1112 B/op 54 allocs/op
|
||||
BenchmarkLARS_ParseAll 300000 6925 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkMacaron_ParseAll 20000 96278 ns/op 24576 B/op 250 allocs/op
|
||||
BenchmarkMartini_ParseAll 5000 271352 ns/op 25072 B/op 253 allocs/op
|
||||
BenchmarkPat_ParseAll 20000 74941 ns/op 17264 B/op 343 allocs/op
|
||||
BenchmarkPossum_ParseAll 50000 39947 ns/op 10816 B/op 78 allocs/op
|
||||
BenchmarkR2router_ParseAll 50000 42479 ns/op 8352 B/op 120 allocs/op
|
||||
BenchmarkRivet_ParseAll 200000 7726 ns/op 912 B/op 16 allocs/op
|
||||
BenchmarkTango_ParseAll 30000 50014 ns/op 7168 B/op 208 allocs/op
|
||||
BenchmarkTigerTonic_ParseAll 10000 106550 ns/op 19728 B/op 379 allocs/op
|
||||
BenchmarkTraffic_ParseAll 10000 216037 ns/op 57776 B/op 642 allocs/op
|
||||
BenchmarkVulcan_ParseAll 50000 34379 ns/op 2548 B/op 78 allocs/op
|
||||
```
|
||||
|
24
vendor/github.com/gin-gonic/gin/CHANGELOG.md
generated
vendored
24
vendor/github.com/gin-gonic/gin/CHANGELOG.md
generated
vendored
@ -1,6 +1,28 @@
|
||||
# CHANGELOG
|
||||
|
||||
### Gin 1.2
|
||||
### Gin 1.3.0
|
||||
|
||||
- [NEW] Add [`func (*Context) QueryMap`](https://godoc.org/github.com/gin-gonic/gin#Context.QueryMap), [`func (*Context) GetQueryMap`](https://godoc.org/github.com/gin-gonic/gin#Context.GetQueryMap), [`func (*Context) PostFormMap`](https://godoc.org/github.com/gin-gonic/gin#Context.PostFormMap) and [`func (*Context) GetPostFormMap`](https://godoc.org/github.com/gin-gonic/gin#Context.GetPostFormMap) to support `type map[string]string` as query string or form parameters, see [#1383](https://github.com/gin-gonic/gin/pull/1383)
|
||||
- [NEW] Add [`func (*Context) AsciiJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.AsciiJSON), see [#1358](https://github.com/gin-gonic/gin/pull/1358)
|
||||
- [NEW] Add `Pusher()` in [`type ResponseWriter`](https://godoc.org/github.com/gin-gonic/gin#ResponseWriter) for supporting http2 push, see [#1273](https://github.com/gin-gonic/gin/pull/1273)
|
||||
- [NEW] Add [`func (*Context) DataFromReader`](https://godoc.org/github.com/gin-gonic/gin#Context.DataFromReader) for serving dynamic data, see [#1304](https://github.com/gin-gonic/gin/pull/1304)
|
||||
- [NEW] Add [`func (*Context) ShouldBindBodyWith`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindBodyWith) allowing to call binding multiple times, see [#1341](https://github.com/gin-gonic/gin/pull/1341)
|
||||
- [NEW] Support pointers in form binding, see [#1336](https://github.com/gin-gonic/gin/pull/1336)
|
||||
- [NEW] Add [`func (*Context) JSONP`](https://godoc.org/github.com/gin-gonic/gin#Context.JSONP), see [#1333](https://github.com/gin-gonic/gin/pull/1333)
|
||||
- [NEW] Support default value in form binding, see [#1138](https://github.com/gin-gonic/gin/pull/1138)
|
||||
- [NEW] Expose validator engine in [`type StructValidator`](https://godoc.org/github.com/gin-gonic/gin/binding#StructValidator), see [#1277](https://github.com/gin-gonic/gin/pull/1277)
|
||||
- [NEW] Add [`func (*Context) ShouldBind`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBind), [`func (*Context) ShouldBindQuery`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindQuery) and [`func (*Context) ShouldBindJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindJSON), see [#1047](https://github.com/gin-gonic/gin/pull/1047)
|
||||
- [NEW] Add support for `time.Time` location in form binding, see [#1117](https://github.com/gin-gonic/gin/pull/1117)
|
||||
- [NEW] Add [`func (*Context) BindQuery`](https://godoc.org/github.com/gin-gonic/gin#Context.BindQuery), see [#1029](https://github.com/gin-gonic/gin/pull/1029)
|
||||
- [NEW] Make [jsonite](https://github.com/json-iterator/go) optional with build tags, see [#1026](https://github.com/gin-gonic/gin/pull/1026)
|
||||
- [NEW] Show query string in logger, see [#999](https://github.com/gin-gonic/gin/pull/999)
|
||||
- [NEW] Add [`func (*Context) SecureJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.SecureJSON), see [#987](https://github.com/gin-gonic/gin/pull/987) and [#993](https://github.com/gin-gonic/gin/pull/993)
|
||||
- [DEPRECATE] `func (*Context) GetCookie` for [`func (*Context) Cookie`](https://godoc.org/github.com/gin-gonic/gin#Context.Cookie)
|
||||
- [FIX] Don't display color tags if [`func DisableConsoleColor`](https://godoc.org/github.com/gin-gonic/gin#DisableConsoleColor) called, see [#1072](https://github.com/gin-gonic/gin/pull/1072)
|
||||
- [FIX] Gin Mode `""` when calling [`func Mode`](https://godoc.org/github.com/gin-gonic/gin#Mode) now returns `const DebugMode`, see [#1250](https://github.com/gin-gonic/gin/pull/1250)
|
||||
- [FIX] `Flush()` now doesn't overwrite `responseWriter` status code, see [#1460](https://github.com/gin-gonic/gin/pull/1460)
|
||||
|
||||
### Gin 1.2.0
|
||||
|
||||
- [NEW] Switch from godeps to govendor
|
||||
- [NEW] Add support for Let's Encrypt via gin-gonic/autotls
|
||||
|
46
vendor/github.com/gin-gonic/gin/CODE_OF_CONDUCT.md
generated
vendored
Normal file
46
vendor/github.com/gin-gonic/gin/CODE_OF_CONDUCT.md
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at teamgingonic@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
13
vendor/github.com/gin-gonic/gin/CONTRIBUTING.md
generated
vendored
Normal file
13
vendor/github.com/gin-gonic/gin/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
## Contributing
|
||||
|
||||
- With issues:
|
||||
- Use the search tool before opening a new issue.
|
||||
- Please provide source code and commit sha if you found a bug.
|
||||
- Review existing issues and provide feedback or react to them.
|
||||
|
||||
- With pull requests:
|
||||
- Open your pull request against `master`
|
||||
- Your pull request should have no more than two commits, if not you should squash them.
|
||||
- It should pass all tests in the available continuous integrations systems such as TravisCI.
|
||||
- You should add/modify tests to cover your proposed code changes.
|
||||
- If your pull request contains a new feature, please document it on the README.
|
7
vendor/github.com/gin-gonic/gin/Makefile
generated
vendored
7
vendor/github.com/gin-gonic/gin/Makefile
generated
vendored
@ -1,15 +1,16 @@
|
||||
GOFMT ?= gofmt "-s"
|
||||
PACKAGES ?= $(shell go list ./... | grep -v /vendor/)
|
||||
VETPACKAGES ?= $(shell go list ./... | grep -v /vendor/ | grep -v /examples/)
|
||||
GOFILES := $(shell find . -name "*.go" -type f -not -path "./vendor/*")
|
||||
|
||||
all: build
|
||||
all: install
|
||||
|
||||
install: deps
|
||||
govendor sync
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -v -covermode=count -coverprofile=coverage.out
|
||||
sh coverage.sh
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
@ -26,7 +27,7 @@ fmt-check:
|
||||
fi;
|
||||
|
||||
vet:
|
||||
go vet $(PACKAGES)
|
||||
go vet $(VETPACKAGES)
|
||||
|
||||
deps:
|
||||
@hash govendor > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
|
1075
vendor/github.com/gin-gonic/gin/README.md
generated
vendored
1075
vendor/github.com/gin-gonic/gin/README.md
generated
vendored
File diff suppressed because it is too large
Load Diff
46
vendor/github.com/gin-gonic/gin/auth.go
generated
vendored
46
vendor/github.com/gin-gonic/gin/auth.go
generated
vendored
@ -7,27 +7,30 @@ package gin
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"encoding/base64"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// AuthUserKey is the cookie name for user credential in basic auth.
|
||||
const AuthUserKey = "user"
|
||||
|
||||
type (
|
||||
Accounts map[string]string
|
||||
authPair struct {
|
||||
Value string
|
||||
User string
|
||||
}
|
||||
authPairs []authPair
|
||||
)
|
||||
// Accounts defines a key/value for user/pass list of authorized logins.
|
||||
type Accounts map[string]string
|
||||
|
||||
type authPair struct {
|
||||
value string
|
||||
user string
|
||||
}
|
||||
|
||||
type authPairs []authPair
|
||||
|
||||
func (a authPairs) searchCredential(authValue string) (string, bool) {
|
||||
if len(authValue) == 0 {
|
||||
if authValue == "" {
|
||||
return "", false
|
||||
}
|
||||
for _, pair := range a {
|
||||
if pair.Value == authValue {
|
||||
return pair.User, true
|
||||
if pair.value == authValue {
|
||||
return pair.user, true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
@ -45,16 +48,17 @@ func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc {
|
||||
pairs := processAccounts(accounts)
|
||||
return func(c *Context) {
|
||||
// Search user in the slice of allowed credentials
|
||||
user, found := pairs.searchCredential(c.Request.Header.Get("Authorization"))
|
||||
user, found := pairs.searchCredential(c.requestHeader("Authorization"))
|
||||
if !found {
|
||||
// Credentials doesn't match, we return 401 and abort handlers chain.
|
||||
c.Header("WWW-Authenticate", realm)
|
||||
c.AbortWithStatus(401)
|
||||
} else {
|
||||
// The user credentials was found, set user's id to key AuthUserKey in this context, the userId can be read later using
|
||||
// c.MustGet(gin.AuthUserKey)
|
||||
c.Set(AuthUserKey, user)
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
// The user credentials was found, set user's id to key AuthUserKey in this context, the user's id can be read later using
|
||||
// c.MustGet(gin.AuthUserKey).
|
||||
c.Set(AuthUserKey, user)
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,11 +72,11 @@ func processAccounts(accounts Accounts) authPairs {
|
||||
assert1(len(accounts) > 0, "Empty list of authorized credentials")
|
||||
pairs := make(authPairs, 0, len(accounts))
|
||||
for user, password := range accounts {
|
||||
assert1(len(user) > 0, "User can not be empty")
|
||||
assert1(user != "", "User can not be empty")
|
||||
value := authorizationHeader(user, password)
|
||||
pairs = append(pairs, authPair{
|
||||
Value: value,
|
||||
User: user,
|
||||
value: value,
|
||||
user: user,
|
||||
})
|
||||
}
|
||||
return pairs
|
||||
@ -87,6 +91,6 @@ func secureCompare(given, actual string) bool {
|
||||
if subtle.ConstantTimeEq(int32(len(given)), int32(len(actual))) == 1 {
|
||||
return subtle.ConstantTimeCompare([]byte(given), []byte(actual)) == 1
|
||||
}
|
||||
/* Securely compare actual to itself to keep constant time, but always return false */
|
||||
// Securely compare actual to itself to keep constant time, but always return false.
|
||||
return subtle.ConstantTimeCompare([]byte(actual), []byte(actual)) == 1 && false
|
||||
}
|
||||
|
27
vendor/github.com/gin-gonic/gin/binding/binding.go
generated
vendored
27
vendor/github.com/gin-gonic/gin/binding/binding.go
generated
vendored
@ -6,6 +6,7 @@ package binding
|
||||
|
||||
import "net/http"
|
||||
|
||||
// Content-Type MIME of the most common data formats.
|
||||
const (
|
||||
MIMEJSON = "application/json"
|
||||
MIMEHTML = "text/html"
|
||||
@ -19,11 +20,25 @@ const (
|
||||
MIMEMSGPACK2 = "application/msgpack"
|
||||
)
|
||||
|
||||
// Binding describes the interface which needs to be implemented for binding the
|
||||
// data present in the request such as JSON request body, query parameters or
|
||||
// the form POST.
|
||||
type Binding interface {
|
||||
Name() string
|
||||
Bind(*http.Request, interface{}) error
|
||||
}
|
||||
|
||||
// BindingBody adds BindBody method to Binding. BindBody is similar with Bind,
|
||||
// but it reads the body from supplied bytes instead of req.Body.
|
||||
type BindingBody interface {
|
||||
Binding
|
||||
BindBody([]byte, interface{}) error
|
||||
}
|
||||
|
||||
// StructValidator is the minimal interface which needs to be implemented in
|
||||
// order for it to be used as the validator engine for ensuring the correctness
|
||||
// of the reqest. Gin provides a default implementation for this using
|
||||
// https://github.com/go-playground/validator/tree/v8.18.2.
|
||||
type StructValidator interface {
|
||||
// ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right.
|
||||
// If the received type is not a struct, any validation should be skipped and nil must be returned.
|
||||
@ -31,20 +46,32 @@ type StructValidator interface {
|
||||
// If the struct is not valid or the validation itself fails, a descriptive error should be returned.
|
||||
// Otherwise nil must be returned.
|
||||
ValidateStruct(interface{}) error
|
||||
|
||||
// Engine returns the underlying validator engine which powers the
|
||||
// StructValidator implementation.
|
||||
Engine() interface{}
|
||||
}
|
||||
|
||||
// Validator is the default validator which implements the StructValidator
|
||||
// interface. It uses https://github.com/go-playground/validator/tree/v8.18.2
|
||||
// under the hood.
|
||||
var Validator StructValidator = &defaultValidator{}
|
||||
|
||||
// These implement the Binding interface and can be used to bind the data
|
||||
// present in the request to struct instances.
|
||||
var (
|
||||
JSON = jsonBinding{}
|
||||
XML = xmlBinding{}
|
||||
Form = formBinding{}
|
||||
Query = queryBinding{}
|
||||
FormPost = formPostBinding{}
|
||||
FormMultipart = formMultipartBinding{}
|
||||
ProtoBuf = protobufBinding{}
|
||||
MsgPack = msgpackBinding{}
|
||||
)
|
||||
|
||||
// Default returns the appropriate Binding instance based on the HTTP method
|
||||
// and the content type.
|
||||
func Default(method, contentType string) Binding {
|
||||
if method == "GET" {
|
||||
return Form
|
||||
|
28
vendor/github.com/gin-gonic/gin/binding/default_validator.go
generated
vendored
28
vendor/github.com/gin-gonic/gin/binding/default_validator.go
generated
vendored
@ -18,28 +18,34 @@ type defaultValidator struct {
|
||||
|
||||
var _ StructValidator = &defaultValidator{}
|
||||
|
||||
// ValidateStruct receives any kind of type, but only performed struct or pointer to struct type.
|
||||
func (v *defaultValidator) ValidateStruct(obj interface{}) error {
|
||||
if kindOfData(obj) == reflect.Struct {
|
||||
value := reflect.ValueOf(obj)
|
||||
valueType := value.Kind()
|
||||
if valueType == reflect.Ptr {
|
||||
valueType = value.Elem().Kind()
|
||||
}
|
||||
if valueType == reflect.Struct {
|
||||
v.lazyinit()
|
||||
if err := v.validate.Struct(obj); err != nil {
|
||||
return error(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Engine returns the underlying validator engine which powers the default
|
||||
// Validator instance. This is useful if you want to register custom validations
|
||||
// or struct level validations. See validator GoDoc for more info -
|
||||
// https://godoc.org/gopkg.in/go-playground/validator.v8
|
||||
func (v *defaultValidator) Engine() interface{} {
|
||||
v.lazyinit()
|
||||
return v.validate
|
||||
}
|
||||
|
||||
func (v *defaultValidator) lazyinit() {
|
||||
v.once.Do(func() {
|
||||
config := &validator.Config{TagName: "binding"}
|
||||
v.validate = validator.New(config)
|
||||
})
|
||||
}
|
||||
|
||||
func kindOfData(data interface{}) reflect.Kind {
|
||||
value := reflect.ValueOf(data)
|
||||
valueType := value.Kind()
|
||||
if valueType == reflect.Ptr {
|
||||
valueType = value.Elem().Kind()
|
||||
}
|
||||
return valueType
|
||||
}
|
||||
|
6
vendor/github.com/gin-gonic/gin/binding/form.go
generated
vendored
6
vendor/github.com/gin-gonic/gin/binding/form.go
generated
vendored
@ -6,6 +6,8 @@ package binding
|
||||
|
||||
import "net/http"
|
||||
|
||||
const defaultMemory = 32 * 1024 * 1024
|
||||
|
||||
type formBinding struct{}
|
||||
type formPostBinding struct{}
|
||||
type formMultipartBinding struct{}
|
||||
@ -18,7 +20,7 @@ func (formBinding) Bind(req *http.Request, obj interface{}) error {
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
req.ParseMultipartForm(32 << 10) // 32 MB
|
||||
req.ParseMultipartForm(defaultMemory)
|
||||
if err := mapForm(obj, req.Form); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -44,7 +46,7 @@ func (formMultipartBinding) Name() string {
|
||||
}
|
||||
|
||||
func (formMultipartBinding) Bind(req *http.Request, obj interface{}) error {
|
||||
if err := req.ParseMultipartForm(32 << 10); err != nil {
|
||||
if err := req.ParseMultipartForm(defaultMemory); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := mapForm(obj, req.MultipartForm.Value); err != nil {
|
||||
|
51
vendor/github.com/gin-gonic/gin/binding/form_mapping.go
generated
vendored
51
vendor/github.com/gin-gonic/gin/binding/form_mapping.go
generated
vendored
@ -8,6 +8,7 @@ import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -23,12 +24,28 @@ func mapForm(ptr interface{}, form map[string][]string) error {
|
||||
|
||||
structFieldKind := structField.Kind()
|
||||
inputFieldName := typeField.Tag.Get("form")
|
||||
inputFieldNameList := strings.Split(inputFieldName, ",")
|
||||
inputFieldName = inputFieldNameList[0]
|
||||
var defaultValue string
|
||||
if len(inputFieldNameList) > 1 {
|
||||
defaultList := strings.SplitN(inputFieldNameList[1], "=", 2)
|
||||
if defaultList[0] == "default" {
|
||||
defaultValue = defaultList[1]
|
||||
}
|
||||
}
|
||||
if inputFieldName == "" {
|
||||
inputFieldName = typeField.Name
|
||||
|
||||
// if "form" tag is nil, we inspect if the field is a struct.
|
||||
// if "form" tag is nil, we inspect if the field is a struct or struct pointer.
|
||||
// this would not make sense for JSON parsing but it does for a form
|
||||
// since data is flatten
|
||||
if structFieldKind == reflect.Ptr {
|
||||
if !structField.Elem().IsValid() {
|
||||
structField.Set(reflect.New(structField.Type().Elem()))
|
||||
}
|
||||
structField = structField.Elem()
|
||||
structFieldKind = structField.Kind()
|
||||
}
|
||||
if structFieldKind == reflect.Struct {
|
||||
err := mapForm(structField.Addr().Interface(), form)
|
||||
if err != nil {
|
||||
@ -38,8 +55,13 @@ func mapForm(ptr interface{}, form map[string][]string) error {
|
||||
}
|
||||
}
|
||||
inputValue, exists := form[inputFieldName]
|
||||
|
||||
if !exists {
|
||||
continue
|
||||
if defaultValue == "" {
|
||||
continue
|
||||
}
|
||||
inputValue = make([]string, 1)
|
||||
inputValue[0] = defaultValue
|
||||
}
|
||||
|
||||
numElems := len(inputValue)
|
||||
@ -97,6 +119,12 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V
|
||||
return setFloatField(val, 64, structField)
|
||||
case reflect.String:
|
||||
structField.SetString(val)
|
||||
case reflect.Ptr:
|
||||
if !structField.Elem().IsValid() {
|
||||
structField.Set(reflect.New(structField.Type().Elem()))
|
||||
}
|
||||
structFieldElem := structField.Elem()
|
||||
return setWithProperType(structFieldElem.Kind(), val, structFieldElem)
|
||||
default:
|
||||
return errors.New("Unknown type")
|
||||
}
|
||||
@ -133,7 +161,7 @@ func setBoolField(val string, field reflect.Value) error {
|
||||
if err == nil {
|
||||
field.SetBool(boolVal)
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func setFloatField(val string, bitSize int, field reflect.Value) error {
|
||||
@ -163,6 +191,14 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val
|
||||
l = time.UTC
|
||||
}
|
||||
|
||||
if locTag := structField.Tag.Get("time_location"); locTag != "" {
|
||||
loc, err := time.LoadLocation(locTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l = loc
|
||||
}
|
||||
|
||||
t, err := time.ParseInLocation(timeFormat, val, l)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -171,12 +207,3 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val
|
||||
value.Set(reflect.ValueOf(t))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Don't pass in pointers to bind to. Can lead to bugs. See:
|
||||
// https://github.com/codegangsta/martini-contrib/issues/40
|
||||
// https://github.com/codegangsta/martini-contrib/pull/34#issuecomment-29683659
|
||||
func ensureNotPointer(obj interface{}) {
|
||||
if reflect.TypeOf(obj).Kind() == reflect.Ptr {
|
||||
panic("Pointers are not accepted as binding models")
|
||||
}
|
||||
}
|
||||
|
23
vendor/github.com/gin-gonic/gin/binding/json.go
generated
vendored
23
vendor/github.com/gin-gonic/gin/binding/json.go
generated
vendored
@ -5,10 +5,18 @@
|
||||
package binding
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin/json"
|
||||
)
|
||||
|
||||
// EnableDecoderUseNumber is used to call the UseNumber method on the JSON
|
||||
// Decoder instance. UseNumber causes the Decoder to unmarshal a number into an
|
||||
// interface{} as a Number instead of as a float64.
|
||||
var EnableDecoderUseNumber = false
|
||||
|
||||
type jsonBinding struct{}
|
||||
|
||||
func (jsonBinding) Name() string {
|
||||
@ -16,7 +24,18 @@ func (jsonBinding) Name() string {
|
||||
}
|
||||
|
||||
func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
|
||||
decoder := json.NewDecoder(req.Body)
|
||||
return decodeJSON(req.Body, obj)
|
||||
}
|
||||
|
||||
func (jsonBinding) BindBody(body []byte, obj interface{}) error {
|
||||
return decodeJSON(bytes.NewReader(body), obj)
|
||||
}
|
||||
|
||||
func decodeJSON(r io.Reader, obj interface{}) error {
|
||||
decoder := json.NewDecoder(r)
|
||||
if EnableDecoderUseNumber {
|
||||
decoder.UseNumber()
|
||||
}
|
||||
if err := decoder.Decode(obj); err != nil {
|
||||
return err
|
||||
}
|
||||
|
15
vendor/github.com/gin-gonic/gin/binding/msgpack.go
generated
vendored
15
vendor/github.com/gin-gonic/gin/binding/msgpack.go
generated
vendored
@ -5,6 +5,8 @@
|
||||
package binding
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/ugorji/go/codec"
|
||||
@ -17,12 +19,17 @@ func (msgpackBinding) Name() string {
|
||||
}
|
||||
|
||||
func (msgpackBinding) Bind(req *http.Request, obj interface{}) error {
|
||||
return decodeMsgPack(req.Body, obj)
|
||||
}
|
||||
|
||||
if err := codec.NewDecoder(req.Body, new(codec.MsgpackHandle)).Decode(&obj); err != nil {
|
||||
//var decoder *codec.Decoder = codec.NewDecoder(req.Body, &codec.MsgpackHandle)
|
||||
//if err := decoder.Decode(&obj); err != nil {
|
||||
func (msgpackBinding) BindBody(body []byte, obj interface{}) error {
|
||||
return decodeMsgPack(bytes.NewReader(body), obj)
|
||||
}
|
||||
|
||||
func decodeMsgPack(r io.Reader, obj interface{}) error {
|
||||
cdc := new(codec.MsgpackHandle)
|
||||
if err := codec.NewDecoder(r, cdc).Decode(&obj); err != nil {
|
||||
return err
|
||||
}
|
||||
return validate(obj)
|
||||
|
||||
}
|
||||
|
15
vendor/github.com/gin-gonic/gin/binding/protobuf.go
generated
vendored
15
vendor/github.com/gin-gonic/gin/binding/protobuf.go
generated
vendored
@ -17,19 +17,20 @@ func (protobufBinding) Name() string {
|
||||
return "protobuf"
|
||||
}
|
||||
|
||||
func (protobufBinding) Bind(req *http.Request, obj interface{}) error {
|
||||
|
||||
func (b protobufBinding) Bind(req *http.Request, obj interface{}) error {
|
||||
buf, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return b.BindBody(buf, obj)
|
||||
}
|
||||
|
||||
if err = proto.Unmarshal(buf, obj.(proto.Message)); err != nil {
|
||||
func (protobufBinding) BindBody(body []byte, obj interface{}) error {
|
||||
if err := proto.Unmarshal(body, 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
|
||||
// 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)
|
||||
// return validate(obj)
|
||||
}
|
||||
|
21
vendor/github.com/gin-gonic/gin/binding/query.go
generated
vendored
Normal file
21
vendor/github.com/gin-gonic/gin/binding/query.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2017 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 "net/http"
|
||||
|
||||
type queryBinding struct{}
|
||||
|
||||
func (queryBinding) Name() string {
|
||||
return "query"
|
||||
}
|
||||
|
||||
func (queryBinding) Bind(req *http.Request, obj interface{}) error {
|
||||
values := req.URL.Query()
|
||||
if err := mapForm(obj, values); err != nil {
|
||||
return err
|
||||
}
|
||||
return validate(obj)
|
||||
}
|
11
vendor/github.com/gin-gonic/gin/binding/xml.go
generated
vendored
11
vendor/github.com/gin-gonic/gin/binding/xml.go
generated
vendored
@ -5,7 +5,9 @@
|
||||
package binding
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@ -16,7 +18,14 @@ func (xmlBinding) Name() string {
|
||||
}
|
||||
|
||||
func (xmlBinding) Bind(req *http.Request, obj interface{}) error {
|
||||
decoder := xml.NewDecoder(req.Body)
|
||||
return decodeXML(req.Body, obj)
|
||||
}
|
||||
|
||||
func (xmlBinding) BindBody(body []byte, obj interface{}) error {
|
||||
return decodeXML(bytes.NewReader(body), obj)
|
||||
}
|
||||
func decodeXML(r io.Reader, obj interface{}) error {
|
||||
decoder := xml.NewDecoder(r)
|
||||
if err := decoder.Decode(obj); err != nil {
|
||||
return err
|
||||
}
|
||||
|
343
vendor/github.com/gin-gonic/gin/context.go
generated
vendored
343
vendor/github.com/gin-gonic/gin/context.go
generated
vendored
@ -13,6 +13,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -21,7 +22,7 @@ import (
|
||||
"github.com/gin-gonic/gin/render"
|
||||
)
|
||||
|
||||
// Content-Type MIME of the most common data formats
|
||||
// Content-Type MIME of the most common data formats.
|
||||
const (
|
||||
MIMEJSON = binding.MIMEJSON
|
||||
MIMEHTML = binding.MIMEHTML
|
||||
@ -30,12 +31,10 @@ const (
|
||||
MIMEPlain = binding.MIMEPlain
|
||||
MIMEPOSTForm = binding.MIMEPOSTForm
|
||||
MIMEMultipartPOSTForm = binding.MIMEMultipartPOSTForm
|
||||
BodyBytesKey = "_gin-gonic/gin/bodybyteskey"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultMemory = 32 << 20 // 32 MB
|
||||
abortIndex int8 = math.MaxInt8 / 2
|
||||
)
|
||||
const abortIndex int8 = math.MaxInt8 / 2
|
||||
|
||||
// Context is the most important part of gin. It allows us to pass variables between middleware,
|
||||
// manage the flow, validate the JSON of a request and render a JSON response for example.
|
||||
@ -48,9 +47,15 @@ type Context struct {
|
||||
handlers HandlersChain
|
||||
index int8
|
||||
|
||||
engine *Engine
|
||||
Keys map[string]interface{}
|
||||
Errors errorMsgs
|
||||
engine *Engine
|
||||
|
||||
// Keys is a key/value pair exclusively for the context of each request.
|
||||
Keys map[string]interface{}
|
||||
|
||||
// Errors is a list of errors attached to all the handlers/middlewares who used this context.
|
||||
Errors errorMsgs
|
||||
|
||||
// Accepted defines a list of manually accepted formats for content negotiation.
|
||||
Accepted []string
|
||||
}
|
||||
|
||||
@ -79,8 +84,8 @@ func (c *Context) Copy() *Context {
|
||||
return &cp
|
||||
}
|
||||
|
||||
// HandlerName returns the main handler's name. For example if the handler is "handleGetUsers()", this
|
||||
// function will return "main.handleGetUsers"
|
||||
// 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())
|
||||
}
|
||||
@ -99,8 +104,7 @@ func (c *Context) Handler() HandlerFunc {
|
||||
// See example in GitHub.
|
||||
func (c *Context) Next() {
|
||||
c.index++
|
||||
s := int8(len(c.handlers))
|
||||
for ; c.index < s; c.index++ {
|
||||
for s := int8(len(c.handlers)); c.index < s; c.index++ {
|
||||
c.handlers[c.index](c)
|
||||
}
|
||||
}
|
||||
@ -111,8 +115,8 @@ func (c *Context) IsAborted() bool {
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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
|
||||
@ -126,15 +130,16 @@ func (c *Context) AbortWithStatus(code int) {
|
||||
c.Abort()
|
||||
}
|
||||
|
||||
// AbortWithStatusJSON calls `Abort()` and then `JSON` internally. This method stops the chain, writes the status code and return a JSON body
|
||||
// AbortWithStatusJSON calls `Abort()` and then `JSON` internally.
|
||||
// This method stops the chain, writes the status code and return a JSON body.
|
||||
// It also sets the Content-Type as "application/json".
|
||||
func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{}) {
|
||||
c.Abort()
|
||||
c.JSON(code, jsonObj)
|
||||
}
|
||||
|
||||
// AbortWithError calls `AbortWithStatus()` and `Error()` internally. This method stops the chain, writes the status code and
|
||||
// pushes the specified error to `c.Errors`.
|
||||
// AbortWithError calls `AbortWithStatus()` and `Error()` internally.
|
||||
// This method stops the chain, writes the status code and pushes the specified error to `c.Errors`.
|
||||
// See Context.Error() for more details.
|
||||
func (c *Context) AbortWithError(code int, err error) *Error {
|
||||
c.AbortWithStatus(code)
|
||||
@ -145,21 +150,24 @@ func (c *Context) AbortWithError(code int, err error) *Error {
|
||||
/********* ERROR MANAGEMENT *********/
|
||||
/************************************/
|
||||
|
||||
// Attaches an error to the current context. The error is pushed to a list of errors.
|
||||
// Error attaches an error to the current context. The error is pushed to a list of errors.
|
||||
// It's a good idea to call Error for each error that occurred during the resolution of a request.
|
||||
// A middleware can be used to collect all the errors
|
||||
// and push them to a database together, print a log, or append it in the HTTP response.
|
||||
// A middleware can be used to collect all the errors and push them to a database together,
|
||||
// print a log, or append it in the HTTP response.
|
||||
// Error will panic if err is nil.
|
||||
func (c *Context) Error(err error) *Error {
|
||||
var parsedError *Error
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
parsedError = err.(*Error)
|
||||
default:
|
||||
if err == nil {
|
||||
panic("err is nil")
|
||||
}
|
||||
|
||||
parsedError, ok := err.(*Error)
|
||||
if !ok {
|
||||
parsedError = &Error{
|
||||
Err: err,
|
||||
Type: ErrorTypePrivate,
|
||||
}
|
||||
}
|
||||
|
||||
c.Errors = append(c.Errors, parsedError)
|
||||
return parsedError
|
||||
}
|
||||
@ -286,10 +294,10 @@ func (c *Context) GetStringMapStringSlice(key string) (smss map[string][]string)
|
||||
|
||||
// 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"
|
||||
// })
|
||||
// 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)
|
||||
}
|
||||
@ -297,11 +305,11 @@ func (c *Context) Param(key string) string {
|
||||
// Query returns the keyed url query value if it exists,
|
||||
// otherwise 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") == ""
|
||||
// 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
|
||||
@ -310,10 +318,10 @@ func (c *Context) Query(key string) string {
|
||||
// DefaultQuery returns the keyed url query value if it exists,
|
||||
// otherwise 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") == ""
|
||||
// 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 value, ok := c.GetQuery(key); ok {
|
||||
return value
|
||||
@ -325,10 +333,10 @@ func (c *Context) DefaultQuery(key, defaultValue string) string {
|
||||
// if it exists `(value, true)` (even when the value is an empty string),
|
||||
// otherwise 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")
|
||||
// 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) {
|
||||
if values, ok := c.GetQueryArray(key); ok {
|
||||
return values[0], ok
|
||||
@ -346,13 +354,24 @@ func (c *Context) QueryArray(key string) []string {
|
||||
// GetQueryArray returns a slice of strings for a given query key, plus
|
||||
// a boolean value whether at least one value exists for the given key.
|
||||
func (c *Context) GetQueryArray(key string) ([]string, bool) {
|
||||
req := c.Request
|
||||
if values, ok := req.URL.Query()[key]; ok && len(values) > 0 {
|
||||
if values, ok := c.Request.URL.Query()[key]; ok && len(values) > 0 {
|
||||
return values, true
|
||||
}
|
||||
return []string{}, false
|
||||
}
|
||||
|
||||
// QueryMap returns a map for a given query key.
|
||||
func (c *Context) QueryMap(key string) map[string]string {
|
||||
dicts, _ := c.GetQueryMap(key)
|
||||
return dicts
|
||||
}
|
||||
|
||||
// GetQueryMap returns a map for a given query key, plus a boolean value
|
||||
// whether at least one value exists for the given key.
|
||||
func (c *Context) GetQueryMap(key string) (map[string]string, bool) {
|
||||
return c.get(c.Request.URL.Query(), key)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@ -374,9 +393,9 @@ func (c *Context) DefaultPostForm(key, defaultValue string) string {
|
||||
// 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
|
||||
// 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) {
|
||||
if values, ok := c.GetPostFormArray(key); ok {
|
||||
return values[0], ok
|
||||
@ -396,7 +415,7 @@ func (c *Context) PostFormArray(key string) []string {
|
||||
func (c *Context) GetPostFormArray(key string) ([]string, bool) {
|
||||
req := c.Request
|
||||
req.ParseForm()
|
||||
req.ParseMultipartForm(defaultMemory)
|
||||
req.ParseMultipartForm(c.engine.MaxMultipartMemory)
|
||||
if values := req.PostForm[key]; len(values) > 0 {
|
||||
return values, true
|
||||
}
|
||||
@ -408,6 +427,42 @@ func (c *Context) GetPostFormArray(key string) ([]string, bool) {
|
||||
return []string{}, false
|
||||
}
|
||||
|
||||
// PostFormMap returns a map for a given form key.
|
||||
func (c *Context) PostFormMap(key string) map[string]string {
|
||||
dicts, _ := c.GetPostFormMap(key)
|
||||
return dicts
|
||||
}
|
||||
|
||||
// GetPostFormMap returns a map for a given form key, plus a boolean value
|
||||
// whether at least one value exists for the given key.
|
||||
func (c *Context) GetPostFormMap(key string) (map[string]string, bool) {
|
||||
req := c.Request
|
||||
req.ParseForm()
|
||||
req.ParseMultipartForm(c.engine.MaxMultipartMemory)
|
||||
dicts, exist := c.get(req.PostForm, key)
|
||||
|
||||
if !exist && req.MultipartForm != nil && req.MultipartForm.File != nil {
|
||||
dicts, exist = c.get(req.MultipartForm.Value, key)
|
||||
}
|
||||
|
||||
return dicts, exist
|
||||
}
|
||||
|
||||
// get is an internal method and returns a map which satisfy conditions.
|
||||
func (c *Context) get(m map[string][]string, key string) (map[string]string, bool) {
|
||||
dicts := make(map[string]string)
|
||||
exist := false
|
||||
for k, v := range m {
|
||||
if i := strings.IndexByte(k, '['); i >= 1 && k[0:i] == key {
|
||||
if j := strings.IndexByte(k[i+1:], ']'); j >= 1 {
|
||||
exist = true
|
||||
dicts[k[i+1:][:j]] = v[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
return dicts, exist
|
||||
}
|
||||
|
||||
// FormFile returns the first file for the provided form key.
|
||||
func (c *Context) FormFile(name string) (*multipart.FileHeader, error) {
|
||||
_, fh, err := c.Request.FormFile(name)
|
||||
@ -416,67 +471,132 @@ func (c *Context) FormFile(name string) (*multipart.FileHeader, error) {
|
||||
|
||||
// MultipartForm is the parsed multipart form, including file uploads.
|
||||
func (c *Context) MultipartForm() (*multipart.Form, error) {
|
||||
err := c.Request.ParseMultipartForm(defaultMemory)
|
||||
err := c.Request.ParseMultipartForm(c.engine.MaxMultipartMemory)
|
||||
return c.Request.MultipartForm, err
|
||||
}
|
||||
|
||||
// SaveUploadedFile uploads the form file to specific dst.
|
||||
func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error {
|
||||
src, err := file.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
out, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
io.Copy(out, src)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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
|
||||
// otherwise --> returns an error
|
||||
// "application/json" --> JSON binding
|
||||
// "application/xml" --> XML binding
|
||||
// otherwise --> returns an error.
|
||||
// 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.
|
||||
// It writes a 400 error and sets Content-Type header "text/plain" in the response if input is not valid.
|
||||
func (c *Context) Bind(obj interface{}) error {
|
||||
b := binding.Default(c.Request.Method, c.ContentType())
|
||||
return c.MustBindWith(obj, b)
|
||||
}
|
||||
|
||||
// BindJSON is a shortcut for c.MustBindWith(obj, binding.JSON)
|
||||
// BindJSON is a shortcut for c.MustBindWith(obj, binding.JSON).
|
||||
func (c *Context) BindJSON(obj interface{}) error {
|
||||
return c.MustBindWith(obj, binding.JSON)
|
||||
}
|
||||
|
||||
// MustBindWith binds the passed struct pointer using the specified binding
|
||||
// engine. It will abort the request with HTTP 400 if any error ocurrs.
|
||||
// BindQuery is a shortcut for c.MustBindWith(obj, binding.Query).
|
||||
func (c *Context) BindQuery(obj interface{}) error {
|
||||
return c.MustBindWith(obj, binding.Query)
|
||||
}
|
||||
|
||||
// MustBindWith binds the passed struct pointer using the specified binding engine.
|
||||
// It will abort the request with HTTP 400 if any error ocurrs.
|
||||
// See the binding package.
|
||||
func (c *Context) MustBindWith(obj interface{}, b binding.Binding) (err error) {
|
||||
if err = c.ShouldBindWith(obj, b); err != nil {
|
||||
c.AbortWithError(400, err).SetType(ErrorTypeBind)
|
||||
c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ShouldBindWith binds the passed struct pointer using the specified binding
|
||||
// engine.
|
||||
// ShouldBind 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
|
||||
// otherwise --> returns an error
|
||||
// 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 c.Bind() but this method does not set the response status code to 400 and abort if the json is not valid.
|
||||
func (c *Context) ShouldBind(obj interface{}) error {
|
||||
b := binding.Default(c.Request.Method, c.ContentType())
|
||||
return c.ShouldBindWith(obj, b)
|
||||
}
|
||||
|
||||
// ShouldBindJSON is a shortcut for c.ShouldBindWith(obj, binding.JSON).
|
||||
func (c *Context) ShouldBindJSON(obj interface{}) error {
|
||||
return c.ShouldBindWith(obj, binding.JSON)
|
||||
}
|
||||
|
||||
// ShouldBindQuery is a shortcut for c.ShouldBindWith(obj, binding.Query).
|
||||
func (c *Context) ShouldBindQuery(obj interface{}) error {
|
||||
return c.ShouldBindWith(obj, binding.Query)
|
||||
}
|
||||
|
||||
// ShouldBindWith binds the passed struct pointer using the specified binding engine.
|
||||
// See the binding package.
|
||||
func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
|
||||
return b.Bind(c.Request, obj)
|
||||
}
|
||||
|
||||
// ShouldBindBodyWith is similar with ShouldBindWith, but it stores the request
|
||||
// body into the context, and reuse when it is called again.
|
||||
//
|
||||
// NOTE: This method reads the body before binding. So you should use
|
||||
// ShouldBindWith for better performance if you need to call only once.
|
||||
func (c *Context) ShouldBindBodyWith(
|
||||
obj interface{}, bb binding.BindingBody,
|
||||
) (err error) {
|
||||
var body []byte
|
||||
if cb, ok := c.Get(BodyBytesKey); ok {
|
||||
if cbb, ok := cb.([]byte); ok {
|
||||
body = cbb
|
||||
}
|
||||
}
|
||||
if body == nil {
|
||||
body, err = ioutil.ReadAll(c.Request.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Set(BodyBytesKey, body)
|
||||
}
|
||||
return bb.BindBody(body, obj)
|
||||
}
|
||||
|
||||
// ClientIP implements a best effort algorithm to return the real client IP, it parses
|
||||
// X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy.
|
||||
// Use X-Forwarded-For before X-Real-Ip as nginx uses X-Real-Ip with the proxy's IP.
|
||||
func (c *Context) ClientIP() string {
|
||||
if c.engine.ForwardedByClientIP {
|
||||
clientIP := c.requestHeader("X-Forwarded-For")
|
||||
if index := strings.IndexByte(clientIP, ','); index >= 0 {
|
||||
clientIP = clientIP[0:index]
|
||||
clientIP = strings.TrimSpace(strings.Split(clientIP, ",")[0])
|
||||
if clientIP == "" {
|
||||
clientIP = strings.TrimSpace(c.requestHeader("X-Real-Ip"))
|
||||
}
|
||||
clientIP = strings.TrimSpace(clientIP)
|
||||
if len(clientIP) > 0 {
|
||||
return clientIP
|
||||
}
|
||||
clientIP = strings.TrimSpace(c.requestHeader("X-Real-Ip"))
|
||||
if len(clientIP) > 0 {
|
||||
if clientIP != "" {
|
||||
return clientIP
|
||||
}
|
||||
}
|
||||
|
||||
if c.engine.AppEngine {
|
||||
if addr := c.Request.Header.Get("X-Appengine-Remote-Addr"); addr != "" {
|
||||
if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" {
|
||||
return addr
|
||||
}
|
||||
}
|
||||
@ -504,63 +624,56 @@ func (c *Context) IsWebsocket() bool {
|
||||
}
|
||||
|
||||
func (c *Context) requestHeader(key string) string {
|
||||
if values, _ := c.Request.Header[key]; len(values) > 0 {
|
||||
return values[0]
|
||||
}
|
||||
return ""
|
||||
return c.Request.Header.Get(key)
|
||||
}
|
||||
|
||||
/************************************/
|
||||
/******** RESPONSE RENDERING ********/
|
||||
/************************************/
|
||||
|
||||
// bodyAllowedForStatus is a copy of http.bodyAllowedForStatus non-exported function
|
||||
// bodyAllowedForStatus is a copy of http.bodyAllowedForStatus non-exported function.
|
||||
func bodyAllowedForStatus(status int) bool {
|
||||
switch {
|
||||
case status >= 100 && status <= 199:
|
||||
return false
|
||||
case status == 204:
|
||||
case status == http.StatusNoContent:
|
||||
return false
|
||||
case status == 304:
|
||||
case status == http.StatusNotModified:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Status sets the HTTP response code.
|
||||
func (c *Context) Status(code int) {
|
||||
c.writermem.WriteHeader(code)
|
||||
}
|
||||
|
||||
// Header is a intelligent shortcut for c.Writer.Header().Set(key, value)
|
||||
// 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)`
|
||||
func (c *Context) Header(key, value string) {
|
||||
if len(value) == 0 {
|
||||
if value == "" {
|
||||
c.Writer.Header().Del(key)
|
||||
} else {
|
||||
c.Writer.Header().Set(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
// GetHeader returns value from request headers
|
||||
// GetHeader returns value from request headers.
|
||||
func (c *Context) GetHeader(key string) string {
|
||||
return c.requestHeader(key)
|
||||
}
|
||||
|
||||
// GetRawData return stream data
|
||||
// GetRawData return stream data.
|
||||
func (c *Context) GetRawData() ([]byte, error) {
|
||||
return ioutil.ReadAll(c.Request.Body)
|
||||
}
|
||||
|
||||
func (c *Context) SetCookie(
|
||||
name string,
|
||||
value string,
|
||||
maxAge int,
|
||||
path string,
|
||||
domain string,
|
||||
secure bool,
|
||||
httpOnly bool,
|
||||
) {
|
||||
// SetCookie adds a Set-Cookie header to the ResponseWriter's headers.
|
||||
// The provided cookie must have a valid Name. Invalid cookies may be
|
||||
// silently dropped.
|
||||
func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) {
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
@ -575,6 +688,10 @@ func (c *Context) SetCookie(
|
||||
})
|
||||
}
|
||||
|
||||
// Cookie returns the named cookie provided in the request or
|
||||
// ErrNoCookie if not found. And return the named cookie is unescaped.
|
||||
// If multiple cookies match the given name, only one cookie will
|
||||
// be returned.
|
||||
func (c *Context) Cookie(name string) (string, error) {
|
||||
cookie, err := c.Request.Cookie(name)
|
||||
if err != nil {
|
||||
@ -614,12 +731,37 @@ func (c *Context) IndentedJSON(code int, obj interface{}) {
|
||||
c.Render(code, render.IndentedJSON{Data: obj})
|
||||
}
|
||||
|
||||
// SecureJSON serializes the given struct as Secure JSON into the response body.
|
||||
// Default prepends "while(1)," to response body if the given struct is array values.
|
||||
// It also sets the Content-Type as "application/json".
|
||||
func (c *Context) SecureJSON(code int, obj interface{}) {
|
||||
c.Render(code, render.SecureJSON{Prefix: c.engine.secureJsonPrefix, Data: obj})
|
||||
}
|
||||
|
||||
// JSONP serializes the given struct as JSON into the response body.
|
||||
// It add padding to response body to request data from a server residing in a different domain than the client.
|
||||
// It also sets the Content-Type as "application/javascript".
|
||||
func (c *Context) JSONP(code int, obj interface{}) {
|
||||
callback := c.DefaultQuery("callback", "")
|
||||
if callback == "" {
|
||||
c.Render(code, render.JSON{Data: obj})
|
||||
} else {
|
||||
c.Render(code, render.JsonpJSON{Callback: callback, Data: obj})
|
||||
}
|
||||
}
|
||||
|
||||
// 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.Render(code, render.JSON{Data: obj})
|
||||
}
|
||||
|
||||
// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string.
|
||||
// It also sets the Content-Type as "application/json".
|
||||
func (c *Context) AsciiJSON(code int, obj interface{}) {
|
||||
c.Render(code, render.AsciiJSON{Data: obj})
|
||||
}
|
||||
|
||||
// XML serializes the given struct as XML into the response body.
|
||||
// It also sets the Content-Type as "application/xml".
|
||||
func (c *Context) XML(code int, obj interface{}) {
|
||||
@ -653,6 +795,16 @@ func (c *Context) Data(code int, contentType string, data []byte) {
|
||||
})
|
||||
}
|
||||
|
||||
// DataFromReader writes the specified reader into the body stream and updates the HTTP code.
|
||||
func (c *Context) DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string) {
|
||||
c.Render(code, render.Reader{
|
||||
Headers: extraHeaders,
|
||||
ContentType: contentType,
|
||||
ContentLength: contentLength,
|
||||
Reader: reader,
|
||||
})
|
||||
}
|
||||
|
||||
// File writes the specified file into the body stream in a efficient way.
|
||||
func (c *Context) File(filepath string) {
|
||||
http.ServeFile(c.Writer, c.Request, filepath)
|
||||
@ -742,18 +894,33 @@ func (c *Context) SetAccepted(formats ...string) {
|
||||
/***** GOLANG.ORG/X/NET/CONTEXT *****/
|
||||
/************************************/
|
||||
|
||||
// Deadline returns the time when work done on behalf of this context
|
||||
// should be canceled. Deadline returns ok==false when no deadline is
|
||||
// set. Successive calls to Deadline return the same results.
|
||||
func (c *Context) Deadline() (deadline time.Time, ok bool) {
|
||||
return
|
||||
}
|
||||
|
||||
// Done returns a channel that's closed when work done on behalf of this
|
||||
// context should be canceled. Done may return nil if this context can
|
||||
// never be canceled. Successive calls to Done return the same value.
|
||||
func (c *Context) Done() <-chan struct{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Err returns a non-nil error value after Done is closed,
|
||||
// successive calls to Err return the same error.
|
||||
// If Done is not yet closed, Err returns nil.
|
||||
// If Done is closed, Err returns a non-nil error explaining why:
|
||||
// Canceled if the context was canceled
|
||||
// or DeadlineExceeded if the context's deadline passed.
|
||||
func (c *Context) Err() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns the value associated with this context for key, or nil
|
||||
// if no value is associated with key. Successive calls to Value with
|
||||
// the same key returns the same result.
|
||||
func (c *Context) Value(key interface{}) interface{} {
|
||||
if key == 0 {
|
||||
return c.Request
|
||||
|
13
vendor/github.com/gin-gonic/gin/coverage.sh
generated
vendored
Normal file
13
vendor/github.com/gin-gonic/gin/coverage.sh
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "mode: count" > coverage.out
|
||||
|
||||
for d in $(go list ./... | grep -E 'gin$|binding$|render$' | grep -v 'examples'); do
|
||||
go test -v -covermode=count -coverprofile=profile.out $d
|
||||
if [ -f profile.out ]; then
|
||||
cat profile.out | grep -v "mode:" >> coverage.out
|
||||
rm profile.out
|
||||
fi
|
||||
done
|
11
vendor/github.com/gin-gonic/gin/debug.go
generated
vendored
11
vendor/github.com/gin-gonic/gin/debug.go
generated
vendored
@ -15,7 +15,7 @@ func init() {
|
||||
}
|
||||
|
||||
// IsDebugging returns true if the framework is running in debug mode.
|
||||
// Use SetMode(gin.Release) to switch to disable the debug mode.
|
||||
// Use SetMode(gin.ReleaseMode) to disable debug mode.
|
||||
func IsDebugging() bool {
|
||||
return ginMode == debugCode
|
||||
}
|
||||
@ -46,6 +46,15 @@ func debugPrint(format string, values ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func debugPrintWARNINGDefault() {
|
||||
debugPrint(`[WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.
|
||||
|
||||
`)
|
||||
debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
|
||||
|
||||
`)
|
||||
}
|
||||
|
||||
func debugPrintWARNINGNew() {
|
||||
debugPrint(`[WARNING] Running in "debug" mode. Switch to "release" mode in production.
|
||||
- using env: export GIN_MODE=release
|
||||
|
10
vendor/github.com/gin-gonic/gin/deprecated.go
generated
vendored
10
vendor/github.com/gin-gonic/gin/deprecated.go
generated
vendored
@ -5,21 +5,17 @@
|
||||
package gin
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
"log"
|
||||
)
|
||||
|
||||
func (c *Context) GetCookie(name string) (string, error) {
|
||||
log.Println("GetCookie() method is deprecated. Use Cookie() instead.")
|
||||
return c.Cookie(name)
|
||||
}
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// BindWith binds the passed struct pointer using the specified binding engine.
|
||||
// See the binding package.
|
||||
func (c *Context) BindWith(obj interface{}, b binding.Binding) error {
|
||||
log.Println(`BindWith(\"interface{}, binding.Binding\") error is going to
|
||||
be deprecated, please check issue #662 and either use MustBindWith() if you
|
||||
want HTTP 400 to be automatically returned if any error occur, of use
|
||||
want HTTP 400 to be automatically returned if any error occur, or use
|
||||
ShouldBindWith() if you need to manage the error.`)
|
||||
return c.MustBindWith(obj, b)
|
||||
}
|
||||
|
6
vendor/github.com/gin-gonic/gin/doc.go
generated
vendored
Normal file
6
vendor/github.com/gin-gonic/gin/doc.go
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/*
|
||||
Package gin implements a HTTP web framework called gin.
|
||||
|
||||
See https://gin-gonic.github.io/gin/ for more information about gin.
|
||||
*/
|
||||
package gin // import "github.com/gin-gonic/gin"
|
36
vendor/github.com/gin-gonic/gin/errors.go
generated
vendored
36
vendor/github.com/gin-gonic/gin/errors.go
generated
vendored
@ -6,9 +6,10 @@ package gin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/gin-gonic/gin/json"
|
||||
)
|
||||
|
||||
type ErrorType uint64
|
||||
@ -23,15 +24,13 @@ const (
|
||||
ErrorTypeNu = 2
|
||||
)
|
||||
|
||||
type (
|
||||
Error struct {
|
||||
Err error
|
||||
Type ErrorType
|
||||
Meta interface{}
|
||||
}
|
||||
type Error struct {
|
||||
Err error
|
||||
Type ErrorType
|
||||
Meta interface{}
|
||||
}
|
||||
|
||||
errorMsgs []*Error
|
||||
)
|
||||
type errorMsgs []*Error
|
||||
|
||||
var _ error = &Error{}
|
||||
|
||||
@ -66,12 +65,12 @@ func (msg *Error) JSON() interface{} {
|
||||
return json
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaller interface
|
||||
// MarshalJSON implements the json.Marshaller interface.
|
||||
func (msg *Error) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(msg.JSON())
|
||||
}
|
||||
|
||||
// Implements the error interface
|
||||
// Error implements the error interface
|
||||
func (msg Error) Error() string {
|
||||
return msg.Err.Error()
|
||||
}
|
||||
@ -80,8 +79,8 @@ func (msg *Error) IsType(flags ErrorType) bool {
|
||||
return (msg.Type & flags) > 0
|
||||
}
|
||||
|
||||
// Returns a readonly copy filtered the byte.
|
||||
// ie ByType(gin.ErrorTypePublic) returns a slice of errors with type=ErrorTypePublic
|
||||
// ByType returns a readonly copy filtered the byte.
|
||||
// ie ByType(gin.ErrorTypePublic) returns a slice of errors with type=ErrorTypePublic.
|
||||
func (a errorMsgs) ByType(typ ErrorType) errorMsgs {
|
||||
if len(a) == 0 {
|
||||
return nil
|
||||
@ -98,17 +97,16 @@ func (a errorMsgs) ByType(typ ErrorType) errorMsgs {
|
||||
return result
|
||||
}
|
||||
|
||||
// Returns the last error in the slice. It returns nil if the array is empty.
|
||||
// Shortcut for errors[len(errors)-1]
|
||||
// Last returns the last error in the slice. It returns nil if the array is empty.
|
||||
// Shortcut for errors[len(errors)-1].
|
||||
func (a errorMsgs) Last() *Error {
|
||||
length := len(a)
|
||||
if length > 0 {
|
||||
if length := len(a); length > 0 {
|
||||
return a[length-1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Returns an array will all the error messages.
|
||||
// Errors returns an array will all the error messages.
|
||||
// Example:
|
||||
// c.Error(errors.New("first"))
|
||||
// c.Error(errors.New("second"))
|
||||
@ -150,7 +148,7 @@ func (a errorMsgs) String() string {
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
for i, msg := range a {
|
||||
fmt.Fprintf(&buffer, "Error #%02d: %s\n", (i + 1), msg.Err)
|
||||
fmt.Fprintf(&buffer, "Error #%02d: %s\n", i+1, msg.Err)
|
||||
if msg.Meta != nil {
|
||||
fmt.Fprintf(&buffer, " Meta: %v\n", msg.Meta)
|
||||
}
|
||||
|
19
vendor/github.com/gin-gonic/gin/fs.go
generated
vendored
19
vendor/github.com/gin-gonic/gin/fs.go
generated
vendored
@ -9,14 +9,13 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
type (
|
||||
onlyfilesFS struct {
|
||||
fs http.FileSystem
|
||||
}
|
||||
neuteredReaddirFile struct {
|
||||
http.File
|
||||
}
|
||||
)
|
||||
type onlyfilesFS struct {
|
||||
fs http.FileSystem
|
||||
}
|
||||
|
||||
type neuteredReaddirFile struct {
|
||||
http.File
|
||||
}
|
||||
|
||||
// Dir returns a http.Filesystem that can be used by http.FileServer(). It is used internally
|
||||
// in router.Static().
|
||||
@ -30,7 +29,7 @@ func Dir(root string, listDirectory bool) http.FileSystem {
|
||||
return &onlyfilesFS{fs}
|
||||
}
|
||||
|
||||
// Conforms to http.Filesystem
|
||||
// Open conforms to http.Filesystem.
|
||||
func (fs onlyfilesFS) Open(name string) (http.File, error) {
|
||||
f, err := fs.fs.Open(name)
|
||||
if err != nil {
|
||||
@ -39,7 +38,7 @@ func (fs onlyfilesFS) Open(name string) (http.File, error) {
|
||||
return neuteredReaddirFile{f}, nil
|
||||
}
|
||||
|
||||
// Overrides the http.File default implementation
|
||||
// Readdir overrides the http.File default implementation.
|
||||
func (f neuteredReaddirFile) Readdir(count int) ([]os.FileInfo, error) {
|
||||
// this disables directory listing
|
||||
return nil, nil
|
||||
|
299
vendor/github.com/gin-gonic/gin/gin.go
generated
vendored
299
vendor/github.com/gin-gonic/gin/gin.go
generated
vendored
@ -14,86 +14,96 @@ import (
|
||||
"github.com/gin-gonic/gin/render"
|
||||
)
|
||||
|
||||
// Version is Framework's version
|
||||
const Version = "v1.2"
|
||||
const (
|
||||
// Version is Framework's version.
|
||||
Version = "v1.3.0"
|
||||
defaultMultipartMemory = 32 << 20 // 32 MB
|
||||
)
|
||||
|
||||
var default404Body = []byte("404 page not found")
|
||||
var default405Body = []byte("405 method not allowed")
|
||||
var defaultAppEngine bool
|
||||
var (
|
||||
default404Body = []byte("404 page not found")
|
||||
default405Body = []byte("405 method not allowed")
|
||||
defaultAppEngine bool
|
||||
)
|
||||
|
||||
type HandlerFunc func(*Context)
|
||||
type HandlersChain []HandlerFunc
|
||||
|
||||
// Last returns the last handler in the chain. ie. the last handler is the main own.
|
||||
func (c HandlersChain) Last() HandlerFunc {
|
||||
length := len(c)
|
||||
if length > 0 {
|
||||
if length := len(c); length > 0 {
|
||||
return c[length-1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type (
|
||||
RoutesInfo []RouteInfo
|
||||
RouteInfo struct {
|
||||
Method string
|
||||
Path string
|
||||
Handler string
|
||||
}
|
||||
type RouteInfo struct {
|
||||
Method string
|
||||
Path string
|
||||
Handler string
|
||||
}
|
||||
|
||||
// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
|
||||
// Create an instance of Engine, by using New() or Default()
|
||||
Engine struct {
|
||||
RouterGroup
|
||||
delims render.Delims
|
||||
HTMLRender render.HTMLRender
|
||||
FuncMap template.FuncMap
|
||||
allNoRoute HandlersChain
|
||||
allNoMethod HandlersChain
|
||||
noRoute HandlersChain
|
||||
noMethod HandlersChain
|
||||
pool sync.Pool
|
||||
trees methodTrees
|
||||
type RoutesInfo []RouteInfo
|
||||
|
||||
// Enables automatic redirection if the current route can't be matched but a
|
||||
// handler for the path with (without) the trailing slash exists.
|
||||
// For example if /foo/ is requested but a route only exists for /foo, the
|
||||
// client is redirected to /foo with http status code 301 for GET requests
|
||||
// and 307 for all other request methods.
|
||||
RedirectTrailingSlash bool
|
||||
// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
|
||||
// Create an instance of Engine, by using New() or Default()
|
||||
type Engine struct {
|
||||
RouterGroup
|
||||
|
||||
// If enabled, the router tries to fix the current request path, if no
|
||||
// handle is registered for it.
|
||||
// First superfluous path elements like ../ or // are removed.
|
||||
// Afterwards the router does a case-insensitive lookup of the cleaned path.
|
||||
// If a handle can be found for this route, the router makes a redirection
|
||||
// to the corrected path with status code 301 for GET requests and 307 for
|
||||
// all other request methods.
|
||||
// For example /FOO and /..//Foo could be redirected to /foo.
|
||||
// RedirectTrailingSlash is independent of this option.
|
||||
RedirectFixedPath bool
|
||||
// Enables automatic redirection if the current route can't be matched but a
|
||||
// handler for the path with (without) the trailing slash exists.
|
||||
// For example if /foo/ is requested but a route only exists for /foo, the
|
||||
// client is redirected to /foo with http status code 301 for GET requests
|
||||
// and 307 for all other request methods.
|
||||
RedirectTrailingSlash bool
|
||||
|
||||
// If enabled, the router checks if another method is allowed for the
|
||||
// current route, if the current request can not be routed.
|
||||
// If this is the case, the request is answered with 'Method Not Allowed'
|
||||
// and HTTP status code 405.
|
||||
// If no other Method is allowed, the request is delegated to the NotFound
|
||||
// handler.
|
||||
HandleMethodNotAllowed bool
|
||||
ForwardedByClientIP bool
|
||||
// If enabled, the router tries to fix the current request path, if no
|
||||
// handle is registered for it.
|
||||
// First superfluous path elements like ../ or // are removed.
|
||||
// Afterwards the router does a case-insensitive lookup of the cleaned path.
|
||||
// If a handle can be found for this route, the router makes a redirection
|
||||
// to the corrected path with status code 301 for GET requests and 307 for
|
||||
// all other request methods.
|
||||
// For example /FOO and /..//Foo could be redirected to /foo.
|
||||
// RedirectTrailingSlash is independent of this option.
|
||||
RedirectFixedPath bool
|
||||
|
||||
// #726 #755 If enabled, it will thrust some headers starting with
|
||||
// 'X-AppEngine...' for better integration with that PaaS.
|
||||
AppEngine bool
|
||||
// If enabled, the router checks if another method is allowed for the
|
||||
// current route, if the current request can not be routed.
|
||||
// If this is the case, the request is answered with 'Method Not Allowed'
|
||||
// and HTTP status code 405.
|
||||
// If no other Method is allowed, the request is delegated to the NotFound
|
||||
// handler.
|
||||
HandleMethodNotAllowed bool
|
||||
ForwardedByClientIP bool
|
||||
|
||||
// If enabled, the url.RawPath will be used to find parameters.
|
||||
UseRawPath bool
|
||||
// If true, the path value will be unescaped.
|
||||
// If UseRawPath is false (by default), the UnescapePathValues effectively is true,
|
||||
// as url.Path gonna be used, which is already unescaped.
|
||||
UnescapePathValues bool
|
||||
}
|
||||
)
|
||||
// #726 #755 If enabled, it will thrust some headers starting with
|
||||
// 'X-AppEngine...' for better integration with that PaaS.
|
||||
AppEngine bool
|
||||
|
||||
// If enabled, the url.RawPath will be used to find parameters.
|
||||
UseRawPath bool
|
||||
|
||||
// If true, the path value will be unescaped.
|
||||
// If UseRawPath is false (by default), the UnescapePathValues effectively is true,
|
||||
// as url.Path gonna be used, which is already unescaped.
|
||||
UnescapePathValues bool
|
||||
|
||||
// Value of 'maxMemory' param that is given to http.Request's ParseMultipartForm
|
||||
// method call.
|
||||
MaxMultipartMemory int64
|
||||
|
||||
delims render.Delims
|
||||
secureJsonPrefix string
|
||||
HTMLRender render.HTMLRender
|
||||
FuncMap template.FuncMap
|
||||
allNoRoute HandlersChain
|
||||
allNoMethod HandlersChain
|
||||
noRoute HandlersChain
|
||||
noMethod HandlersChain
|
||||
pool sync.Pool
|
||||
trees methodTrees
|
||||
}
|
||||
|
||||
var _ IRouter = &Engine{}
|
||||
|
||||
@ -121,8 +131,10 @@ func New() *Engine {
|
||||
AppEngine: defaultAppEngine,
|
||||
UseRawPath: false,
|
||||
UnescapePathValues: true,
|
||||
MaxMultipartMemory: defaultMultipartMemory,
|
||||
trees: make(methodTrees, 0, 9),
|
||||
delims: render.Delims{"{{", "}}"},
|
||||
delims: render.Delims{Left: "{{", Right: "}}"},
|
||||
secureJsonPrefix: "while(1);",
|
||||
}
|
||||
engine.RouterGroup.engine = engine
|
||||
engine.pool.New = func() interface{} {
|
||||
@ -133,6 +145,7 @@ func New() *Engine {
|
||||
|
||||
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
|
||||
func Default() *Engine {
|
||||
debugPrintWARNINGDefault()
|
||||
engine := New()
|
||||
engine.Use(Logger(), Recovery())
|
||||
return engine
|
||||
@ -143,29 +156,45 @@ func (engine *Engine) allocateContext() *Context {
|
||||
}
|
||||
|
||||
func (engine *Engine) Delims(left, right string) *Engine {
|
||||
engine.delims = render.Delims{left, right}
|
||||
engine.delims = render.Delims{Left: left, Right: right}
|
||||
return engine
|
||||
}
|
||||
|
||||
func (engine *Engine) LoadHTMLGlob(pattern string) {
|
||||
if IsDebugging() {
|
||||
debugPrintLoadTemplate(template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseGlob(pattern)))
|
||||
engine.HTMLRender = render.HTMLDebug{Glob: pattern, FuncMap: engine.FuncMap, Delims: engine.delims}
|
||||
} else {
|
||||
templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseGlob(pattern))
|
||||
engine.SetHTMLTemplate(templ)
|
||||
}
|
||||
// SecureJsonPrefix sets the secureJsonPrefix used in Context.SecureJSON.
|
||||
func (engine *Engine) SecureJsonPrefix(prefix string) *Engine {
|
||||
engine.secureJsonPrefix = prefix
|
||||
return engine
|
||||
}
|
||||
|
||||
// LoadHTMLGlob loads HTML files identified by glob pattern
|
||||
// and associates the result with HTML renderer.
|
||||
func (engine *Engine) LoadHTMLGlob(pattern string) {
|
||||
left := engine.delims.Left
|
||||
right := engine.delims.Right
|
||||
templ := template.Must(template.New("").Delims(left, right).Funcs(engine.FuncMap).ParseGlob(pattern))
|
||||
|
||||
if IsDebugging() {
|
||||
debugPrintLoadTemplate(templ)
|
||||
engine.HTMLRender = render.HTMLDebug{Glob: pattern, FuncMap: engine.FuncMap, Delims: engine.delims}
|
||||
return
|
||||
}
|
||||
|
||||
engine.SetHTMLTemplate(templ)
|
||||
}
|
||||
|
||||
// LoadHTMLFiles loads a slice of HTML files
|
||||
// and associates the result with HTML renderer.
|
||||
func (engine *Engine) LoadHTMLFiles(files ...string) {
|
||||
if IsDebugging() {
|
||||
engine.HTMLRender = render.HTMLDebug{Files: files, FuncMap: engine.FuncMap, Delims: engine.delims}
|
||||
} else {
|
||||
templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseFiles(files...))
|
||||
engine.SetHTMLTemplate(templ)
|
||||
return
|
||||
}
|
||||
|
||||
templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseFiles(files...))
|
||||
engine.SetHTMLTemplate(templ)
|
||||
}
|
||||
|
||||
// SetHTMLTemplate associate a template with HTML renderer.
|
||||
func (engine *Engine) SetHTMLTemplate(templ *template.Template) {
|
||||
if len(engine.trees) > 0 {
|
||||
debugPrintWARNINGSetHTMLTemplate()
|
||||
@ -174,6 +203,7 @@ func (engine *Engine) SetHTMLTemplate(templ *template.Template) {
|
||||
engine.HTMLRender = render.HTMLProduction{Template: templ.Funcs(engine.FuncMap)}
|
||||
}
|
||||
|
||||
// SetFuncMap sets the FuncMap used for template.FuncMap.
|
||||
func (engine *Engine) SetFuncMap(funcMap template.FuncMap) {
|
||||
engine.FuncMap = funcMap
|
||||
}
|
||||
@ -184,7 +214,7 @@ func (engine *Engine) NoRoute(handlers ...HandlerFunc) {
|
||||
engine.rebuild404Handlers()
|
||||
}
|
||||
|
||||
// NoMethod sets the handlers called when... TODO
|
||||
// NoMethod sets the handlers called when... TODO.
|
||||
func (engine *Engine) NoMethod(handlers ...HandlerFunc) {
|
||||
engine.noMethod = handlers
|
||||
engine.rebuild405Handlers()
|
||||
@ -210,7 +240,7 @@ 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(method != "", "HTTP method can not be empty")
|
||||
assert1(len(handlers) > 0, "there must be at least one handler")
|
||||
|
||||
debugPrintRoute(method, path, handlers)
|
||||
@ -261,7 +291,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 indefinitely unless an error happens.
|
||||
func (engine *Engine) RunTLS(addr string, certFile string, keyFile string) (err error) {
|
||||
func (engine *Engine) RunTLS(addr, certFile, keyFile string) (err error) {
|
||||
debugPrint("Listening and serving HTTPS on %s\n", addr)
|
||||
defer func() { debugPrintError(err) }()
|
||||
|
||||
@ -286,7 +316,7 @@ func (engine *Engine) RunUnix(file string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Conforms to the http.Handler interface.
|
||||
// ServeHTTP conforms to the http.Handler interface.
|
||||
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
c := engine.pool.Get().(*Context)
|
||||
c.writermem.reset(w)
|
||||
@ -298,8 +328,8 @@ func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
engine.pool.Put(c)
|
||||
}
|
||||
|
||||
// Re-enter a context that has been rewritten.
|
||||
// This can be done by setting c.Request.Path to your new target.
|
||||
// HandleContext re-enter a context that has been rewritten.
|
||||
// This can be done by setting c.Request.URL.Path to your new target.
|
||||
// Disclaimer: You can loop yourself to death with this, use wisely.
|
||||
func (engine *Engine) HandleContext(c *Context) {
|
||||
c.reset()
|
||||
@ -307,59 +337,57 @@ func (engine *Engine) HandleContext(c *Context) {
|
||||
engine.pool.Put(c)
|
||||
}
|
||||
|
||||
func (engine *Engine) handleHTTPRequest(context *Context) {
|
||||
httpMethod := context.Request.Method
|
||||
var path string
|
||||
var unescape bool
|
||||
if engine.UseRawPath && len(context.Request.URL.RawPath) > 0 {
|
||||
path = context.Request.URL.RawPath
|
||||
func (engine *Engine) handleHTTPRequest(c *Context) {
|
||||
httpMethod := c.Request.Method
|
||||
path := c.Request.URL.Path
|
||||
unescape := false
|
||||
if engine.UseRawPath && len(c.Request.URL.RawPath) > 0 {
|
||||
path = c.Request.URL.RawPath
|
||||
unescape = engine.UnescapePathValues
|
||||
} else {
|
||||
path = context.Request.URL.Path
|
||||
unescape = false
|
||||
}
|
||||
|
||||
// Find root of the tree for the given HTTP method
|
||||
t := engine.trees
|
||||
for i, tl := 0, len(t); i < tl; i++ {
|
||||
if t[i].method == httpMethod {
|
||||
root := t[i].root
|
||||
// Find route in tree
|
||||
handlers, params, tsr := root.getValue(path, context.Params, unescape)
|
||||
if handlers != nil {
|
||||
context.handlers = handlers
|
||||
context.Params = params
|
||||
context.Next()
|
||||
context.writermem.WriteHeaderNow()
|
||||
if t[i].method != httpMethod {
|
||||
continue
|
||||
}
|
||||
root := t[i].root
|
||||
// Find route in tree
|
||||
handlers, params, tsr := root.getValue(path, c.Params, unescape)
|
||||
if handlers != nil {
|
||||
c.handlers = handlers
|
||||
c.Params = params
|
||||
c.Next()
|
||||
c.writermem.WriteHeaderNow()
|
||||
return
|
||||
}
|
||||
if httpMethod != "CONNECT" && path != "/" {
|
||||
if tsr && engine.RedirectTrailingSlash {
|
||||
redirectTrailingSlash(c)
|
||||
return
|
||||
}
|
||||
if httpMethod != "CONNECT" && path != "/" {
|
||||
if tsr && engine.RedirectTrailingSlash {
|
||||
redirectTrailingSlash(context)
|
||||
return
|
||||
}
|
||||
if engine.RedirectFixedPath && redirectFixedPath(context, root, engine.RedirectFixedPath) {
|
||||
return
|
||||
}
|
||||
if engine.RedirectFixedPath && redirectFixedPath(c, root, engine.RedirectFixedPath) {
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
// TODO: unit test
|
||||
if engine.HandleMethodNotAllowed {
|
||||
for _, tree := range engine.trees {
|
||||
if tree.method != httpMethod {
|
||||
if handlers, _, _ := tree.root.getValue(path, nil, unescape); handlers != nil {
|
||||
context.handlers = engine.allNoMethod
|
||||
serveError(context, 405, default405Body)
|
||||
return
|
||||
}
|
||||
if tree.method == httpMethod {
|
||||
continue
|
||||
}
|
||||
if handlers, _, _ := tree.root.getValue(path, nil, unescape); handlers != nil {
|
||||
c.handlers = engine.allNoMethod
|
||||
serveError(c, http.StatusMethodNotAllowed, default405Body)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
context.handlers = engine.allNoRoute
|
||||
serveError(context, 404, default404Body)
|
||||
c.handlers = engine.allNoRoute
|
||||
serveError(c, http.StatusNotFound, default404Body)
|
||||
}
|
||||
|
||||
var mimePlain = []string{MIMEPlain}
|
||||
@ -367,28 +395,29 @@ var mimePlain = []string{MIMEPlain}
|
||||
func serveError(c *Context, code int, defaultMessage []byte) {
|
||||
c.writermem.status = code
|
||||
c.Next()
|
||||
if !c.writermem.Written() {
|
||||
if c.writermem.Status() == code {
|
||||
c.writermem.Header()["Content-Type"] = mimePlain
|
||||
c.Writer.Write(defaultMessage)
|
||||
} else {
|
||||
c.writermem.WriteHeaderNow()
|
||||
}
|
||||
if c.writermem.Written() {
|
||||
return
|
||||
}
|
||||
if c.writermem.Status() == code {
|
||||
c.writermem.Header()["Content-Type"] = mimePlain
|
||||
c.Writer.Write(defaultMessage)
|
||||
return
|
||||
}
|
||||
c.writermem.WriteHeaderNow()
|
||||
return
|
||||
}
|
||||
|
||||
func redirectTrailingSlash(c *Context) {
|
||||
req := c.Request
|
||||
path := req.URL.Path
|
||||
code := 301 // Permanent redirect, request with GET method
|
||||
code := http.StatusMovedPermanently // Permanent redirect, request with GET method
|
||||
if req.Method != "GET" {
|
||||
code = 307
|
||||
code = http.StatusTemporaryRedirect
|
||||
}
|
||||
|
||||
if len(path) > 1 && path[len(path)-1] == '/' {
|
||||
req.URL.Path = path[:len(path)-1]
|
||||
} else {
|
||||
req.URL.Path = path + "/"
|
||||
req.URL.Path = path + "/"
|
||||
if length := len(path); length > 1 && path[length-1] == '/' {
|
||||
req.URL.Path = path[:length-1]
|
||||
}
|
||||
debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String())
|
||||
http.Redirect(c.Writer, req, req.URL.String(), code)
|
||||
@ -399,14 +428,10 @@ func redirectFixedPath(c *Context, root *node, trailingSlash bool) bool {
|
||||
req := c.Request
|
||||
path := req.URL.Path
|
||||
|
||||
fixedPath, found := root.findCaseInsensitivePath(
|
||||
cleanPath(path),
|
||||
trailingSlash,
|
||||
)
|
||||
if found {
|
||||
code := 301 // Permanent redirect, request with GET method
|
||||
if fixedPath, ok := root.findCaseInsensitivePath(cleanPath(path), trailingSlash); ok {
|
||||
code := http.StatusMovedPermanently // Permanent redirect, request with GET method
|
||||
if req.Method != "GET" {
|
||||
code = 307
|
||||
code = http.StatusTemporaryRedirect
|
||||
}
|
||||
req.URL.Path = string(fixedPath)
|
||||
debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String())
|
||||
|
15
vendor/github.com/gin-gonic/gin/json/json.go
generated
vendored
Normal file
15
vendor/github.com/gin-gonic/gin/json/json.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2017 Bo-Yi Wu. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !jsoniter
|
||||
|
||||
package json
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
var (
|
||||
Marshal = json.Marshal
|
||||
MarshalIndent = json.MarshalIndent
|
||||
NewDecoder = json.NewDecoder
|
||||
)
|
16
vendor/github.com/gin-gonic/gin/json/jsoniter.go
generated
vendored
Normal file
16
vendor/github.com/gin-gonic/gin/json/jsoniter.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2017 Bo-Yi Wu. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build jsoniter
|
||||
|
||||
package json
|
||||
|
||||
import "github.com/json-iterator/go"
|
||||
|
||||
var (
|
||||
json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
Marshal = json.Marshal
|
||||
MarshalIndent = json.MarshalIndent
|
||||
NewDecoder = json.NewDecoder
|
||||
)
|
28
vendor/github.com/gin-gonic/gin/logger.go
generated
vendored
28
vendor/github.com/gin-gonic/gin/logger.go
generated
vendored
@ -7,6 +7,7 @@ package gin
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@ -25,14 +26,17 @@ var (
|
||||
disableColor = false
|
||||
)
|
||||
|
||||
// DisableConsoleColor disables color output in the console.
|
||||
func DisableConsoleColor() {
|
||||
disableColor = true
|
||||
}
|
||||
|
||||
// ErrorLogger returns a handlerfunc for any error type.
|
||||
func ErrorLogger() HandlerFunc {
|
||||
return ErrorLoggerT(ErrorTypeAny)
|
||||
}
|
||||
|
||||
// ErrorLoggerT returns a handlerfunc for a given error type.
|
||||
func ErrorLoggerT(typ ErrorType) HandlerFunc {
|
||||
return func(c *Context) {
|
||||
c.Next()
|
||||
@ -43,8 +47,8 @@ func ErrorLoggerT(typ ErrorType) HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// Logger instances a Logger middleware that will write the logs to gin.DefaultWriter
|
||||
// By default gin.DefaultWriter = os.Stdout
|
||||
// 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)
|
||||
}
|
||||
@ -74,6 +78,7 @@ func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
|
||||
// Start timer
|
||||
start := time.Now()
|
||||
path := c.Request.URL.Path
|
||||
raw := c.Request.URL.RawQuery
|
||||
|
||||
// Process request
|
||||
c.Next()
|
||||
@ -87,19 +92,24 @@ func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
|
||||
clientIP := c.ClientIP()
|
||||
method := c.Request.Method
|
||||
statusCode := c.Writer.Status()
|
||||
var statusColor, methodColor string
|
||||
var statusColor, methodColor, resetColor string
|
||||
if isTerm {
|
||||
statusColor = colorForStatus(statusCode)
|
||||
methodColor = colorForMethod(method)
|
||||
resetColor = reset
|
||||
}
|
||||
comment := c.Errors.ByType(ErrorTypePrivate).String()
|
||||
|
||||
fmt.Fprintf(out, "[GIN] %v |%s %3d %s| %13v | %15s |%s %s %-7s %s\n%s",
|
||||
if raw != "" {
|
||||
path = path + "?" + raw
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, "[GIN] %v |%s %3d %s| %13v | %15s |%s %-7s %s %s\n%s",
|
||||
end.Format("2006/01/02 - 15:04:05"),
|
||||
statusColor, statusCode, reset,
|
||||
statusColor, statusCode, resetColor,
|
||||
latency,
|
||||
clientIP,
|
||||
methodColor, method, reset,
|
||||
methodColor, method, resetColor,
|
||||
path,
|
||||
comment,
|
||||
)
|
||||
@ -109,11 +119,11 @@ func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
|
||||
|
||||
func colorForStatus(code int) string {
|
||||
switch {
|
||||
case code >= 200 && code < 300:
|
||||
case code >= http.StatusOK && code < http.StatusMultipleChoices:
|
||||
return green
|
||||
case code >= 300 && code < 400:
|
||||
case code >= http.StatusMultipleChoices && code < http.StatusBadRequest:
|
||||
return white
|
||||
case code >= 400 && code < 500:
|
||||
case code >= http.StatusBadRequest && code < http.StatusInternalServerError:
|
||||
return yellow
|
||||
default:
|
||||
return red
|
||||
|
BIN
vendor/github.com/gin-gonic/gin/logo.jpg
generated
vendored
BIN
vendor/github.com/gin-gonic/gin/logo.jpg
generated
vendored
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
21
vendor/github.com/gin-gonic/gin/mode.go
generated
vendored
21
vendor/github.com/gin-gonic/gin/mode.go
generated
vendored
@ -14,9 +14,9 @@ import (
|
||||
const ENV_GIN_MODE = "GIN_MODE"
|
||||
|
||||
const (
|
||||
DebugMode string = "debug"
|
||||
ReleaseMode string = "release"
|
||||
TestMode string = "test"
|
||||
DebugMode = "debug"
|
||||
ReleaseMode = "release"
|
||||
TestMode = "test"
|
||||
)
|
||||
const (
|
||||
debugCode = iota
|
||||
@ -39,16 +39,12 @@ var modeName = DebugMode
|
||||
|
||||
func init() {
|
||||
mode := os.Getenv(ENV_GIN_MODE)
|
||||
if len(mode) == 0 {
|
||||
SetMode(DebugMode)
|
||||
} else {
|
||||
SetMode(mode)
|
||||
}
|
||||
SetMode(mode)
|
||||
}
|
||||
|
||||
func SetMode(value string) {
|
||||
switch value {
|
||||
case DebugMode:
|
||||
case DebugMode, "":
|
||||
ginMode = debugCode
|
||||
case ReleaseMode:
|
||||
ginMode = releaseCode
|
||||
@ -57,6 +53,9 @@ func SetMode(value string) {
|
||||
default:
|
||||
panic("gin mode unknown: " + value)
|
||||
}
|
||||
if value == "" {
|
||||
value = DebugMode
|
||||
}
|
||||
modeName = value
|
||||
}
|
||||
|
||||
@ -64,6 +63,10 @@ func DisableBindValidation() {
|
||||
binding.Validator = nil
|
||||
}
|
||||
|
||||
func EnableJsonDecoderUseNumber() {
|
||||
binding.EnableDecoderUseNumber = true
|
||||
}
|
||||
|
||||
func Mode() string {
|
||||
return modeName
|
||||
}
|
||||
|
12
vendor/github.com/gin-gonic/gin/path.go
generated
vendored
12
vendor/github.com/gin-gonic/gin/path.go
generated
vendored
@ -5,7 +5,7 @@
|
||||
|
||||
package gin
|
||||
|
||||
// CleanPath is the URL version of path.Clean, it returns a canonical URL path
|
||||
// cleanPath is the URL version of path.Clean, it returns a canonical URL path
|
||||
// for p, eliminating . and .. elements.
|
||||
//
|
||||
// The following rules are applied iteratively until no further processing can
|
||||
@ -17,7 +17,7 @@ package gin
|
||||
// 4. Eliminate .. elements that begin a rooted path:
|
||||
// that is, replace "/.." by "/" at the beginning of a path.
|
||||
//
|
||||
// If the result of this process is an empty string, "/" is returned
|
||||
// If the result of this process is an empty string, "/" is returned.
|
||||
func cleanPath(p string) string {
|
||||
// Turn empty string into "/"
|
||||
if p == "" {
|
||||
@ -41,7 +41,7 @@ func cleanPath(p string) string {
|
||||
buf[0] = '/'
|
||||
}
|
||||
|
||||
trailing := n > 2 && p[n-1] == '/'
|
||||
trailing := n > 1 && p[n-1] == '/'
|
||||
|
||||
// A bit more clunky without a 'lazybuf' like the path package, but the loop
|
||||
// gets completely inlined (bufApp). So in contrast to the path package this
|
||||
@ -59,11 +59,11 @@ func cleanPath(p string) string {
|
||||
|
||||
case p[r] == '.' && p[r+1] == '/':
|
||||
// . element
|
||||
r++
|
||||
r += 2
|
||||
|
||||
case p[r] == '.' && p[r+1] == '.' && (r+2 == n || p[r+2] == '/'):
|
||||
// .. element: remove to last /
|
||||
r += 2
|
||||
r += 3
|
||||
|
||||
if w > 1 {
|
||||
// can backtrack
|
||||
@ -109,7 +109,7 @@ func cleanPath(p string) string {
|
||||
return string(buf[:w])
|
||||
}
|
||||
|
||||
// internal helper to lazily create a buffer if necessary
|
||||
// internal helper to lazily create a buffer if necessary.
|
||||
func bufApp(buf *[]byte, s string, w int, c byte) {
|
||||
if *buf == nil {
|
||||
if s[w] == c {
|
||||
|
14
vendor/github.com/gin-gonic/gin/recovery.go
generated
vendored
14
vendor/github.com/gin-gonic/gin/recovery.go
generated
vendored
@ -10,8 +10,10 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -26,6 +28,7 @@ func Recovery() HandlerFunc {
|
||||
return RecoveryWithWriter(DefaultErrorWriter)
|
||||
}
|
||||
|
||||
// RecoveryWithWriter returns a middleware for a given writer that recovers from any panics and writes a 500 if there was one.
|
||||
func RecoveryWithWriter(out io.Writer) HandlerFunc {
|
||||
var logger *log.Logger
|
||||
if out != nil {
|
||||
@ -37,16 +40,16 @@ func RecoveryWithWriter(out io.Writer) HandlerFunc {
|
||||
if logger != nil {
|
||||
stack := stack(3)
|
||||
httprequest, _ := httputil.DumpRequest(c.Request, false)
|
||||
logger.Printf("[Recovery] panic recovered:\n%s\n%s\n%s%s", string(httprequest), err, stack, reset)
|
||||
logger.Printf("[Recovery] %s panic recovered:\n%s\n%s\n%s%s", timeFormat(time.Now()), string(httprequest), err, stack, reset)
|
||||
}
|
||||
c.AbortWithStatus(500)
|
||||
c.AbortWithStatus(http.StatusInternalServerError)
|
||||
}
|
||||
}()
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// stack returns a nicely formated stack frame, skipping skip frames
|
||||
// stack returns a nicely formatted stack frame, skipping skip frames.
|
||||
func stack(skip int) []byte {
|
||||
buf := new(bytes.Buffer) // the returned data
|
||||
// As we loop, we open files and read them. These variables record the currently
|
||||
@ -106,3 +109,8 @@ func function(pc uintptr) []byte {
|
||||
name = bytes.Replace(name, centerDot, dot, -1)
|
||||
return name
|
||||
}
|
||||
|
||||
func timeFormat(t time.Time) string {
|
||||
var timeString = t.Format("2006/01/02 - 15:04:05")
|
||||
return timeString
|
||||
}
|
||||
|
2
vendor/github.com/gin-gonic/gin/render/data.go
generated
vendored
2
vendor/github.com/gin-gonic/gin/render/data.go
generated
vendored
@ -11,7 +11,7 @@ type Data struct {
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// Render (Data) writes data with custom ContentType
|
||||
// Render (Data) writes data with custom ContentType.
|
||||
func (r Data) Render(w http.ResponseWriter) (err error) {
|
||||
r.WriteContentType(w)
|
||||
_, err = w.Write(r.Data)
|
||||
|
50
vendor/github.com/gin-gonic/gin/render/html.go
generated
vendored
50
vendor/github.com/gin-gonic/gin/render/html.go
generated
vendored
@ -9,34 +9,32 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type (
|
||||
Delims struct {
|
||||
Left string
|
||||
Right string
|
||||
}
|
||||
type Delims struct {
|
||||
Left string
|
||||
Right string
|
||||
}
|
||||
|
||||
HTMLRender interface {
|
||||
Instance(string, interface{}) Render
|
||||
}
|
||||
type HTMLRender interface {
|
||||
Instance(string, interface{}) Render
|
||||
}
|
||||
|
||||
HTMLProduction struct {
|
||||
Template *template.Template
|
||||
Delims Delims
|
||||
}
|
||||
type HTMLProduction struct {
|
||||
Template *template.Template
|
||||
Delims Delims
|
||||
}
|
||||
|
||||
HTMLDebug struct {
|
||||
Files []string
|
||||
Glob string
|
||||
Delims Delims
|
||||
FuncMap template.FuncMap
|
||||
}
|
||||
type HTMLDebug struct {
|
||||
Files []string
|
||||
Glob string
|
||||
Delims Delims
|
||||
FuncMap template.FuncMap
|
||||
}
|
||||
|
||||
HTML struct {
|
||||
Template *template.Template
|
||||
Name string
|
||||
Data interface{}
|
||||
}
|
||||
)
|
||||
type HTML struct {
|
||||
Template *template.Template
|
||||
Name string
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
var htmlContentType = []string{"text/html; charset=utf-8"}
|
||||
|
||||
@ -62,7 +60,7 @@ func (r HTMLDebug) loadTemplate() *template.Template {
|
||||
if len(r.Files) > 0 {
|
||||
return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap).ParseFiles(r.Files...))
|
||||
}
|
||||
if len(r.Glob) > 0 {
|
||||
if r.Glob != "" {
|
||||
return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap).ParseGlob(r.Glob))
|
||||
}
|
||||
panic("the HTML debug render was created without files or glob pattern")
|
||||
@ -71,7 +69,7 @@ func (r HTMLDebug) loadTemplate() *template.Template {
|
||||
func (r HTML) Render(w http.ResponseWriter) error {
|
||||
r.WriteContentType(w)
|
||||
|
||||
if len(r.Name) == 0 {
|
||||
if r.Name == "" {
|
||||
return r.Template.Execute(w, r.Data)
|
||||
}
|
||||
return r.Template.ExecuteTemplate(w, r.Name, r.Data)
|
||||
|
107
vendor/github.com/gin-gonic/gin/render/json.go
generated
vendored
107
vendor/github.com/gin-gonic/gin/render/json.go
generated
vendored
@ -5,21 +5,41 @@
|
||||
package render
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin/json"
|
||||
)
|
||||
|
||||
type (
|
||||
JSON struct {
|
||||
Data interface{}
|
||||
}
|
||||
type JSON struct {
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
IndentedJSON struct {
|
||||
Data interface{}
|
||||
}
|
||||
)
|
||||
type IndentedJSON struct {
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
type SecureJSON struct {
|
||||
Prefix string
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
type JsonpJSON struct {
|
||||
Callback string
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
type AsciiJSON struct {
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
type SecureJSONPrefix string
|
||||
|
||||
var jsonContentType = []string{"application/json; charset=utf-8"}
|
||||
var jsonpContentType = []string{"application/javascript; charset=utf-8"}
|
||||
var jsonAsciiContentType = []string{"application/json"}
|
||||
|
||||
func (r JSON) Render(w http.ResponseWriter) (err error) {
|
||||
if err = WriteJSON(w, r.Data); err != nil {
|
||||
@ -55,3 +75,72 @@ func (r IndentedJSON) Render(w http.ResponseWriter) error {
|
||||
func (r IndentedJSON) WriteContentType(w http.ResponseWriter) {
|
||||
writeContentType(w, jsonContentType)
|
||||
}
|
||||
|
||||
func (r SecureJSON) Render(w http.ResponseWriter) error {
|
||||
r.WriteContentType(w)
|
||||
jsonBytes, err := json.Marshal(r.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if the jsonBytes is array values
|
||||
if bytes.HasPrefix(jsonBytes, []byte("[")) && bytes.HasSuffix(jsonBytes, []byte("]")) {
|
||||
w.Write([]byte(r.Prefix))
|
||||
}
|
||||
w.Write(jsonBytes)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r SecureJSON) WriteContentType(w http.ResponseWriter) {
|
||||
writeContentType(w, jsonContentType)
|
||||
}
|
||||
|
||||
func (r JsonpJSON) Render(w http.ResponseWriter) (err error) {
|
||||
r.WriteContentType(w)
|
||||
ret, err := json.Marshal(r.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if r.Callback == "" {
|
||||
w.Write(ret)
|
||||
return nil
|
||||
}
|
||||
|
||||
callback := template.JSEscapeString(r.Callback)
|
||||
w.Write([]byte(callback))
|
||||
w.Write([]byte("("))
|
||||
w.Write(ret)
|
||||
w.Write([]byte(")"))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r JsonpJSON) WriteContentType(w http.ResponseWriter) {
|
||||
writeContentType(w, jsonpContentType)
|
||||
}
|
||||
|
||||
func (r AsciiJSON) Render(w http.ResponseWriter) (err error) {
|
||||
r.WriteContentType(w)
|
||||
ret, err := json.Marshal(r.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buffer bytes.Buffer
|
||||
for _, r := range string(ret) {
|
||||
cvt := ""
|
||||
if r < 128 {
|
||||
cvt = string(r)
|
||||
} else {
|
||||
cvt = fmt.Sprintf("\\u%04x", int64(r))
|
||||
}
|
||||
buffer.WriteString(cvt)
|
||||
}
|
||||
|
||||
w.Write(buffer.Bytes())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r AsciiJSON) WriteContentType(w http.ResponseWriter) {
|
||||
writeContentType(w, jsonAsciiContentType)
|
||||
}
|
||||
|
36
vendor/github.com/gin-gonic/gin/render/reader.go
generated
vendored
Normal file
36
vendor/github.com/gin-gonic/gin/render/reader.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
package render
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Reader struct {
|
||||
ContentType string
|
||||
ContentLength int64
|
||||
Reader io.Reader
|
||||
Headers map[string]string
|
||||
}
|
||||
|
||||
// Render (Reader) writes data with custom ContentType and headers.
|
||||
func (r Reader) Render(w http.ResponseWriter) (err error) {
|
||||
r.WriteContentType(w)
|
||||
r.Headers["Content-Length"] = strconv.FormatInt(r.ContentLength, 10)
|
||||
r.writeHeaders(w, r.Headers)
|
||||
_, err = io.Copy(w, r.Reader)
|
||||
return
|
||||
}
|
||||
|
||||
func (r Reader) WriteContentType(w http.ResponseWriter) {
|
||||
writeContentType(w, []string{r.ContentType})
|
||||
}
|
||||
|
||||
func (r Reader) writeHeaders(w http.ResponseWriter, headers map[string]string) {
|
||||
header := w.Header()
|
||||
for k, v := range headers {
|
||||
if val := header[k]; len(val) == 0 {
|
||||
header[k] = []string{v}
|
||||
}
|
||||
}
|
||||
}
|
2
vendor/github.com/gin-gonic/gin/render/redirect.go
generated
vendored
2
vendor/github.com/gin-gonic/gin/render/redirect.go
generated
vendored
@ -16,6 +16,8 @@ type Redirect struct {
|
||||
}
|
||||
|
||||
func (r Redirect) Render(w http.ResponseWriter) error {
|
||||
// todo(thinkerou): go1.6 not support StatusPermanentRedirect(308)
|
||||
// when we upgrade go version we can use http.StatusPermanentRedirect
|
||||
if (r.Code < 300 || r.Code > 308) && r.Code != 201 {
|
||||
panic(fmt.Sprintf("Cannot redirect with status code %d", r.Code))
|
||||
}
|
||||
|
5
vendor/github.com/gin-gonic/gin/render/render.go
generated
vendored
5
vendor/github.com/gin-gonic/gin/render/render.go
generated
vendored
@ -14,6 +14,8 @@ type Render interface {
|
||||
var (
|
||||
_ Render = JSON{}
|
||||
_ Render = IndentedJSON{}
|
||||
_ Render = SecureJSON{}
|
||||
_ Render = JsonpJSON{}
|
||||
_ Render = XML{}
|
||||
_ Render = String{}
|
||||
_ Render = Redirect{}
|
||||
@ -23,7 +25,8 @@ var (
|
||||
_ HTMLRender = HTMLProduction{}
|
||||
_ Render = YAML{}
|
||||
_ Render = MsgPack{}
|
||||
_ Render = MsgPack{}
|
||||
_ Render = Reader{}
|
||||
_ Render = AsciiJSON{}
|
||||
)
|
||||
|
||||
func writeContentType(w http.ResponseWriter, value []string) {
|
||||
|
55
vendor/github.com/gin-gonic/gin/response_writer.go
generated
vendored
55
vendor/github.com/gin-gonic/gin/response_writer.go
generated
vendored
@ -13,39 +13,37 @@ import (
|
||||
|
||||
const (
|
||||
noWritten = -1
|
||||
defaultStatus = 200
|
||||
defaultStatus = http.StatusOK
|
||||
)
|
||||
|
||||
type (
|
||||
ResponseWriter interface {
|
||||
http.ResponseWriter
|
||||
http.Hijacker
|
||||
http.Flusher
|
||||
http.CloseNotifier
|
||||
type responseWriterBase interface {
|
||||
http.ResponseWriter
|
||||
http.Hijacker
|
||||
http.Flusher
|
||||
http.CloseNotifier
|
||||
|
||||
// Returns the HTTP response status code of the current request.
|
||||
Status() int
|
||||
// Returns the HTTP response status code of the current request.
|
||||
Status() int
|
||||
|
||||
// Returns the number of bytes already written into the response http body.
|
||||
// See Written()
|
||||
Size() int
|
||||
// Returns the number of bytes already written into the response http body.
|
||||
// See Written()
|
||||
Size() int
|
||||
|
||||
// Writes the string into the response body.
|
||||
WriteString(string) (int, error)
|
||||
// Writes the string into the response body.
|
||||
WriteString(string) (int, error)
|
||||
|
||||
// Returns true if the response body was already written.
|
||||
Written() bool
|
||||
// Returns true if the response body was already written.
|
||||
Written() bool
|
||||
|
||||
// Forces to write the http header (status code + headers).
|
||||
WriteHeaderNow()
|
||||
}
|
||||
// Forces to write the http header (status code + headers).
|
||||
WriteHeaderNow()
|
||||
}
|
||||
|
||||
responseWriter struct {
|
||||
http.ResponseWriter
|
||||
size int
|
||||
status int
|
||||
}
|
||||
)
|
||||
type responseWriter struct {
|
||||
http.ResponseWriter
|
||||
size int
|
||||
status int
|
||||
}
|
||||
|
||||
var _ ResponseWriter = &responseWriter{}
|
||||
|
||||
@ -97,7 +95,7 @@ func (w *responseWriter) Written() bool {
|
||||
return w.size != noWritten
|
||||
}
|
||||
|
||||
// Implements the http.Hijacker interface
|
||||
// Hijack implements the http.Hijacker interface.
|
||||
func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
if w.size < 0 {
|
||||
w.size = 0
|
||||
@ -105,12 +103,13 @@ func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
return w.ResponseWriter.(http.Hijacker).Hijack()
|
||||
}
|
||||
|
||||
// Implements the http.CloseNotify interface
|
||||
// CloseNotify implements the http.CloseNotify interface.
|
||||
func (w *responseWriter) CloseNotify() <-chan bool {
|
||||
return w.ResponseWriter.(http.CloseNotifier).CloseNotify()
|
||||
}
|
||||
|
||||
// Implements the http.Flush interface
|
||||
// Flush implements the http.Flush interface.
|
||||
func (w *responseWriter) Flush() {
|
||||
w.WriteHeaderNow()
|
||||
w.ResponseWriter.(http.Flusher).Flush()
|
||||
}
|
||||
|
12
vendor/github.com/gin-gonic/gin/response_writer_1.7.go
generated
vendored
Normal file
12
vendor/github.com/gin-gonic/gin/response_writer_1.7.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
// +build !go1.8
|
||||
|
||||
// Copyright 2018 Gin Core Team. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gin
|
||||
|
||||
// ResponseWriter ...
|
||||
type ResponseWriter interface {
|
||||
responseWriterBase
|
||||
}
|
25
vendor/github.com/gin-gonic/gin/response_writer_1.8.go
generated
vendored
Normal file
25
vendor/github.com/gin-gonic/gin/response_writer_1.8.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// +build go1.8
|
||||
|
||||
// Copyright 2018 Gin Core Team. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ResponseWriter ...
|
||||
type ResponseWriter interface {
|
||||
responseWriterBase
|
||||
// get the http.Pusher for server push
|
||||
Pusher() http.Pusher
|
||||
}
|
||||
|
||||
func (w *responseWriter) Pusher() (pusher http.Pusher) {
|
||||
if pusher, ok := w.ResponseWriter.(http.Pusher); ok {
|
||||
return pusher
|
||||
}
|
||||
return nil
|
||||
}
|
76
vendor/github.com/gin-gonic/gin/routergroup.go
generated
vendored
76
vendor/github.com/gin-gonic/gin/routergroup.go
generated
vendored
@ -11,39 +11,37 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type (
|
||||
IRouter interface {
|
||||
IRoutes
|
||||
Group(string, ...HandlerFunc) *RouterGroup
|
||||
}
|
||||
type IRouter interface {
|
||||
IRoutes
|
||||
Group(string, ...HandlerFunc) *RouterGroup
|
||||
}
|
||||
|
||||
IRoutes interface {
|
||||
Use(...HandlerFunc) IRoutes
|
||||
type IRoutes interface {
|
||||
Use(...HandlerFunc) IRoutes
|
||||
|
||||
Handle(string, string, ...HandlerFunc) IRoutes
|
||||
Any(string, ...HandlerFunc) IRoutes
|
||||
GET(string, ...HandlerFunc) IRoutes
|
||||
POST(string, ...HandlerFunc) IRoutes
|
||||
DELETE(string, ...HandlerFunc) IRoutes
|
||||
PATCH(string, ...HandlerFunc) IRoutes
|
||||
PUT(string, ...HandlerFunc) IRoutes
|
||||
OPTIONS(string, ...HandlerFunc) IRoutes
|
||||
HEAD(string, ...HandlerFunc) IRoutes
|
||||
Handle(string, string, ...HandlerFunc) IRoutes
|
||||
Any(string, ...HandlerFunc) IRoutes
|
||||
GET(string, ...HandlerFunc) IRoutes
|
||||
POST(string, ...HandlerFunc) IRoutes
|
||||
DELETE(string, ...HandlerFunc) IRoutes
|
||||
PATCH(string, ...HandlerFunc) IRoutes
|
||||
PUT(string, ...HandlerFunc) IRoutes
|
||||
OPTIONS(string, ...HandlerFunc) IRoutes
|
||||
HEAD(string, ...HandlerFunc) IRoutes
|
||||
|
||||
StaticFile(string, string) IRoutes
|
||||
Static(string, string) IRoutes
|
||||
StaticFS(string, http.FileSystem) IRoutes
|
||||
}
|
||||
StaticFile(string, string) IRoutes
|
||||
Static(string, string) IRoutes
|
||||
StaticFS(string, http.FileSystem) IRoutes
|
||||
}
|
||||
|
||||
// RouterGroup is used internally to configure router, a RouterGroup is associated with a prefix
|
||||
// and an array of handlers (middleware)
|
||||
RouterGroup struct {
|
||||
Handlers HandlersChain
|
||||
basePath string
|
||||
engine *Engine
|
||||
root bool
|
||||
}
|
||||
)
|
||||
// RouterGroup is used internally to configure router, a RouterGroup is associated with a prefix
|
||||
// and an array of handlers (middleware).
|
||||
type RouterGroup struct {
|
||||
Handlers HandlersChain
|
||||
basePath string
|
||||
engine *Engine
|
||||
root bool
|
||||
}
|
||||
|
||||
var _ IRouter = &RouterGroup{}
|
||||
|
||||
@ -91,43 +89,43 @@ func (group *RouterGroup) Handle(httpMethod, relativePath string, handlers ...Ha
|
||||
return group.handle(httpMethod, relativePath, handlers)
|
||||
}
|
||||
|
||||
// POST is a shortcut for router.Handle("POST", path, handle)
|
||||
// POST is a shortcut for router.Handle("POST", path, handle).
|
||||
func (group *RouterGroup) POST(relativePath string, handlers ...HandlerFunc) IRoutes {
|
||||
return group.handle("POST", relativePath, handlers)
|
||||
}
|
||||
|
||||
// GET is a shortcut for router.Handle("GET", path, handle)
|
||||
// GET is a shortcut for router.Handle("GET", path, handle).
|
||||
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
|
||||
return group.handle("GET", relativePath, handlers)
|
||||
}
|
||||
|
||||
// DELETE is a shortcut for router.Handle("DELETE", path, handle)
|
||||
// DELETE is a shortcut for router.Handle("DELETE", path, handle).
|
||||
func (group *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc) IRoutes {
|
||||
return group.handle("DELETE", relativePath, handlers)
|
||||
}
|
||||
|
||||
// PATCH is a shortcut for router.Handle("PATCH", path, handle)
|
||||
// PATCH is a shortcut for router.Handle("PATCH", path, handle).
|
||||
func (group *RouterGroup) PATCH(relativePath string, handlers ...HandlerFunc) IRoutes {
|
||||
return group.handle("PATCH", relativePath, handlers)
|
||||
}
|
||||
|
||||
// PUT is a shortcut for router.Handle("PUT", path, handle)
|
||||
// PUT is a shortcut for router.Handle("PUT", path, handle).
|
||||
func (group *RouterGroup) PUT(relativePath string, handlers ...HandlerFunc) IRoutes {
|
||||
return group.handle("PUT", relativePath, handlers)
|
||||
}
|
||||
|
||||
// OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle)
|
||||
// OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle).
|
||||
func (group *RouterGroup) OPTIONS(relativePath string, handlers ...HandlerFunc) IRoutes {
|
||||
return group.handle("OPTIONS", relativePath, handlers)
|
||||
}
|
||||
|
||||
// HEAD is a shortcut for router.Handle("HEAD", path, handle)
|
||||
// HEAD is a shortcut for router.Handle("HEAD", path, handle).
|
||||
func (group *RouterGroup) HEAD(relativePath string, handlers ...HandlerFunc) IRoutes {
|
||||
return group.handle("HEAD", relativePath, handlers)
|
||||
}
|
||||
|
||||
// Any registers a route that matches all the HTTP methods.
|
||||
// GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE
|
||||
// GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.
|
||||
func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRoutes {
|
||||
group.handle("GET", relativePath, handlers)
|
||||
group.handle("POST", relativePath, handlers)
|
||||
@ -141,7 +139,7 @@ func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRou
|
||||
return group.returnObj()
|
||||
}
|
||||
|
||||
// StaticFile registers a single route in order to server a single file of the local filesystem.
|
||||
// StaticFile registers a single route in order to serve a single file of the local filesystem.
|
||||
// router.StaticFile("favicon.ico", "./resources/favicon.ico")
|
||||
func (group *RouterGroup) StaticFile(relativePath, filepath string) IRoutes {
|
||||
if strings.Contains(relativePath, ":") || strings.Contains(relativePath, "*") {
|
||||
@ -186,7 +184,7 @@ func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileS
|
||||
_, nolisting := fs.(*onlyfilesFS)
|
||||
return func(c *Context) {
|
||||
if nolisting {
|
||||
c.Writer.WriteHeader(404)
|
||||
c.Writer.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
fileServer.ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
|
5
vendor/github.com/gin-gonic/gin/test_helpers.go
generated
vendored
5
vendor/github.com/gin-gonic/gin/test_helpers.go
generated
vendored
@ -4,10 +4,9 @@
|
||||
|
||||
package gin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
import "net/http"
|
||||
|
||||
// CreateTestContext returns a fresh engine and context for testing purposes
|
||||
func CreateTestContext(w http.ResponseWriter) (c *Context, r *Engine) {
|
||||
r = New()
|
||||
c = r.allocateContext()
|
||||
|
28
vendor/github.com/gin-gonic/gin/tree.go
generated
vendored
28
vendor/github.com/gin-gonic/gin/tree.go
generated
vendored
@ -87,16 +87,16 @@ const (
|
||||
|
||||
type node struct {
|
||||
path string
|
||||
wildChild bool
|
||||
nType nodeType
|
||||
maxParams uint8
|
||||
indices string
|
||||
children []*node
|
||||
handlers HandlersChain
|
||||
priority uint32
|
||||
nType nodeType
|
||||
maxParams uint8
|
||||
wildChild bool
|
||||
}
|
||||
|
||||
// increments priority of the given child and reorders if necessary
|
||||
// increments priority of the given child and reorders if necessary.
|
||||
func (n *node) incrementChildPrio(pos int) int {
|
||||
n.children[pos].priority++
|
||||
prio := n.children[pos].priority
|
||||
@ -105,9 +105,7 @@ func (n *node) incrementChildPrio(pos int) int {
|
||||
newPos := pos
|
||||
for newPos > 0 && n.children[newPos-1].priority < prio {
|
||||
// swap node positions
|
||||
tmpN := n.children[newPos-1]
|
||||
n.children[newPos-1] = n.children[newPos]
|
||||
n.children[newPos] = tmpN
|
||||
n.children[newPos-1], n.children[newPos] = n.children[newPos], n.children[newPos-1]
|
||||
|
||||
newPos--
|
||||
}
|
||||
@ -234,7 +232,7 @@ func (n *node) addRoute(path string, handlers HandlersChain) {
|
||||
|
||||
} else if i == len(path) { // Make node a (in-path) leaf
|
||||
if n.handlers != nil {
|
||||
panic("handlers are already registered for path ''" + fullPath + "'")
|
||||
panic("handlers are already registered for path '" + fullPath + "'")
|
||||
}
|
||||
n.handlers = handlers
|
||||
}
|
||||
@ -249,7 +247,7 @@ func (n *node) addRoute(path string, handlers HandlersChain) {
|
||||
func (n *node) insertChild(numParams uint8, path string, fullPath string, handlers HandlersChain) {
|
||||
var offset int // already handled bytes of the path
|
||||
|
||||
// find prefix until first wildcard (beginning with ':'' or '*'')
|
||||
// find prefix until first wildcard (beginning with ':' or '*')
|
||||
for i, max := 0, len(path); numParams > 0; i++ {
|
||||
c := path[i]
|
||||
if c != ':' && c != '*' {
|
||||
@ -359,7 +357,7 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle
|
||||
n.handlers = handlers
|
||||
}
|
||||
|
||||
// Returns the handle registered with the given path (key). The values of
|
||||
// getValue returns the handle registered with the given path (key). The values of
|
||||
// wildcards are saved to a map.
|
||||
// If no handle can be found, a TSR (trailing slash redirect) recommendation is
|
||||
// made if a handle exists with an extra (without the) trailing slash for the
|
||||
@ -386,7 +384,7 @@ walk: // Outer loop for walking the tree
|
||||
// Nothing found.
|
||||
// We can recommend to redirect to the same URL without a
|
||||
// trailing slash if a leaf exists for that path.
|
||||
tsr = (path == "/" && n.handlers != nil)
|
||||
tsr = path == "/" && n.handlers != nil
|
||||
return
|
||||
}
|
||||
|
||||
@ -426,7 +424,7 @@ walk: // Outer loop for walking the tree
|
||||
}
|
||||
|
||||
// ... but we can't
|
||||
tsr = (len(path) == end+1)
|
||||
tsr = len(path) == end+1
|
||||
return
|
||||
}
|
||||
|
||||
@ -437,7 +435,7 @@ walk: // Outer loop for walking the tree
|
||||
// No handle found. Check if a handle for this path + a
|
||||
// trailing slash exists for TSR recommendation
|
||||
n = n.children[0]
|
||||
tsr = (n.path == "/" && n.handlers != nil)
|
||||
tsr = n.path == "/" && n.handlers != nil
|
||||
}
|
||||
|
||||
return
|
||||
@ -501,7 +499,7 @@ walk: // Outer loop for walking the tree
|
||||
}
|
||||
}
|
||||
|
||||
// Makes a case-insensitive lookup of the given path and tries to find a handler.
|
||||
// findCaseInsensitivePath makes a case-insensitive lookup of the given path and tries to find a handler.
|
||||
// It can optionally also fix trailing slashes.
|
||||
// It returns the case-corrected path and a bool indicating whether the lookup
|
||||
// was successful.
|
||||
@ -532,7 +530,7 @@ func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPa
|
||||
|
||||
// Nothing found. We can recommend to redirect to the same URL
|
||||
// without a trailing slash if a leaf exists for that path
|
||||
found = (fixTrailingSlash && path == "/" && n.handlers != nil)
|
||||
found = fixTrailingSlash && path == "/" && n.handlers != nil
|
||||
return
|
||||
}
|
||||
|
||||
|
29
vendor/github.com/gin-gonic/gin/utils.go
generated
vendored
29
vendor/github.com/gin-gonic/gin/utils.go
generated
vendored
@ -33,21 +33,26 @@ func Bind(val interface{}) HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// WrapF is a helper function for wrapping http.HandlerFunc
|
||||
// Returns a Gin middleware
|
||||
func WrapF(f http.HandlerFunc) HandlerFunc {
|
||||
return func(c *Context) {
|
||||
f(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// WrapH is a helper function for wrapping http.Handler
|
||||
// Returns a Gin middleware
|
||||
func WrapH(h http.Handler) HandlerFunc {
|
||||
return func(c *Context) {
|
||||
h.ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// H is a shortcut for map[string]interface{}
|
||||
type H map[string]interface{}
|
||||
|
||||
// MarshalXML 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: "",
|
||||
@ -65,10 +70,8 @@ func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
return e.EncodeToken(xml.EndElement{Name: start.Name})
|
||||
}
|
||||
|
||||
func assert1(guard bool, text string) {
|
||||
@ -100,12 +103,7 @@ func parseAccept(acceptHeader string) []string {
|
||||
parts := strings.Split(acceptHeader, ",")
|
||||
out := make([]string, 0, len(parts))
|
||||
for _, part := range parts {
|
||||
index := strings.IndexByte(part, ';')
|
||||
if index >= 0 {
|
||||
part = part[0:index]
|
||||
}
|
||||
part = strings.TrimSpace(part)
|
||||
if len(part) > 0 {
|
||||
if part = strings.TrimSpace(strings.Split(part, ";")[0]); part != "" {
|
||||
out = append(out, part)
|
||||
}
|
||||
}
|
||||
@ -113,11 +111,10 @@ func parseAccept(acceptHeader string) []string {
|
||||
}
|
||||
|
||||
func lastChar(str string) uint8 {
|
||||
size := len(str)
|
||||
if size == 0 {
|
||||
if str == "" {
|
||||
panic("The length of the string can't be 0")
|
||||
}
|
||||
return str[size-1]
|
||||
return str[len(str)-1]
|
||||
}
|
||||
|
||||
func nameOfFunction(f interface{}) string {
|
||||
@ -125,7 +122,7 @@ func nameOfFunction(f interface{}) string {
|
||||
}
|
||||
|
||||
func joinPaths(absolutePath, relativePath string) string {
|
||||
if len(relativePath) == 0 {
|
||||
if relativePath == "" {
|
||||
return absolutePath
|
||||
}
|
||||
|
||||
@ -140,7 +137,7 @@ func joinPaths(absolutePath, relativePath string) string {
|
||||
func resolveAddress(addr []string) string {
|
||||
switch len(addr) {
|
||||
case 0:
|
||||
if port := os.Getenv("PORT"); len(port) > 0 {
|
||||
if port := os.Getenv("PORT"); port != "" {
|
||||
debugPrint("Environment variable PORT=\"%s\"", port)
|
||||
return ":" + port
|
||||
}
|
||||
|
0
vendor/gopkg.in/irc.v2/.gitignore → vendor/github.com/go-irc/irc/.gitignore
generated
vendored
0
vendor/gopkg.in/irc.v2/.gitignore → vendor/github.com/go-irc/irc/.gitignore
generated
vendored
0
vendor/gopkg.in/irc.v2/.gitmodules → vendor/github.com/go-irc/irc/.gitmodules
generated
vendored
0
vendor/gopkg.in/irc.v2/.gitmodules → vendor/github.com/go-irc/irc/.gitmodules
generated
vendored
0
vendor/gopkg.in/irc.v2/.travis.yml → vendor/github.com/go-irc/irc/.travis.yml
generated
vendored
0
vendor/gopkg.in/irc.v2/.travis.yml → vendor/github.com/go-irc/irc/.travis.yml
generated
vendored
0
vendor/gopkg.in/irc.v2/LICENSE → vendor/github.com/go-irc/irc/LICENSE
generated
vendored
0
vendor/gopkg.in/irc.v2/LICENSE → vendor/github.com/go-irc/irc/LICENSE
generated
vendored
0
vendor/gopkg.in/irc.v2/README.md → vendor/github.com/go-irc/irc/README.md
generated
vendored
0
vendor/gopkg.in/irc.v2/README.md → vendor/github.com/go-irc/irc/README.md
generated
vendored
0
vendor/gopkg.in/irc.v2/client.go → vendor/github.com/go-irc/irc/client.go
generated
vendored
0
vendor/gopkg.in/irc.v2/client.go → vendor/github.com/go-irc/irc/client.go
generated
vendored
0
vendor/gopkg.in/irc.v2/conn.go → vendor/github.com/go-irc/irc/conn.go
generated
vendored
0
vendor/gopkg.in/irc.v2/conn.go → vendor/github.com/go-irc/irc/conn.go
generated
vendored
0
vendor/gopkg.in/irc.v2/handler.go → vendor/github.com/go-irc/irc/handler.go
generated
vendored
0
vendor/gopkg.in/irc.v2/handler.go → vendor/github.com/go-irc/irc/handler.go
generated
vendored
0
vendor/gopkg.in/irc.v2/parser.go → vendor/github.com/go-irc/irc/parser.go
generated
vendored
0
vendor/gopkg.in/irc.v2/parser.go → vendor/github.com/go-irc/irc/parser.go
generated
vendored
0
vendor/gopkg.in/irc.v2/utils.go → vendor/github.com/go-irc/irc/utils.go
generated
vendored
0
vendor/gopkg.in/irc.v2/utils.go → vendor/github.com/go-irc/irc/utils.go
generated
vendored
3
vendor/github.com/golang/protobuf/LICENSE
generated
vendored
3
vendor/github.com/golang/protobuf/LICENSE
generated
vendored
@ -1,7 +1,4 @@
|
||||
Go support for Protocol Buffers - Google's data interchange format
|
||||
|
||||
Copyright 2010 The Go Authors. All rights reserved.
|
||||
https://github.com/golang/protobuf
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
|
18
vendor/github.com/golang/protobuf/proto/encode.go
generated
vendored
18
vendor/github.com/golang/protobuf/proto/encode.go
generated
vendored
@ -37,27 +37,9 @@ package proto
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// RequiredNotSetError is the error returned if Marshal is called with
|
||||
// a protocol buffer struct whose required fields have not
|
||||
// all been initialized. It is also the error returned if Unmarshal is
|
||||
// called with an encoded protocol buffer that does not include all the
|
||||
// required fields.
|
||||
//
|
||||
// When printed, RequiredNotSetError reports the first unset required field in a
|
||||
// message. If the field cannot be precisely determined, it is reported as
|
||||
// "{Unknown}".
|
||||
type RequiredNotSetError struct {
|
||||
field string
|
||||
}
|
||||
|
||||
func (e *RequiredNotSetError) Error() string {
|
||||
return fmt.Sprintf("proto: required field %q not set", e.field)
|
||||
}
|
||||
|
||||
var (
|
||||
// errRepeatedHasNil is the error returned if Marshal is called with
|
||||
// a struct with a repeated field containing a nil element.
|
||||
|
62
vendor/github.com/golang/protobuf/proto/lib.go
generated
vendored
62
vendor/github.com/golang/protobuf/proto/lib.go
generated
vendored
@ -265,7 +265,6 @@ package proto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
@ -274,7 +273,66 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var errInvalidUTF8 = errors.New("proto: invalid UTF-8 string")
|
||||
// RequiredNotSetError is an error type returned by either Marshal or Unmarshal.
|
||||
// Marshal reports this when a required field is not initialized.
|
||||
// Unmarshal reports this when a required field is missing from the wire data.
|
||||
type RequiredNotSetError struct{ field string }
|
||||
|
||||
func (e *RequiredNotSetError) Error() string {
|
||||
if e.field == "" {
|
||||
return fmt.Sprintf("proto: required field not set")
|
||||
}
|
||||
return fmt.Sprintf("proto: required field %q not set", e.field)
|
||||
}
|
||||
func (e *RequiredNotSetError) RequiredNotSet() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type invalidUTF8Error struct{ field string }
|
||||
|
||||
func (e *invalidUTF8Error) Error() string {
|
||||
if e.field == "" {
|
||||
return "proto: invalid UTF-8 detected"
|
||||
}
|
||||
return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field)
|
||||
}
|
||||
func (e *invalidUTF8Error) InvalidUTF8() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8.
|
||||
// This error should not be exposed to the external API as such errors should
|
||||
// be recreated with the field information.
|
||||
var errInvalidUTF8 = &invalidUTF8Error{}
|
||||
|
||||
// isNonFatal reports whether the error is either a RequiredNotSet error
|
||||
// or a InvalidUTF8 error.
|
||||
func isNonFatal(err error) bool {
|
||||
if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() {
|
||||
return true
|
||||
}
|
||||
if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type nonFatal struct{ E error }
|
||||
|
||||
// Merge merges err into nf and reports whether it was successful.
|
||||
// Otherwise it returns false for any fatal non-nil errors.
|
||||
func (nf *nonFatal) Merge(err error) (ok bool) {
|
||||
if err == nil {
|
||||
return true // not an error
|
||||
}
|
||||
if !isNonFatal(err) {
|
||||
return false // fatal error
|
||||
}
|
||||
if nf.E == nil {
|
||||
nf.E = err // store first instance of non-fatal error
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Message is implemented by generated protocol buffer messages.
|
||||
type Message interface {
|
||||
|
16
vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
16
vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
@ -139,7 +139,7 @@ type Properties struct {
|
||||
Repeated bool
|
||||
Packed bool // relevant for repeated primitives only
|
||||
Enum string // set for enum types only
|
||||
proto3 bool // whether this is known to be a proto3 field; set for []byte only
|
||||
proto3 bool // whether this is known to be a proto3 field
|
||||
oneof bool // whether this is a oneof field
|
||||
|
||||
Default string // default value
|
||||
@ -148,9 +148,9 @@ type Properties struct {
|
||||
stype reflect.Type // set for struct types only
|
||||
sprop *StructProperties // set for struct types only
|
||||
|
||||
mtype reflect.Type // set for map types only
|
||||
mkeyprop *Properties // set for map types only
|
||||
mvalprop *Properties // set for map types only
|
||||
mtype reflect.Type // set for map types only
|
||||
MapKeyProp *Properties // set for map types only
|
||||
MapValProp *Properties // set for map types only
|
||||
}
|
||||
|
||||
// String formats the properties in the protobuf struct field tag style.
|
||||
@ -275,16 +275,16 @@ func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, loc
|
||||
|
||||
case reflect.Map:
|
||||
p.mtype = t1
|
||||
p.mkeyprop = &Properties{}
|
||||
p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
|
||||
p.mvalprop = &Properties{}
|
||||
p.MapKeyProp = &Properties{}
|
||||
p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
|
||||
p.MapValProp = &Properties{}
|
||||
vtype := p.mtype.Elem()
|
||||
if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
|
||||
// The value type is not a message (*T) or bytes ([]byte),
|
||||
// so we need encoders for the pointer to this type.
|
||||
vtype = reflect.PtrTo(vtype)
|
||||
}
|
||||
p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
|
||||
p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
|
||||
}
|
||||
|
||||
if p.stype != nil {
|
||||
|
190
vendor/github.com/golang/protobuf/proto/table_marshal.go
generated
vendored
190
vendor/github.com/golang/protobuf/proto/table_marshal.go
generated
vendored
@ -231,7 +231,7 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
|
||||
return b, err
|
||||
}
|
||||
|
||||
var err, errreq error
|
||||
var err, errLater error
|
||||
// The old marshaler encodes extensions at beginning.
|
||||
if u.extensions.IsValid() {
|
||||
e := ptr.offset(u.extensions).toExtensions()
|
||||
@ -252,11 +252,13 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
|
||||
}
|
||||
}
|
||||
for _, f := range u.fields {
|
||||
if f.required && errreq == nil {
|
||||
if f.required {
|
||||
if ptr.offset(f.field).getPointer().isNil() {
|
||||
// Required field is not set.
|
||||
// We record the error but keep going, to give a complete marshaling.
|
||||
errreq = &RequiredNotSetError{f.name}
|
||||
if errLater == nil {
|
||||
errLater = &RequiredNotSetError{f.name}
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -269,14 +271,21 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
|
||||
if err1, ok := err.(*RequiredNotSetError); ok {
|
||||
// Required field in submessage is not set.
|
||||
// We record the error but keep going, to give a complete marshaling.
|
||||
if errreq == nil {
|
||||
errreq = &RequiredNotSetError{f.name + "." + err1.field}
|
||||
if errLater == nil {
|
||||
errLater = &RequiredNotSetError{f.name + "." + err1.field}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err == errRepeatedHasNil {
|
||||
err = errors.New("proto: repeated field " + f.name + " has nil element")
|
||||
}
|
||||
if err == errInvalidUTF8 {
|
||||
if errLater == nil {
|
||||
fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
|
||||
errLater = &invalidUTF8Error{fullName}
|
||||
}
|
||||
continue
|
||||
}
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
@ -284,7 +293,7 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
|
||||
s := *ptr.offset(u.unrecognized).toBytes()
|
||||
b = append(b, s...)
|
||||
}
|
||||
return b, errreq
|
||||
return b, errLater
|
||||
}
|
||||
|
||||
// computeMarshalInfo initializes the marshal info.
|
||||
@ -530,6 +539,7 @@ func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, ma
|
||||
|
||||
packed := false
|
||||
proto3 := false
|
||||
validateUTF8 := true
|
||||
for i := 2; i < len(tags); i++ {
|
||||
if tags[i] == "packed" {
|
||||
packed = true
|
||||
@ -538,6 +548,7 @@ func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, ma
|
||||
proto3 = true
|
||||
}
|
||||
}
|
||||
validateUTF8 = validateUTF8 && proto3
|
||||
|
||||
switch t.Kind() {
|
||||
case reflect.Bool:
|
||||
@ -735,6 +746,18 @@ func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, ma
|
||||
}
|
||||
return sizeFloat64Value, appendFloat64Value
|
||||
case reflect.String:
|
||||
if validateUTF8 {
|
||||
if pointer {
|
||||
return sizeStringPtr, appendUTF8StringPtr
|
||||
}
|
||||
if slice {
|
||||
return sizeStringSlice, appendUTF8StringSlice
|
||||
}
|
||||
if nozero {
|
||||
return sizeStringValueNoZero, appendUTF8StringValueNoZero
|
||||
}
|
||||
return sizeStringValue, appendUTF8StringValue
|
||||
}
|
||||
if pointer {
|
||||
return sizeStringPtr, appendStringPtr
|
||||
}
|
||||
@ -1984,9 +2007,6 @@ func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byt
|
||||
}
|
||||
func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
|
||||
v := *ptr.toString()
|
||||
if !utf8.ValidString(v) {
|
||||
return nil, errInvalidUTF8
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(v)))
|
||||
b = append(b, v...)
|
||||
@ -1997,9 +2017,6 @@ func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]b
|
||||
if v == "" {
|
||||
return b, nil
|
||||
}
|
||||
if !utf8.ValidString(v) {
|
||||
return nil, errInvalidUTF8
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(v)))
|
||||
b = append(b, v...)
|
||||
@ -2011,24 +2028,83 @@ func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, err
|
||||
return b, nil
|
||||
}
|
||||
v := *p
|
||||
if !utf8.ValidString(v) {
|
||||
return nil, errInvalidUTF8
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(v)))
|
||||
b = append(b, v...)
|
||||
return b, nil
|
||||
}
|
||||
func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
|
||||
s := *ptr.toStringSlice()
|
||||
for _, v := range s {
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(v)))
|
||||
b = append(b, v...)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
|
||||
var invalidUTF8 bool
|
||||
v := *ptr.toString()
|
||||
if !utf8.ValidString(v) {
|
||||
invalidUTF8 = true
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(v)))
|
||||
b = append(b, v...)
|
||||
if invalidUTF8 {
|
||||
return b, errInvalidUTF8
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
|
||||
var invalidUTF8 bool
|
||||
v := *ptr.toString()
|
||||
if v == "" {
|
||||
return b, nil
|
||||
}
|
||||
if !utf8.ValidString(v) {
|
||||
invalidUTF8 = true
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(v)))
|
||||
b = append(b, v...)
|
||||
if invalidUTF8 {
|
||||
return b, errInvalidUTF8
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
|
||||
var invalidUTF8 bool
|
||||
p := *ptr.toStringPtr()
|
||||
if p == nil {
|
||||
return b, nil
|
||||
}
|
||||
v := *p
|
||||
if !utf8.ValidString(v) {
|
||||
invalidUTF8 = true
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(v)))
|
||||
b = append(b, v...)
|
||||
if invalidUTF8 {
|
||||
return b, errInvalidUTF8
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
|
||||
var invalidUTF8 bool
|
||||
s := *ptr.toStringSlice()
|
||||
for _, v := range s {
|
||||
if !utf8.ValidString(v) {
|
||||
return nil, errInvalidUTF8
|
||||
invalidUTF8 = true
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(v)))
|
||||
b = append(b, v...)
|
||||
}
|
||||
if invalidUTF8 {
|
||||
return b, errInvalidUTF8
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
|
||||
@ -2107,7 +2183,8 @@ func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getPointerSlice()
|
||||
var err, errreq error
|
||||
var err error
|
||||
var nerr nonFatal
|
||||
for _, v := range s {
|
||||
if v.isNil() {
|
||||
return b, errRepeatedHasNil
|
||||
@ -2115,22 +2192,14 @@ func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
b = appendVarint(b, wiretag) // start group
|
||||
b, err = u.marshal(b, v, deterministic)
|
||||
b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group
|
||||
if err != nil {
|
||||
if _, ok := err.(*RequiredNotSetError); ok {
|
||||
// Required field in submessage is not set.
|
||||
// We record the error but keep going, to give a complete marshaling.
|
||||
if errreq == nil {
|
||||
errreq = err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !nerr.Merge(err) {
|
||||
if err == ErrNil {
|
||||
err = errRepeatedHasNil
|
||||
}
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, errreq
|
||||
return b, nerr.E
|
||||
}
|
||||
}
|
||||
|
||||
@ -2174,7 +2243,8 @@ func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getPointerSlice()
|
||||
var err, errreq error
|
||||
var err error
|
||||
var nerr nonFatal
|
||||
for _, v := range s {
|
||||
if v.isNil() {
|
||||
return b, errRepeatedHasNil
|
||||
@ -2184,22 +2254,14 @@ func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b, err = u.marshal(b, v, deterministic)
|
||||
|
||||
if err != nil {
|
||||
if _, ok := err.(*RequiredNotSetError); ok {
|
||||
// Required field in submessage is not set.
|
||||
// We record the error but keep going, to give a complete marshaling.
|
||||
if errreq == nil {
|
||||
errreq = err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !nerr.Merge(err) {
|
||||
if err == ErrNil {
|
||||
err = errRepeatedHasNil
|
||||
}
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, errreq
|
||||
return b, nerr.E
|
||||
}
|
||||
}
|
||||
|
||||
@ -2223,6 +2285,25 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
|
||||
// value.
|
||||
// Key cannot be pointer-typed.
|
||||
valIsPtr := valType.Kind() == reflect.Ptr
|
||||
|
||||
// If value is a message with nested maps, calling
|
||||
// valSizer in marshal may be quadratic. We should use
|
||||
// cached version in marshal (but not in size).
|
||||
// If value is not message type, we don't have size cache,
|
||||
// but it cannot be nested either. Just use valSizer.
|
||||
valCachedSizer := valSizer
|
||||
if valIsPtr && valType.Elem().Kind() == reflect.Struct {
|
||||
u := getMarshalInfo(valType.Elem())
|
||||
valCachedSizer = func(ptr pointer, tagsize int) int {
|
||||
// Same as message sizer, but use cache.
|
||||
p := ptr.getPointer()
|
||||
if p.isNil() {
|
||||
return 0
|
||||
}
|
||||
siz := u.cachedsize(p)
|
||||
return siz + SizeVarint(uint64(siz)) + tagsize
|
||||
}
|
||||
}
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
m := ptr.asPointerTo(t).Elem() // the map
|
||||
n := 0
|
||||
@ -2243,24 +2324,26 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
|
||||
if len(keys) > 1 && deterministic {
|
||||
sort.Sort(mapKeys(keys))
|
||||
}
|
||||
|
||||
var nerr nonFatal
|
||||
for _, k := range keys {
|
||||
ki := k.Interface()
|
||||
vi := m.MapIndex(k).Interface()
|
||||
kaddr := toAddrPointer(&ki, false) // pointer to key
|
||||
vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value
|
||||
b = appendVarint(b, tag)
|
||||
siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
|
||||
siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic)
|
||||
if err != nil {
|
||||
if !nerr.Merge(err) {
|
||||
return b, err
|
||||
}
|
||||
b, err = valMarshaler(b, vaddr, valWireTag, deterministic)
|
||||
if err != nil && err != ErrNil { // allow nil value in map
|
||||
if err != ErrNil && !nerr.Merge(err) { // allow nil value in map
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
return b, nerr.E
|
||||
}
|
||||
}
|
||||
|
||||
@ -2333,6 +2416,7 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
|
||||
defer mu.Unlock()
|
||||
|
||||
var err error
|
||||
var nerr nonFatal
|
||||
|
||||
// Fast-path for common cases: zero or one extensions.
|
||||
// Don't bother sorting the keys.
|
||||
@ -2352,11 +2436,11 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
|
||||
v := e.value
|
||||
p := toAddrPointer(&v, ei.isptr)
|
||||
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
||||
if err != nil {
|
||||
if !nerr.Merge(err) {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
return b, nerr.E
|
||||
}
|
||||
|
||||
// Sort the keys to provide a deterministic encoding.
|
||||
@ -2383,11 +2467,11 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
|
||||
v := e.value
|
||||
p := toAddrPointer(&v, ei.isptr)
|
||||
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
||||
if err != nil {
|
||||
if !nerr.Merge(err) {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
return b, nerr.E
|
||||
}
|
||||
|
||||
// message set format is:
|
||||
@ -2444,6 +2528,7 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
|
||||
defer mu.Unlock()
|
||||
|
||||
var err error
|
||||
var nerr nonFatal
|
||||
|
||||
// Fast-path for common cases: zero or one extensions.
|
||||
// Don't bother sorting the keys.
|
||||
@ -2470,12 +2555,12 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
|
||||
v := e.value
|
||||
p := toAddrPointer(&v, ei.isptr)
|
||||
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
|
||||
if err != nil {
|
||||
if !nerr.Merge(err) {
|
||||
return b, err
|
||||
}
|
||||
b = append(b, 1<<3|WireEndGroup)
|
||||
}
|
||||
return b, nil
|
||||
return b, nerr.E
|
||||
}
|
||||
|
||||
// Sort the keys to provide a deterministic encoding.
|
||||
@ -2509,11 +2594,11 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
|
||||
p := toAddrPointer(&v, ei.isptr)
|
||||
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
|
||||
b = append(b, 1<<3|WireEndGroup)
|
||||
if err != nil {
|
||||
if !nerr.Merge(err) {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
return b, nerr.E
|
||||
}
|
||||
|
||||
// sizeV1Extensions computes the size of encoded data for a V1-API extension field.
|
||||
@ -2556,6 +2641,7 @@ func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, determ
|
||||
sort.Ints(keys)
|
||||
|
||||
var err error
|
||||
var nerr nonFatal
|
||||
for _, k := range keys {
|
||||
e := m[int32(k)]
|
||||
if e.value == nil || e.desc == nil {
|
||||
@ -2572,11 +2658,11 @@ func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, determ
|
||||
v := e.value
|
||||
p := toAddrPointer(&v, ei.isptr)
|
||||
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
||||
if err != nil {
|
||||
if !nerr.Merge(err) {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
return b, nerr.E
|
||||
}
|
||||
|
||||
// newMarshaler is the interface representing objects that can marshal themselves.
|
||||
|
146
vendor/github.com/golang/protobuf/proto/table_unmarshal.go
generated
vendored
146
vendor/github.com/golang/protobuf/proto/table_unmarshal.go
generated
vendored
@ -97,6 +97,8 @@ type unmarshalFieldInfo struct {
|
||||
|
||||
// if a required field, contains a single set bit at this field's index in the required field list.
|
||||
reqMask uint64
|
||||
|
||||
name string // name of the field, for error reporting
|
||||
}
|
||||
|
||||
var (
|
||||
@ -136,8 +138,8 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
|
||||
if u.isMessageSet {
|
||||
return UnmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
|
||||
}
|
||||
var reqMask uint64 // bitmask of required fields we've seen.
|
||||
var rnse *RequiredNotSetError // an instance of a RequiredNotSetError returned by a submessage.
|
||||
var reqMask uint64 // bitmask of required fields we've seen.
|
||||
var errLater error
|
||||
for len(b) > 0 {
|
||||
// Read tag and wire type.
|
||||
// Special case 1 and 2 byte varints.
|
||||
@ -176,11 +178,20 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
|
||||
if r, ok := err.(*RequiredNotSetError); ok {
|
||||
// Remember this error, but keep parsing. We need to produce
|
||||
// a full parse even if a required field is missing.
|
||||
rnse = r
|
||||
if errLater == nil {
|
||||
errLater = r
|
||||
}
|
||||
reqMask |= f.reqMask
|
||||
continue
|
||||
}
|
||||
if err != errInternalBadWireType {
|
||||
if err == errInvalidUTF8 {
|
||||
if errLater == nil {
|
||||
fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
|
||||
errLater = &invalidUTF8Error{fullName}
|
||||
}
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
// Fragments with bad wire type are treated as unknown fields.
|
||||
@ -239,20 +250,16 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
|
||||
emap[int32(tag)] = e
|
||||
}
|
||||
}
|
||||
if rnse != nil {
|
||||
// A required field of a submessage/group is missing. Return that error.
|
||||
return rnse
|
||||
}
|
||||
if reqMask != u.reqMask {
|
||||
if reqMask != u.reqMask && errLater == nil {
|
||||
// A required field of this message is missing.
|
||||
for _, n := range u.reqFields {
|
||||
if reqMask&1 == 0 {
|
||||
return &RequiredNotSetError{n}
|
||||
errLater = &RequiredNotSetError{n}
|
||||
}
|
||||
reqMask >>= 1
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return errLater
|
||||
}
|
||||
|
||||
// computeUnmarshalInfo fills in u with information for use
|
||||
@ -351,7 +358,7 @@ func (u *unmarshalInfo) computeUnmarshalInfo() {
|
||||
}
|
||||
|
||||
// Store the info in the correct slot in the message.
|
||||
u.setTag(tag, toField(&f), unmarshal, reqMask)
|
||||
u.setTag(tag, toField(&f), unmarshal, reqMask, name)
|
||||
}
|
||||
|
||||
// Find any types associated with oneof fields.
|
||||
@ -366,10 +373,17 @@ func (u *unmarshalInfo) computeUnmarshalInfo() {
|
||||
|
||||
f := typ.Field(0) // oneof implementers have one field
|
||||
baseUnmarshal := fieldUnmarshaler(&f)
|
||||
tagstr := strings.Split(f.Tag.Get("protobuf"), ",")[1]
|
||||
tag, err := strconv.Atoi(tagstr)
|
||||
tags := strings.Split(f.Tag.Get("protobuf"), ",")
|
||||
fieldNum, err := strconv.Atoi(tags[1])
|
||||
if err != nil {
|
||||
panic("protobuf tag field not an integer: " + tagstr)
|
||||
panic("protobuf tag field not an integer: " + tags[1])
|
||||
}
|
||||
var name string
|
||||
for _, tag := range tags {
|
||||
if strings.HasPrefix(tag, "name=") {
|
||||
name = strings.TrimPrefix(tag, "name=")
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Find the oneof field that this struct implements.
|
||||
@ -380,7 +394,7 @@ func (u *unmarshalInfo) computeUnmarshalInfo() {
|
||||
// That lets us know where this struct should be stored
|
||||
// when we encounter it during unmarshaling.
|
||||
unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal)
|
||||
u.setTag(tag, of.field, unmarshal, 0)
|
||||
u.setTag(fieldNum, of.field, unmarshal, 0, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -401,7 +415,7 @@ func (u *unmarshalInfo) computeUnmarshalInfo() {
|
||||
// [0 0] is [tag=0/wiretype=varint varint-encoded-0].
|
||||
u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w)
|
||||
}, 0)
|
||||
}, 0, "")
|
||||
|
||||
// Set mask for required field check.
|
||||
u.reqMask = uint64(1)<<uint(len(u.reqFields)) - 1
|
||||
@ -413,8 +427,9 @@ func (u *unmarshalInfo) computeUnmarshalInfo() {
|
||||
// tag = tag # for field
|
||||
// field/unmarshal = unmarshal info for that field.
|
||||
// reqMask = if required, bitmask for field position in required field list. 0 otherwise.
|
||||
func (u *unmarshalInfo) setTag(tag int, field field, unmarshal unmarshaler, reqMask uint64) {
|
||||
i := unmarshalFieldInfo{field: field, unmarshal: unmarshal, reqMask: reqMask}
|
||||
// name = short name of the field.
|
||||
func (u *unmarshalInfo) setTag(tag int, field field, unmarshal unmarshaler, reqMask uint64, name string) {
|
||||
i := unmarshalFieldInfo{field: field, unmarshal: unmarshal, reqMask: reqMask, name: name}
|
||||
n := u.typ.NumField()
|
||||
if tag >= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here?
|
||||
for len(u.dense) <= tag {
|
||||
@ -442,11 +457,17 @@ func typeUnmarshaler(t reflect.Type, tags string) unmarshaler {
|
||||
tagArray := strings.Split(tags, ",")
|
||||
encoding := tagArray[0]
|
||||
name := "unknown"
|
||||
proto3 := false
|
||||
validateUTF8 := true
|
||||
for _, tag := range tagArray[3:] {
|
||||
if strings.HasPrefix(tag, "name=") {
|
||||
name = tag[5:]
|
||||
}
|
||||
if tag == "proto3" {
|
||||
proto3 = true
|
||||
}
|
||||
}
|
||||
validateUTF8 = validateUTF8 && proto3
|
||||
|
||||
// Figure out packaging (pointer, slice, or both)
|
||||
slice := false
|
||||
@ -594,6 +615,15 @@ func typeUnmarshaler(t reflect.Type, tags string) unmarshaler {
|
||||
}
|
||||
return unmarshalBytesValue
|
||||
case reflect.String:
|
||||
if validateUTF8 {
|
||||
if pointer {
|
||||
return unmarshalUTF8StringPtr
|
||||
}
|
||||
if slice {
|
||||
return unmarshalUTF8StringSlice
|
||||
}
|
||||
return unmarshalUTF8StringValue
|
||||
}
|
||||
if pointer {
|
||||
return unmarshalStringPtr
|
||||
}
|
||||
@ -1448,9 +1478,6 @@ func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
v := string(b[:x])
|
||||
if !utf8.ValidString(v) {
|
||||
return nil, errInvalidUTF8
|
||||
}
|
||||
*f.toString() = v
|
||||
return b[x:], nil
|
||||
}
|
||||
@ -1468,9 +1495,6 @@ func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
v := string(b[:x])
|
||||
if !utf8.ValidString(v) {
|
||||
return nil, errInvalidUTF8
|
||||
}
|
||||
*f.toStringPtr() = &v
|
||||
return b[x:], nil
|
||||
}
|
||||
@ -1488,14 +1512,72 @@ func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
v := string(b[:x])
|
||||
if !utf8.ValidString(v) {
|
||||
return nil, errInvalidUTF8
|
||||
}
|
||||
s := f.toStringSlice()
|
||||
*s = append(*s, v)
|
||||
return b[x:], nil
|
||||
}
|
||||
|
||||
func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return b, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
v := string(b[:x])
|
||||
*f.toString() = v
|
||||
if !utf8.ValidString(v) {
|
||||
return b[x:], errInvalidUTF8
|
||||
}
|
||||
return b[x:], nil
|
||||
}
|
||||
|
||||
func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return b, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
v := string(b[:x])
|
||||
*f.toStringPtr() = &v
|
||||
if !utf8.ValidString(v) {
|
||||
return b[x:], errInvalidUTF8
|
||||
}
|
||||
return b[x:], nil
|
||||
}
|
||||
|
||||
func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return b, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
v := string(b[:x])
|
||||
s := f.toStringSlice()
|
||||
*s = append(*s, v)
|
||||
if !utf8.ValidString(v) {
|
||||
return b[x:], errInvalidUTF8
|
||||
}
|
||||
return b[x:], nil
|
||||
}
|
||||
|
||||
var emptyBuf [0]byte
|
||||
|
||||
func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) {
|
||||
@ -1674,6 +1756,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
|
||||
// Maps will be somewhat slow. Oh well.
|
||||
|
||||
// Read key and value from data.
|
||||
var nerr nonFatal
|
||||
k := reflect.New(kt)
|
||||
v := reflect.New(vt)
|
||||
for len(b) > 0 {
|
||||
@ -1694,7 +1777,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
|
||||
err = errInternalBadWireType // skip unknown tag
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
if nerr.Merge(err) {
|
||||
continue
|
||||
}
|
||||
if err != errInternalBadWireType {
|
||||
@ -1717,7 +1800,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
|
||||
// Insert into map.
|
||||
m.SetMapIndex(k.Elem(), v.Elem())
|
||||
|
||||
return r, nil
|
||||
return r, nerr.E
|
||||
}
|
||||
}
|
||||
|
||||
@ -1743,15 +1826,16 @@ func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshal
|
||||
// Unmarshal data into holder.
|
||||
// We unmarshal into the first field of the holder object.
|
||||
var err error
|
||||
var nerr nonFatal
|
||||
b, err = unmarshal(b, valToPointer(v).offset(field0), w)
|
||||
if err != nil {
|
||||
if !nerr.Merge(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Write pointer to holder into target field.
|
||||
f.asPointerTo(ityp).Elem().Set(v)
|
||||
|
||||
return b, nil
|
||||
return b, nerr.E
|
||||
}
|
||||
}
|
||||
|
||||
|
4
vendor/github.com/golang/protobuf/proto/text.go
generated
vendored
4
vendor/github.com/golang/protobuf/proto/text.go
generated
vendored
@ -353,7 +353,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tm.writeAny(w, key, props.mkeyprop); err != nil {
|
||||
if err := tm.writeAny(w, key, props.MapKeyProp); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
@ -370,7 +370,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tm.writeAny(w, val, props.mvalprop); err != nil {
|
||||
if err := tm.writeAny(w, val, props.MapValProp); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
|
6
vendor/github.com/golang/protobuf/proto/text_parser.go
generated
vendored
6
vendor/github.com/golang/protobuf/proto/text_parser.go
generated
vendored
@ -630,17 +630,17 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||
if err := p.consumeToken(":"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.readAny(key, props.mkeyprop); err != nil {
|
||||
if err := p.readAny(key, props.MapKeyProp); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.consumeOptionalSeparator(); err != nil {
|
||||
return err
|
||||
}
|
||||
case "value":
|
||||
if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
|
||||
if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.readAny(val, props.mvalprop); err != nil {
|
||||
if err := p.readAny(val, props.MapValProp); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.consumeOptionalSeparator(); err != nil {
|
||||
|
@ -12,7 +12,7 @@
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package internal // import "github.com/garyburd/redigo/internal"
|
||||
package internal // import "github.com/gomodule/redigo/internal"
|
||||
|
||||
import (
|
||||
"strings"
|
@ -14,7 +14,7 @@
|
||||
|
||||
// Package redis is a client for the Redis database.
|
||||
//
|
||||
// The Redigo FAQ (https://github.com/garyburd/redigo/wiki/FAQ) contains more
|
||||
// The Redigo FAQ (https://github.com/gomodule/redigo/wiki/FAQ) contains more
|
||||
// documentation about this package.
|
||||
//
|
||||
// Connections
|
||||
@ -174,4 +174,4 @@
|
||||
// non-recoverable error such as a network error or protocol parsing error. If
|
||||
// Err() returns a non-nil value, then the connection is not usable and should
|
||||
// be closed.
|
||||
package redis // import "github.com/garyburd/redigo/redis"
|
||||
package redis // import "github.com/gomodule/redigo/redis"
|
@ -25,12 +25,12 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/garyburd/redigo/internal"
|
||||
"github.com/gomodule/redigo/internal"
|
||||
)
|
||||
|
||||
var (
|
||||
_ ConnWithTimeout = (*pooledConnection)(nil)
|
||||
_ ConnWithTimeout = (*errorConnection)(nil)
|
||||
_ ConnWithTimeout = (*activeConn)(nil)
|
||||
_ ConnWithTimeout = (*errorConn)(nil)
|
||||
)
|
||||
|
||||
var nowFunc = time.Now // for testing
|
||||
@ -150,6 +150,10 @@ type Pool struct {
|
||||
// for a connection to be returned to the pool before returning.
|
||||
Wait bool
|
||||
|
||||
// Close connections older than this duration. If the value is zero, then
|
||||
// the pool does not close connections based on age.
|
||||
MaxConnLifetime time.Duration
|
||||
|
||||
chInitialized uint32 // set to 1 when field ch is initialized
|
||||
|
||||
mu sync.Mutex // mu protects the following fields
|
||||
@ -172,11 +176,11 @@ func NewPool(newFn func() (Conn, error), maxIdle int) *Pool {
|
||||
// getting an underlying connection, then the connection Err, Do, Send, Flush
|
||||
// and Receive methods return that error.
|
||||
func (p *Pool) Get() Conn {
|
||||
c, err := p.get(nil)
|
||||
pc, err := p.get(nil)
|
||||
if err != nil {
|
||||
return errorConnection{err}
|
||||
return errorConn{err}
|
||||
}
|
||||
return &pooledConnection{p: p, c: c}
|
||||
return &activeConn{p: p, pc: pc}
|
||||
}
|
||||
|
||||
// PoolStats contains pool statistics.
|
||||
@ -226,15 +230,15 @@ func (p *Pool) Close() error {
|
||||
}
|
||||
p.closed = true
|
||||
p.active -= p.idle.count
|
||||
ic := p.idle.front
|
||||
pc := p.idle.front
|
||||
p.idle.count = 0
|
||||
p.idle.front, p.idle.back = nil, nil
|
||||
if p.ch != nil {
|
||||
close(p.ch)
|
||||
}
|
||||
p.mu.Unlock()
|
||||
for ; ic != nil; ic = ic.next {
|
||||
ic.c.Close()
|
||||
for ; pc != nil; pc = pc.next {
|
||||
pc.c.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -265,7 +269,7 @@ func (p *Pool) lazyInit() {
|
||||
func (p *Pool) get(ctx interface {
|
||||
Done() <-chan struct{}
|
||||
Err() error
|
||||
}) (Conn, error) {
|
||||
}) (*poolConn, error) {
|
||||
|
||||
// Handle limit for p.Wait == true.
|
||||
if p.Wait && p.MaxActive > 0 {
|
||||
@ -287,10 +291,10 @@ func (p *Pool) get(ctx interface {
|
||||
if p.IdleTimeout > 0 {
|
||||
n := p.idle.count
|
||||
for i := 0; i < n && p.idle.back != nil && p.idle.back.t.Add(p.IdleTimeout).Before(nowFunc()); i++ {
|
||||
c := p.idle.back.c
|
||||
pc := p.idle.back
|
||||
p.idle.popBack()
|
||||
p.mu.Unlock()
|
||||
c.Close()
|
||||
pc.c.Close()
|
||||
p.mu.Lock()
|
||||
p.active--
|
||||
}
|
||||
@ -298,13 +302,14 @@ func (p *Pool) get(ctx interface {
|
||||
|
||||
// Get idle connection from the front of idle list.
|
||||
for p.idle.front != nil {
|
||||
ic := p.idle.front
|
||||
pc := p.idle.front
|
||||
p.idle.popFront()
|
||||
p.mu.Unlock()
|
||||
if p.TestOnBorrow == nil || p.TestOnBorrow(ic.c, ic.t) == nil {
|
||||
return ic.c, nil
|
||||
if (p.TestOnBorrow == nil || p.TestOnBorrow(pc.c, pc.t) == nil) &&
|
||||
(p.MaxConnLifetime == 0 || nowFunc().Sub(pc.created) < p.MaxConnLifetime) {
|
||||
return pc, nil
|
||||
}
|
||||
ic.c.Close()
|
||||
pc.c.Close()
|
||||
p.mu.Lock()
|
||||
p.active--
|
||||
}
|
||||
@ -333,24 +338,25 @@ func (p *Pool) get(ctx interface {
|
||||
}
|
||||
p.mu.Unlock()
|
||||
}
|
||||
return c, err
|
||||
return &poolConn{c: c, created: nowFunc()}, err
|
||||
}
|
||||
|
||||
func (p *Pool) put(c Conn, forceClose bool) error {
|
||||
func (p *Pool) put(pc *poolConn, forceClose bool) error {
|
||||
p.mu.Lock()
|
||||
if !p.closed && !forceClose {
|
||||
p.idle.pushFront(&idleConn{t: nowFunc(), c: c})
|
||||
pc.t = nowFunc()
|
||||
p.idle.pushFront(pc)
|
||||
if p.idle.count > p.MaxIdle {
|
||||
c = p.idle.back.c
|
||||
pc = p.idle.back
|
||||
p.idle.popBack()
|
||||
} else {
|
||||
c = nil
|
||||
pc = nil
|
||||
}
|
||||
}
|
||||
|
||||
if c != nil {
|
||||
if pc != nil {
|
||||
p.mu.Unlock()
|
||||
c.Close()
|
||||
pc.c.Close()
|
||||
p.mu.Lock()
|
||||
p.active--
|
||||
}
|
||||
@ -362,9 +368,9 @@ func (p *Pool) put(c Conn, forceClose bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type pooledConnection struct {
|
||||
type activeConn struct {
|
||||
p *Pool
|
||||
c Conn
|
||||
pc *poolConn
|
||||
state int
|
||||
}
|
||||
|
||||
@ -385,79 +391,107 @@ func initSentinel() {
|
||||
}
|
||||
}
|
||||
|
||||
func (pc *pooledConnection) Close() error {
|
||||
c := pc.c
|
||||
if _, ok := c.(errorConnection); ok {
|
||||
func (ac *activeConn) Close() error {
|
||||
pc := ac.pc
|
||||
if pc == nil {
|
||||
return nil
|
||||
}
|
||||
pc.c = errorConnection{errConnClosed}
|
||||
ac.pc = nil
|
||||
|
||||
if pc.state&internal.MultiState != 0 {
|
||||
c.Send("DISCARD")
|
||||
pc.state &^= (internal.MultiState | internal.WatchState)
|
||||
} else if pc.state&internal.WatchState != 0 {
|
||||
c.Send("UNWATCH")
|
||||
pc.state &^= internal.WatchState
|
||||
if ac.state&internal.MultiState != 0 {
|
||||
pc.c.Send("DISCARD")
|
||||
ac.state &^= (internal.MultiState | internal.WatchState)
|
||||
} else if ac.state&internal.WatchState != 0 {
|
||||
pc.c.Send("UNWATCH")
|
||||
ac.state &^= internal.WatchState
|
||||
}
|
||||
if pc.state&internal.SubscribeState != 0 {
|
||||
c.Send("UNSUBSCRIBE")
|
||||
c.Send("PUNSUBSCRIBE")
|
||||
if ac.state&internal.SubscribeState != 0 {
|
||||
pc.c.Send("UNSUBSCRIBE")
|
||||
pc.c.Send("PUNSUBSCRIBE")
|
||||
// To detect the end of the message stream, ask the server to echo
|
||||
// a sentinel value and read until we see that value.
|
||||
sentinelOnce.Do(initSentinel)
|
||||
c.Send("ECHO", sentinel)
|
||||
c.Flush()
|
||||
pc.c.Send("ECHO", sentinel)
|
||||
pc.c.Flush()
|
||||
for {
|
||||
p, err := c.Receive()
|
||||
p, err := pc.c.Receive()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) {
|
||||
pc.state &^= internal.SubscribeState
|
||||
ac.state &^= internal.SubscribeState
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
c.Do("")
|
||||
pc.p.put(c, pc.state != 0 || c.Err() != nil)
|
||||
pc.c.Do("")
|
||||
ac.p.put(pc, ac.state != 0 || pc.c.Err() != nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pc *pooledConnection) Err() error {
|
||||
func (ac *activeConn) Err() error {
|
||||
pc := ac.pc
|
||||
if pc == nil {
|
||||
return errConnClosed
|
||||
}
|
||||
return pc.c.Err()
|
||||
}
|
||||
|
||||
func (pc *pooledConnection) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
|
||||
func (ac *activeConn) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
|
||||
pc := ac.pc
|
||||
if pc == nil {
|
||||
return nil, errConnClosed
|
||||
}
|
||||
ci := internal.LookupCommandInfo(commandName)
|
||||
pc.state = (pc.state | ci.Set) &^ ci.Clear
|
||||
ac.state = (ac.state | ci.Set) &^ ci.Clear
|
||||
return pc.c.Do(commandName, args...)
|
||||
}
|
||||
|
||||
func (pc *pooledConnection) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) {
|
||||
func (ac *activeConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) {
|
||||
pc := ac.pc
|
||||
if pc == nil {
|
||||
return nil, errConnClosed
|
||||
}
|
||||
cwt, ok := pc.c.(ConnWithTimeout)
|
||||
if !ok {
|
||||
return nil, errTimeoutNotSupported
|
||||
}
|
||||
ci := internal.LookupCommandInfo(commandName)
|
||||
pc.state = (pc.state | ci.Set) &^ ci.Clear
|
||||
ac.state = (ac.state | ci.Set) &^ ci.Clear
|
||||
return cwt.DoWithTimeout(timeout, commandName, args...)
|
||||
}
|
||||
|
||||
func (pc *pooledConnection) Send(commandName string, args ...interface{}) error {
|
||||
func (ac *activeConn) Send(commandName string, args ...interface{}) error {
|
||||
pc := ac.pc
|
||||
if pc == nil {
|
||||
return errConnClosed
|
||||
}
|
||||
ci := internal.LookupCommandInfo(commandName)
|
||||
pc.state = (pc.state | ci.Set) &^ ci.Clear
|
||||
ac.state = (ac.state | ci.Set) &^ ci.Clear
|
||||
return pc.c.Send(commandName, args...)
|
||||
}
|
||||
|
||||
func (pc *pooledConnection) Flush() error {
|
||||
func (ac *activeConn) Flush() error {
|
||||
pc := ac.pc
|
||||
if pc == nil {
|
||||
return errConnClosed
|
||||
}
|
||||
return pc.c.Flush()
|
||||
}
|
||||
|
||||
func (pc *pooledConnection) Receive() (reply interface{}, err error) {
|
||||
func (ac *activeConn) Receive() (reply interface{}, err error) {
|
||||
pc := ac.pc
|
||||
if pc == nil {
|
||||
return nil, errConnClosed
|
||||
}
|
||||
return pc.c.Receive()
|
||||
}
|
||||
|
||||
func (pc *pooledConnection) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) {
|
||||
func (ac *activeConn) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) {
|
||||
pc := ac.pc
|
||||
if pc == nil {
|
||||
return nil, errConnClosed
|
||||
}
|
||||
cwt, ok := pc.c.(ConnWithTimeout)
|
||||
if !ok {
|
||||
return nil, errTimeoutNotSupported
|
||||
@ -465,63 +499,64 @@ func (pc *pooledConnection) ReceiveWithTimeout(timeout time.Duration) (reply int
|
||||
return cwt.ReceiveWithTimeout(timeout)
|
||||
}
|
||||
|
||||
type errorConnection struct{ err error }
|
||||
type errorConn struct{ err error }
|
||||
|
||||
func (ec errorConnection) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }
|
||||
func (ec errorConnection) DoWithTimeout(time.Duration, string, ...interface{}) (interface{}, error) {
|
||||
func (ec errorConn) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }
|
||||
func (ec errorConn) DoWithTimeout(time.Duration, string, ...interface{}) (interface{}, error) {
|
||||
return nil, ec.err
|
||||
}
|
||||
func (ec errorConnection) Send(string, ...interface{}) error { return ec.err }
|
||||
func (ec errorConnection) Err() error { return ec.err }
|
||||
func (ec errorConnection) Close() error { return nil }
|
||||
func (ec errorConnection) Flush() error { return ec.err }
|
||||
func (ec errorConnection) Receive() (interface{}, error) { return nil, ec.err }
|
||||
func (ec errorConnection) ReceiveWithTimeout(time.Duration) (interface{}, error) { return nil, ec.err }
|
||||
func (ec errorConn) Send(string, ...interface{}) error { return ec.err }
|
||||
func (ec errorConn) Err() error { return ec.err }
|
||||
func (ec errorConn) Close() error { return nil }
|
||||
func (ec errorConn) Flush() error { return ec.err }
|
||||
func (ec errorConn) Receive() (interface{}, error) { return nil, ec.err }
|
||||
func (ec errorConn) ReceiveWithTimeout(time.Duration) (interface{}, error) { return nil, ec.err }
|
||||
|
||||
type idleList struct {
|
||||
count int
|
||||
front, back *idleConn
|
||||
front, back *poolConn
|
||||
}
|
||||
|
||||
type idleConn struct {
|
||||
type poolConn struct {
|
||||
c Conn
|
||||
t time.Time
|
||||
next, prev *idleConn
|
||||
created time.Time
|
||||
next, prev *poolConn
|
||||
}
|
||||
|
||||
func (l *idleList) pushFront(ic *idleConn) {
|
||||
ic.next = l.front
|
||||
ic.prev = nil
|
||||
func (l *idleList) pushFront(pc *poolConn) {
|
||||
pc.next = l.front
|
||||
pc.prev = nil
|
||||
if l.count == 0 {
|
||||
l.back = ic
|
||||
l.back = pc
|
||||
} else {
|
||||
l.front.prev = ic
|
||||
l.front.prev = pc
|
||||
}
|
||||
l.front = ic
|
||||
l.front = pc
|
||||
l.count++
|
||||
return
|
||||
}
|
||||
|
||||
func (l *idleList) popFront() {
|
||||
ic := l.front
|
||||
pc := l.front
|
||||
l.count--
|
||||
if l.count == 0 {
|
||||
l.front, l.back = nil, nil
|
||||
} else {
|
||||
ic.next.prev = nil
|
||||
l.front = ic.next
|
||||
pc.next.prev = nil
|
||||
l.front = pc.next
|
||||
}
|
||||
ic.next, ic.prev = nil, nil
|
||||
pc.next, pc.prev = nil, nil
|
||||
}
|
||||
|
||||
func (l *idleList) popBack() {
|
||||
ic := l.back
|
||||
pc := l.back
|
||||
l.count--
|
||||
if l.count == 0 {
|
||||
l.front, l.back = nil, nil
|
||||
} else {
|
||||
ic.prev.next = nil
|
||||
l.back = ic.prev
|
||||
pc.prev.next = nil
|
||||
l.back = pc.prev
|
||||
}
|
||||
ic.next, ic.prev = nil, nil
|
||||
pc.next, pc.prev = nil, nil
|
||||
}
|
@ -27,9 +27,9 @@ import "context"
|
||||
// If the function completes without error, then the application must close the
|
||||
// returned connection.
|
||||
func (p *Pool) GetContext(ctx context.Context) (Conn, error) {
|
||||
c, err := p.get(ctx)
|
||||
pc, err := p.get(ctx)
|
||||
if err != nil {
|
||||
return errorConnection{err}, err
|
||||
return errorConn{err}, err
|
||||
}
|
||||
return &pooledConnection{p: p, c: c}, nil
|
||||
return &activeConn{p: p, pc: pc}, nil
|
||||
}
|
@ -36,18 +36,9 @@ type Message struct {
|
||||
// The originating channel.
|
||||
Channel string
|
||||
|
||||
// The message data.
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// PMessage represents a pmessage notification.
|
||||
type PMessage struct {
|
||||
// The matched pattern.
|
||||
// The matched pattern, if any
|
||||
Pattern string
|
||||
|
||||
// The originating channel.
|
||||
Channel string
|
||||
|
||||
// The message data.
|
||||
Data []byte
|
||||
}
|
||||
@ -102,9 +93,9 @@ func (c PubSubConn) Ping(data string) error {
|
||||
return c.Conn.Flush()
|
||||
}
|
||||
|
||||
// Receive returns a pushed message as a Subscription, Message, PMessage, Pong
|
||||
// or error. The return value is intended to be used directly in a type switch
|
||||
// as illustrated in the PubSubConn example.
|
||||
// Receive returns a pushed message as a Subscription, Message, Pong or error.
|
||||
// The return value is intended to be used directly in a type switch as
|
||||
// illustrated in the PubSubConn example.
|
||||
func (c PubSubConn) Receive() interface{} {
|
||||
return c.receiveInternal(c.Conn.Receive())
|
||||
}
|
||||
@ -135,11 +126,11 @@ func (c PubSubConn) receiveInternal(replyArg interface{}, errArg error) interfac
|
||||
}
|
||||
return m
|
||||
case "pmessage":
|
||||
var pm PMessage
|
||||
if _, err := Scan(reply, &pm.Pattern, &pm.Channel, &pm.Data); err != nil {
|
||||
var m Message
|
||||
if _, err := Scan(reply, &m.Pattern, &m.Channel, &m.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
return pm
|
||||
return m
|
||||
case "subscribe", "psubscribe", "unsubscribe", "punsubscribe":
|
||||
s := Subscription{Kind: kind}
|
||||
if _, err := Scan(reply, &s.Channel, &s.Count); err != nil {
|
18
vendor/github.com/gorilla/sessions/.travis.yml
generated
vendored
18
vendor/github.com/gorilla/sessions/.travis.yml
generated
vendored
@ -3,11 +3,17 @@ sudo: false
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- go: 1.3
|
||||
- go: 1.4
|
||||
- go: 1.5
|
||||
- go: 1.6
|
||||
- go: 1.7
|
||||
- go: 1.3.x
|
||||
- go: 1.4.x
|
||||
- go: 1.5.x
|
||||
- go: 1.6.x
|
||||
- go: 1.7.x
|
||||
- go: 1.8.x
|
||||
- go: 1.9.x
|
||||
- go: 1.10.x
|
||||
- go: 1.11.x
|
||||
- go: 1.x
|
||||
env: LATEST=true
|
||||
- go: tip
|
||||
allow_failures:
|
||||
- go: tip
|
||||
@ -18,5 +24,5 @@ install:
|
||||
script:
|
||||
- go get -t -v ./...
|
||||
- diff -u <(echo -n) <(gofmt -d .)
|
||||
- go vet $(go list ./... | grep -v /vendor/)
|
||||
- if [[ "$LATEST" = true ]]; then go vet $(go list ./... | grep -v /vendor/); fi
|
||||
- go test -v -race ./...
|
||||
|
63
vendor/github.com/gorilla/sessions/README.md
generated
vendored
63
vendor/github.com/gorilla/sessions/README.md
generated
vendored
@ -1,23 +1,22 @@
|
||||
sessions
|
||||
========
|
||||
# sessions
|
||||
|
||||
[![GoDoc](https://godoc.org/github.com/gorilla/sessions?status.svg)](https://godoc.org/github.com/gorilla/sessions) [![Build Status](https://travis-ci.org/gorilla/sessions.svg?branch=master)](https://travis-ci.org/gorilla/sessions)
|
||||
[![Sourcegraph](https://sourcegraph.com/github.com/gorilla/sessions/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/sessions?badge)
|
||||
|
||||
|
||||
gorilla/sessions provides cookie and filesystem sessions and infrastructure for
|
||||
custom session backends.
|
||||
|
||||
The key features are:
|
||||
|
||||
* Simple API: use it as an easy way to set signed (and optionally
|
||||
- Simple API: use it as an easy way to set signed (and optionally
|
||||
encrypted) cookies.
|
||||
* Built-in backends to store sessions in cookies or the filesystem.
|
||||
* Flash messages: session values that last until read.
|
||||
* Convenient way to switch session persistency (aka "remember me") and set
|
||||
- Built-in backends to store sessions in cookies or the filesystem.
|
||||
- Flash messages: session values that last until read.
|
||||
- Convenient way to switch session persistency (aka "remember me") and set
|
||||
other attributes.
|
||||
* Mechanism to rotate authentication and encryption keys.
|
||||
* Multiple sessions per request, even using different backends.
|
||||
* Interfaces and infrastructure for custom session backends: sessions from
|
||||
- Mechanism to rotate authentication and encryption keys.
|
||||
- Multiple sessions per request, even using different backends.
|
||||
- Interfaces and infrastructure for custom session backends: sessions from
|
||||
different stores can be retrieved and batch-saved using a common API.
|
||||
|
||||
Let's start with an example that shows the sessions API in a nutshell:
|
||||
@ -28,7 +27,11 @@ Let's start with an example that shows the sessions API in a nutshell:
|
||||
"github.com/gorilla/sessions"
|
||||
)
|
||||
|
||||
var store = sessions.NewCookieStore([]byte("something-very-secret"))
|
||||
// Note: Don't store your key in your source code. Pass it via an
|
||||
// environmental variable, or flag (or both), and don't accidentally commit it
|
||||
// alongside your code. Ensure your key is sufficiently random - i.e. use Go's
|
||||
// crypto/rand or securecookie.GenerateRandomKey(32) and persist the result.
|
||||
var store = sessions.NewCookieStore(os.Getenv("SESSION_KEY"))
|
||||
|
||||
func MyHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// Get a session. We're ignoring the error resulted from decoding an
|
||||
@ -67,25 +70,25 @@ website](http://www.gorillatoolkit.org/pkg/sessions).
|
||||
|
||||
Other implementations of the `sessions.Store` interface:
|
||||
|
||||
* [github.com/starJammer/gorilla-sessions-arangodb](https://github.com/starJammer/gorilla-sessions-arangodb) - ArangoDB
|
||||
* [github.com/yosssi/boltstore](https://github.com/yosssi/boltstore) - Bolt
|
||||
* [github.com/srinathgs/couchbasestore](https://github.com/srinathgs/couchbasestore) - Couchbase
|
||||
* [github.com/denizeren/dynamostore](https://github.com/denizeren/dynamostore) - Dynamodb on AWS
|
||||
* [github.com/savaki/dynastore](https://github.com/savaki/dynastore) - DynamoDB on AWS (Official AWS library)
|
||||
* [github.com/bradleypeabody/gorilla-sessions-memcache](https://github.com/bradleypeabody/gorilla-sessions-memcache) - Memcache
|
||||
* [github.com/dsoprea/go-appengine-sessioncascade](https://github.com/dsoprea/go-appengine-sessioncascade) - Memcache/Datastore/Context in AppEngine
|
||||
* [github.com/kidstuff/mongostore](https://github.com/kidstuff/mongostore) - MongoDB
|
||||
* [github.com/srinathgs/mysqlstore](https://github.com/srinathgs/mysqlstore) - MySQL
|
||||
* [github.com/EnumApps/clustersqlstore](https://github.com/EnumApps/clustersqlstore) - MySQL Cluster
|
||||
* [github.com/antonlindstrom/pgstore](https://github.com/antonlindstrom/pgstore) - PostgreSQL
|
||||
* [github.com/boj/redistore](https://github.com/boj/redistore) - Redis
|
||||
* [github.com/boj/rethinkstore](https://github.com/boj/rethinkstore) - RethinkDB
|
||||
* [github.com/boj/riakstore](https://github.com/boj/riakstore) - Riak
|
||||
* [github.com/michaeljs1990/sqlitestore](https://github.com/michaeljs1990/sqlitestore) - SQLite
|
||||
* [github.com/wader/gormstore](https://github.com/wader/gormstore) - GORM (MySQL, PostgreSQL, SQLite)
|
||||
* [github.com/gernest/qlstore](https://github.com/gernest/qlstore) - ql
|
||||
* [github.com/quasoft/memstore](https://github.com/quasoft/memstore) - In-memory implementation for use in unit tests
|
||||
* [github.com/lafriks/xormstore](https://github.com/lafriks/xormstore) - XORM (MySQL, PostgreSQL, SQLite, Microsoft SQL Server, TiDB)
|
||||
- [github.com/starJammer/gorilla-sessions-arangodb](https://github.com/starJammer/gorilla-sessions-arangodb) - ArangoDB
|
||||
- [github.com/yosssi/boltstore](https://github.com/yosssi/boltstore) - Bolt
|
||||
- [github.com/srinathgs/couchbasestore](https://github.com/srinathgs/couchbasestore) - Couchbase
|
||||
- [github.com/denizeren/dynamostore](https://github.com/denizeren/dynamostore) - Dynamodb on AWS
|
||||
- [github.com/savaki/dynastore](https://github.com/savaki/dynastore) - DynamoDB on AWS (Official AWS library)
|
||||
- [github.com/bradleypeabody/gorilla-sessions-memcache](https://github.com/bradleypeabody/gorilla-sessions-memcache) - Memcache
|
||||
- [github.com/dsoprea/go-appengine-sessioncascade](https://github.com/dsoprea/go-appengine-sessioncascade) - Memcache/Datastore/Context in AppEngine
|
||||
- [github.com/kidstuff/mongostore](https://github.com/kidstuff/mongostore) - MongoDB
|
||||
- [github.com/srinathgs/mysqlstore](https://github.com/srinathgs/mysqlstore) - MySQL
|
||||
- [github.com/EnumApps/clustersqlstore](https://github.com/EnumApps/clustersqlstore) - MySQL Cluster
|
||||
- [github.com/antonlindstrom/pgstore](https://github.com/antonlindstrom/pgstore) - PostgreSQL
|
||||
- [github.com/boj/redistore](https://github.com/boj/redistore) - Redis
|
||||
- [github.com/boj/rethinkstore](https://github.com/boj/rethinkstore) - RethinkDB
|
||||
- [github.com/boj/riakstore](https://github.com/boj/riakstore) - Riak
|
||||
- [github.com/michaeljs1990/sqlitestore](https://github.com/michaeljs1990/sqlitestore) - SQLite
|
||||
- [github.com/wader/gormstore](https://github.com/wader/gormstore) - GORM (MySQL, PostgreSQL, SQLite)
|
||||
- [github.com/gernest/qlstore](https://github.com/gernest/qlstore) - ql
|
||||
- [github.com/quasoft/memstore](https://github.com/quasoft/memstore) - In-memory implementation for use in unit tests
|
||||
- [github.com/lafriks/xormstore](https://github.com/lafriks/xormstore) - XORM (MySQL, PostgreSQL, SQLite, Microsoft SQL Server, TiDB)
|
||||
|
||||
## License
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user