Update vendored dependencies (#147)
* Prepare readme for release * Update vendored packages * New version of dns dependency handles rejecting UPDATEs under the hood * Go 1.11 required
This commit is contained in:
parent
a88ee29755
commit
09dc25d336
@ -1,6 +1,5 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.9
|
||||
- 1.11
|
||||
env:
|
||||
- "PATH=/home/travis/gopath/bin:$PATH"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
FROM golang:1.9.2-alpine AS builder
|
||||
FROM golang:1.11.4-alpine3.8 AS builder
|
||||
LABEL maintainer="joona@kuori.org"
|
||||
|
||||
RUN apk add --update gcc musl-dev git
|
||||
|
||||
116
Gopkg.lock
generated
116
Gopkg.lock
generated
@ -2,12 +2,12 @@
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:289dd4d7abfb3ad2b5f728fbe9b1d5c1bf7d265a3eb9ef92869af1f7baba4c7a"
|
||||
digest = "1:e4b30804a381d7603b8a344009987c1ba351c26043501b23b8c7ce21f0b67474"
|
||||
name = "github.com/BurntSushi/toml"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "b26d9c308763d68093482582cea63d69be07a0f0"
|
||||
version = "v0.3.0"
|
||||
revision = "3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005"
|
||||
version = "v0.3.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:9ceecb4271682fd824475d451b6abf02b99ad04e72f8de3408a9d8b7fd15b933"
|
||||
@ -18,12 +18,12 @@
|
||||
version = "v1.5"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:56c130d885a4aacae1dd9c7b71cfe39912c7ebc1ff7d2b46083c8812996dc43b"
|
||||
digest = "1:0deddd908b6b4b768cfc272c16ee61e7088a60f7fe2f06c547bd3d8e1f8b8e77"
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
pruneopts = ""
|
||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||
version = "v1.1.0"
|
||||
revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@ -34,12 +34,12 @@
|
||||
revision = "8d10e4a1bae52cd8b81ffdec3445890d6dccab3d"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:55848e643a99a9dfceb19e090ce67111328fbb1780f34c62a0430994ff85fb90"
|
||||
digest = "1:2defd14040b1ca18840524e9d0f9cfab0ea8d2f2d396b343d221f8bc8e21ab9d"
|
||||
name = "github.com/fatih/structs"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "a720dfa8df582c51dee1b36feabb906bde1588bd"
|
||||
version = "v1.0"
|
||||
revision = "4966fc68f5b7593aafa6cbbba2d65ec6e1416047"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@ -58,20 +58,20 @@
|
||||
revision = "6f8212e8d10df7383609d3c377ca08884d8f3ec0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:9abc49f39e3e23e262594bb4fb70abf74c0c99e94f99153f43b143805e850719"
|
||||
digest = "1:cea4aa2038169ee558bf507d5ea02c94ca85bcca28a4c7bb99fd59b31e43a686"
|
||||
name = "github.com/google/go-querystring"
|
||||
packages = ["query"]
|
||||
pruneopts = ""
|
||||
revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a"
|
||||
revision = "44c6ddd0a2342c386950e880b658017258da92fc"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c1d7e883c50a26ea34019320d8ae40fad86c9e5d56e63a1ba2cb618cef43e986"
|
||||
digest = "1:a25a2c5ae694b01713fb6cd03c3b1ac1ccc1902b9f0a922680a88ec254f968e1"
|
||||
name = "github.com/google/uuid"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "064e2069ce9c359c118179501254f67d7d37ba24"
|
||||
version = "0.2"
|
||||
revision = "9b3b1e0f5f99ae461456d768e7d301a7acdaa2d8"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:788735d9cba7f51b7cc86e6c7ba7b40b0b7c7b374bf3a0b5fa7c929fa2af2da8"
|
||||
@ -82,15 +82,15 @@
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3c818dada3e41bdb0f509f78e6775610f1bb179449ec8c4c86a45fae35460f3f"
|
||||
digest = "1:deeb6536ebbcb66ab11213ecfaac9daadfcd004dd057446a4980ffd6c15c36e2"
|
||||
name = "github.com/julienschmidt/httprouter"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "8c199fb6259ffc1af525cc3ad52ee60ba8359669"
|
||||
version = "v1.1"
|
||||
revision = "348b672cd90d8190f8240323e372ecd1e66b59dc"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4d0614a5d2e5e394368521b087428b2996ae95ebc4699afabc61adac9b7cec38"
|
||||
digest = "1:064eb4d2277fb6a23944380644268b99acc0ae0576c72d0b6d7288d3c2fe4a1e"
|
||||
name = "github.com/klauspost/compress"
|
||||
packages = [
|
||||
"flate",
|
||||
@ -98,51 +98,59 @@
|
||||
"zlib",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "b939724e787a27c0005cabe3f78e7ed7987ac74f"
|
||||
version = "v1.4.0"
|
||||
revision = "30be6041bed523c18e269a700ebd9c2ea9328574"
|
||||
version = "v1.4.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f0117357f14b0a625ddbbe25e23637291ac0276402fcfd25fc447422456364ce"
|
||||
digest = "1:198af4ad42013a3779477b597458f860a6a99e57e1674fa4f61eb04b8b5b768f"
|
||||
name = "github.com/klauspost/cpuid"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "ae7887de9fa5d2db4eaa8174a7eff2c1ac00f2da"
|
||||
version = "v1.1"
|
||||
revision = "e7e905edc00ea8827e58662220139109efea09db"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:6a874e3ddfb9db2b42bd8c85b6875407c702fa868eed20634ff489bc896ccfd3"
|
||||
name = "github.com/konsorten/go-windows-terminal-sequences"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "5c8c8bd35d3832f5d134ae1e1e375b69a4d25242"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:09792d732b079867772cdbabdf7dc54ef9f9d04c998a9ce6226657151fccbb94"
|
||||
digest = "1:bc36cd980d0069137800b505af4937c6109f4dc7cefe39d7c2efc7c8d51528d6"
|
||||
name = "github.com/lib/pq"
|
||||
packages = [
|
||||
".",
|
||||
"oid",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "90697d60dd844d5ef6ff15135d0203f65d2f53b8"
|
||||
revision = "9eb73efc1fcc404148b56765b0d3f61d9a5ef8ee"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bc03901fc8f0965ccba8bc453eae21a9b04f95999eab664c7de6dc7290f4e8f4"
|
||||
digest = "1:8bbdb2b3dce59271877770d6fe7dcbb8362438fa7d2e1e1f688e4bf2aac72706"
|
||||
name = "github.com/mattn/go-sqlite3"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "25ecb14adfc7543176f7d85291ec7dba82c6f7e4"
|
||||
version = "v1.9.0"
|
||||
revision = "c7c4067b79cc51e6dfdcef5c702e74b1e0fa7c75"
|
||||
version = "v1.10.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4c8d8358c45ba11ab7bb15df749d4df8664ff1582daead28bae58cf8cbe49890"
|
||||
digest = "1:103c1001b79009329824bc60f93f8f7150bf1ad31f18d29a476deb8a2de0f002"
|
||||
name = "github.com/miekg/dns"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "5a2b9fab83ff0f8bfc99684bd5f43a37abe560f1"
|
||||
version = "v1.0.8"
|
||||
revision = "8fc2e5773bbd308ca2fcc962fd8d25c1bd0f6743"
|
||||
version = "v1.1.4"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:fe67641b990bdc1802f8a1e462a4924210a8762a8a17b72e09656049c906b871"
|
||||
name = "github.com/moul/http2curl"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "9ac6cf4d929b2fa8fd2d2e6dec5bb0feb4f4911d"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:256484dbbcd271f9ecebc6795b2df8cad4c458dd0f5fd82a8c2fa0c29f233411"
|
||||
@ -153,12 +161,12 @@
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:78c9cf43ddeacd0e472f412082227a0fac2ae107ee60e9112156f9371f9912cf"
|
||||
digest = "1:5f47c69f85311c4dc292be6cc995a0a3fe8337a6ce38ef4f71e5b7efd5ad42e0"
|
||||
name = "github.com/rs/cors"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "3fb1b69b103a84de38a19c3c6ec073dd6caa4d3f"
|
||||
version = "v1.5.0"
|
||||
revision = "9a47f48565a795472d43519dd49aac781f3034fb"
|
||||
version = "v1.6.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3962f553b77bf6c03fc07cd687a22dd3b00fe11aa14d31194f5505f5bb65cdc8"
|
||||
@ -169,38 +177,38 @@
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3fcbf733a8d810a21265a7f2fe08a3353db2407da052b233f8b204b5afc03d9b"
|
||||
digest = "1:9a3c631555e0351fdc4e696577bb63afd90c399d782a8462dba9d100d7021db3"
|
||||
name = "github.com/sirupsen/logrus"
|
||||
packages = [
|
||||
".",
|
||||
"hooks/test",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "3e01752db0189b9157070a0e1668a620f9a85da2"
|
||||
version = "v1.0.6"
|
||||
revision = "e1e72e9de974bd926e5c56f83753fba2df402ce5"
|
||||
version = "v1.3.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c587772fb8ad29ad4db67575dad25ba17a51f072ff18a22b4f0257a4d9c24f75"
|
||||
digest = "1:381bcbeb112a51493d9d998bbba207a529c73dbb49b3fd789e48c63fac1f192c"
|
||||
name = "github.com/stretchr/testify"
|
||||
packages = [
|
||||
"assert",
|
||||
"require",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
|
||||
version = "v1.2.2"
|
||||
revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053"
|
||||
version = "v1.3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:857a9ecd5cb13379ecc8f798f6e6b6b574c98b9355657d91e068275f1120aaf7"
|
||||
name = "github.com/valyala/bytebufferpool"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:ed95b0b73de30dc5507de18b0cd6a2b79dc0ef685eefeb27fd1386f7a4e04f2b"
|
||||
digest = "1:5838606075eb2e11d5b99d4526e36863a9315f006d322abfbf5a7fff73250271"
|
||||
name = "github.com/valyala/fasthttp"
|
||||
packages = [
|
||||
".",
|
||||
@ -208,7 +216,7 @@
|
||||
"stackless",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "e5f51c11919d4f66400334047b897ef0a94c6f3c"
|
||||
revision = "aaec9b0fe2d01bd3ff761345ba47bb94a9b0dc59"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@ -227,12 +235,12 @@
|
||||
revision = "bd5ef7bd5415a7ac448318e64f11a24cd21e594b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:0dd2250939dcf18c0b1a7b0e364e13b083331f723a6853ff2950a0c4273ff6e2"
|
||||
digest = "1:c2c74271189fe48e23c25216570008b7ecc5782688d6efd81325886ac6f62ad0"
|
||||
name = "github.com/xeipuuv/gojsonschema"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "6cd6dcbc9e7514bea255a9241665a6c2d0b37fb4"
|
||||
revision = "f971f3cd73b2899de6923801c147f075263e0c50"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@ -263,7 +271,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:4cae11053a5fc8e7b08228fcc14d161d3e60b64ba508a8b216937da472690991"
|
||||
digest = "1:cbc1ebc01ec2ceb2c3cc7b9e33357dbc3eff173335f02d9f01603f14102602a7"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = [
|
||||
"acme",
|
||||
@ -275,11 +283,11 @@
|
||||
"ssh/terminal",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "de0752318171da717af4ce24d0a2e8626afaeb11"
|
||||
revision = "b8fe1690c61389d7d2a8074a507d1d40c5d30448"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:67c2d940f2d5c017ef88e9847709dca9b38d5fe82f1e33fb42ace515219f22f1"
|
||||
digest = "1:1e9704e5379e68ac473c28aeb3f7e7cd4036ae8a246bf0285b5ebdbb8e0cfacf"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"bpf",
|
||||
@ -291,18 +299,18 @@
|
||||
"publicsuffix",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "f9ce57c11b242f0f1599cf25c89d8cb02c45295a"
|
||||
revision = "d26f9f9a57f3fab6a695bec0d84433c2c50f8bbf"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8812fbc18f45708b5580ed61267fefe5eeb29b36773bdfaad48b0843e3810c02"
|
||||
digest = "1:4d6f20f5bc52af99569b1be5ea55d4e22646d5e022b92f2d3d75347628614734"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"unix",
|
||||
"windows",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "f0d5e33068cb57c22a181f5df0ffda885309eb5a"
|
||||
revision = "7ae0202eb74c2b534255c71b5a15fa4115aabbcc"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5acd3512b047305d49e8763eef7ba423901e85d5dd2fd1e71778a0ea8de10bd4"
|
||||
|
||||
@ -133,7 +133,7 @@ See the INSTALL section for information on how to do this.
|
||||
|
||||
## Installation
|
||||
|
||||
1) Install [Go 1.9 or newer](https://golang.org/doc/install).
|
||||
1) Install [Go 1.11 or newer](https://golang.org/doc/install).
|
||||
|
||||
2) Install acme-dns: `go get github.com/joohoi/acme-dns/...`. This will install acme-dns to `~/go/bin/acme-dns`.
|
||||
|
||||
|
||||
4
dns.go
4
dns.go
@ -84,11 +84,7 @@ func (d *DNSServer) handleRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
|
||||
if r.Opcode == dns.OpcodeQuery {
|
||||
d.readQuery(m)
|
||||
} else if r.Opcode == dns.OpcodeUpdate {
|
||||
log.Debug("Refusing DNS Dynamic update request")
|
||||
m.MsgHdr.Rcode = dns.RcodeRefused
|
||||
}
|
||||
|
||||
w.WriteMsg(m)
|
||||
}
|
||||
|
||||
|
||||
16
dns_test.go
16
dns_test.go
@ -116,22 +116,6 @@ func TestEDNS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpcodeUpdate(t *testing.T) {
|
||||
msg := new(dns.Msg)
|
||||
msg.Id = dns.Id()
|
||||
msg.Question = make([]dns.Question, 1)
|
||||
msg.Question[0] = dns.Question{Name: dns.Fqdn("auth.example.org"), Qtype: dns.TypeANY, Qclass: dns.ClassINET}
|
||||
msg.MsgHdr.Opcode = dns.OpcodeUpdate
|
||||
in, err := dns.Exchange(msg, "127.0.0.1:15353")
|
||||
if err != nil || in == nil {
|
||||
t.Errorf("Encountered an error with UPDATE request")
|
||||
} else if err == nil {
|
||||
if in.Rcode != dns.RcodeRefused {
|
||||
t.Errorf("Expected RCODE Refused from UPDATE request, but got [%s] instead", dns.RcodeToString[in.Rcode])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveCNAME(t *testing.T) {
|
||||
resolv := resolver{server: "127.0.0.1:15353"}
|
||||
expected := "cn.example.org. 3600 IN CNAME something.example.org."
|
||||
|
||||
27
vendor/github.com/BurntSushi/toml/COPYING
generated
vendored
27
vendor/github.com/BurntSushi/toml/COPYING
generated
vendored
@ -1,14 +1,21 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
Copyright (c) 2013 TOML authors
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
27
vendor/github.com/BurntSushi/toml/cmd/toml-test-decoder/COPYING
generated
vendored
27
vendor/github.com/BurntSushi/toml/cmd/toml-test-decoder/COPYING
generated
vendored
@ -1,14 +1,21 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
Copyright (c) 2013 TOML authors
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
27
vendor/github.com/BurntSushi/toml/cmd/toml-test-encoder/COPYING
generated
vendored
27
vendor/github.com/BurntSushi/toml/cmd/toml-test-encoder/COPYING
generated
vendored
@ -1,14 +1,21 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
Copyright (c) 2013 TOML authors
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
27
vendor/github.com/BurntSushi/toml/cmd/tomlv/COPYING
generated
vendored
27
vendor/github.com/BurntSushi/toml/cmd/tomlv/COPYING
generated
vendored
@ -1,14 +1,21 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
Copyright (c) 2013 TOML authors
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
14
vendor/github.com/BurntSushi/toml/decode_test.go
generated
vendored
14
vendor/github.com/BurntSushi/toml/decode_test.go
generated
vendored
@ -16,6 +16,8 @@ age = 250
|
||||
andrew = "gallant"
|
||||
kait = "brady"
|
||||
now = 1987-07-05T05:45:00Z
|
||||
nowEast = 2017-06-22T16:15:21+08:00
|
||||
nowWest = 2017-06-22T02:14:36-06:00
|
||||
yesOrNo = true
|
||||
pi = 3.14
|
||||
colors = [
|
||||
@ -38,6 +40,8 @@ cauchy = "cat 2"
|
||||
Pi float64
|
||||
YesOrNo bool
|
||||
Now time.Time
|
||||
NowEast time.Time
|
||||
NowWest time.Time
|
||||
Andrew string
|
||||
Kait string
|
||||
My map[string]cats
|
||||
@ -53,11 +57,21 @@ cauchy = "cat 2"
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
nowEast, err := time.Parse("2006-01-02T15:04:05-07:00", "2017-06-22T16:15:21+08:00")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
nowWest, err := time.Parse("2006-01-02T15:04:05-07:00", "2017-06-22T02:14:36-06:00")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var answer = simple{
|
||||
Age: 250,
|
||||
Andrew: "gallant",
|
||||
Kait: "brady",
|
||||
Now: now,
|
||||
NowEast: nowEast,
|
||||
NowWest: nowWest,
|
||||
YesOrNo: true,
|
||||
Pi: 3.14,
|
||||
Colors: [][]string{
|
||||
|
||||
2
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
2
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
@ -775,7 +775,7 @@ func lexDatetime(lx *lexer) stateFn {
|
||||
return lexDatetime
|
||||
}
|
||||
switch r {
|
||||
case '-', 'T', ':', '.', 'Z':
|
||||
case '-', 'T', ':', '.', 'Z', '+':
|
||||
return lexDatetime
|
||||
}
|
||||
|
||||
|
||||
28
vendor/github.com/davecgh/go-spew/.travis.yml
generated
vendored
28
vendor/github.com/davecgh/go-spew/.travis.yml
generated
vendored
@ -1,14 +1,28 @@
|
||||
language: go
|
||||
go_import_path: github.com/davecgh/go-spew
|
||||
go:
|
||||
- 1.5.4
|
||||
- 1.6.3
|
||||
- 1.7
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- tip
|
||||
sudo: false
|
||||
install:
|
||||
- go get -v golang.org/x/tools/cmd/cover
|
||||
- go get -v github.com/alecthomas/gometalinter
|
||||
- gometalinter --install
|
||||
script:
|
||||
- go test -v -tags=safe ./spew
|
||||
- go test -v -tags=testcgo ./spew -covermode=count -coverprofile=profile.cov
|
||||
- export PATH=$PATH:$HOME/gopath/bin
|
||||
- export GORACE="halt_on_error=1"
|
||||
- test -z "$(gometalinter --disable-all
|
||||
--enable=gofmt
|
||||
--enable=golint
|
||||
--enable=vet
|
||||
--enable=gosimple
|
||||
--enable=unconvert
|
||||
--deadline=4m ./spew | tee /dev/stderr)"
|
||||
- go test -v -race -tags safe ./spew
|
||||
- go test -v -race -tags testcgo ./spew -covermode=atomic -coverprofile=profile.cov
|
||||
after_success:
|
||||
- go get -v github.com/mattn/goveralls
|
||||
- export PATH=$PATH:$HOME/gopath/bin
|
||||
- goveralls -coverprofile=profile.cov -service=travis-ci
|
||||
|
||||
2
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
2
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
@ -2,7 +2,7 @@ ISC License
|
||||
|
||||
Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
|
||||
12
vendor/github.com/davecgh/go-spew/README.md
generated
vendored
12
vendor/github.com/davecgh/go-spew/README.md
generated
vendored
@ -1,12 +1,9 @@
|
||||
go-spew
|
||||
=======
|
||||
|
||||
[]
|
||||
(https://travis-ci.org/davecgh/go-spew) [![ISC License]
|
||||
(http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) [![Coverage Status]
|
||||
(https://img.shields.io/coveralls/davecgh/go-spew.svg)]
|
||||
(https://coveralls.io/r/davecgh/go-spew?branch=master)
|
||||
|
||||
[](https://travis-ci.org/davecgh/go-spew)
|
||||
[](http://copyfree.org)
|
||||
[](https://coveralls.io/r/davecgh/go-spew?branch=master)
|
||||
|
||||
Go-spew implements a deep pretty printer for Go data structures to aid in
|
||||
debugging. A comprehensive suite of tests with 100% test coverage is provided
|
||||
@ -21,8 +18,7 @@ post about it
|
||||
|
||||
## Documentation
|
||||
|
||||
[]
|
||||
(http://godoc.org/github.com/davecgh/go-spew/spew)
|
||||
[](http://godoc.org/github.com/davecgh/go-spew/spew)
|
||||
|
||||
Full `go doc` style documentation for the project can be viewed online without
|
||||
installing this package by using the excellent GoDoc site here:
|
||||
|
||||
183
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
183
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
@ -16,7 +16,9 @@
|
||||
// when the code is not running on Google App Engine, compiled by GopherJS, and
|
||||
// "-tags safe" is not added to the go build command line. The "disableunsafe"
|
||||
// tag is deprecated and thus should not be used.
|
||||
// +build !js,!appengine,!safe,!disableunsafe
|
||||
// Go versions prior to 1.4 are disabled because they use a different layout
|
||||
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
||||
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
||||
|
||||
package spew
|
||||
|
||||
@ -34,80 +36,49 @@ const (
|
||||
ptrSize = unsafe.Sizeof((*byte)(nil))
|
||||
)
|
||||
|
||||
var (
|
||||
// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
|
||||
// internal reflect.Value fields. These values are valid before golang
|
||||
// commit ecccf07e7f9d which changed the format. The are also valid
|
||||
// after commit 82f48826c6c7 which changed the format again to mirror
|
||||
// the original format. Code in the init function updates these offsets
|
||||
// as necessary.
|
||||
offsetPtr = uintptr(ptrSize)
|
||||
offsetScalar = uintptr(0)
|
||||
offsetFlag = uintptr(ptrSize * 2)
|
||||
type flag uintptr
|
||||
|
||||
// flagKindWidth and flagKindShift indicate various bits that the
|
||||
// reflect package uses internally to track kind information.
|
||||
//
|
||||
// flagRO indicates whether or not the value field of a reflect.Value is
|
||||
// read-only.
|
||||
//
|
||||
// flagIndir indicates whether the value field of a reflect.Value is
|
||||
// the actual data or a pointer to the data.
|
||||
//
|
||||
// These values are valid before golang commit 90a7c3c86944 which
|
||||
// changed their positions. Code in the init function updates these
|
||||
// flags as necessary.
|
||||
flagKindWidth = uintptr(5)
|
||||
flagKindShift = uintptr(flagKindWidth - 1)
|
||||
flagRO = uintptr(1 << 0)
|
||||
flagIndir = uintptr(1 << 1)
|
||||
var (
|
||||
// flagRO indicates whether the value field of a reflect.Value
|
||||
// is read-only.
|
||||
flagRO flag
|
||||
|
||||
// flagAddr indicates whether the address of the reflect.Value's
|
||||
// value may be taken.
|
||||
flagAddr flag
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Older versions of reflect.Value stored small integers directly in the
|
||||
// ptr field (which is named val in the older versions). Versions
|
||||
// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
|
||||
// scalar for this purpose which unfortunately came before the flag
|
||||
// field, so the offset of the flag field is different for those
|
||||
// versions.
|
||||
//
|
||||
// This code constructs a new reflect.Value from a known small integer
|
||||
// and checks if the size of the reflect.Value struct indicates it has
|
||||
// the scalar field. When it does, the offsets are updated accordingly.
|
||||
vv := reflect.ValueOf(0xf00)
|
||||
if unsafe.Sizeof(vv) == (ptrSize * 4) {
|
||||
offsetScalar = ptrSize * 2
|
||||
offsetFlag = ptrSize * 3
|
||||
}
|
||||
// flagKindMask holds the bits that make up the kind
|
||||
// part of the flags field. In all the supported versions,
|
||||
// it is in the lower 5 bits.
|
||||
const flagKindMask = flag(0x1f)
|
||||
|
||||
// Commit 90a7c3c86944 changed the flag positions such that the low
|
||||
// order bits are the kind. This code extracts the kind from the flags
|
||||
// field and ensures it's the correct type. When it's not, the flag
|
||||
// order has been changed to the newer format, so the flags are updated
|
||||
// accordingly.
|
||||
upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
|
||||
upfv := *(*uintptr)(upf)
|
||||
flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
|
||||
if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
|
||||
flagKindShift = 0
|
||||
flagRO = 1 << 5
|
||||
flagIndir = 1 << 6
|
||||
// Different versions of Go have used different
|
||||
// bit layouts for the flags type. This table
|
||||
// records the known combinations.
|
||||
var okFlags = []struct {
|
||||
ro, addr flag
|
||||
}{{
|
||||
// From Go 1.4 to 1.5
|
||||
ro: 1 << 5,
|
||||
addr: 1 << 7,
|
||||
}, {
|
||||
// Up to Go tip.
|
||||
ro: 1<<5 | 1<<6,
|
||||
addr: 1 << 8,
|
||||
}}
|
||||
|
||||
// Commit adf9b30e5594 modified the flags to separate the
|
||||
// flagRO flag into two bits which specifies whether or not the
|
||||
// field is embedded. This causes flagIndir to move over a bit
|
||||
// and means that flagRO is the combination of either of the
|
||||
// original flagRO bit and the new bit.
|
||||
//
|
||||
// This code detects the change by extracting what used to be
|
||||
// the indirect bit to ensure it's set. When it's not, the flag
|
||||
// order has been changed to the newer format, so the flags are
|
||||
// updated accordingly.
|
||||
if upfv&flagIndir == 0 {
|
||||
flagRO = 3 << 5
|
||||
flagIndir = 1 << 7
|
||||
}
|
||||
var flagValOffset = func() uintptr {
|
||||
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||
if !ok {
|
||||
panic("reflect.Value has no flag field")
|
||||
}
|
||||
return field.Offset
|
||||
}()
|
||||
|
||||
// flagField returns a pointer to the flag field of a reflect.Value.
|
||||
func flagField(v *reflect.Value) *flag {
|
||||
return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
|
||||
}
|
||||
|
||||
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
||||
@ -119,34 +90,56 @@ func init() {
|
||||
// This allows us to check for implementations of the Stringer and error
|
||||
// interfaces to be used for pretty printing ordinarily unaddressable and
|
||||
// inaccessible values such as unexported struct fields.
|
||||
func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
|
||||
indirects := 1
|
||||
vt := v.Type()
|
||||
upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
|
||||
rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
|
||||
if rvf&flagIndir != 0 {
|
||||
vt = reflect.PtrTo(v.Type())
|
||||
indirects++
|
||||
} else if offsetScalar != 0 {
|
||||
// The value is in the scalar field when it's not one of the
|
||||
// reference types.
|
||||
switch vt.Kind() {
|
||||
case reflect.Uintptr:
|
||||
case reflect.Chan:
|
||||
case reflect.Func:
|
||||
case reflect.Map:
|
||||
case reflect.Ptr:
|
||||
case reflect.UnsafePointer:
|
||||
default:
|
||||
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
|
||||
offsetScalar)
|
||||
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
||||
if !v.IsValid() || (v.CanInterface() && v.CanAddr()) {
|
||||
return v
|
||||
}
|
||||
flagFieldPtr := flagField(&v)
|
||||
*flagFieldPtr &^= flagRO
|
||||
*flagFieldPtr |= flagAddr
|
||||
return v
|
||||
}
|
||||
|
||||
pv := reflect.NewAt(vt, upv)
|
||||
rv = pv
|
||||
for i := 0; i < indirects; i++ {
|
||||
rv = rv.Elem()
|
||||
// Sanity checks against future reflect package changes
|
||||
// to the type or semantics of the Value.flag field.
|
||||
func init() {
|
||||
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||
if !ok {
|
||||
panic("reflect.Value has no flag field")
|
||||
}
|
||||
return rv
|
||||
if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
|
||||
panic("reflect.Value flag field has changed kind")
|
||||
}
|
||||
type t0 int
|
||||
var t struct {
|
||||
A t0
|
||||
// t0 will have flagEmbedRO set.
|
||||
t0
|
||||
// a will have flagStickyRO set
|
||||
a t0
|
||||
}
|
||||
vA := reflect.ValueOf(t).FieldByName("A")
|
||||
va := reflect.ValueOf(t).FieldByName("a")
|
||||
vt0 := reflect.ValueOf(t).FieldByName("t0")
|
||||
|
||||
// Infer flagRO from the difference between the flags
|
||||
// for the (otherwise identical) fields in t.
|
||||
flagPublic := *flagField(&vA)
|
||||
flagWithRO := *flagField(&va) | *flagField(&vt0)
|
||||
flagRO = flagPublic ^ flagWithRO
|
||||
|
||||
// Infer flagAddr from the difference between a value
|
||||
// taken from a pointer and not.
|
||||
vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A")
|
||||
flagNoPtr := *flagField(&vA)
|
||||
flagPtr := *flagField(&vPtrA)
|
||||
flagAddr = flagNoPtr ^ flagPtr
|
||||
|
||||
// Check that the inferred flags tally with one of the known versions.
|
||||
for _, f := range okFlags {
|
||||
if flagRO == f.ro && flagAddr == f.addr {
|
||||
return
|
||||
}
|
||||
}
|
||||
panic("reflect.Value read-only flag has changed semantics")
|
||||
}
|
||||
|
||||
2
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
2
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
@ -16,7 +16,7 @@
|
||||
// when the code is running on Google App Engine, compiled by GopherJS, or
|
||||
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
||||
// tag is deprecated and thus should not be used.
|
||||
// +build js appengine safe disableunsafe
|
||||
// +build js appengine safe disableunsafe !go1.4
|
||||
|
||||
package spew
|
||||
|
||||
|
||||
2
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
2
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
@ -180,7 +180,7 @@ func printComplex(w io.Writer, c complex128, floatPrecision int) {
|
||||
w.Write(closeParenBytes)
|
||||
}
|
||||
|
||||
// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
|
||||
// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'
|
||||
// prefix to Writer w.
|
||||
func printHexPtr(w io.Writer, p uintptr) {
|
||||
// Null pointer.
|
||||
|
||||
10
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
10
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
@ -35,16 +35,16 @@ var (
|
||||
|
||||
// cCharRE is a regular expression that matches a cgo char.
|
||||
// It is used to detect character arrays to hexdump them.
|
||||
cCharRE = regexp.MustCompile("^.*\\._Ctype_char$")
|
||||
cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`)
|
||||
|
||||
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
|
||||
// char. It is used to detect unsigned character arrays to hexdump
|
||||
// them.
|
||||
cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$")
|
||||
cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`)
|
||||
|
||||
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
|
||||
// It is used to detect uint8_t arrays to hexdump them.
|
||||
cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$")
|
||||
cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`)
|
||||
)
|
||||
|
||||
// dumpState contains information about the state of a dump operation.
|
||||
@ -143,10 +143,10 @@ func (d *dumpState) dumpPtr(v reflect.Value) {
|
||||
// Display dereferenced value.
|
||||
d.w.Write(openParenBytes)
|
||||
switch {
|
||||
case nilFound == true:
|
||||
case nilFound:
|
||||
d.w.Write(nilAngleBytes)
|
||||
|
||||
case cycleFound == true:
|
||||
case cycleFound:
|
||||
d.w.Write(circularBytes)
|
||||
|
||||
default:
|
||||
|
||||
2
vendor/github.com/davecgh/go-spew/spew/dump_test.go
generated
vendored
2
vendor/github.com/davecgh/go-spew/spew/dump_test.go
generated
vendored
@ -768,7 +768,7 @@ func addUintptrDumpTests() {
|
||||
|
||||
func addUnsafePointerDumpTests() {
|
||||
// Null pointer.
|
||||
v := unsafe.Pointer(uintptr(0))
|
||||
v := unsafe.Pointer(nil)
|
||||
nv := (*unsafe.Pointer)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
|
||||
6
vendor/github.com/davecgh/go-spew/spew/dumpcgo_test.go
generated
vendored
6
vendor/github.com/davecgh/go-spew/spew/dumpcgo_test.go
generated
vendored
@ -82,18 +82,20 @@ func addCgoDumpTests() {
|
||||
v5Len := fmt.Sprintf("%d", v5l)
|
||||
v5Cap := fmt.Sprintf("%d", v5c)
|
||||
v5t := "[6]testdata._Ctype_uint8_t"
|
||||
v5t2 := "[6]testdata._Ctype_uchar"
|
||||
v5s := "(len=" + v5Len + " cap=" + v5Cap + ") " +
|
||||
"{\n 00000000 74 65 73 74 35 00 " +
|
||||
" |test5.|\n}"
|
||||
addDumpTest(v5, "("+v5t+") "+v5s+"\n")
|
||||
addDumpTest(v5, "("+v5t+") "+v5s+"\n", "("+v5t2+") "+v5s+"\n")
|
||||
|
||||
// C typedefed unsigned char array.
|
||||
v6, v6l, v6c := testdata.GetCgoTypdefedUnsignedCharArray()
|
||||
v6Len := fmt.Sprintf("%d", v6l)
|
||||
v6Cap := fmt.Sprintf("%d", v6c)
|
||||
v6t := "[6]testdata._Ctype_custom_uchar_t"
|
||||
v6t2 := "[6]testdata._Ctype_uchar"
|
||||
v6s := "(len=" + v6Len + " cap=" + v6Cap + ") " +
|
||||
"{\n 00000000 74 65 73 74 36 00 " +
|
||||
" |test6.|\n}"
|
||||
addDumpTest(v6, "("+v6t+") "+v6s+"\n")
|
||||
addDumpTest(v6, "("+v6t+") "+v6s+"\n", "("+v6t2+") "+v6s+"\n")
|
||||
}
|
||||
|
||||
4
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
4
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
@ -182,10 +182,10 @@ func (f *formatState) formatPtr(v reflect.Value) {
|
||||
|
||||
// Display dereferenced value.
|
||||
switch {
|
||||
case nilFound == true:
|
||||
case nilFound:
|
||||
f.fs.Write(nilAngleBytes)
|
||||
|
||||
case cycleFound == true:
|
||||
case cycleFound:
|
||||
f.fs.Write(circularShortBytes)
|
||||
|
||||
default:
|
||||
|
||||
6
vendor/github.com/davecgh/go-spew/spew/format_test.go
generated
vendored
6
vendor/github.com/davecgh/go-spew/spew/format_test.go
generated
vendored
@ -1083,7 +1083,7 @@ func addUintptrFormatterTests() {
|
||||
|
||||
func addUnsafePointerFormatterTests() {
|
||||
// Null pointer.
|
||||
v := unsafe.Pointer(uintptr(0))
|
||||
v := unsafe.Pointer(nil)
|
||||
nv := (*unsafe.Pointer)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
@ -1536,14 +1536,14 @@ func TestPrintSortedKeys(t *testing.T) {
|
||||
t.Errorf("Sorted keys mismatch 3:\n %v %v", s, expected)
|
||||
}
|
||||
|
||||
s = cfg.Sprint(map[testStruct]int{testStruct{1}: 1, testStruct{3}: 3, testStruct{2}: 2})
|
||||
s = cfg.Sprint(map[testStruct]int{{1}: 1, {3}: 3, {2}: 2})
|
||||
expected = "map[ts.1:1 ts.2:2 ts.3:3]"
|
||||
if s != expected {
|
||||
t.Errorf("Sorted keys mismatch 4:\n %v %v", s, expected)
|
||||
}
|
||||
|
||||
if !spew.UnsafeDisabled {
|
||||
s = cfg.Sprint(map[testStructP]int{testStructP{1}: 1, testStructP{3}: 3, testStructP{2}: 2})
|
||||
s = cfg.Sprint(map[testStructP]int{{1}: 1, {3}: 3, {2}: 2})
|
||||
expected = "map[ts.1:1 ts.2:2 ts.3:3]"
|
||||
if s != expected {
|
||||
t.Errorf("Sorted keys mismatch 5:\n %v %v", s, expected)
|
||||
|
||||
5
vendor/github.com/davecgh/go-spew/spew/internal_test.go
generated
vendored
5
vendor/github.com/davecgh/go-spew/spew/internal_test.go
generated
vendored
@ -36,10 +36,7 @@ type dummyFmtState struct {
|
||||
}
|
||||
|
||||
func (dfs *dummyFmtState) Flag(f int) bool {
|
||||
if f == int('+') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return f == int('+')
|
||||
}
|
||||
|
||||
func (dfs *dummyFmtState) Precision() (int, bool) {
|
||||
|
||||
11
vendor/github.com/davecgh/go-spew/spew/internalunsafe_test.go
generated
vendored
11
vendor/github.com/davecgh/go-spew/spew/internalunsafe_test.go
generated
vendored
@ -16,7 +16,7 @@
|
||||
// when the code is not running on Google App Engine, compiled by GopherJS, and
|
||||
// "-tags safe" is not added to the go build command line. The "disableunsafe"
|
||||
// tag is deprecated and thus should not be used.
|
||||
// +build !js,!appengine,!safe,!disableunsafe
|
||||
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
||||
|
||||
/*
|
||||
This test file is part of the spew package rather than than the spew_test
|
||||
@ -30,7 +30,6 @@ import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// changeKind uses unsafe to intentionally change the kind of a reflect.Value to
|
||||
@ -38,13 +37,13 @@ import (
|
||||
// fallback code which punts to the standard fmt library for new types that
|
||||
// might get added to the language.
|
||||
func changeKind(v *reflect.Value, readOnly bool) {
|
||||
rvf := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + offsetFlag))
|
||||
*rvf = *rvf | ((1<<flagKindWidth - 1) << flagKindShift)
|
||||
flags := flagField(v)
|
||||
if readOnly {
|
||||
*rvf |= flagRO
|
||||
*flags |= flagRO
|
||||
} else {
|
||||
*rvf &= ^uintptr(flagRO)
|
||||
*flags &^= flagRO
|
||||
}
|
||||
*flags |= flagKindMask
|
||||
}
|
||||
|
||||
// TestAddedReflectValue tests functionaly of the dump and formatter code which
|
||||
|
||||
2
vendor/github.com/fatih/structs/.travis.yml
generated
vendored
2
vendor/github.com/fatih/structs/.travis.yml
generated
vendored
@ -1,6 +1,8 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- tip
|
||||
sudo: false
|
||||
before_install:
|
||||
|
||||
4
vendor/github.com/fatih/structs/README.md
generated
vendored
4
vendor/github.com/fatih/structs/README.md
generated
vendored
@ -81,8 +81,8 @@ n := s.Names() // Get a []string
|
||||
f := s.Field(name) // Get a *Field based on the given field name
|
||||
f, ok := s.FieldOk(name) // Get a *Field based on the given field name
|
||||
n := s.Name() // Get the struct name
|
||||
h := s.HasZero() // Check if any field is initialized
|
||||
z := s.IsZero() // Check if all fields are initialized
|
||||
h := s.HasZero() // Check if any field is uninitialized
|
||||
z := s.IsZero() // Check if all fields are uninitialized
|
||||
```
|
||||
|
||||
### Field methods
|
||||
|
||||
2
vendor/github.com/fatih/structs/field_test.go
generated
vendored
2
vendor/github.com/fatih/structs/field_test.go
generated
vendored
@ -135,7 +135,7 @@ func TestField_Set(t *testing.T) {
|
||||
|
||||
func TestField_NotSettable(t *testing.T) {
|
||||
a := map[int]Baz{
|
||||
4: Baz{
|
||||
4: {
|
||||
A: "value",
|
||||
},
|
||||
}
|
||||
|
||||
6
vendor/github.com/fatih/structs/structs.go
generated
vendored
6
vendor/github.com/fatih/structs/structs.go
generated
vendored
@ -203,9 +203,7 @@ func (s *Struct) Values() []interface{} {
|
||||
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
|
||||
// look out for embedded structs, and convert them to a
|
||||
// []interface{} to be added to the final values slice
|
||||
for _, embeddedVal := range Values(val.Interface()) {
|
||||
t = append(t, embeddedVal)
|
||||
}
|
||||
t = append(t, Values(val.Interface())...)
|
||||
} else {
|
||||
t = append(t, val.Interface())
|
||||
}
|
||||
@ -573,7 +571,7 @@ func (s *Struct) nested(val reflect.Value) interface{} {
|
||||
break
|
||||
}
|
||||
|
||||
slices := make([]interface{}, val.Len(), val.Len())
|
||||
slices := make([]interface{}, val.Len())
|
||||
for x := 0; x < val.Len(); x++ {
|
||||
slices[x] = s.nested(val.Index(x))
|
||||
}
|
||||
|
||||
2
vendor/github.com/fatih/structs/structs_example_test.go
generated
vendored
2
vendor/github.com/fatih/structs/structs_example_test.go
generated
vendored
@ -301,7 +301,7 @@ func ExampleIsZero() {
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
// Nothing is initalized
|
||||
// Nothing is initialized
|
||||
a := &Server{}
|
||||
isZeroA := IsZero(a)
|
||||
|
||||
|
||||
18
vendor/github.com/fatih/structs/structs_test.go
generated
vendored
18
vendor/github.com/fatih/structs/structs_test.go
generated
vendored
@ -380,7 +380,7 @@ func TestMap_NestedMapWithSliceIntValues(t *testing.T) {
|
||||
|
||||
b := &B{
|
||||
Foo: map[string][]int{
|
||||
"example_key": []int{80},
|
||||
"example_key": {80},
|
||||
},
|
||||
}
|
||||
|
||||
@ -399,7 +399,7 @@ func TestMap_NestedMapWithSliceIntValues(t *testing.T) {
|
||||
|
||||
foo := in["Foo"].(map[string][]int)
|
||||
if name := foo["example_key"]; name[0] != 80 {
|
||||
t.Errorf("Map nested struct's name field should give example, got: %s", name)
|
||||
t.Errorf("Map nested struct's name field should give example, got: %v", name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -418,7 +418,7 @@ func TestMap_NestedMapWithSliceStructValues(t *testing.T) {
|
||||
|
||||
b := &B{
|
||||
Foo: map[string][]address{
|
||||
"example_key": []address{
|
||||
"example_key": {
|
||||
{Country: "Turkey"},
|
||||
},
|
||||
},
|
||||
@ -463,8 +463,8 @@ func TestMap_NestedSliceWithStructValues(t *testing.T) {
|
||||
p := person{
|
||||
Name: "test",
|
||||
Addresses: []address{
|
||||
address{Country: "England"},
|
||||
address{Country: "Italy"},
|
||||
{Country: "England"},
|
||||
{Country: "Italy"},
|
||||
},
|
||||
}
|
||||
mp := Map(p)
|
||||
@ -492,8 +492,8 @@ func TestMap_NestedSliceWithPointerOfStructValues(t *testing.T) {
|
||||
p := person{
|
||||
Name: "test",
|
||||
Addresses: []*address{
|
||||
&address{Country: "England"},
|
||||
&address{Country: "Italy"},
|
||||
{Country: "England"},
|
||||
{Country: "Italy"},
|
||||
},
|
||||
}
|
||||
mp := Map(p)
|
||||
@ -1430,14 +1430,14 @@ func TestPointer2Pointer(t *testing.T) {
|
||||
func TestMap_InterfaceTypeWithMapValue(t *testing.T) {
|
||||
type A struct {
|
||||
Name string `structs:"name"`
|
||||
Ip string `structs:"ip"`
|
||||
IP string `structs:"ip"`
|
||||
Query string `structs:"query"`
|
||||
Payload interface{} `structs:"payload"`
|
||||
}
|
||||
|
||||
a := A{
|
||||
Name: "test",
|
||||
Ip: "127.0.0.1",
|
||||
IP: "127.0.0.1",
|
||||
Query: "",
|
||||
Payload: map[string]string{"test_param": "test_param"},
|
||||
}
|
||||
|
||||
2
vendor/github.com/fatih/structs/tags.go
generated
vendored
2
vendor/github.com/fatih/structs/tags.go
generated
vendored
@ -5,7 +5,7 @@ import "strings"
|
||||
// tagOptions contains a slice of tag options
|
||||
type tagOptions []string
|
||||
|
||||
// Has returns true if the given optiton is available in tagOptions
|
||||
// Has returns true if the given option is available in tagOptions
|
||||
func (t tagOptions) Has(opt string) bool {
|
||||
for _, tagOpt := range t {
|
||||
if tagOpt == opt {
|
||||
|
||||
1
vendor/github.com/google/go-querystring/go.mod
generated
vendored
Normal file
1
vendor/github.com/google/go-querystring/go.mod
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module github.com/google/go-querystring
|
||||
4
vendor/github.com/google/uuid/README.md
generated
vendored
4
vendor/github.com/google/uuid/README.md
generated
vendored
@ -1,7 +1,3 @@
|
||||
**This package is currently in development and the API may not be stable.**
|
||||
|
||||
The API will become stable with v1.
|
||||
|
||||
# uuid 
|
||||
The uuid package generates and inspects UUIDs based on
|
||||
[RFC 4122](http://tools.ietf.org/html/rfc4122)
|
||||
|
||||
4
vendor/github.com/google/uuid/dce.go
generated
vendored
4
vendor/github.com/google/uuid/dce.go
generated
vendored
@ -42,7 +42,7 @@ func NewDCESecurity(domain Domain, id uint32) (UUID, error) {
|
||||
// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
|
||||
// domain with the id returned by os.Getuid.
|
||||
//
|
||||
// NewDCEPerson(Person, uint32(os.Getuid()))
|
||||
// NewDCESecurity(Person, uint32(os.Getuid()))
|
||||
func NewDCEPerson() (UUID, error) {
|
||||
return NewDCESecurity(Person, uint32(os.Getuid()))
|
||||
}
|
||||
@ -50,7 +50,7 @@ func NewDCEPerson() (UUID, error) {
|
||||
// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
|
||||
// domain with the id returned by os.Getgid.
|
||||
//
|
||||
// NewDCEGroup(Group, uint32(os.Getgid()))
|
||||
// NewDCESecurity(Group, uint32(os.Getgid()))
|
||||
func NewDCEGroup() (UUID, error) {
|
||||
return NewDCESecurity(Group, uint32(os.Getgid()))
|
||||
}
|
||||
|
||||
1
vendor/github.com/google/uuid/go.mod
generated
vendored
Normal file
1
vendor/github.com/google/uuid/go.mod
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module github.com/google/uuid
|
||||
2
vendor/github.com/google/uuid/hash.go
generated
vendored
2
vendor/github.com/google/uuid/hash.go
generated
vendored
@ -27,7 +27,7 @@ var (
|
||||
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
|
||||
h.Reset()
|
||||
h.Write(space[:])
|
||||
h.Write([]byte(data))
|
||||
h.Write(data)
|
||||
s := h.Sum(nil)
|
||||
var uuid UUID
|
||||
copy(uuid[:], s)
|
||||
|
||||
2
vendor/github.com/google/uuid/marshal.go
generated
vendored
2
vendor/github.com/google/uuid/marshal.go
generated
vendored
@ -15,8 +15,6 @@ func (uuid UUID) MarshalText() ([]byte, error) {
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (uuid *UUID) UnmarshalText(data []byte) error {
|
||||
// See comment in ParseBytes why we do this.
|
||||
// id, err := ParseBytes(data)
|
||||
id, err := ParseBytes(data)
|
||||
if err == nil {
|
||||
*uuid = id
|
||||
|
||||
22
vendor/github.com/google/uuid/node.go
generated
vendored
22
vendor/github.com/google/uuid/node.go
generated
vendored
@ -5,13 +5,11 @@
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
nodeMu sync.Mutex
|
||||
interfaces []net.Interface // cached list of interfaces
|
||||
ifname string // name of interface being used
|
||||
nodeID [6]byte // hardware for version 1 UUIDs
|
||||
zeroID [6]byte // nodeID with only 0's
|
||||
@ -39,21 +37,12 @@ func SetNodeInterface(name string) bool {
|
||||
}
|
||||
|
||||
func setNodeInterface(name string) bool {
|
||||
if interfaces == nil {
|
||||
var err error
|
||||
interfaces, err = net.Interfaces()
|
||||
if err != nil && name != "" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for _, ifs := range interfaces {
|
||||
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
|
||||
copy(nodeID[:], ifs.HardwareAddr)
|
||||
ifname = ifs.Name
|
||||
iname, addr := getHardwareInterface(name) // null implementation for js
|
||||
if iname != "" && addr != nil {
|
||||
ifname = iname
|
||||
copy(nodeID[:], addr)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// We found no interfaces with a valid hardware address. If name
|
||||
// does not specify a specific interface generate a random Node ID
|
||||
@ -94,9 +83,6 @@ func SetNodeID(id []byte) bool {
|
||||
// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
|
||||
// not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
|
||||
func (uuid UUID) NodeID() []byte {
|
||||
if len(uuid) != 16 {
|
||||
return nil
|
||||
}
|
||||
var node [6]byte
|
||||
copy(node[:], uuid[10:])
|
||||
return node[:]
|
||||
|
||||
12
vendor/github.com/google/uuid/node_js.go
generated
vendored
Normal file
12
vendor/github.com/google/uuid/node_js.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build js
|
||||
|
||||
package uuid
|
||||
|
||||
// getHardwareInterface returns nil values for the JS version of the code.
|
||||
// This remvoves the "net" dependency, because it is not used in the browser.
|
||||
// Using the "net" library inflates the size of the transpiled JS code by 673k bytes.
|
||||
func getHardwareInterface(name string) (string, []byte) { return "", nil }
|
||||
33
vendor/github.com/google/uuid/node_net.go
generated
vendored
Normal file
33
vendor/github.com/google/uuid/node_net.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !js
|
||||
|
||||
package uuid
|
||||
|
||||
import "net"
|
||||
|
||||
var interfaces []net.Interface // cached list of interfaces
|
||||
|
||||
// getHardwareInterface returns the name and hardware address of interface name.
|
||||
// If name is "" then the name and hardware address of one of the system's
|
||||
// interfaces is returned. If no interfaces are found (name does not exist or
|
||||
// there are no interfaces) then "", nil is returned.
|
||||
//
|
||||
// Only addresses of at least 6 bytes are returned.
|
||||
func getHardwareInterface(name string) (string, []byte) {
|
||||
if interfaces == nil {
|
||||
var err error
|
||||
interfaces, err = net.Interfaces()
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
for _, ifs := range interfaces {
|
||||
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
|
||||
return ifs.Name, ifs.HardwareAddr
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
2
vendor/github.com/google/uuid/seq_test.go
generated
vendored
2
vendor/github.com/google/uuid/seq_test.go
generated
vendored
@ -16,7 +16,7 @@ var regressions = flag.Bool("regressions", false, "run uuid regression tests")
|
||||
|
||||
// TestClockSeqRace tests for a particular race condition of returning two
|
||||
// identical Version1 UUIDs. The duration of 1 minute was chosen as the race
|
||||
// condition, before being fixed, nearly always occured in under 30 seconds.
|
||||
// condition, before being fixed, nearly always occurred in under 30 seconds.
|
||||
func TestClockSeqRace(t *testing.T) {
|
||||
if !*regressions {
|
||||
t.Skip("skipping regression tests")
|
||||
|
||||
21
vendor/github.com/google/uuid/sql.go
generated
vendored
21
vendor/github.com/google/uuid/sql.go
generated
vendored
@ -13,35 +13,36 @@ import (
|
||||
// Currently, database types that map to string and []byte are supported. Please
|
||||
// consult database-specific driver documentation for matching types.
|
||||
func (uuid *UUID) Scan(src interface{}) error {
|
||||
switch src.(type) {
|
||||
switch src := src.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
|
||||
case string:
|
||||
// if an empty UUID comes from a table, we return a null UUID
|
||||
if src.(string) == "" {
|
||||
if src == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// see Parse for required string format
|
||||
u, err := Parse(src.(string))
|
||||
|
||||
u, err := Parse(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Scan: %v", err)
|
||||
}
|
||||
|
||||
*uuid = u
|
||||
case []byte:
|
||||
b := src.([]byte)
|
||||
|
||||
case []byte:
|
||||
// if an empty UUID comes from a table, we return a null UUID
|
||||
if len(b) == 0 {
|
||||
if len(src) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// assumes a simple slice of bytes if 16 bytes
|
||||
// otherwise attempts to parse
|
||||
if len(b) != 16 {
|
||||
return uuid.Scan(string(b))
|
||||
if len(src) != 16 {
|
||||
return uuid.Scan(string(src))
|
||||
}
|
||||
copy((*uuid)[:], b)
|
||||
copy((*uuid)[:], src)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
|
||||
|
||||
17
vendor/github.com/google/uuid/sql_test.go
generated
vendored
17
vendor/github.com/google/uuid/sql_test.go
generated
vendored
@ -10,9 +10,9 @@ import (
|
||||
)
|
||||
|
||||
func TestScan(t *testing.T) {
|
||||
var stringTest string = "f47ac10b-58cc-0372-8567-0e02b2c3d479"
|
||||
var badTypeTest int = 6
|
||||
var invalidTest string = "f47ac10b-58cc-0372-8567-0e02b2c3d4"
|
||||
stringTest := "f47ac10b-58cc-0372-8567-0e02b2c3d479"
|
||||
badTypeTest := 6
|
||||
invalidTest := "f47ac10b-58cc-0372-8567-0e02b2c3d4"
|
||||
|
||||
byteTest := make([]byte, 16)
|
||||
byteTestUUID := Must(Parse(stringTest))
|
||||
@ -90,6 +90,17 @@ func TestScan(t *testing.T) {
|
||||
t.Error("UUID was not nil after scanning empty byte slice")
|
||||
}
|
||||
}
|
||||
|
||||
uuid = UUID{}
|
||||
err = (&uuid).Scan(nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, v := range uuid {
|
||||
if v != 0 {
|
||||
t.Error("UUID was not nil after scanning nil")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValue(t *testing.T) {
|
||||
|
||||
6
vendor/github.com/google/uuid/time.go
generated
vendored
6
vendor/github.com/google/uuid/time.go
generated
vendored
@ -86,7 +86,7 @@ func clockSequence() int {
|
||||
return int(clockSeq & 0x3fff)
|
||||
}
|
||||
|
||||
// SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to
|
||||
// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to
|
||||
// -1 causes a new sequence to be generated.
|
||||
func SetClockSequence(seq int) {
|
||||
defer timeMu.Unlock()
|
||||
@ -100,9 +100,9 @@ func setClockSequence(seq int) {
|
||||
randomBits(b[:]) // clock sequence
|
||||
seq = int(b[0])<<8 | int(b[1])
|
||||
}
|
||||
old_seq := clockSeq
|
||||
oldSeq := clockSeq
|
||||
clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant
|
||||
if old_seq != clockSeq {
|
||||
if oldSeq != clockSeq {
|
||||
lasttime = 0
|
||||
}
|
||||
}
|
||||
|
||||
94
vendor/github.com/google/uuid/uuid.go
generated
vendored
94
vendor/github.com/google/uuid/uuid.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Copyright 2018 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@ -35,20 +35,43 @@ const (
|
||||
|
||||
var rander = rand.Reader // random function
|
||||
|
||||
// Parse decodes s into a UUID or returns an error. Both the UUID form of
|
||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded.
|
||||
// Parse decodes s into a UUID or returns an error. Both the standard UUID
|
||||
// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the
|
||||
// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex
|
||||
// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
|
||||
func Parse(s string) (UUID, error) {
|
||||
var uuid UUID
|
||||
if len(s) != 36 {
|
||||
if len(s) != 36+9 {
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(s))
|
||||
}
|
||||
switch len(s) {
|
||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36:
|
||||
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36 + 9:
|
||||
if strings.ToLower(s[:9]) != "urn:uuid:" {
|
||||
return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9])
|
||||
}
|
||||
s = s[9:]
|
||||
|
||||
// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
case 36 + 2:
|
||||
s = s[1:]
|
||||
|
||||
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
case 32:
|
||||
var ok bool
|
||||
for i := range uuid {
|
||||
uuid[i], ok = xtob(s[i*2], s[i*2+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(s))
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
@ -58,11 +81,11 @@ func Parse(s string) (UUID, error) {
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34} {
|
||||
if v, ok := xtob(s[x], s[x+1]); !ok {
|
||||
v, ok := xtob(s[x], s[x+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
} else {
|
||||
uuid[i] = v
|
||||
}
|
||||
uuid[i] = v
|
||||
}
|
||||
return uuid, nil
|
||||
}
|
||||
@ -70,15 +93,29 @@ func Parse(s string) (UUID, error) {
|
||||
// ParseBytes is like Parse, except it parses a byte slice instead of a string.
|
||||
func ParseBytes(b []byte) (UUID, error) {
|
||||
var uuid UUID
|
||||
if len(b) != 36 {
|
||||
if len(b) != 36+9 {
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
|
||||
}
|
||||
switch len(b) {
|
||||
case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) {
|
||||
return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9])
|
||||
}
|
||||
b = b[9:]
|
||||
case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
b = b[1:]
|
||||
case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
var ok bool
|
||||
for i := 0; i < 32; i += 2 {
|
||||
uuid[i/2], ok = xtob(b[i], b[i+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
@ -88,15 +125,32 @@ func ParseBytes(b []byte) (UUID, error) {
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34} {
|
||||
if v, ok := xtob(b[x], b[x+1]); !ok {
|
||||
v, ok := xtob(b[x], b[x+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
} else {
|
||||
}
|
||||
uuid[i] = v
|
||||
}
|
||||
}
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// MustParse is like Parse but panics if the string cannot be parsed.
|
||||
// It simplifies safe initialization of global variables holding compiled UUIDs.
|
||||
func MustParse(s string) UUID {
|
||||
uuid, err := Parse(s)
|
||||
if err != nil {
|
||||
panic(`uuid: Parse(` + s + `): ` + err.Error())
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
// FromBytes creates a new UUID from a byte slice. Returns an error if the slice
|
||||
// does not have a length of 16. The bytes are copied from the slice.
|
||||
func FromBytes(b []byte) (uuid UUID, err error) {
|
||||
err = uuid.UnmarshalBinary(b)
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
// Must returns uuid if err is nil and panics otherwise.
|
||||
func Must(uuid UUID, err error) UUID {
|
||||
if err != nil {
|
||||
@ -123,7 +177,7 @@ func (uuid UUID) URN() string {
|
||||
}
|
||||
|
||||
func encodeHex(dst []byte, uuid UUID) {
|
||||
hex.Encode(dst[:], uuid[:4])
|
||||
hex.Encode(dst, uuid[:4])
|
||||
dst[8] = '-'
|
||||
hex.Encode(dst[9:13], uuid[4:6])
|
||||
dst[13] = '-'
|
||||
@ -176,7 +230,7 @@ func (v Variant) String() string {
|
||||
return fmt.Sprintf("BadVariant%d", int(v))
|
||||
}
|
||||
|
||||
// SetRand sets the random number generator to r, which implents io.Reader.
|
||||
// SetRand sets the random number generator to r, which implements io.Reader.
|
||||
// If r.Read returns an error when the package requests random data then
|
||||
// a panic will be issued.
|
||||
//
|
||||
|
||||
49
vendor/github.com/google/uuid/uuid_test.go
generated
vendored
49
vendor/github.com/google/uuid/uuid_test.go
generated
vendored
@ -8,6 +8,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@ -58,12 +59,22 @@ var tests = []test{
|
||||
{"f47ac10b-58cc-4372-e567-0e02b2c3d479", 4, Future, true},
|
||||
{"f47ac10b-58cc-4372-f567-0e02b2c3d479", 4, Future, true},
|
||||
|
||||
|
||||
{"f47ac10b158cc-5372-a567-0e02b2c3d479", 0, Invalid, false},
|
||||
{"f47ac10b-58cc25372-a567-0e02b2c3d479", 0, Invalid, false},
|
||||
{"f47ac10b-58cc-53723a567-0e02b2c3d479", 0, Invalid, false},
|
||||
{"f47ac10b-58cc-5372-a56740e02b2c3d479", 0, Invalid, false},
|
||||
{"f47ac10b-58cc-5372-a567-0e02-2c3d479", 0, Invalid, false},
|
||||
{"g47ac10b-58cc-4372-a567-0e02b2c3d479", 0, Invalid, false},
|
||||
|
||||
|
||||
{"{f47ac10b-58cc-0372-8567-0e02b2c3d479}", 0, RFC4122, true},
|
||||
{"{f47ac10b-58cc-0372-8567-0e02b2c3d479", 0, Invalid, false},
|
||||
{"f47ac10b-58cc-0372-8567-0e02b2c3d479}", 0, Invalid, false},
|
||||
|
||||
{"f47ac10b58cc037285670e02b2c3d479", 0, RFC4122, true},
|
||||
{"f47ac10b58cc037285670e02b2c3d4790", 0, Invalid, false},
|
||||
{"f47ac10b58cc037285670e02b2c3d47", 0, Invalid, false},
|
||||
}
|
||||
|
||||
var constants = []struct {
|
||||
@ -121,6 +132,25 @@ func TestUUID(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromBytes(t *testing.T) {
|
||||
b := []byte{
|
||||
0x7d, 0x44, 0x48, 0x40,
|
||||
0x9d, 0xc0,
|
||||
0x11, 0xd1,
|
||||
0xb2, 0x45,
|
||||
0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2,
|
||||
}
|
||||
uuid, err := FromBytes(b)
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err)
|
||||
}
|
||||
for i := 0; i < len(uuid); i++ {
|
||||
if b[i] != uuid[i] {
|
||||
t.Fatalf("FromBytes() got %v expected %v\b", uuid[:], b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConstants(t *testing.T) {
|
||||
for x, tt := range constants {
|
||||
v, ok := tt.c.(fmt.Stringer)
|
||||
@ -246,7 +276,7 @@ func TestCoding(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("Parse returned unexpected error %v", err)
|
||||
}
|
||||
if data != data {
|
||||
if data != uuid {
|
||||
t.Errorf("%s: decoded to %s, expected %s", text, uuid, data)
|
||||
}
|
||||
}
|
||||
@ -286,7 +316,7 @@ func TestVersion1(t *testing.T) {
|
||||
case t1 > t2 && q1 == q2:
|
||||
t.Error("time reversed")
|
||||
case t1 < t2 && q1 != q2:
|
||||
t.Error("clock sequence chaned unexpectedly")
|
||||
t.Error("clock sequence changed unexpectedly")
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,9 +332,11 @@ func TestNode(t *testing.T) {
|
||||
if !SetNodeInterface("") {
|
||||
t.Error("SetNodeInterface failed")
|
||||
}
|
||||
if runtime.GOARCH != "js" {
|
||||
if ni := NodeInterface(); ni == "" {
|
||||
t.Error("NodeInterface returned an empty string")
|
||||
}
|
||||
}
|
||||
|
||||
ni := NodeID()
|
||||
if len(ni) != 6 {
|
||||
@ -328,7 +360,7 @@ func TestNode(t *testing.T) {
|
||||
}
|
||||
|
||||
if ni := NodeInterface(); ni != "user" {
|
||||
t.Errorf("got inteface %q, want %q", ni, "user")
|
||||
t.Errorf("got interface %q, want %q", ni, "user")
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,8 +404,10 @@ func TestNodeID(t *testing.T) {
|
||||
nid := []byte{1, 2, 3, 4, 5, 6}
|
||||
SetNodeInterface("")
|
||||
s := NodeInterface()
|
||||
if runtime.GOARCH != "js" {
|
||||
if s == "" || s == "user" {
|
||||
t.Errorf("NodeInterface %q after SetInteface", s)
|
||||
t.Errorf("NodeInterface %q after SetInterface", s)
|
||||
}
|
||||
}
|
||||
node1 := NodeID()
|
||||
if node1 == nil {
|
||||
@ -424,7 +458,7 @@ func TestDCE(t *testing.T) {
|
||||
type badRand struct{}
|
||||
|
||||
func (r badRand) Read(buf []byte) (int, error) {
|
||||
for i, _ := range buf {
|
||||
for i := range buf {
|
||||
buf[i] = byte(i)
|
||||
}
|
||||
return len(buf), nil
|
||||
@ -435,13 +469,13 @@ func TestBadRand(t *testing.T) {
|
||||
uuid1 := New()
|
||||
uuid2 := New()
|
||||
if uuid1 != uuid2 {
|
||||
t.Errorf("execpted duplicates, got %q and %q", uuid1, uuid2)
|
||||
t.Errorf("expected duplicates, got %q and %q", uuid1, uuid2)
|
||||
}
|
||||
SetRand(nil)
|
||||
uuid1 = New()
|
||||
uuid2 = New()
|
||||
if uuid1 == uuid2 {
|
||||
t.Errorf("unexecpted duplicates, got %q", uuid1)
|
||||
t.Errorf("unexpected duplicates, got %q", uuid1)
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,7 +505,6 @@ func parseBytesUnsafe(b []byte) (UUID, error) {
|
||||
return Parse(*(*string)(unsafe.Pointer(&b)))
|
||||
}
|
||||
|
||||
|
||||
func BenchmarkParseBytesUnsafe(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := parseBytesUnsafe(asBytes)
|
||||
|
||||
2
vendor/github.com/google/uuid/version1.go
generated
vendored
2
vendor/github.com/google/uuid/version1.go
generated
vendored
@ -13,7 +13,7 @@ import (
|
||||
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
|
||||
// be set NewUUID returns nil. If clock sequence has not been set by
|
||||
// SetClockSequence then it will be set automatically. If GetTime fails to
|
||||
// return the current NewUUID returns Nil and an error.
|
||||
// return the current NewUUID returns nil and an error.
|
||||
//
|
||||
// In most cases, New should be used.
|
||||
func NewUUID() (UUID, error) {
|
||||
|
||||
6
vendor/github.com/google/uuid/version4.go
generated
vendored
6
vendor/github.com/google/uuid/version4.go
generated
vendored
@ -6,7 +6,7 @@ package uuid
|
||||
|
||||
import "io"
|
||||
|
||||
// New is creates a new random UUID or panics. New is equivalent to
|
||||
// New creates a new random UUID or panics. New is equivalent to
|
||||
// the expression
|
||||
//
|
||||
// uuid.Must(uuid.NewRandom())
|
||||
@ -14,12 +14,12 @@ func New() UUID {
|
||||
return Must(NewRandom())
|
||||
}
|
||||
|
||||
// NewRandom returns a Random (Version 4) UUID or panics.
|
||||
// NewRandom returns a Random (Version 4) UUID.
|
||||
//
|
||||
// The strength of the UUIDs is based on the strength of the crypto/rand
|
||||
// package.
|
||||
//
|
||||
// A note about uniqueness derived from from the UUID Wikipedia entry:
|
||||
// A note about uniqueness derived from the UUID Wikipedia entry:
|
||||
//
|
||||
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
|
||||
// hit by a meteorite is estimated to be one chance in 17 billion, that
|
||||
|
||||
18
vendor/github.com/julienschmidt/httprouter/.travis.yml
generated
vendored
18
vendor/github.com/julienschmidt/httprouter/.travis.yml
generated
vendored
@ -1,8 +1,18 @@
|
||||
sudo: false
|
||||
language: go
|
||||
go:
|
||||
- 1.1
|
||||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.7
|
||||
- 1.8
|
||||
- 1.9
|
||||
- "1.10"
|
||||
- tip
|
||||
before_install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get github.com/golang/lint/golint
|
||||
script:
|
||||
- go test -v -covermode=count -coverprofile=coverage.out
|
||||
- go vet ./...
|
||||
- test -z "$(gofmt -d -s . | tee /dev/stderr)"
|
||||
- test -z "$(golint ./... | tee /dev/stderr)"
|
||||
- $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci
|
||||
|
||||
185
vendor/github.com/julienschmidt/httprouter/README.md
generated
vendored
185
vendor/github.com/julienschmidt/httprouter/README.md
generated
vendored
@ -1,58 +1,37 @@
|
||||
# HttpRouter [](https://travis-ci.org/julienschmidt/httprouter) [](http://gocover.io/github.com/julienschmidt/httprouter) [](http://godoc.org/github.com/julienschmidt/httprouter)
|
||||
# HttpRouter [](https://travis-ci.org/julienschmidt/httprouter) [](https://coveralls.io/github/julienschmidt/httprouter?branch=master) [](http://godoc.org/github.com/julienschmidt/httprouter)
|
||||
|
||||
HttpRouter is a lightweight high performance HTTP request router
|
||||
(also called *multiplexer* or just *mux* for short) for [Go](http://golang.org/).
|
||||
HttpRouter is a lightweight high performance HTTP request router (also called *multiplexer* or just *mux* for short) for [Go](https://golang.org/).
|
||||
|
||||
In contrast to the [default mux](http://golang.org/pkg/net/http/#ServeMux) of Go's net/http package, this router supports
|
||||
variables in the routing pattern and matches against the request method.
|
||||
It also scales better.
|
||||
In contrast to the [default mux](https://golang.org/pkg/net/http/#ServeMux) of Go's `net/http` package, this router supports variables in the routing pattern and matches against the request method. It also scales better.
|
||||
|
||||
The router is optimized for high performance and a small memory footprint.
|
||||
It scales well even with very long paths and a large number of routes.
|
||||
A compressing dynamic trie (radix tree) structure is used for efficient matching.
|
||||
The router is optimized for high performance and a small memory footprint. It scales well even with very long paths and a large number of routes. A compressing dynamic trie (radix tree) structure is used for efficient matching.
|
||||
|
||||
## Features
|
||||
**Only explicit matches:** With other routers, like [http.ServeMux](http://golang.org/pkg/net/http/#ServeMux),
|
||||
a requested URL path could match multiple patterns. Therefore they have some
|
||||
awkward pattern priority rules, like *longest match* or *first registered,
|
||||
first matched*. By design of this router, a request can only match exactly one
|
||||
or no route. As a result, there are also no unintended matches, which makes it
|
||||
great for SEO and improves the user experience.
|
||||
|
||||
**Stop caring about trailing slashes:** Choose the URL style you like, the
|
||||
router automatically redirects the client if a trailing slash is missing or if
|
||||
there is one extra. Of course it only does so, if the new path has a handler.
|
||||
If you don't like it, you can [turn off this behavior](http://godoc.org/github.com/julienschmidt/httprouter#Router.RedirectTrailingSlash).
|
||||
**Only explicit matches:** With other routers, like [`http.ServeMux`](https://golang.org/pkg/net/http/#ServeMux), a requested URL path could match multiple patterns. Therefore they have some awkward pattern priority rules, like *longest match* or *first registered, first matched*. By design of this router, a request can only match exactly one or no route. As a result, there are also no unintended matches, which makes it great for SEO and improves the user experience.
|
||||
|
||||
**Path auto-correction:** Besides detecting the missing or additional trailing
|
||||
slash at no extra cost, the router can also fix wrong cases and remove
|
||||
superfluous path elements (like `../` or `//`).
|
||||
Is [CAPTAIN CAPS LOCK](http://www.urbandictionary.com/define.php?term=Captain+Caps+Lock) one of your users?
|
||||
HttpRouter can help him by making a case-insensitive look-up and redirecting him
|
||||
to the correct URL.
|
||||
**Stop caring about trailing slashes:** Choose the URL style you like, the router automatically redirects the client if a trailing slash is missing or if there is one extra. Of course it only does so, if the new path has a handler. If you don't like it, you can [turn off this behavior](https://godoc.org/github.com/julienschmidt/httprouter#Router.RedirectTrailingSlash).
|
||||
|
||||
**Parameters in your routing pattern:** Stop parsing the requested URL path,
|
||||
just give the path segment a name and the router delivers the dynamic value to
|
||||
you. Because of the design of the router, path parameters are very cheap.
|
||||
**Path auto-correction:** Besides detecting the missing or additional trailing slash at no extra cost, the router can also fix wrong cases and remove superfluous path elements (like `../` or `//`). Is [CAPTAIN CAPS LOCK](http://www.urbandictionary.com/define.php?term=Captain+Caps+Lock) one of your users? HttpRouter can help him by making a case-insensitive look-up and redirecting him to the correct URL.
|
||||
|
||||
**Zero Garbage:** The matching and dispatching process generates zero bytes of
|
||||
garbage. In fact, the only heap allocations that are made, is by building the
|
||||
slice of the key-value pairs for path parameters. If the request path contains
|
||||
no parameters, not a single heap allocation is necessary.
|
||||
**Parameters in your routing pattern:** Stop parsing the requested URL path, just give the path segment a name and the router delivers the dynamic value to you. Because of the design of the router, path parameters are very cheap.
|
||||
|
||||
**Best Performance:** [Benchmarks speak for themselves](https://github.com/julienschmidt/go-http-routing-benchmark).
|
||||
See below for technical details of the implementation.
|
||||
**Zero Garbage:** The matching and dispatching process generates zero bytes of garbage. The only heap allocations that are made are building the slice of the key-value pairs for path parameters, and building new context and request objects (the latter only in the standard `Handler`/`HandlerFunc` api). In the 3-argument API, if the request path contains no parameters not a single heap allocation is necessary.
|
||||
|
||||
**No more server crashes:** You can set a [Panic handler](http://godoc.org/github.com/julienschmidt/httprouter#Router.PanicHandler) to deal with panics
|
||||
occurring during handling a HTTP request. The router then recovers and lets the
|
||||
PanicHandler log what happened and deliver a nice error page.
|
||||
**Best Performance:** [Benchmarks speak for themselves](https://github.com/julienschmidt/go-http-routing-benchmark). See below for technical details of the implementation.
|
||||
|
||||
Of course you can also set **custom [NotFound](http://godoc.org/github.com/julienschmidt/httprouter#Router.NotFound) and [MethodNotAllowed](http://godoc.org/github.com/julienschmidt/httprouter#Router.MethodNotAllowed) handlers** and [**serve static files**](http://godoc.org/github.com/julienschmidt/httprouter#Router.ServeFiles).
|
||||
**No more server crashes:** You can set a [Panic handler](https://godoc.org/github.com/julienschmidt/httprouter#Router.PanicHandler) to deal with panics occurring during handling a HTTP request. The router then recovers and lets the `PanicHandler` log what happened and deliver a nice error page.
|
||||
|
||||
**Perfect for APIs:** The router design encourages to build sensible, hierarchical RESTful APIs. Moreover it has builtin native support for [OPTIONS requests](http://zacstewart.com/2012/04/14/http-options-method.html) and `405 Method Not Allowed` replies.
|
||||
|
||||
Of course you can also set **custom [`NotFound`](https://godoc.org/github.com/julienschmidt/httprouter#Router.NotFound) and [`MethodNotAllowed`](https://godoc.org/github.com/julienschmidt/httprouter#Router.MethodNotAllowed) handlers** and [**serve static files**](https://godoc.org/github.com/julienschmidt/httprouter#Router.ServeFiles).
|
||||
|
||||
## Usage
|
||||
|
||||
This is just a quick introduction, view the [GoDoc](http://godoc.org/github.com/julienschmidt/httprouter) for details.
|
||||
|
||||
Let's start with a trivial example:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@ -81,12 +60,11 @@ func main() {
|
||||
```
|
||||
|
||||
### Named parameters
|
||||
As you can see, `:name` is a *named parameter*.
|
||||
The values are accessible via `httprouter.Params`, which is just a slice of `httprouter.Param`s.
|
||||
You can get the value of a parameter either by its index in the slice, or by using the `ByName(name)` method:
|
||||
`:name` can be retrived by `ByName("name")`.
|
||||
|
||||
As you can see, `:name` is a *named parameter*. The values are accessible via `httprouter.Params`, which is just a slice of `httprouter.Param`s. You can get the value of a parameter either by its index in the slice, or by using the `ByName(name)` method: `:name` can be retrived by `ByName("name")`.
|
||||
|
||||
Named parameters only match a single path segment:
|
||||
|
||||
```
|
||||
Pattern: /user/:user
|
||||
|
||||
@ -99,9 +77,9 @@ Pattern: /user/:user
|
||||
**Note:** Since this router has only explicit matches, you can not register static routes and parameters for the same path segment. For example you can not register the patterns `/user/new` and `/user/:user` for the same request method at the same time. The routing of different request methods is independent from each other.
|
||||
|
||||
### Catch-All parameters
|
||||
The second type are *catch-all* parameters and have the form `*name`.
|
||||
Like the name suggests, they match everything.
|
||||
Therefore they must always be at the **end** of the pattern:
|
||||
|
||||
The second type are *catch-all* parameters and have the form `*name`. Like the name suggests, they match everything. Therefore they must always be at the **end** of the pattern:
|
||||
|
||||
```
|
||||
Pattern: /src/*filepath
|
||||
|
||||
@ -111,11 +89,8 @@ Pattern: /src/*filepath
|
||||
```
|
||||
|
||||
## How does it work?
|
||||
The router relies on a tree structure which makes heavy use of *common prefixes*,
|
||||
it is basically a *compact* [*prefix tree*](http://en.wikipedia.org/wiki/Trie)
|
||||
(or just [*Radix tree*](http://en.wikipedia.org/wiki/Radix_tree)).
|
||||
Nodes with a common prefix also share a common parent. Here is a short example
|
||||
what the routing tree for the `GET` request method could look like:
|
||||
|
||||
The router relies on a tree structure which makes heavy use of *common prefixes*, it is basically a *compact* [*prefix tree*](https://en.wikipedia.org/wiki/Trie) (or just [*Radix tree*](https://en.wikipedia.org/wiki/Radix_tree)). Nodes with a common prefix also share a common parent. Here is a short example what the routing tree for the `GET` request method could look like:
|
||||
|
||||
```
|
||||
Priority Path Handle
|
||||
@ -130,33 +105,15 @@ Priority Path Handle
|
||||
1 | └team\ *<7>
|
||||
1 └contact\ *<8>
|
||||
```
|
||||
Every `*<num>` represents the memory address of a handler function (a pointer).
|
||||
If you follow a path trough the tree from the root to the leaf, you get the
|
||||
complete route path, e.g `\blog\:post\`, where `:post` is just a placeholder
|
||||
([*parameter*](#named-parameters)) for an actual post name. Unlike hash-maps, a
|
||||
tree structure also allows us to use dynamic parts like the `:post` parameter,
|
||||
since we actually match against the routing patterns instead of just comparing
|
||||
hashes. [As benchmarks show](https://github.com/julienschmidt/go-http-routing-benchmark),
|
||||
this works very well and efficient.
|
||||
|
||||
Since URL paths have a hierarchical structure and make use only of a limited set
|
||||
of characters (byte values), it is very likely that there are a lot of common
|
||||
prefixes. This allows us to easily reduce the routing into ever smaller problems.
|
||||
Moreover the router manages a separate tree for every request method.
|
||||
For one thing it is more space efficient than holding a method->handle map in
|
||||
every single node, for another thing is also allows us to greatly reduce the
|
||||
routing problem before even starting the look-up in the prefix-tree.
|
||||
Every `*<num>` represents the memory address of a handler function (a pointer). If you follow a path trough the tree from the root to the leaf, you get the complete route path, e.g `\blog\:post\`, where `:post` is just a placeholder ([*parameter*](#named-parameters)) for an actual post name. Unlike hash-maps, a tree structure also allows us to use dynamic parts like the `:post` parameter, since we actually match against the routing patterns instead of just comparing hashes. [As benchmarks show](https://github.com/julienschmidt/go-http-routing-benchmark), this works very well and efficient.
|
||||
|
||||
For even better scalability, the child nodes on each tree level are ordered by
|
||||
priority, where the priority is just the number of handles registered in sub
|
||||
nodes (children, grandchildren, and so on..).
|
||||
This helps in two ways:
|
||||
Since URL paths have a hierarchical structure and make use only of a limited set of characters (byte values), it is very likely that there are a lot of common prefixes. This allows us to easily reduce the routing into ever smaller problems. Moreover the router manages a separate tree for every request method. For one thing it is more space efficient than holding a method->handle map in every single node, it also allows us to greatly reduce the routing problem before even starting the look-up in the prefix-tree.
|
||||
|
||||
1. Nodes which are part of the most routing paths are evaluated first. This
|
||||
helps to make as much routes as possible to be reachable as fast as possible.
|
||||
2. It is some sort of cost compensation. The longest reachable path (highest
|
||||
cost) can always be evaluated first. The following scheme visualizes the tree
|
||||
structure. Nodes are evaluated from top to bottom and from left to right.
|
||||
For even better scalability, the child nodes on each tree level are ordered by priority, where the priority is just the number of handles registered in sub nodes (children, grandchildren, and so on..). This helps in two ways:
|
||||
|
||||
1. Nodes which are part of the most routing paths are evaluated first. This helps to make as much routes as possible to be reachable as fast as possible.
|
||||
2. It is some sort of cost compensation. The longest reachable path (highest cost) can always be evaluated first. The following scheme visualizes the tree structure. Nodes are evaluated from top to bottom and from left to right.
|
||||
|
||||
```
|
||||
├------------
|
||||
@ -168,47 +125,38 @@ structure. Nodes are evaluated from top to bottom and from left to right.
|
||||
└-
|
||||
```
|
||||
|
||||
## Why doesn't this work with `http.Handler`?
|
||||
|
||||
## Why doesn't this work with http.Handler?
|
||||
**It does!** The router itself implements the http.Handler interface.
|
||||
Moreover the router provides convenient [adapters for http.Handler](http://godoc.org/github.com/julienschmidt/httprouter#Router.Handler)s and [http.HandlerFunc](http://godoc.org/github.com/julienschmidt/httprouter#Router.HandlerFunc)s
|
||||
which allows them to be used as a [httprouter.Handle](http://godoc.org/github.com/julienschmidt/httprouter#Router.Handle) when registering a route.
|
||||
The only disadvantage is, that no parameter values can be retrieved when a
|
||||
http.Handler or http.HandlerFunc is used, since there is no efficient way to
|
||||
pass the values with the existing function parameters.
|
||||
Therefore [httprouter.Handle](http://godoc.org/github.com/julienschmidt/httprouter#Router.Handle) has a third function parameter.
|
||||
**It does!** The router itself implements the `http.Handler` interface. Moreover the router provides convenient [adapters for `http.Handler`](https://godoc.org/github.com/julienschmidt/httprouter#Router.Handler)s and [`http.HandlerFunc`](https://godoc.org/github.com/julienschmidt/httprouter#Router.HandlerFunc)s which allows them to be used as a [`httprouter.Handle`](https://godoc.org/github.com/julienschmidt/httprouter#Router.Handle) when registering a route. The only disadvantage is, that no parameter values can be retrieved when a `http.Handler` or `http.HandlerFunc` is used, since there is no efficient way to pass the values with the existing function parameters. Therefore [`httprouter.Handle`](https://godoc.org/github.com/julienschmidt/httprouter#Router.Handle) has a third function parameter.
|
||||
|
||||
Just try it out for yourself, the usage of HttpRouter is very straightforward. The package is compact and minimalistic, but also probably one of the easiest routers to set up.
|
||||
|
||||
|
||||
## Where can I find Middleware *X*?
|
||||
This package just provides a very efficient request router with a few extra
|
||||
features. The router is just a [http.Handler](http://golang.org/pkg/net/http/#Handler),
|
||||
you can chain any http.Handler compatible middleware before the router,
|
||||
for example the [Gorilla handlers](http://www.gorillatoolkit.org/pkg/handlers).
|
||||
Or you could [just write your own](http://justinas.org/writing-http-middleware-in-go/),
|
||||
it's very easy!
|
||||
|
||||
This package just provides a very efficient request router with a few extra features. The router is just a [`http.Handler`](https://golang.org/pkg/net/http/#Handler), you can chain any http.Handler compatible middleware before the router, for example the [Gorilla handlers](http://www.gorillatoolkit.org/pkg/handlers). Or you could [just write your own](https://justinas.org/writing-http-middleware-in-go/), it's very easy!
|
||||
|
||||
Alternatively, you could try [a web framework based on HttpRouter](#web-frameworks-based-on-httprouter).
|
||||
|
||||
### Multi-domain / Sub-domains
|
||||
|
||||
Here is a quick example: Does your server serve multiple domains / hosts?
|
||||
You want to use sub-domains?
|
||||
Define a router per host!
|
||||
|
||||
```go
|
||||
// We need an object that implements the http.Handler interface.
|
||||
// Therefore we need a type for which we implement the ServeHTTP method.
|
||||
// We just use a map here, in which we map host names (with port) to http.Handlers
|
||||
type HostSwitch map[string]http.Handler
|
||||
|
||||
// Implement the ServerHTTP method on our new type
|
||||
// Implement the ServeHTTP method on our new type
|
||||
func (hs HostSwitch) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Check if a http.Handler is registered for the given host.
|
||||
// If yes, use it to handle the request.
|
||||
if handler := hs[r.Host]; handler != nil {
|
||||
handler.ServeHTTP(w, r)
|
||||
} else {
|
||||
// Handle host names for wich no handler is registered
|
||||
// Handle host names for which no handler is registered
|
||||
http.Error(w, "Forbidden", 403) // Or Redirect?
|
||||
}
|
||||
}
|
||||
@ -230,48 +178,35 @@ func main() {
|
||||
```
|
||||
|
||||
### Basic Authentication
|
||||
Another quick example: Basic Authentification (RFC 2617) for handles:
|
||||
|
||||
Another quick example: Basic Authentication (RFC 2617) for handles:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"net/http"
|
||||
"log"
|
||||
"strings"
|
||||
"net/http"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
func BasicAuth(h httprouter.Handle, user, pass []byte) httprouter.Handle {
|
||||
func BasicAuth(h httprouter.Handle, requiredUser, requiredPassword string) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
const basicAuthPrefix string = "Basic "
|
||||
|
||||
// Get the Basic Authentication credentials
|
||||
auth := r.Header.Get("Authorization")
|
||||
if strings.HasPrefix(auth, basicAuthPrefix) {
|
||||
// Check credentials
|
||||
payload, err := base64.StdEncoding.DecodeString(auth[len(basicAuthPrefix):])
|
||||
if err == nil {
|
||||
pair := bytes.SplitN(payload, []byte(":"), 2)
|
||||
if len(pair) == 2 &&
|
||||
bytes.Equal(pair[0], user) &&
|
||||
bytes.Equal(pair[1], pass) {
|
||||
user, password, hasAuth := r.BasicAuth()
|
||||
|
||||
if hasAuth && user == requiredUser && password == requiredPassword {
|
||||
// Delegate request to the given handle
|
||||
h(w, r, ps)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Request Basic Authentication otherwise
|
||||
w.Header().Set("WWW-Authenticate", "Basic realm=Restricted")
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||
fmt.Fprint(w, "Not protected!\n")
|
||||
@ -282,8 +217,8 @@ func Protected(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
user := []byte("gordon")
|
||||
pass := []byte("secret!")
|
||||
user := "gordon"
|
||||
pass := "secret!"
|
||||
|
||||
router := httprouter.New()
|
||||
router.GET("/", Index)
|
||||
@ -295,29 +230,37 @@ func main() {
|
||||
|
||||
## Chaining with the NotFound handler
|
||||
|
||||
**NOTE: It might be required to set [Router.HandleMethodNotAllowed](http://godoc.org/github.com/julienschmidt/httprouter#Router.HandleMethodNotAllowed) to `false` to avoid problems.**
|
||||
**NOTE: It might be required to set [`Router.HandleMethodNotAllowed`](https://godoc.org/github.com/julienschmidt/httprouter#Router.HandleMethodNotAllowed) to `false` to avoid problems.**
|
||||
|
||||
You can use another [http.HandlerFunc](http://golang.org/pkg/net/http/#HandlerFunc), for example another router, to handle requests which could not be matched by this router by using the [Router.NotFound](http://godoc.org/github.com/julienschmidt/httprouter#Router.NotFound) handler. This allows chaining.
|
||||
You can use another [`http.Handler`](https://golang.org/pkg/net/http/#Handler), for example another router, to handle requests which could not be matched by this router by using the [`Router.NotFound`](https://godoc.org/github.com/julienschmidt/httprouter#Router.NotFound) handler. This allows chaining.
|
||||
|
||||
### Static files
|
||||
The `NotFound` handler can for example be used to serve static files from the root path `/` (like an index.html file along with other assets):
|
||||
|
||||
The `NotFound` handler can for example be used to serve static files from the root path `/` (like an `index.html` file along with other assets):
|
||||
|
||||
```go
|
||||
// Serve static files from the ./public directory
|
||||
router.NotFound = http.FileServer(http.Dir("public")).ServeHTTP
|
||||
router.NotFound = http.FileServer(http.Dir("public"))
|
||||
```
|
||||
|
||||
But this approach sidesteps the strict core rules of this router to avoid routing problems. A cleaner approach is to use a distinct sub-path for serving files, like `/static/*filepath` or `/files/*filepath`.
|
||||
|
||||
## Web Frameworks based on HttpRouter
|
||||
|
||||
If the HttpRouter is a bit too minimalistic for you, you might try one of the following more high-level 3rd-party web frameworks building upon the HttpRouter package:
|
||||
|
||||
* [Ace](https://github.com/plimble/ace): Blazing fast Go Web Framework
|
||||
* [api2go](https://github.com/univedo/api2go): A JSON API Implementation for Go
|
||||
* [api2go](https://github.com/manyminds/api2go): A JSON API Implementation for Go
|
||||
* [Gin](https://github.com/gin-gonic/gin): Features a martini-like API with much better performance
|
||||
* [Goat](https://github.com/bahlo/goat): A minimalistic REST API server in Go
|
||||
* [goMiddlewareChain](https://github.com/TobiEiss/goMiddlewareChain): An express.js-like-middleware-chain
|
||||
* [Hikaru](https://github.com/najeira/hikaru): Supports standalone and Google AppEngine
|
||||
* [Hitch](https://github.com/nbio/hitch): Hitch ties httprouter, [httpcontext](https://github.com/nbio/httpcontext), and middleware up in a bow
|
||||
* [httpway](https://github.com/corneldamian/httpway): Simple middleware extension with context for httprouter and a server with gracefully shutdown support
|
||||
* [kami](https://github.com/guregu/kami): A tiny web framework using x/net/context
|
||||
* [Medeina](https://github.com/imdario/medeina): Inspired by Ruby's Roda and Cuba
|
||||
* [Neko](https://github.com/rocwong/neko): A lightweight web application framework for Golang
|
||||
* [River](https://github.com/abiosoft/river): River is a simple and lightweight REST server
|
||||
* [Roxanna](https://github.com/iamthemuffinman/Roxanna): An amalgamation of httprouter, better logging, and hot reload
|
||||
* [siesta](https://github.com/VividCortex/siesta): Composable HTTP handlers with contexts
|
||||
* [xmux](https://github.com/rs/xmux): xmux is a httprouter fork on top of xhandler (net/context aware)
|
||||
|
||||
38
vendor/github.com/julienschmidt/httprouter/params_go17.go
generated
vendored
Normal file
38
vendor/github.com/julienschmidt/httprouter/params_go17.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
// +build go1.7
|
||||
|
||||
package httprouter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type paramsKey struct{}
|
||||
|
||||
// ParamsKey is the request context key under which URL params are stored.
|
||||
//
|
||||
// This is only present from go 1.7.
|
||||
var ParamsKey = paramsKey{}
|
||||
|
||||
// Handler is an adapter which allows the usage of an http.Handler as a
|
||||
// request handle. With go 1.7+, the Params will be available in the
|
||||
// request context under ParamsKey.
|
||||
func (r *Router) Handler(method, path string, handler http.Handler) {
|
||||
r.Handle(method, path,
|
||||
func(w http.ResponseWriter, req *http.Request, p Params) {
|
||||
ctx := req.Context()
|
||||
ctx = context.WithValue(ctx, ParamsKey, p)
|
||||
req = req.WithContext(ctx)
|
||||
handler.ServeHTTP(w, req)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// ParamsFromContext pulls the URL parameters from a request context,
|
||||
// or returns nil if none are present.
|
||||
//
|
||||
// This is only present from go 1.7.
|
||||
func ParamsFromContext(ctx context.Context) Params {
|
||||
p, _ := ctx.Value(ParamsKey).(Params)
|
||||
return p
|
||||
}
|
||||
16
vendor/github.com/julienschmidt/httprouter/params_legacy.go
generated
vendored
Normal file
16
vendor/github.com/julienschmidt/httprouter/params_legacy.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// +build !go1.7
|
||||
|
||||
package httprouter
|
||||
|
||||
import "net/http"
|
||||
|
||||
// Handler is an adapter which allows the usage of an http.Handler as a
|
||||
// request handle. With go 1.7+, the Params will be available in the
|
||||
// request context under ParamsKey.
|
||||
func (r *Router) Handler(method, path string, handler http.Handler) {
|
||||
r.Handle(method, path,
|
||||
func(w http.ResponseWriter, req *http.Request, _ Params) {
|
||||
handler.ServeHTTP(w, req)
|
||||
},
|
||||
)
|
||||
}
|
||||
6
vendor/github.com/julienschmidt/httprouter/path.go
generated
vendored
6
vendor/github.com/julienschmidt/httprouter/path.go
generated
vendored
@ -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
|
||||
|
||||
1
vendor/github.com/julienschmidt/httprouter/path_test.go
generated
vendored
1
vendor/github.com/julienschmidt/httprouter/path_test.go
generated
vendored
@ -22,6 +22,7 @@ var cleanTests = []struct {
|
||||
|
||||
// missing root
|
||||
{"", "/"},
|
||||
{"a/", "/a/"},
|
||||
{"abc", "/abc"},
|
||||
{"abc/def", "/abc/def"},
|
||||
{"a/b/c", "/a/b/c"},
|
||||
|
||||
90
vendor/github.com/julienschmidt/httprouter/router.go
generated
vendored
90
vendor/github.com/julienschmidt/httprouter/router.go
generated
vendored
@ -55,7 +55,7 @@
|
||||
//
|
||||
// Catch-all parameters match anything until the path end, including the
|
||||
// directory index (the '/' before the catch-all). Since they match anything
|
||||
// until the end, catch-all paramerters must always be the final path element.
|
||||
// until the end, catch-all parameters must always be the final path element.
|
||||
// Path: /files/*filepath
|
||||
//
|
||||
// Requests:
|
||||
@ -138,14 +138,20 @@ type Router struct {
|
||||
// handler.
|
||||
HandleMethodNotAllowed bool
|
||||
|
||||
// Configurable http.HandlerFunc which is called when no matching route is
|
||||
// found. If it is not set, http.NotFound is used.
|
||||
NotFound http.HandlerFunc
|
||||
// If enabled, the router automatically replies to OPTIONS requests.
|
||||
// Custom OPTIONS handlers take priority over automatic replies.
|
||||
HandleOPTIONS bool
|
||||
|
||||
// Configurable http.HandlerFunc which is called when a request
|
||||
// Configurable http.Handler which is called when no matching route is
|
||||
// found. If it is not set, http.NotFound is used.
|
||||
NotFound http.Handler
|
||||
|
||||
// Configurable http.Handler which is called when a request
|
||||
// cannot be routed and HandleMethodNotAllowed is true.
|
||||
// If it is not set, http.Error with http.StatusMethodNotAllowed is used.
|
||||
MethodNotAllowed http.HandlerFunc
|
||||
// The "Allow" header with allowed request methods is set before the handler
|
||||
// is called.
|
||||
MethodNotAllowed http.Handler
|
||||
|
||||
// Function to handle panics recovered from http handlers.
|
||||
// It should be used to generate a error page and return the http error code
|
||||
@ -165,6 +171,7 @@ func New() *Router {
|
||||
RedirectTrailingSlash: true,
|
||||
RedirectFixedPath: true,
|
||||
HandleMethodNotAllowed: true,
|
||||
HandleOPTIONS: true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,16 +236,6 @@ func (r *Router) Handle(method, path string, handle Handle) {
|
||||
root.addRoute(path, handle)
|
||||
}
|
||||
|
||||
// Handler is an adapter which allows the usage of an http.Handler as a
|
||||
// request handle.
|
||||
func (r *Router) Handler(method, path string, handler http.Handler) {
|
||||
r.Handle(method, path,
|
||||
func(w http.ResponseWriter, req *http.Request, _ Params) {
|
||||
handler.ServeHTTP(w, req)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// HandlerFunc is an adapter which allows the usage of an http.HandlerFunc as a
|
||||
// request handle.
|
||||
func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc) {
|
||||
@ -286,15 +283,53 @@ func (r *Router) Lookup(method, path string) (Handle, Params, bool) {
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
func (r *Router) allowed(path, reqMethod string) (allow string) {
|
||||
if path == "*" { // server-wide
|
||||
for method := range r.trees {
|
||||
if method == "OPTIONS" {
|
||||
continue
|
||||
}
|
||||
|
||||
// add request method to list of allowed methods
|
||||
if len(allow) == 0 {
|
||||
allow = method
|
||||
} else {
|
||||
allow += ", " + method
|
||||
}
|
||||
}
|
||||
} else { // specific path
|
||||
for method := range r.trees {
|
||||
// Skip the requested method - we already tried this one
|
||||
if method == reqMethod || method == "OPTIONS" {
|
||||
continue
|
||||
}
|
||||
|
||||
handle, _, _ := r.trees[method].getValue(path)
|
||||
if handle != nil {
|
||||
// add request method to list of allowed methods
|
||||
if len(allow) == 0 {
|
||||
allow = method
|
||||
} else {
|
||||
allow += ", " + method
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(allow) > 0 {
|
||||
allow += ", OPTIONS"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ServeHTTP makes the router implement the http.Handler interface.
|
||||
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
if r.PanicHandler != nil {
|
||||
defer r.recv(w, req)
|
||||
}
|
||||
|
||||
if root := r.trees[req.Method]; root != nil {
|
||||
path := req.URL.Path
|
||||
|
||||
if root := r.trees[req.Method]; root != nil {
|
||||
if handle, ps, tsr := root.getValue(path); handle != nil {
|
||||
handle(w, req, ps)
|
||||
return
|
||||
@ -331,18 +366,19 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
if req.Method == "OPTIONS" && r.HandleOPTIONS {
|
||||
// Handle OPTIONS requests
|
||||
if allow := r.allowed(path, req.Method); len(allow) > 0 {
|
||||
w.Header().Set("Allow", allow)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// Handle 405
|
||||
if r.HandleMethodNotAllowed {
|
||||
for method := range r.trees {
|
||||
// Skip the requested method - we already tried this one
|
||||
if method == req.Method {
|
||||
continue
|
||||
}
|
||||
|
||||
handle, _, _ := r.trees[method].getValue(req.URL.Path)
|
||||
if handle != nil {
|
||||
if allow := r.allowed(path, req.Method); len(allow) > 0 {
|
||||
w.Header().Set("Allow", allow)
|
||||
if r.MethodNotAllowed != nil {
|
||||
r.MethodNotAllowed(w, req)
|
||||
r.MethodNotAllowed.ServeHTTP(w, req)
|
||||
} else {
|
||||
http.Error(w,
|
||||
http.StatusText(http.StatusMethodNotAllowed),
|
||||
@ -356,7 +392,7 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
// Handle 404
|
||||
if r.NotFound != nil {
|
||||
r.NotFound(w, req)
|
||||
r.NotFound.ServeHTTP(w, req)
|
||||
} else {
|
||||
http.NotFound(w, req)
|
||||
}
|
||||
|
||||
188
vendor/github.com/julienschmidt/httprouter/router_test.go
generated
vendored
188
vendor/github.com/julienschmidt/httprouter/router_test.go
generated
vendored
@ -68,11 +68,11 @@ func TestRouter(t *testing.T) {
|
||||
}
|
||||
|
||||
type handlerStruct struct {
|
||||
handeled *bool
|
||||
handled *bool
|
||||
}
|
||||
|
||||
func (h handlerStruct) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
*h.handeled = true
|
||||
*h.handled = true
|
||||
}
|
||||
|
||||
func TestRouterAPI(t *testing.T) {
|
||||
@ -174,26 +174,175 @@ func TestRouterRoot(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterChaining(t *testing.T) {
|
||||
router1 := New()
|
||||
router2 := New()
|
||||
router1.NotFound = router2
|
||||
|
||||
fooHit := false
|
||||
router1.POST("/foo", func(w http.ResponseWriter, req *http.Request, _ Params) {
|
||||
fooHit = true
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
barHit := false
|
||||
router2.POST("/bar", func(w http.ResponseWriter, req *http.Request, _ Params) {
|
||||
barHit = true
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
r, _ := http.NewRequest("POST", "/foo", nil)
|
||||
w := httptest.NewRecorder()
|
||||
router1.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusOK && fooHit) {
|
||||
t.Errorf("Regular routing failed with router chaining.")
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
r, _ = http.NewRequest("POST", "/bar", nil)
|
||||
w = httptest.NewRecorder()
|
||||
router1.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusOK && barHit) {
|
||||
t.Errorf("Chained routing failed with router chaining.")
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
r, _ = http.NewRequest("POST", "/qax", nil)
|
||||
w = httptest.NewRecorder()
|
||||
router1.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusNotFound) {
|
||||
t.Errorf("NotFound behavior failed with router chaining.")
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterOPTIONS(t *testing.T) {
|
||||
handlerFunc := func(_ http.ResponseWriter, _ *http.Request, _ Params) {}
|
||||
|
||||
router := New()
|
||||
router.POST("/path", handlerFunc)
|
||||
|
||||
// test not allowed
|
||||
// * (server)
|
||||
r, _ := http.NewRequest("OPTIONS", "*", nil)
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusOK) {
|
||||
t.Errorf("OPTIONS handling failed: Code=%d, Header=%v", w.Code, w.Header())
|
||||
} else if allow := w.Header().Get("Allow"); allow != "POST, OPTIONS" {
|
||||
t.Error("unexpected Allow header value: " + allow)
|
||||
}
|
||||
|
||||
// path
|
||||
r, _ = http.NewRequest("OPTIONS", "/path", nil)
|
||||
w = httptest.NewRecorder()
|
||||
router.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusOK) {
|
||||
t.Errorf("OPTIONS handling failed: Code=%d, Header=%v", w.Code, w.Header())
|
||||
} else if allow := w.Header().Get("Allow"); allow != "POST, OPTIONS" {
|
||||
t.Error("unexpected Allow header value: " + allow)
|
||||
}
|
||||
|
||||
r, _ = http.NewRequest("OPTIONS", "/doesnotexist", nil)
|
||||
w = httptest.NewRecorder()
|
||||
router.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusNotFound) {
|
||||
t.Errorf("OPTIONS handling failed: Code=%d, Header=%v", w.Code, w.Header())
|
||||
}
|
||||
|
||||
// add another method
|
||||
router.GET("/path", handlerFunc)
|
||||
|
||||
// test again
|
||||
// * (server)
|
||||
r, _ = http.NewRequest("OPTIONS", "*", nil)
|
||||
w = httptest.NewRecorder()
|
||||
router.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusOK) {
|
||||
t.Errorf("OPTIONS handling failed: Code=%d, Header=%v", w.Code, w.Header())
|
||||
} else if allow := w.Header().Get("Allow"); allow != "POST, GET, OPTIONS" && allow != "GET, POST, OPTIONS" {
|
||||
t.Error("unexpected Allow header value: " + allow)
|
||||
}
|
||||
|
||||
// path
|
||||
r, _ = http.NewRequest("OPTIONS", "/path", nil)
|
||||
w = httptest.NewRecorder()
|
||||
router.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusOK) {
|
||||
t.Errorf("OPTIONS handling failed: Code=%d, Header=%v", w.Code, w.Header())
|
||||
} else if allow := w.Header().Get("Allow"); allow != "POST, GET, OPTIONS" && allow != "GET, POST, OPTIONS" {
|
||||
t.Error("unexpected Allow header value: " + allow)
|
||||
}
|
||||
|
||||
// custom handler
|
||||
var custom bool
|
||||
router.OPTIONS("/path", func(w http.ResponseWriter, r *http.Request, _ Params) {
|
||||
custom = true
|
||||
})
|
||||
|
||||
// test again
|
||||
// * (server)
|
||||
r, _ = http.NewRequest("OPTIONS", "*", nil)
|
||||
w = httptest.NewRecorder()
|
||||
router.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusOK) {
|
||||
t.Errorf("OPTIONS handling failed: Code=%d, Header=%v", w.Code, w.Header())
|
||||
} else if allow := w.Header().Get("Allow"); allow != "POST, GET, OPTIONS" && allow != "GET, POST, OPTIONS" {
|
||||
t.Error("unexpected Allow header value: " + allow)
|
||||
}
|
||||
if custom {
|
||||
t.Error("custom handler called on *")
|
||||
}
|
||||
|
||||
// path
|
||||
r, _ = http.NewRequest("OPTIONS", "/path", nil)
|
||||
w = httptest.NewRecorder()
|
||||
router.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusOK) {
|
||||
t.Errorf("OPTIONS handling failed: Code=%d, Header=%v", w.Code, w.Header())
|
||||
}
|
||||
if !custom {
|
||||
t.Error("custom handler not called")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterNotAllowed(t *testing.T) {
|
||||
handlerFunc := func(_ http.ResponseWriter, _ *http.Request, _ Params) {}
|
||||
|
||||
router := New()
|
||||
router.POST("/path", handlerFunc)
|
||||
|
||||
// Test not allowed
|
||||
// test not allowed
|
||||
r, _ := http.NewRequest("GET", "/path", nil)
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusMethodNotAllowed) {
|
||||
t.Errorf("NotAllowed handling failed: Code=%d, Header=%v", w.Code, w.Header())
|
||||
} else if allow := w.Header().Get("Allow"); allow != "POST, OPTIONS" {
|
||||
t.Error("unexpected Allow header value: " + allow)
|
||||
}
|
||||
|
||||
// add another method
|
||||
router.DELETE("/path", handlerFunc)
|
||||
router.OPTIONS("/path", handlerFunc) // must be ignored
|
||||
|
||||
// test again
|
||||
r, _ = http.NewRequest("GET", "/path", nil)
|
||||
w = httptest.NewRecorder()
|
||||
router.ServeHTTP(w, r)
|
||||
if !(w.Code == http.StatusMethodNotAllowed) {
|
||||
t.Errorf("NotAllowed handling failed: Code=%d, Header=%v", w.Code, w.Header())
|
||||
} else if allow := w.Header().Get("Allow"); allow != "POST, DELETE, OPTIONS" && allow != "DELETE, POST, OPTIONS" {
|
||||
t.Error("unexpected Allow header value: " + allow)
|
||||
}
|
||||
|
||||
// test custom handler
|
||||
w = httptest.NewRecorder()
|
||||
responseText := "custom method"
|
||||
router.MethodNotAllowed = func(w http.ResponseWriter, req *http.Request) {
|
||||
router.MethodNotAllowed = http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
w.WriteHeader(http.StatusTeapot)
|
||||
w.Write([]byte(responseText))
|
||||
}
|
||||
})
|
||||
router.ServeHTTP(w, r)
|
||||
if got := w.Body.String(); !(got == responseText) {
|
||||
t.Errorf("unexpected response got %q want %q", got, responseText)
|
||||
@ -201,6 +350,9 @@ func TestRouterNotAllowed(t *testing.T) {
|
||||
if w.Code != http.StatusTeapot {
|
||||
t.Errorf("unexpected response code %d want %d", w.Code, http.StatusTeapot)
|
||||
}
|
||||
if allow := w.Header().Get("Allow"); allow != "POST, DELETE, OPTIONS" && allow != "DELETE, POST, OPTIONS" {
|
||||
t.Error("unexpected Allow header value: " + allow)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterNotFound(t *testing.T) {
|
||||
@ -214,33 +366,33 @@ func TestRouterNotFound(t *testing.T) {
|
||||
testRoutes := []struct {
|
||||
route string
|
||||
code int
|
||||
header string
|
||||
location string
|
||||
}{
|
||||
{"/path/", 301, "map[Location:[/path]]"}, // TSR -/
|
||||
{"/dir", 301, "map[Location:[/dir/]]"}, // TSR +/
|
||||
{"", 301, "map[Location:[/]]"}, // TSR +/
|
||||
{"/PATH", 301, "map[Location:[/path]]"}, // Fixed Case
|
||||
{"/DIR/", 301, "map[Location:[/dir/]]"}, // Fixed Case
|
||||
{"/PATH/", 301, "map[Location:[/path]]"}, // Fixed Case -/
|
||||
{"/DIR", 301, "map[Location:[/dir/]]"}, // Fixed Case +/
|
||||
{"/../path", 301, "map[Location:[/path]]"}, // CleanPath
|
||||
{"/path/", 301, "/path"}, // TSR -/
|
||||
{"/dir", 301, "/dir/"}, // TSR +/
|
||||
{"", 301, "/"}, // TSR +/
|
||||
{"/PATH", 301, "/path"}, // Fixed Case
|
||||
{"/DIR/", 301, "/dir/"}, // Fixed Case
|
||||
{"/PATH/", 301, "/path"}, // Fixed Case -/
|
||||
{"/DIR", 301, "/dir/"}, // Fixed Case +/
|
||||
{"/../path", 301, "/path"}, // CleanPath
|
||||
{"/nope", 404, ""}, // NotFound
|
||||
}
|
||||
for _, tr := range testRoutes {
|
||||
r, _ := http.NewRequest("GET", tr.route, nil)
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, r)
|
||||
if !(w.Code == tr.code && (w.Code == 404 || fmt.Sprint(w.Header()) == tr.header)) {
|
||||
t.Errorf("NotFound handling route %s failed: Code=%d, Header=%v", tr.route, w.Code, w.Header())
|
||||
if !(w.Code == tr.code && (w.Code == 404 || fmt.Sprint(w.Header().Get("Location")) == tr.location)) {
|
||||
t.Errorf("NotFound handling route %s failed: Code=%d, Header=%v", tr.route, w.Code, w.Header().Get("Location"))
|
||||
}
|
||||
}
|
||||
|
||||
// Test custom not found handler
|
||||
var notFound bool
|
||||
router.NotFound = func(rw http.ResponseWriter, r *http.Request) {
|
||||
router.NotFound = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
rw.WriteHeader(404)
|
||||
notFound = true
|
||||
}
|
||||
})
|
||||
r, _ := http.NewRequest("GET", "/nope", nil)
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, r)
|
||||
|
||||
179
vendor/github.com/julienschmidt/httprouter/tree.go
generated
vendored
179
vendor/github.com/julienschmidt/httprouter/tree.go
generated
vendored
@ -7,6 +7,7 @@ package httprouter
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func min(a, b int) int {
|
||||
@ -33,9 +34,10 @@ func countParams(path string) uint8 {
|
||||
type nodeType uint8
|
||||
|
||||
const (
|
||||
static nodeType = 0
|
||||
param nodeType = 1
|
||||
catchAll nodeType = 2
|
||||
static nodeType = iota // default
|
||||
root
|
||||
param
|
||||
catchAll
|
||||
)
|
||||
|
||||
type node struct {
|
||||
@ -58,9 +60,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--
|
||||
}
|
||||
@ -105,6 +105,7 @@ func (n *node) addRoute(path string, handle Handle) {
|
||||
child := node{
|
||||
path: n.path[i:],
|
||||
wildChild: n.wildChild,
|
||||
nType: static,
|
||||
indices: n.indices,
|
||||
children: n.children,
|
||||
handle: n.handle,
|
||||
@ -141,16 +142,25 @@ func (n *node) addRoute(path string, handle Handle) {
|
||||
numParams--
|
||||
|
||||
// Check if the wildcard matches
|
||||
if len(path) >= len(n.path) && n.path == path[:len(n.path)] {
|
||||
// check for longer wildcard, e.g. :name and :names
|
||||
if len(n.path) >= len(path) || path[len(n.path)] == '/' {
|
||||
if len(path) >= len(n.path) && n.path == path[:len(n.path)] &&
|
||||
// Check for longer wildcard, e.g. :name and :names
|
||||
(len(n.path) >= len(path) || path[len(n.path)] == '/') {
|
||||
continue walk
|
||||
} else {
|
||||
// Wildcard conflict
|
||||
var pathSeg string
|
||||
if n.nType == catchAll {
|
||||
pathSeg = path
|
||||
} else {
|
||||
pathSeg = strings.SplitN(path, "/", 2)[0]
|
||||
}
|
||||
}
|
||||
|
||||
panic("path segment '" + path +
|
||||
prefix := fullPath[:strings.Index(fullPath, pathSeg)] + n.path
|
||||
panic("'" + pathSeg +
|
||||
"' in new path '" + fullPath +
|
||||
"' conflicts with existing wildcard '" + n.path +
|
||||
"' in path '" + fullPath + "'")
|
||||
"' in existing prefix '" + prefix +
|
||||
"'")
|
||||
}
|
||||
}
|
||||
|
||||
c := path[0]
|
||||
@ -187,7 +197,7 @@ func (n *node) addRoute(path string, handle Handle) {
|
||||
|
||||
} else if i == len(path) { // Make node a (in-path) leaf
|
||||
if n.handle != nil {
|
||||
panic("a handle is already registered for path ''" + fullPath + "'")
|
||||
panic("a handle is already registered for path '" + fullPath + "'")
|
||||
}
|
||||
n.handle = handle
|
||||
}
|
||||
@ -195,6 +205,7 @@ func (n *node) addRoute(path string, handle Handle) {
|
||||
}
|
||||
} else { // Empty tree
|
||||
n.insertChild(numParams, path, fullPath, handle)
|
||||
n.nType = root
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,7 +328,7 @@ func (n *node) insertChild(numParams uint8, path, fullPath string, handle Handle
|
||||
// made if a handle exists with an extra (without the) trailing slash for the
|
||||
// given path.
|
||||
func (n *node) getValue(path string) (handle Handle, p Params, tsr bool) {
|
||||
walk: // Outer loop for walking the tree
|
||||
walk: // outer loop for walking the tree
|
||||
for {
|
||||
if len(path) > len(n.path) {
|
||||
if path[:len(n.path)] == n.path {
|
||||
@ -411,6 +422,11 @@ walk: // Outer loop for walking the tree
|
||||
return
|
||||
}
|
||||
|
||||
if path == "/" && n.wildChild && n.nType != root {
|
||||
tsr = true
|
||||
return
|
||||
}
|
||||
|
||||
// No handle found. Check if a handle for this path + a
|
||||
// trailing slash exists for trailing slash recommendation
|
||||
for i := 0; i < len(n.indices); i++ {
|
||||
@ -439,34 +455,117 @@ walk: // Outer loop for walking the tree
|
||||
// It returns the case-corrected path and a bool indicating whether the lookup
|
||||
// was successful.
|
||||
func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPath []byte, found bool) {
|
||||
ciPath = make([]byte, 0, len(path)+1) // preallocate enough memory
|
||||
return n.findCaseInsensitivePathRec(
|
||||
path,
|
||||
strings.ToLower(path),
|
||||
make([]byte, 0, len(path)+1), // preallocate enough memory for new path
|
||||
[4]byte{}, // empty rune buffer
|
||||
fixTrailingSlash,
|
||||
)
|
||||
}
|
||||
|
||||
// Outer loop for walking the tree
|
||||
for len(path) >= len(n.path) && strings.ToLower(path[:len(n.path)]) == strings.ToLower(n.path) {
|
||||
path = path[len(n.path):]
|
||||
// shift bytes in array by n bytes left
|
||||
func shiftNRuneBytes(rb [4]byte, n int) [4]byte {
|
||||
switch n {
|
||||
case 0:
|
||||
return rb
|
||||
case 1:
|
||||
return [4]byte{rb[1], rb[2], rb[3], 0}
|
||||
case 2:
|
||||
return [4]byte{rb[2], rb[3]}
|
||||
case 3:
|
||||
return [4]byte{rb[3]}
|
||||
default:
|
||||
return [4]byte{}
|
||||
}
|
||||
}
|
||||
|
||||
// recursive case-insensitive lookup function used by n.findCaseInsensitivePath
|
||||
func (n *node) findCaseInsensitivePathRec(path, loPath string, ciPath []byte, rb [4]byte, fixTrailingSlash bool) ([]byte, bool) {
|
||||
loNPath := strings.ToLower(n.path)
|
||||
|
||||
walk: // outer loop for walking the tree
|
||||
for len(loPath) >= len(loNPath) && (len(loNPath) == 0 || loPath[1:len(loNPath)] == loNPath[1:]) {
|
||||
// add common path to result
|
||||
ciPath = append(ciPath, n.path...)
|
||||
|
||||
if len(path) > 0 {
|
||||
if path = path[len(n.path):]; len(path) > 0 {
|
||||
loOld := loPath
|
||||
loPath = loPath[len(loNPath):]
|
||||
|
||||
// If this node does not have a wildcard (param or catchAll) child,
|
||||
// we can just look up the next child node and continue to walk down
|
||||
// the tree
|
||||
if !n.wildChild {
|
||||
r := unicode.ToLower(rune(path[0]))
|
||||
for i, index := range n.indices {
|
||||
// must use recursive approach since both index and
|
||||
// ToLower(index) could exist. We must check both.
|
||||
if r == unicode.ToLower(index) {
|
||||
out, found := n.children[i].findCaseInsensitivePath(path, fixTrailingSlash)
|
||||
if found {
|
||||
return append(ciPath, out...), true
|
||||
// skip rune bytes already processed
|
||||
rb = shiftNRuneBytes(rb, len(loNPath))
|
||||
|
||||
if rb[0] != 0 {
|
||||
// old rune not finished
|
||||
for i := 0; i < len(n.indices); i++ {
|
||||
if n.indices[i] == rb[0] {
|
||||
// continue with child node
|
||||
n = n.children[i]
|
||||
loNPath = strings.ToLower(n.path)
|
||||
continue walk
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// process a new rune
|
||||
var rv rune
|
||||
|
||||
// find rune start
|
||||
// runes are up to 4 byte long,
|
||||
// -4 would definitely be another rune
|
||||
var off int
|
||||
for max := min(len(loNPath), 3); off < max; off++ {
|
||||
if i := len(loNPath) - off; utf8.RuneStart(loOld[i]) {
|
||||
// read rune from cached lowercase path
|
||||
rv, _ = utf8.DecodeRuneInString(loOld[i:])
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// calculate lowercase bytes of current rune
|
||||
utf8.EncodeRune(rb[:], rv)
|
||||
// skipp already processed bytes
|
||||
rb = shiftNRuneBytes(rb, off)
|
||||
|
||||
for i := 0; i < len(n.indices); i++ {
|
||||
// lowercase matches
|
||||
if n.indices[i] == rb[0] {
|
||||
// must use a recursive approach since both the
|
||||
// uppercase byte and the lowercase byte might exist
|
||||
// as an index
|
||||
if out, found := n.children[i].findCaseInsensitivePathRec(
|
||||
path, loPath, ciPath, rb, fixTrailingSlash,
|
||||
); found {
|
||||
return out, true
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// same for uppercase rune, if it differs
|
||||
if up := unicode.ToUpper(rv); up != rv {
|
||||
utf8.EncodeRune(rb[:], up)
|
||||
rb = shiftNRuneBytes(rb, off)
|
||||
|
||||
for i := 0; i < len(n.indices); i++ {
|
||||
// uppercase matches
|
||||
if n.indices[i] == rb[0] {
|
||||
// continue with child node
|
||||
n = n.children[i]
|
||||
loNPath = strings.ToLower(n.path)
|
||||
continue walk
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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.handle != nil)
|
||||
return
|
||||
return ciPath, (fixTrailingSlash && path == "/" && n.handle != nil)
|
||||
}
|
||||
|
||||
n = n.children[0]
|
||||
@ -484,8 +583,11 @@ func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPa
|
||||
// we need to go deeper!
|
||||
if k < len(path) {
|
||||
if len(n.children) > 0 {
|
||||
path = path[k:]
|
||||
// continue with child node
|
||||
n = n.children[0]
|
||||
loNPath = strings.ToLower(n.path)
|
||||
loPath = loPath[k:]
|
||||
path = path[k:]
|
||||
continue
|
||||
}
|
||||
|
||||
@ -493,7 +595,7 @@ func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPa
|
||||
if fixTrailingSlash && len(path) == k+1 {
|
||||
return ciPath, true
|
||||
}
|
||||
return
|
||||
return ciPath, false
|
||||
}
|
||||
|
||||
if n.handle != nil {
|
||||
@ -506,7 +608,7 @@ func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPa
|
||||
return append(ciPath, '/'), true
|
||||
}
|
||||
}
|
||||
return
|
||||
return ciPath, false
|
||||
|
||||
case catchAll:
|
||||
return append(ciPath, path...), true
|
||||
@ -531,11 +633,11 @@ func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPa
|
||||
(n.nType == catchAll && n.children[0].handle != nil) {
|
||||
return append(ciPath, '/'), true
|
||||
}
|
||||
return
|
||||
return ciPath, false
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
return ciPath, false
|
||||
}
|
||||
}
|
||||
|
||||
@ -545,11 +647,10 @@ func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPa
|
||||
if path == "/" {
|
||||
return ciPath, true
|
||||
}
|
||||
if len(path)+1 == len(n.path) && n.path[len(path)] == '/' &&
|
||||
strings.ToLower(path) == strings.ToLower(n.path[:len(path)]) &&
|
||||
n.handle != nil {
|
||||
if len(loPath)+1 == len(loNPath) && loNPath[len(loPath)] == '/' &&
|
||||
loPath[1:] == loNPath[1:len(loPath)] && n.handle != nil {
|
||||
return append(ciPath, n.path...), true
|
||||
}
|
||||
}
|
||||
return
|
||||
return ciPath, false
|
||||
}
|
||||
|
||||
92
vendor/github.com/julienschmidt/httprouter/tree_test.go
generated
vendored
92
vendor/github.com/julienschmidt/httprouter/tree_test.go
generated
vendored
@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@ -22,7 +23,7 @@ func printChildren(n *node, prefix string) {
|
||||
}
|
||||
}
|
||||
|
||||
// Used as a workaround since we can't compare functions or their adresses
|
||||
// Used as a workaround since we can't compare functions or their addresses
|
||||
var fakeHandlerValue string
|
||||
|
||||
func fakeHandler(val string) Handle {
|
||||
@ -89,7 +90,7 @@ func checkMaxParams(t *testing.T, n *node) uint8 {
|
||||
maxParams = params
|
||||
}
|
||||
}
|
||||
if n.nType != static && !n.wildChild {
|
||||
if n.nType > root && !n.wildChild {
|
||||
maxParams++
|
||||
}
|
||||
|
||||
@ -394,6 +395,9 @@ func TestTreeTrailingSlashRedirect(t *testing.T) {
|
||||
"/1/:id/2",
|
||||
"/aa",
|
||||
"/a/",
|
||||
"/admin",
|
||||
"/admin/:category",
|
||||
"/admin/:category/:page",
|
||||
"/doc",
|
||||
"/doc/go_faq.html",
|
||||
"/doc/go1.html",
|
||||
@ -423,6 +427,9 @@ func TestTreeTrailingSlashRedirect(t *testing.T) {
|
||||
"/0/go/",
|
||||
"/1/go",
|
||||
"/a",
|
||||
"/admin/",
|
||||
"/admin/config/",
|
||||
"/admin/config/permissions/",
|
||||
"/doc/",
|
||||
}
|
||||
for _, route := range tsrRoutes {
|
||||
@ -452,6 +459,24 @@ func TestTreeTrailingSlashRedirect(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTreeRootTrailingSlashRedirect(t *testing.T) {
|
||||
tree := &node{}
|
||||
|
||||
recv := catchPanic(func() {
|
||||
tree.addRoute("/:test", fakeHandler("/:test"))
|
||||
})
|
||||
if recv != nil {
|
||||
t.Fatalf("panic inserting test route: %v", recv)
|
||||
}
|
||||
|
||||
handler, _, tsr := tree.getValue("/")
|
||||
if handler != nil {
|
||||
t.Fatalf("non-nil handler")
|
||||
} else if tsr {
|
||||
t.Errorf("expected no TSR recommendation")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTreeFindCaseInsensitivePath(t *testing.T) {
|
||||
tree := &node{}
|
||||
|
||||
@ -478,6 +503,16 @@ func TestTreeFindCaseInsensitivePath(t *testing.T) {
|
||||
"/doc/go/away",
|
||||
"/no/a",
|
||||
"/no/b",
|
||||
"/Π",
|
||||
"/u/apfêl/",
|
||||
"/u/äpfêl/",
|
||||
"/u/öpfêl",
|
||||
"/v/Äpfêl/",
|
||||
"/v/Öpfêl",
|
||||
"/w/♬", // 3 byte
|
||||
"/w/♭/", // 3 byte, last byte differs
|
||||
"/w/𠜎", // 4 byte
|
||||
"/w/𠜏/", // 4 byte
|
||||
}
|
||||
|
||||
for _, route := range routes {
|
||||
@ -556,6 +591,20 @@ func TestTreeFindCaseInsensitivePath(t *testing.T) {
|
||||
{"/DOC/", "/doc", true, true},
|
||||
{"/NO", "", false, true},
|
||||
{"/DOC/GO", "", false, true},
|
||||
{"/π", "/Π", true, false},
|
||||
{"/π/", "/Π", true, true},
|
||||
{"/u/ÄPFÊL/", "/u/äpfêl/", true, false},
|
||||
{"/u/ÄPFÊL", "/u/äpfêl/", true, true},
|
||||
{"/u/ÖPFÊL/", "/u/öpfêl", true, true},
|
||||
{"/u/ÖPFÊL", "/u/öpfêl", true, false},
|
||||
{"/v/äpfêL/", "/v/Äpfêl/", true, false},
|
||||
{"/v/äpfêL", "/v/Äpfêl/", true, true},
|
||||
{"/v/öpfêL/", "/v/Öpfêl", true, true},
|
||||
{"/v/öpfêL", "/v/Öpfêl", true, false},
|
||||
{"/w/♬/", "/w/♬", true, true},
|
||||
{"/w/♭", "/w/♭/", true, true},
|
||||
{"/w/𠜎/", "/w/𠜎", true, true},
|
||||
{"/w/𠜏", "/w/𠜏/", true, true},
|
||||
}
|
||||
// With fixTrailingSlash = true
|
||||
for _, test := range tests {
|
||||
@ -609,3 +658,42 @@ func TestTreeInvalidNodeType(t *testing.T) {
|
||||
t.Fatalf("Expected panic '"+panicMsg+"', got '%v'", recv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTreeWildcardConflictEx(t *testing.T) {
|
||||
conflicts := [...]struct {
|
||||
route string
|
||||
segPath string
|
||||
existPath string
|
||||
existSegPath string
|
||||
}{
|
||||
{"/who/are/foo", "/foo", `/who/are/\*you`, `/\*you`},
|
||||
{"/who/are/foo/", "/foo/", `/who/are/\*you`, `/\*you`},
|
||||
{"/who/are/foo/bar", "/foo/bar", `/who/are/\*you`, `/\*you`},
|
||||
{"/conxxx", "xxx", `/con:tact`, `:tact`},
|
||||
{"/conooo/xxx", "ooo", `/con:tact`, `:tact`},
|
||||
}
|
||||
|
||||
for _, conflict := range conflicts {
|
||||
// I have to re-create a 'tree', because the 'tree' will be
|
||||
// in an inconsistent state when the loop recovers from the
|
||||
// panic which threw by 'addRoute' function.
|
||||
tree := &node{}
|
||||
routes := [...]string{
|
||||
"/con:tact",
|
||||
"/who/are/*you",
|
||||
"/who/foo/hello",
|
||||
}
|
||||
|
||||
for _, route := range routes {
|
||||
tree.addRoute(route, fakeHandler(route))
|
||||
}
|
||||
|
||||
recv := catchPanic(func() {
|
||||
tree.addRoute(conflict.route, fakeHandler(conflict.route))
|
||||
})
|
||||
|
||||
if !regexp.MustCompile(fmt.Sprintf("'%s' in new path .* conflicts with existing wildcard '%s' in existing prefix '%s'", conflict.segPath, conflict.existSegPath, conflict.existPath)).MatchString(fmt.Sprint(recv)) {
|
||||
t.Fatalf("invalid wildcard conflict error (%v)", recv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
vendor/github.com/klauspost/compress/README.md
generated
vendored
1
vendor/github.com/klauspost/compress/README.md
generated
vendored
@ -14,6 +14,7 @@ It offers slightly better compression at lower compression settings, and up to 3
|
||||
|
||||
# changelog
|
||||
|
||||
* Aug 1, 2018: Added [huff0 README](https://github.com/klauspost/compress/tree/master/huff0#huff0-entropy-compression).
|
||||
* Jul 8, 2018: Added [Performance Update 2018](#performance-update-2018) below.
|
||||
* Jun 23, 2018: Merged [Go 1.11 inflate optimizations](https://go-review.googlesource.com/c/go/+/102235). Go 1.9 is now required. Backwards compatible version tagged with [v1.3.0](https://github.com/klauspost/compress/releases/tag/v1.3.0).
|
||||
* Apr 2, 2018: Added [huff0](https://godoc.org/github.com/klauspost/compress/huff0) en/decoder. Experimental for now, API may change.
|
||||
|
||||
1
vendor/github.com/klauspost/compress/flate/crc32_amd64.go
generated
vendored
1
vendor/github.com/klauspost/compress/flate/crc32_amd64.go
generated
vendored
@ -1,5 +1,6 @@
|
||||
//+build !noasm
|
||||
//+build !appengine
|
||||
//+build !gccgo
|
||||
|
||||
// Copyright 2015, Klaus Post, see LICENSE for details.
|
||||
|
||||
|
||||
1
vendor/github.com/klauspost/compress/flate/crc32_amd64.s
generated
vendored
1
vendor/github.com/klauspost/compress/flate/crc32_amd64.s
generated
vendored
@ -1,5 +1,6 @@
|
||||
//+build !noasm
|
||||
//+build !appengine
|
||||
//+build !gccgo
|
||||
|
||||
// Copyright 2015, Klaus Post, see LICENSE for details.
|
||||
|
||||
|
||||
2
vendor/github.com/klauspost/compress/flate/crc32_noasm.go
generated
vendored
2
vendor/github.com/klauspost/compress/flate/crc32_noasm.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
//+build !amd64 noasm appengine
|
||||
//+build !amd64 noasm appengine gccgo
|
||||
|
||||
// Copyright 2015, Klaus Post, see LICENSE for details.
|
||||
|
||||
|
||||
5
vendor/github.com/klauspost/compress/fse/fse.go
generated
vendored
5
vendor/github.com/klauspost/compress/fse/fse.go
generated
vendored
@ -14,6 +14,7 @@ package fse
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -136,3 +137,7 @@ func (s *Scratch) prepare(in []byte) (*Scratch, error) {
|
||||
func tableStep(tableSize uint32) uint32 {
|
||||
return (tableSize >> 1) + (tableSize >> 3) + 3
|
||||
}
|
||||
|
||||
func highBits(val uint32) (n uint32) {
|
||||
return uint32(bits.Len32(val) - 1)
|
||||
}
|
||||
|
||||
9
vendor/github.com/klauspost/compress/fse/highbit_go19.go
generated
vendored
9
vendor/github.com/klauspost/compress/fse/highbit_go19.go
generated
vendored
@ -1,9 +0,0 @@
|
||||
// +build go1.9
|
||||
|
||||
package fse
|
||||
|
||||
import "math/bits"
|
||||
|
||||
func highBits(val uint32) (n uint32) {
|
||||
return uint32(bits.Len32(val) - 1)
|
||||
}
|
||||
18
vendor/github.com/klauspost/compress/fse/highbit_old.go
generated
vendored
18
vendor/github.com/klauspost/compress/fse/highbit_old.go
generated
vendored
@ -1,18 +0,0 @@
|
||||
// +build !go1.9
|
||||
|
||||
package fse
|
||||
|
||||
var deBruijnClz = [...]uint8{0, 9, 1, 10, 13, 21, 2, 29,
|
||||
11, 14, 16, 18, 22, 25, 3, 30,
|
||||
8, 12, 20, 28, 15, 17, 24, 7,
|
||||
19, 27, 23, 6, 26, 5, 4, 31}
|
||||
|
||||
// highBits returns the highest set bit
|
||||
func highBits(v uint32) (n uint32) {
|
||||
v |= v >> 1
|
||||
v |= v >> 2
|
||||
v |= v >> 4
|
||||
v |= v >> 8
|
||||
v |= v >> 16
|
||||
return uint32(deBruijnClz[(v*0x07C4ACDD)>>27])
|
||||
}
|
||||
87
vendor/github.com/klauspost/compress/huff0/README.md
generated
vendored
Normal file
87
vendor/github.com/klauspost/compress/huff0/README.md
generated
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
# Huff0 entropy compression
|
||||
|
||||
This package provides Huff0 encoding and decoding as used in zstd.
|
||||
|
||||
[Huff0](https://github.com/Cyan4973/FiniteStateEntropy#new-generation-entropy-coders),
|
||||
a Huffman codec designed for modern CPU, featuring OoO (Out of Order) operations on multiple ALU
|
||||
(Arithmetic Logic Unit), achieving extremely fast compression and decompression speeds.
|
||||
|
||||
This can be used for compressing input with a lot of similar input values to the smallest number of bytes.
|
||||
This does not perform any multi-byte [dictionary coding](https://en.wikipedia.org/wiki/Dictionary_coder) as LZ coders,
|
||||
but it can be used as a secondary step to compressors (like Snappy) that does not do entropy encoding.
|
||||
|
||||
* [Godoc documentation](https://godoc.org/github.com/klauspost/compress/huff0)
|
||||
|
||||
THIS PACKAGE IS NOT CONSIDERED STABLE AND API OR ENCODING MAY CHANGE IN THE FUTURE.
|
||||
|
||||
## News
|
||||
|
||||
* Mar 2018: First implementation released. Consider this beta software for now.
|
||||
|
||||
# Usage
|
||||
|
||||
This package provides a low level interface that allows to compress single independent blocks.
|
||||
|
||||
Each block is separate, and there is no built in integrity checks.
|
||||
This means that the caller should keep track of block sizes and also do checksums if needed.
|
||||
|
||||
Compressing a block is done via the [`Compress1X`](https://godoc.org/github.com/klauspost/compress/huff0#Compress1X) and
|
||||
[`Compress4X`](https://godoc.org/github.com/klauspost/compress/huff0#Compress4X) functions.
|
||||
You must provide input and will receive the output and maybe an error.
|
||||
|
||||
These error values can be returned:
|
||||
|
||||
| Error | Description |
|
||||
|---------------------|-----------------------------------------------------------------------------|
|
||||
| `<nil>` | Everything ok, output is returned |
|
||||
| `ErrIncompressible` | Returned when input is judged to be too hard to compress |
|
||||
| `ErrUseRLE` | Returned from the compressor when the input is a single byte value repeated |
|
||||
| `ErrTooBig` | Returned if the input block exceeds the maximum allowed size (128 Kib) |
|
||||
| `(error)` | An internal error occurred. |
|
||||
|
||||
|
||||
As can be seen above some of there are errors that will be returned even under normal operation so it is important to handle these.
|
||||
|
||||
To reduce allocations you can provide a [`Scratch`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch) object
|
||||
that can be re-used for successive calls. Both compression and decompression accepts a `Scratch` object, and the same
|
||||
object can be used for both.
|
||||
|
||||
Be aware, that when re-using a `Scratch` object that the *output* buffer is also re-used, so if you are still using this
|
||||
you must set the `Out` field in the scratch to nil. The same buffer is used for compression and decompression output.
|
||||
|
||||
The `Scratch` object will retain state that allows to re-use previous tables for encoding and decoding.
|
||||
|
||||
## Tables and re-use
|
||||
|
||||
Huff0 allows for reusing tables from the previous block to save space if that is expected to give better/faster results.
|
||||
|
||||
The Scratch object allows you to set a [`ReusePolicy`](https://godoc.org/github.com/klauspost/compress/huff0#ReusePolicy)
|
||||
that controls this behaviour. See the documentation for details. This can be altered between each block.
|
||||
|
||||
Do however note that this information is *not* stored in the output block and it is up to the users of the package to
|
||||
record whether [`ReadTable`](https://godoc.org/github.com/klauspost/compress/huff0#ReadTable) should be called,
|
||||
based on the boolean reported back from the CompressXX call.
|
||||
|
||||
If you want to store the table separate from the data, you can access them as `OutData` and `OutTable` on the
|
||||
[`Scratch`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch) object.
|
||||
|
||||
## Decompressing
|
||||
|
||||
The first part of decoding is to initialize the decoding table through [`ReadTable`](https://godoc.org/github.com/klauspost/compress/huff0#ReadTable).
|
||||
This will initialize the decoding tables.
|
||||
You can supply the complete block to `ReadTable` and it will return the data part of the block
|
||||
which can be given to the decompressor.
|
||||
|
||||
Decompressing is done by calling the [`Decompress1X`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch.Decompress1X)
|
||||
or [`Decompress4X`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch.Decompress4X) function.
|
||||
|
||||
You must provide the output from the compression stage, at exactly the size you got back. If you receive an error back
|
||||
your input was likely corrupted.
|
||||
|
||||
It is important to note that a successful decoding does *not* mean your output matches your original input.
|
||||
There are no integrity checks, so relying on errors from the decompressor does not assure your data is valid.
|
||||
|
||||
# Contributing
|
||||
|
||||
Contributions are always welcome. Be aware that adding public functions will require good justification and breaking
|
||||
changes will likely not be accepted. If in doubt open an issue before writing the PR.
|
||||
12
vendor/github.com/klauspost/compress/huff0/bitwriter.go
generated
vendored
12
vendor/github.com/klauspost/compress/huff0/bitwriter.go
generated
vendored
@ -67,21 +67,25 @@ func (b *bitWriter) flush() {
|
||||
v := b.nBits >> 3
|
||||
switch v {
|
||||
case 0:
|
||||
return
|
||||
case 1:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
)
|
||||
b.bitContainer >>= 1 << 3
|
||||
case 2:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
)
|
||||
b.bitContainer >>= 2 << 3
|
||||
case 3:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
)
|
||||
b.bitContainer >>= 3 << 3
|
||||
case 4:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
@ -89,6 +93,7 @@ func (b *bitWriter) flush() {
|
||||
byte(b.bitContainer>>16),
|
||||
byte(b.bitContainer>>24),
|
||||
)
|
||||
b.bitContainer >>= 4 << 3
|
||||
case 5:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
@ -97,6 +102,7 @@ func (b *bitWriter) flush() {
|
||||
byte(b.bitContainer>>24),
|
||||
byte(b.bitContainer>>32),
|
||||
)
|
||||
b.bitContainer >>= 5 << 3
|
||||
case 6:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
@ -106,6 +112,7 @@ func (b *bitWriter) flush() {
|
||||
byte(b.bitContainer>>32),
|
||||
byte(b.bitContainer>>40),
|
||||
)
|
||||
b.bitContainer >>= 6 << 3
|
||||
case 7:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
@ -116,6 +123,7 @@ func (b *bitWriter) flush() {
|
||||
byte(b.bitContainer>>40),
|
||||
byte(b.bitContainer>>48),
|
||||
)
|
||||
b.bitContainer >>= 7 << 3
|
||||
case 8:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
@ -127,10 +135,12 @@ func (b *bitWriter) flush() {
|
||||
byte(b.bitContainer>>48),
|
||||
byte(b.bitContainer>>56),
|
||||
)
|
||||
b.bitContainer = 0
|
||||
b.nBits = 0
|
||||
return
|
||||
default:
|
||||
panic(fmt.Errorf("bits (%d) > 64", b.nBits))
|
||||
}
|
||||
b.bitContainer >>= v << 3
|
||||
b.nBits &= 7
|
||||
}
|
||||
|
||||
|
||||
16
vendor/github.com/klauspost/compress/huff0/compress.go
generated
vendored
16
vendor/github.com/klauspost/compress/huff0/compress.go
generated
vendored
@ -6,6 +6,10 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Compress1X will compress the input.
|
||||
// The output can be decoded using Decompress1X.
|
||||
// Supply a Scratch object. The scratch object contains state about re-use,
|
||||
// So when sharing across independent encodes, be sure to set the re-use policy.
|
||||
func Compress1X(in []byte, s *Scratch) (out []byte, reUsed bool, err error) {
|
||||
s, err = s.prepare(in)
|
||||
if err != nil {
|
||||
@ -14,6 +18,11 @@ func Compress1X(in []byte, s *Scratch) (out []byte, reUsed bool, err error) {
|
||||
return compress(in, s, s.compress1X)
|
||||
}
|
||||
|
||||
// Compress4X will compress the input. The input is split into 4 independent blocks
|
||||
// and compressed similar to Compress1X.
|
||||
// The output can be decoded using Decompress4X.
|
||||
// Supply a Scratch object. The scratch object contains state about re-use,
|
||||
// So when sharing across independent encodes, be sure to set the re-use policy.
|
||||
func Compress4X(in []byte, s *Scratch) (out []byte, reUsed bool, err error) {
|
||||
s, err = s.prepare(in)
|
||||
if err != nil {
|
||||
@ -80,8 +89,7 @@ func compress(in []byte, s *Scratch, compressor func(src []byte) ([]byte, error)
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if !s.canUseTable(s.cTable) {
|
||||
// TODO: Not needed.
|
||||
if false && !s.canUseTable(s.cTable) {
|
||||
panic("invalid table generated")
|
||||
}
|
||||
|
||||
@ -512,7 +520,7 @@ func (s *Scratch) setMaxHeight(lastNonNull int) uint8 {
|
||||
// renorm totalCost
|
||||
totalCost >>= largestBits - maxNbBits /* note : totalCost is necessarily a multiple of baseCost */
|
||||
|
||||
/* repay normalized cost */
|
||||
// repay normalized cost
|
||||
{
|
||||
const noSymbol = 0xF0F0F0F0
|
||||
var rankLast [tableLogMax + 2]uint32
|
||||
@ -528,7 +536,7 @@ func (s *Scratch) setMaxHeight(lastNonNull int) uint8 {
|
||||
if huffNode[pos].nbBits >= currentNbBits {
|
||||
continue
|
||||
}
|
||||
currentNbBits = huffNode[pos].nbBits /* < maxNbBits */
|
||||
currentNbBits = huffNode[pos].nbBits // < maxNbBits
|
||||
rankLast[maxNbBits-currentNbBits] = uint32(pos)
|
||||
}
|
||||
}
|
||||
|
||||
12
vendor/github.com/klauspost/compress/huff0/decompress.go
generated
vendored
12
vendor/github.com/klauspost/compress/huff0/decompress.go
generated
vendored
@ -29,7 +29,7 @@ type dEntryDouble struct {
|
||||
// ReadTable will read a table from the input.
|
||||
// The size of the input may be larger than the table definition.
|
||||
// Any content remaining after the table definition will be returned.
|
||||
// if no Scratch is provided a new one is allocated.
|
||||
// If no Scratch is provided a new one is allocated.
|
||||
// The returned Scratch can be used for decoding input using this table.
|
||||
func ReadTable(in []byte, s *Scratch) (s2 *Scratch, remain []byte, err error) {
|
||||
s, err = s.prepare(in)
|
||||
@ -150,8 +150,9 @@ func ReadTable(in []byte, s *Scratch) (s2 *Scratch, remain []byte, err error) {
|
||||
}
|
||||
|
||||
// Decompress1X will decompress a 1X encoded stream.
|
||||
// The supplied input must match the end of a block exactly.
|
||||
// Before this is called, the table must be initialized with ReadTable.
|
||||
// The length of the supplied input must match the end of a block exactly.
|
||||
// Before this is called, the table must be initialized with ReadTable unless
|
||||
// the encoder re-used the table.
|
||||
func (s *Scratch) Decompress1X(in []byte) (out []byte, err error) {
|
||||
if len(s.dt.single) == 0 {
|
||||
return nil, errors.New("no table loaded")
|
||||
@ -206,8 +207,9 @@ func (s *Scratch) Decompress1X(in []byte) (out []byte, err error) {
|
||||
}
|
||||
|
||||
// Decompress4X will decompress a 4X encoded stream.
|
||||
// Before this is called, the table must be initialized with ReadTable.
|
||||
// The supplied input must match the end of a block exactly.
|
||||
// Before this is called, the table must be initialized with ReadTable unless
|
||||
// the encoder re-used the table.
|
||||
// The length of the supplied input must match the end of a block exactly.
|
||||
// The destination size of the uncompressed data must be known and provided.
|
||||
func (s *Scratch) Decompress4X(in []byte, dstSize int) (out []byte, err error) {
|
||||
if len(s.dt.single) == 0 {
|
||||
|
||||
9
vendor/github.com/klauspost/compress/huff0/highbit_go19.go
generated
vendored
9
vendor/github.com/klauspost/compress/huff0/highbit_go19.go
generated
vendored
@ -1,9 +0,0 @@
|
||||
// +build go1.9
|
||||
|
||||
package huff0
|
||||
|
||||
import "math/bits"
|
||||
|
||||
func highBit32(val uint32) (n uint32) {
|
||||
return uint32(bits.Len32(val) - 1)
|
||||
}
|
||||
18
vendor/github.com/klauspost/compress/huff0/highbit_old.go
generated
vendored
18
vendor/github.com/klauspost/compress/huff0/highbit_old.go
generated
vendored
@ -1,18 +0,0 @@
|
||||
// +build !go1.9
|
||||
|
||||
package huff0
|
||||
|
||||
var deBruijnClz = [...]uint8{0, 9, 1, 10, 13, 21, 2, 29,
|
||||
11, 14, 16, 18, 22, 25, 3, 30,
|
||||
8, 12, 20, 28, 15, 17, 24, 7,
|
||||
19, 27, 23, 6, 26, 5, 4, 31}
|
||||
|
||||
// highBit32 returns the highest set bit
|
||||
func highBit32(v uint32) (n uint32) {
|
||||
v |= v >> 1
|
||||
v |= v >> 2
|
||||
v |= v >> 4
|
||||
v |= v >> 8
|
||||
v |= v >> 16
|
||||
return uint32(deBruijnClz[(v*0x07C4ACDD)>>27])
|
||||
}
|
||||
8
vendor/github.com/klauspost/compress/huff0/huff0.go
generated
vendored
8
vendor/github.com/klauspost/compress/huff0/huff0.go
generated
vendored
@ -1,9 +1,13 @@
|
||||
// Package huff0 provides fast huffman encoding as used in zstd.
|
||||
//
|
||||
// See README.md at https://github.com/klauspost/compress/tree/master/huff0 for details.
|
||||
package huff0
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/bits"
|
||||
|
||||
"github.com/klauspost/compress/fse"
|
||||
)
|
||||
@ -230,3 +234,7 @@ func (s *Scratch) minSize(total int) int {
|
||||
}
|
||||
return int(nbBits) >> 3
|
||||
}
|
||||
|
||||
func highBit32(val uint32) (n uint32) {
|
||||
return uint32(bits.Len32(val) - 1)
|
||||
}
|
||||
|
||||
5
vendor/github.com/klauspost/cpuid/.travis.yml
generated
vendored
5
vendor/github.com/klauspost/cpuid/.travis.yml
generated
vendored
@ -6,10 +6,9 @@ os:
|
||||
- linux
|
||||
- osx
|
||||
go:
|
||||
- 1.5.x
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- master
|
||||
|
||||
script:
|
||||
|
||||
35
vendor/github.com/klauspost/cpuid/CONTRIBUTING.txt
generated
vendored
Normal file
35
vendor/github.com/klauspost/cpuid/CONTRIBUTING.txt
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2015- Klaus Post & Contributors.
|
||||
Email: klauspost@gmail.com
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
14
vendor/github.com/klauspost/cpuid/cpuid.go
generated
vendored
14
vendor/github.com/klauspost/cpuid/cpuid.go
generated
vendored
@ -76,6 +76,8 @@ const (
|
||||
RDTSCP // RDTSCP Instruction
|
||||
CX16 // CMPXCHG16B Instruction
|
||||
SGX // Software Guard Extensions
|
||||
IBPB // Indirect Branch Restricted Speculation (IBRS) and Indirect Branch Predictor Barrier (IBPB)
|
||||
STIBP // Single Thread Indirect Branch Predictors
|
||||
|
||||
// Performance indicators
|
||||
SSE2SLOW // SSE2 is supported, but usually not faster
|
||||
@ -131,6 +133,8 @@ var flagNames = map[Flags]string{
|
||||
RDTSCP: "RDTSCP", // RDTSCP Instruction
|
||||
CX16: "CX16", // CMPXCHG16B Instruction
|
||||
SGX: "SGX", // Software Guard Extensions
|
||||
IBPB: "IBPB", // Indirect Branch Restricted Speculation and Indirect Branch Predictor Barrier
|
||||
STIBP: "STIBP", // Single Thread Indirect Branch Predictors
|
||||
|
||||
// Performance indicators
|
||||
SSE2SLOW: "SSE2SLOW", // SSE2 supported, but usually not faster
|
||||
@ -450,7 +454,7 @@ func (c CPUInfo) CX16() bool {
|
||||
// TSX is split into HLE (Hardware Lock Elision) and RTM (Restricted Transactional Memory) detection.
|
||||
// So TSX simply checks that.
|
||||
func (c CPUInfo) TSX() bool {
|
||||
return c.Features&(MPX|RTM) == MPX|RTM
|
||||
return c.Features&(HLE|RTM) == HLE|RTM
|
||||
}
|
||||
|
||||
// Atom indicates an Atom processor
|
||||
@ -854,7 +858,7 @@ func support() Flags {
|
||||
|
||||
// Check AVX2, AVX2 requires OS support, but BMI1/2 don't.
|
||||
if mfi >= 7 {
|
||||
_, ebx, ecx, _ := cpuidex(7, 0)
|
||||
_, ebx, ecx, edx := cpuidex(7, 0)
|
||||
if (rval&AVX) != 0 && (ebx&0x00000020) != 0 {
|
||||
rval |= AVX2
|
||||
}
|
||||
@ -888,6 +892,12 @@ func support() Flags {
|
||||
if ebx&(1<<29) != 0 {
|
||||
rval |= SHA
|
||||
}
|
||||
if edx&(1<<26) != 0 {
|
||||
rval |= IBPB
|
||||
}
|
||||
if edx&(1<<27) != 0 {
|
||||
rval |= STIBP
|
||||
}
|
||||
|
||||
// Only detect AVX-512 features if XGETBV is supported
|
||||
if c&((1<<26)|(1<<27)) == (1<<26)|(1<<27) {
|
||||
|
||||
12
vendor/github.com/klauspost/cpuid/private/cpuid.go
generated
vendored
12
vendor/github.com/klauspost/cpuid/private/cpuid.go
generated
vendored
@ -70,6 +70,8 @@ const (
|
||||
rdtscp // RDTSCP Instruction
|
||||
cx16 // CMPXCHG16B Instruction
|
||||
sgx // Software Guard Extensions
|
||||
ibpb // Indirect Branch Restricted Speculation (IBRS) and Indirect Branch Predictor Barrier (IBPB)
|
||||
stibp // Single Thread Indirect Branch Predictors
|
||||
|
||||
// Performance indicators
|
||||
sse2slow // SSE2 is supported, but usually not faster
|
||||
@ -125,6 +127,8 @@ var flagNames = map[flags]string{
|
||||
rdtscp: "RDTSCP", // RDTSCP Instruction
|
||||
cx16: "CX16", // CMPXCHG16B Instruction
|
||||
sgx: "SGX", // Software Guard Extensions
|
||||
ibpb: "IBPB", // Indirect Branch Restricted Speculation and Indirect Branch Predictor Barrier
|
||||
stibp: "STIBP", // Single Thread Indirect Branch Predictors
|
||||
|
||||
// Performance indicators
|
||||
sse2slow: "SSE2SLOW", // SSE2 supported, but usually not faster
|
||||
@ -848,7 +852,7 @@ func support() flags {
|
||||
|
||||
// Check AVX2, AVX2 requires OS support, but BMI1/2 don't.
|
||||
if mfi >= 7 {
|
||||
_, ebx, ecx, _ := cpuidex(7, 0)
|
||||
_, ebx, ecx, edx := cpuidex(7, 0)
|
||||
if (rval&avx) != 0 && (ebx&0x00000020) != 0 {
|
||||
rval |= avx2
|
||||
}
|
||||
@ -882,6 +886,12 @@ func support() flags {
|
||||
if ebx&(1<<29) != 0 {
|
||||
rval |= sha
|
||||
}
|
||||
if edx&(1<<26) != 0 {
|
||||
rval |= ibpb
|
||||
}
|
||||
if edx&(1<<27) != 0 {
|
||||
rval |= stibp
|
||||
}
|
||||
|
||||
// Only detect AVX-512 features if XGETBV is supported
|
||||
if c&((1<<26)|(1<<27)) == (1<<26)|(1<<27) {
|
||||
|
||||
BIN
vendor/github.com/klauspost/cpuid/testdata/cpuid_data.zip
generated
vendored
BIN
vendor/github.com/klauspost/cpuid/testdata/cpuid_data.zip
generated
vendored
Binary file not shown.
9
vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE
generated
vendored
Normal file
9
vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
40
vendor/github.com/konsorten/go-windows-terminal-sequences/README.md
generated
vendored
Normal file
40
vendor/github.com/konsorten/go-windows-terminal-sequences/README.md
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
# Windows Terminal Sequences
|
||||
|
||||
This library allow for enabling Windows terminal color support for Go.
|
||||
|
||||
See [Console Virtual Terminal Sequences](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) for details.
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
sequences "github.com/konsorten/go-windows-terminal-sequences"
|
||||
)
|
||||
|
||||
func main() {
|
||||
sequences.EnableVirtualTerminalProcessing(syscall.Stdout, true)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Authors
|
||||
|
||||
The tool is sponsored by the [marvin + konsorten GmbH](http://www.konsorten.de).
|
||||
|
||||
We thank all the authors who provided code to this library:
|
||||
|
||||
* Felix Kollmann
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2018 marvin + konsorten GmbH (open-source@konsorten.de)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
1
vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod
generated
vendored
Normal file
1
vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module github.com/konsorten/go-windows-terminal-sequences
|
||||
36
vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go
generated
vendored
Normal file
36
vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// +build windows
|
||||
|
||||
package sequences
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
kernel32Dll *syscall.LazyDLL = syscall.NewLazyDLL("Kernel32.dll")
|
||||
setConsoleMode *syscall.LazyProc = kernel32Dll.NewProc("SetConsoleMode")
|
||||
)
|
||||
|
||||
func EnableVirtualTerminalProcessing(stream syscall.Handle, enable bool) error {
|
||||
const ENABLE_VIRTUAL_TERMINAL_PROCESSING uint32 = 0x4
|
||||
|
||||
var mode uint32
|
||||
err := syscall.GetConsoleMode(syscall.Stdout, &mode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if enable {
|
||||
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
} else {
|
||||
mode &^= ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
}
|
||||
|
||||
ret, _, err := setConsoleMode.Call(uintptr(unsafe.Pointer(stream)), uintptr(mode))
|
||||
if ret == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
48
vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_test.go
generated
vendored
Normal file
48
vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_test.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
// +build windows
|
||||
|
||||
package sequences
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStdoutSequencesOn(t *testing.T) {
|
||||
err := EnableVirtualTerminalProcessing(syscall.Stdout, true)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to enable VTP: %v", err)
|
||||
}
|
||||
defer EnableVirtualTerminalProcessing(syscall.Stdout, false)
|
||||
|
||||
fmt.Fprintf(os.Stdout, "\x1b[34mHello \x1b[35mWorld\x1b[0m!\n")
|
||||
}
|
||||
|
||||
func TestStdoutSequencesOff(t *testing.T) {
|
||||
err := EnableVirtualTerminalProcessing(syscall.Stdout, false)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to enable VTP: %v", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stdout, "\x1b[34mHello \x1b[35mWorld\x1b[0m!\n")
|
||||
}
|
||||
|
||||
func TestStderrSequencesOn(t *testing.T) {
|
||||
err := EnableVirtualTerminalProcessing(syscall.Stderr, true)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to enable VTP: %v", err)
|
||||
}
|
||||
defer EnableVirtualTerminalProcessing(syscall.Stderr, false)
|
||||
|
||||
fmt.Fprintf(os.Stderr, "\x1b[34mHello \x1b[35mWorld\x1b[0m!\n")
|
||||
}
|
||||
|
||||
func TestStderrSequencesOff(t *testing.T) {
|
||||
err := EnableVirtualTerminalProcessing(syscall.Stderr, false)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to enable VTP: %v", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "\x1b[34mHello \x1b[35mWorld\x1b[0m!\n")
|
||||
}
|
||||
2
vendor/github.com/lib/pq/.travis.sh
generated
vendored
2
vendor/github.com/lib/pq/.travis.sh
generated
vendored
@ -80,7 +80,7 @@ megacheck_install() {
|
||||
}
|
||||
|
||||
golint_install() {
|
||||
go get github.com/golang/lint/golint
|
||||
go get golang.org/x/lint/golint
|
||||
}
|
||||
|
||||
$1
|
||||
|
||||
4
vendor/github.com/lib/pq/.travis.yml
generated
vendored
4
vendor/github.com/lib/pq/.travis.yml
generated
vendored
@ -1,9 +1,9 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- master
|
||||
|
||||
sudo: true
|
||||
@ -44,7 +44,7 @@ script:
|
||||
- >
|
||||
goimports -d -e $(find -name '*.go') | awk '{ print } END { exit NR == 0 ? 0 : 1 }'
|
||||
- go vet ./...
|
||||
- megacheck -go 1.8 ./...
|
||||
- megacheck -go 1.9 ./...
|
||||
- golint ./...
|
||||
- PQTEST_BINARY_PARAMETERS=no go test -race -v ./...
|
||||
- PQTEST_BINARY_PARAMETERS=yes go test -race -v ./...
|
||||
|
||||
2
vendor/github.com/lib/pq/README.md
generated
vendored
2
vendor/github.com/lib/pq/README.md
generated
vendored
@ -10,7 +10,7 @@
|
||||
## Docs
|
||||
|
||||
For detailed documentation and basic usage examples, please see the package
|
||||
documentation at <http://godoc.org/github.com/lib/pq>.
|
||||
documentation at <https://godoc.org/github.com/lib/pq>.
|
||||
|
||||
## Tests
|
||||
|
||||
|
||||
2
vendor/github.com/lib/pq/bench_test.go
generated
vendored
2
vendor/github.com/lib/pq/bench_test.go
generated
vendored
@ -1,5 +1,3 @@
|
||||
// +build go1.1
|
||||
|
||||
package pq
|
||||
|
||||
import (
|
||||
|
||||
2
vendor/github.com/lib/pq/conn_go18.go
generated
vendored
2
vendor/github.com/lib/pq/conn_go18.go
generated
vendored
@ -1,5 +1,3 @@
|
||||
// +build go1.8
|
||||
|
||||
package pq
|
||||
|
||||
import (
|
||||
|
||||
2
vendor/github.com/lib/pq/doc.go
generated
vendored
2
vendor/github.com/lib/pq/doc.go
generated
vendored
@ -239,7 +239,7 @@ for more information). Note that the channel name will be truncated to 63
|
||||
bytes by the PostgreSQL server.
|
||||
|
||||
You can find a complete, working example of Listener usage at
|
||||
http://godoc.org/github.com/lib/pq/example/listen.
|
||||
https://godoc.org/github.com/lib/pq/example/listen.
|
||||
|
||||
*/
|
||||
package pq
|
||||
|
||||
1
vendor/github.com/lib/pq/go.mod
generated
vendored
Normal file
1
vendor/github.com/lib/pq/go.mod
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module github.com/lib/pq
|
||||
2
vendor/github.com/lib/pq/go18_test.go
generated
vendored
2
vendor/github.com/lib/pq/go18_test.go
generated
vendored
@ -1,5 +1,3 @@
|
||||
// +build go1.8
|
||||
|
||||
package pq
|
||||
|
||||
import (
|
||||
|
||||
3
vendor/github.com/lib/pq/notify.go
generated
vendored
3
vendor/github.com/lib/pq/notify.go
generated
vendored
@ -725,6 +725,9 @@ func (l *Listener) Close() error {
|
||||
}
|
||||
l.isClosed = true
|
||||
|
||||
// Unblock calls to Listen()
|
||||
l.reconnectCond.Broadcast()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/lib/pq/rows_test.go
generated
vendored
2
vendor/github.com/lib/pq/rows_test.go
generated
vendored
@ -1,5 +1,3 @@
|
||||
// +build go1.8
|
||||
|
||||
package pq
|
||||
|
||||
import (
|
||||
|
||||
8
vendor/github.com/lib/pq/ssl.go
generated
vendored
8
vendor/github.com/lib/pq/ssl.go
generated
vendored
@ -58,7 +58,13 @@ func ssl(o values) (func(net.Conn) (net.Conn, error), error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sslRenegotiation(&tlsConf)
|
||||
|
||||
// Accept renegotiation requests initiated by the backend.
|
||||
//
|
||||
// Renegotiation was deprecated then removed from PostgreSQL 9.5, but
|
||||
// the default configuration of older versions has it enabled. Redshift
|
||||
// also initiates renegotiations and cannot be reconfigured.
|
||||
tlsConf.Renegotiation = tls.RenegotiateFreelyAsClient
|
||||
|
||||
return func(conn net.Conn) (net.Conn, error) {
|
||||
client := tls.Client(conn, &tlsConf)
|
||||
|
||||
14
vendor/github.com/lib/pq/ssl_go1.7.go
generated
vendored
14
vendor/github.com/lib/pq/ssl_go1.7.go
generated
vendored
@ -1,14 +0,0 @@
|
||||
// +build go1.7
|
||||
|
||||
package pq
|
||||
|
||||
import "crypto/tls"
|
||||
|
||||
// Accept renegotiation requests initiated by the backend.
|
||||
//
|
||||
// Renegotiation was deprecated then removed from PostgreSQL 9.5, but
|
||||
// the default configuration of older versions has it enabled. Redshift
|
||||
// also initiates renegotiations and cannot be reconfigured.
|
||||
func sslRenegotiation(conf *tls.Config) {
|
||||
conf.Renegotiation = tls.RenegotiateFreelyAsClient
|
||||
}
|
||||
8
vendor/github.com/lib/pq/ssl_renegotiation.go
generated
vendored
8
vendor/github.com/lib/pq/ssl_renegotiation.go
generated
vendored
@ -1,8 +0,0 @@
|
||||
// +build !go1.7
|
||||
|
||||
package pq
|
||||
|
||||
import "crypto/tls"
|
||||
|
||||
// Renegotiation is not supported by crypto/tls until Go 1.7.
|
||||
func sslRenegotiation(*tls.Config) {}
|
||||
4
vendor/github.com/mattn/go-sqlite3/.travis.yml
generated
vendored
4
vendor/github.com/mattn/go-sqlite3/.travis.yml
generated
vendored
@ -12,18 +12,18 @@ env:
|
||||
matrix:
|
||||
- GOTAGS=
|
||||
- GOTAGS=libsqlite3
|
||||
- GOTAGS="sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable"
|
||||
- GOTAGS="sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable sqlite_unlock_notify"
|
||||
- GOTAGS=sqlite_vacuum_full
|
||||
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
|
||||
before_install:
|
||||
- |
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
brew update
|
||||
brew upgrade icu4c
|
||||
fi
|
||||
- |
|
||||
go get github.com/smartystreets/goconvey
|
||||
|
||||
7
vendor/github.com/mattn/go-sqlite3/README.md
generated
vendored
7
vendor/github.com/mattn/go-sqlite3/README.md
generated
vendored
@ -67,6 +67,7 @@ This is also known as a DSN string. (Data Source Name).
|
||||
|
||||
Options are append after the filename of the SQLite database.
|
||||
The database filename and options are seperated by an `?` (Question Mark).
|
||||
Options should be URL-encoded (see [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape)).
|
||||
|
||||
This also applies when using an in-memory database instead of a file.
|
||||
|
||||
@ -198,7 +199,7 @@ Additional information:
|
||||
|
||||
# Google Cloud Platform
|
||||
|
||||
Building on GCP is not possible because `Google Cloud Platform does not allow `gcc` to be executed.
|
||||
Building on GCP is not possible because Google Cloud Platform does not allow `gcc` to be executed.
|
||||
|
||||
Please work only with compiled final binaries.
|
||||
|
||||
@ -290,7 +291,7 @@ For example the TDM-GCC Toolchain can be found [here](ttps://sourceforge.net/pro
|
||||
When receiving a compile time error referencing recompile with `-FPIC` then you
|
||||
are probably using a hardend system.
|
||||
|
||||
You can copile the library on a hardend system with the following command.
|
||||
You can compile the library on a hardend system with the following command.
|
||||
|
||||
```bash
|
||||
go build -ldflags '-extldflags=-fno-PIC'
|
||||
@ -473,7 +474,7 @@ For an example see [shaxbee/go-spatialite](https://github.com/shaxbee/go-spatial
|
||||
|
||||
For more information see [#289](https://github.com/mattn/go-sqlite3/issues/289)
|
||||
|
||||
- Trying to execure a `.` (dot) command throws an error.
|
||||
- Trying to execute a `.` (dot) command throws an error.
|
||||
|
||||
Error: `Error: near ".": syntax error`
|
||||
Dot command are part of SQLite3 CLI not of this library.
|
||||
|
||||
6
vendor/github.com/mattn/go-sqlite3/callback.go
generated
vendored
6
vendor/github.com/mattn/go-sqlite3/callback.go
generated
vendored
@ -77,6 +77,12 @@ func updateHookTrampoline(handle uintptr, op int, db *C.char, table *C.char, row
|
||||
callback(op, C.GoString(db), C.GoString(table), rowid)
|
||||
}
|
||||
|
||||
//export authorizerTrampoline
|
||||
func authorizerTrampoline(handle uintptr, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int {
|
||||
callback := lookupHandle(handle).(func(int, string, string, string) int)
|
||||
return callback(op, C.GoString(arg1), C.GoString(arg2), C.GoString(arg3))
|
||||
}
|
||||
|
||||
// Use handles to avoid passing Go pointers to C.
|
||||
|
||||
type handleVal struct {
|
||||
|
||||
20969
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
generated
vendored
20969
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
generated
vendored
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user