mirror of
https://github.com/astaxie/beego.git
synced 2024-11-22 15:30:55 +00:00
update mod
This commit is contained in:
parent
2a8d6f943f
commit
55d9b69cd9
15
go.mod
15
go.mod
@ -7,7 +7,7 @@ require (
|
|||||||
github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542
|
github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542
|
||||||
github.com/belogik/goes v0.0.0-20151229125003-e54d722c3aff
|
github.com/belogik/goes v0.0.0-20151229125003-e54d722c3aff
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737
|
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737
|
||||||
github.com/casbin/casbin v1.6.0
|
github.com/casbin/casbin v1.7.0
|
||||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58
|
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58
|
||||||
github.com/couchbase/go-couchbase v0.0.0-20181019154153-595f46701cbc
|
github.com/couchbase/go-couchbase v0.0.0-20181019154153-595f46701cbc
|
||||||
github.com/couchbase/gomemcached v0.0.0-20180723192129-20e69a1ee160 // indirect
|
github.com/couchbase/gomemcached v0.0.0-20180723192129-20e69a1ee160 // indirect
|
||||||
@ -17,13 +17,14 @@ require (
|
|||||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712 // indirect
|
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712 // indirect
|
||||||
github.com/elazarl/go-bindata-assetfs v0.0.0-20180223110309-38087fe4dafb
|
github.com/elazarl/go-bindata-assetfs v0.0.0-20180223110309-38087fe4dafb
|
||||||
github.com/go-redis/redis v6.14.2+incompatible
|
github.com/go-redis/redis v6.14.2+incompatible
|
||||||
github.com/go-sql-driver/mysql v1.4.0
|
github.com/go-sql-driver/mysql v1.4.1
|
||||||
github.com/gogo/protobuf v1.1.1
|
github.com/gogo/protobuf v1.1.1
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
|
||||||
github.com/gomodule/redigo v2.0.0+incompatible
|
github.com/gomodule/redigo v2.0.0+incompatible
|
||||||
github.com/lib/pq v1.0.0
|
github.com/lib/pq v1.0.0
|
||||||
github.com/mattn/go-sqlite3 v1.10.0
|
github.com/mattn/go-sqlite3 v1.10.0
|
||||||
github.com/onsi/gomega v1.4.2 // indirect
|
github.com/onsi/ginkgo v1.7.0 // indirect
|
||||||
|
github.com/onsi/gomega v1.4.3 // indirect
|
||||||
github.com/pelletier/go-toml v1.2.0 // indirect
|
github.com/pelletier/go-toml v1.2.0 // indirect
|
||||||
github.com/pkg/errors v0.8.0 // indirect
|
github.com/pkg/errors v0.8.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
@ -34,7 +35,11 @@ require (
|
|||||||
github.com/stretchr/testify v1.2.2 // indirect
|
github.com/stretchr/testify v1.2.2 // indirect
|
||||||
github.com/syndtr/goleveldb v0.0.0-20181105012736-f9080354173f // indirect
|
github.com/syndtr/goleveldb v0.0.0-20181105012736-f9080354173f // indirect
|
||||||
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b // indirect
|
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b // indirect
|
||||||
golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb
|
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869
|
||||||
google.golang.org/appengine v1.1.0 // indirect
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a // indirect
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20181121002834-0cf1ed9e522b // indirect
|
||||||
|
google.golang.org/appengine v1.3.0 // indirect
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||||
gopkg.in/yaml.v2 v2.2.1
|
gopkg.in/yaml.v2 v2.2.1
|
||||||
)
|
)
|
||||||
|
16
go.sum
16
go.sum
@ -12,6 +12,8 @@ github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737 h1:rRISKWyXfVx
|
|||||||
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
||||||
github.com/casbin/casbin v1.6.0 h1:uIhuV5I0ilXGUm3y+xJ8nG7VOnYDeZZQiNsFOTF2QmI=
|
github.com/casbin/casbin v1.6.0 h1:uIhuV5I0ilXGUm3y+xJ8nG7VOnYDeZZQiNsFOTF2QmI=
|
||||||
github.com/casbin/casbin v1.6.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
|
github.com/casbin/casbin v1.6.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
|
||||||
|
github.com/casbin/casbin v1.7.0 h1:PuzlE8w0JBg/DhIqnkF1Dewf3z+qmUZMVN07PonvVUQ=
|
||||||
|
github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
|
||||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
|
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
|
||||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||||
github.com/couchbase/go-couchbase v0.0.0-20181019154153-595f46701cbc h1:Byzmalcea3rzOdgt4Ny3xrtXkd25zUMPFI5oeKksSbU=
|
github.com/couchbase/go-couchbase v0.0.0-20181019154153-595f46701cbc h1:Byzmalcea3rzOdgt4Ny3xrtXkd25zUMPFI5oeKksSbU=
|
||||||
@ -34,6 +36,8 @@ github.com/go-redis/redis v6.14.2+incompatible h1:UE9pLhzmWf+xHNmZsoccjXosPicuiN
|
|||||||
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||||
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
|
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
|
||||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||||
@ -50,8 +54,10 @@ github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK86
|
|||||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
|
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
|
github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
|
||||||
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||||
@ -74,18 +80,28 @@ github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b h1:0Ve0/CCjiAiyKddUM
|
|||||||
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
|
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
|
||||||
golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb h1:Ah9YqXLj6fEgeKqcmBuLCbAsrF3ScD7dJ/bYM0C6tXI=
|
golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb h1:Ah9YqXLj6fEgeKqcmBuLCbAsrF3ScD7dJ/bYM0C6tXI=
|
||||||
golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869 h1:kkXA53yGe04D0adEYJwEVQjeBppL01Exg+fnMjfUraU=
|
||||||
|
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
|
||||||
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181121002834-0cf1ed9e522b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
|
google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
||||||
|
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
|
62
vendor/github.com/casbin/casbin/README.md
generated
vendored
62
vendor/github.com/casbin/casbin/README.md
generated
vendored
@ -18,11 +18,10 @@ Casbin is a powerful and efficient open-source access control library for Golang
|
|||||||
|
|
||||||
## All the languages supported by Casbin:
|
## All the languages supported by Casbin:
|
||||||
|
|
||||||
- Golang: [Casbin](https://github.com/casbin/casbin) (production-ready)
|
[![golang](https://casbin.org/docs/assets/langs/golang.png)](https://github.com/casbin/casbin) | [![java](https://casbin.org/docs/assets/langs/java.png)](https://github.com/casbin/jcasbin) | [![nodejs](https://casbin.org/docs/assets/langs/nodejs.png)](https://github.com/casbin/node-casbin) | [![php](https://casbin.org/docs/assets/langs/php.png)](https://github.com/php-casbin/php-casbin)
|
||||||
- Java: [jCasbin](https://github.com/casbin/jcasbin) (production-ready)
|
----|----|----|----
|
||||||
- PHP: [PHP-Casbin](https://github.com/sstutz/php-casbin) (experimental)
|
[Casbin](https://github.com/casbin/casbin) | [jCasbin](https://github.com/casbin/jcasbin) | [node-Casbin](https://github.com/casbin/node-casbin) | [PHP-Casbin](https://github.com/php-casbin/php-casbin)
|
||||||
- Node.js: [node-casbin](https://github.com/casbin/node-casbin) (WIP)
|
production-ready | production-ready | production-ready | production-ready
|
||||||
- C++: xCasbin (WIP)
|
|
||||||
|
|
||||||
## Table of contents
|
## Table of contents
|
||||||
|
|
||||||
@ -81,9 +80,6 @@ e = some(where (p.eft == allow))
|
|||||||
[matchers]
|
[matchers]
|
||||||
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
|
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
|
||||||
|
|
||||||
# We also support multi-line mode by appending '\' in the end:
|
|
||||||
# m = r.sub == p.sub && r.obj == p.obj \
|
|
||||||
# && r.act == p.act
|
|
||||||
```
|
```
|
||||||
|
|
||||||
An example policy for ACL model is like:
|
An example policy for ACL model is like:
|
||||||
@ -98,6 +94,27 @@ It means:
|
|||||||
- alice can read data1
|
- alice can read data1
|
||||||
- bob can write data2
|
- bob can write data2
|
||||||
|
|
||||||
|
We also support multi-line mode by appending '\\' in the end:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# Matchers
|
||||||
|
[matchers]
|
||||||
|
m = r.sub == p.sub && r.obj == p.obj \
|
||||||
|
&& r.act == p.act
|
||||||
|
```
|
||||||
|
|
||||||
|
Further more, if you are using ABAC, you can try operator `in` like following in Casbin **golang** edition (jCasbin and Node-Casbin are not supported yet):
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# Matchers
|
||||||
|
[matchers]
|
||||||
|
m = r.obj == p.obj && r.act == p.act || r.obj in ('data2', 'data3')
|
||||||
|
```
|
||||||
|
|
||||||
|
But you **SHOULD** make sure that the length of the array is **MORE** than **1**, otherwise there will cause it to panic.
|
||||||
|
|
||||||
|
For more operators, you may take a look at [govaluate](https://github.com/Knetic/govaluate)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
What Casbin does:
|
What Casbin does:
|
||||||
@ -121,7 +138,7 @@ go get github.com/casbin/casbin
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
For documentation, please see: [Our Wiki](https://github.com/casbin/casbin/wiki)
|
https://casbin.org/docs/en/overview
|
||||||
|
|
||||||
## Online editor
|
## Online editor
|
||||||
|
|
||||||
@ -129,12 +146,7 @@ You can also use the online editor (http://casbin.org/editor/) to write your Cas
|
|||||||
|
|
||||||
## Tutorials
|
## Tutorials
|
||||||
|
|
||||||
- [Basic Role-Based HTTP Authorization in Go with Casbin](https://zupzup.org/casbin-http-role-auth) (or [Chinese translation](https://studygolang.com/articles/12323))
|
https://casbin.org/docs/en/tutorials
|
||||||
- [Policy enforcements on Kubernetes with Banzai Cloud's Pipeline and Casbin](https://banzaicloud.com/blog/policy-enforcement-k8s/)
|
|
||||||
- [Using Casbin with Beego: 1. Get started and test (in Chinese)](https://blog.csdn.net/hotqin888/article/details/78460385)
|
|
||||||
- [Using Casbin with Beego: 2. Policy storage (in Chinese)](https://blog.csdn.net/hotqin888/article/details/78571240)
|
|
||||||
- [Using Casbin with Beego: 3. Policy query (in Chinese)](https://blog.csdn.net/hotqin888/article/details/78992250)
|
|
||||||
- [Using Casbin with Beego: 4. Policy update (in Chinese)](https://blog.csdn.net/hotqin888/article/details/80032538)
|
|
||||||
|
|
||||||
## Get started
|
## Get started
|
||||||
|
|
||||||
@ -189,7 +201,7 @@ In Casbin, the policy storage is implemented as an adapter (aka middleware for C
|
|||||||
|
|
||||||
Adapter | Type | Author | Description
|
Adapter | Type | Author | Description
|
||||||
----|------|----|----
|
----|------|----|----
|
||||||
[File Adapter (built-in)](https://github.com/casbin/casbin/wiki/Policy-persistence#file-adapter) | File | Casbin | Persistence for [.CSV (Comma-Separated Values)](https://en.wikipedia.org/wiki/Comma-separated_values) files
|
[File Adapter (built-in)](https://casbin.org/docs/en/policy-storage#file-adapter-built-in) | File | Casbin | Persistence for [.CSV (Comma-Separated Values)](https://en.wikipedia.org/wiki/Comma-separated_values) files
|
||||||
[Filtered File Adapter (built-in)](https://github.com/casbin/casbin#policy-enforcement-at-scale) | File | [@faceless-saint](https://github.com/faceless-saint) | Persistence for [.CSV (Comma-Separated Values)](https://en.wikipedia.org/wiki/Comma-separated_values) files with policy subset loading support
|
[Filtered File Adapter (built-in)](https://github.com/casbin/casbin#policy-enforcement-at-scale) | File | [@faceless-saint](https://github.com/faceless-saint) | Persistence for [.CSV (Comma-Separated Values)](https://en.wikipedia.org/wiki/Comma-separated_values) files with policy subset loading support
|
||||||
[Xorm Adapter](https://github.com/casbin/xorm-adapter) | ORM | Casbin | MySQL, PostgreSQL, TiDB, SQLite, SQL Server, Oracle are supported by [Xorm](https://github.com/go-xorm/xorm/)
|
[Xorm Adapter](https://github.com/casbin/xorm-adapter) | ORM | Casbin | MySQL, PostgreSQL, TiDB, SQLite, SQL Server, Oracle are supported by [Xorm](https://github.com/go-xorm/xorm/)
|
||||||
[Gorm Adapter](https://github.com/casbin/gorm-adapter) | ORM | Casbin | MySQL, PostgreSQL, Sqlite3, SQL Server are supported by [Gorm](https://github.com/jinzhu/gorm/)
|
[Gorm Adapter](https://github.com/casbin/gorm-adapter) | ORM | Casbin | MySQL, PostgreSQL, Sqlite3, SQL Server are supported by [Gorm](https://github.com/jinzhu/gorm/)
|
||||||
@ -208,7 +220,7 @@ Adapter | Type | Author | Description
|
|||||||
[Minio/AWS S3 Adapter](https://github.com/Soluto/casbin-minio-adapter) | Object storage | [Soluto](https://github.com/Soluto) | Persistence for [Minio](https://github.com/minio/minio) and [Amazon S3](https://aws.amazon.com/s3/)
|
[Minio/AWS S3 Adapter](https://github.com/Soluto/casbin-minio-adapter) | Object storage | [Soluto](https://github.com/Soluto) | Persistence for [Minio](https://github.com/minio/minio) and [Amazon S3](https://aws.amazon.com/s3/)
|
||||||
[Bolt Adapter](https://github.com/wirepair/bolt-adapter) | KV store | [@wirepair](https://github.com/wirepair) | Persistence for [Bolt](https://github.com/boltdb/bolt)
|
[Bolt Adapter](https://github.com/wirepair/bolt-adapter) | KV store | [@wirepair](https://github.com/wirepair) | Persistence for [Bolt](https://github.com/boltdb/bolt)
|
||||||
|
|
||||||
For details of adapters, please refer to the documentation: https://github.com/casbin/casbin/wiki/Policy-persistence
|
For details of adapters, please refer to the documentation: https://casbin.org/docs/en/policy-storage
|
||||||
|
|
||||||
## Policy enforcement at scale
|
## Policy enforcement at scale
|
||||||
|
|
||||||
@ -311,9 +323,9 @@ Priority | [priority_model.conf](https://github.com/casbin/casbin/blob/master/ex
|
|||||||
|
|
||||||
## How to use Casbin as a service?
|
## How to use Casbin as a service?
|
||||||
|
|
||||||
- [Go-Simple-API-Gateway](https://github.com/Soontao/go-simple-api-gateway): A simple API gateway written by golang, supports for authentication and authorization
|
- [Casbin Server](https://github.com/casbin/casbin-server): The official ``Casbin as a Service`` solution based on [gRPC](https://grpc.io/), both Management API and RBAC API are provided.
|
||||||
- [Casbin Server](https://github.com/casbin/casbin-server): Casbin as a Service via RESTful, only exposed permission checking API
|
- [Go-Simple-API-Gateway](https://github.com/Soontao/go-simple-api-gateway): A simple API gateway written by golang, supports for authentication and authorization.
|
||||||
- [middleware-acl](https://github.com/luk4z7/middleware-acl): RESTful access control middleware based on Casbin
|
- [middleware-acl](https://github.com/luk4z7/middleware-acl): RESTful access control middleware based on Casbin.
|
||||||
|
|
||||||
## Our adopters
|
## Our adopters
|
||||||
|
|
||||||
@ -342,6 +354,7 @@ Priority | [priority_model.conf](https://github.com/casbin/casbin/blob/master/ex
|
|||||||
- [Skydive](https://github.com/skydive-project/skydive): An open source real-time network topology and protocols analyzer, via direct integration, see: [model (in code)](https://github.com/skydive-project/skydive/blob/master/config/config.go#L136-L140), [policy rules](https://github.com/skydive-project/skydive/blob/master/rbac/policy.csv)
|
- [Skydive](https://github.com/skydive-project/skydive): An open source real-time network topology and protocols analyzer, via direct integration, see: [model (in code)](https://github.com/skydive-project/skydive/blob/master/config/config.go#L136-L140), [policy rules](https://github.com/skydive-project/skydive/blob/master/rbac/policy.csv)
|
||||||
- [Zenpress](https://github.com/insionng/zenpress): A CMS system written in Golang, via direct integration, see: [model](https://github.com/insionng/zenpress/blob/master/content/config/rbac_model.conf), [policy rules (in Gorm)](https://github.com/insionng/zenpress/blob/master/model/user.go#L53-L77)
|
- [Zenpress](https://github.com/insionng/zenpress): A CMS system written in Golang, via direct integration, see: [model](https://github.com/insionng/zenpress/blob/master/content/config/rbac_model.conf), [policy rules (in Gorm)](https://github.com/insionng/zenpress/blob/master/model/user.go#L53-L77)
|
||||||
- [Argo CD](https://github.com/argoproj/argo-cd): GitOps continuous delivery for Kubernetes, via direct integration, see: [model](https://github.com/argoproj/argo-cd/blob/master/util/rbac/model.conf), [policy rules](https://github.com/argoproj/argo-cd/blob/master/util/rbac/builtin-policy.csv)
|
- [Argo CD](https://github.com/argoproj/argo-cd): GitOps continuous delivery for Kubernetes, via direct integration, see: [model](https://github.com/argoproj/argo-cd/blob/master/util/rbac/model.conf), [policy rules](https://github.com/argoproj/argo-cd/blob/master/util/rbac/builtin-policy.csv)
|
||||||
|
- [Muxi Cloud](https://github.com/muxiyun/Mae): PaaS of Muxi Cloud, an easier way to manage Kubernetes cluster, via direct integration, see: [model](https://github.com/muxiyun/Mae/blob/master/conf/casbinmodel.conf), [policy rules (in code)](https://github.com/muxiyun/Mae/blob/master/pkg/casbin/initPolicy.go#L21-L95)
|
||||||
- [EngineerCMS](https://github.com/3xxx/EngineerCMS): A CMS to manage knowledge for engineers, via direct integration, see: [model](https://github.com/3xxx/EngineerCMS/blob/master/conf/rbac_model.conf), [policy rules (in SQLite)](https://github.com/3xxx/EngineerCMS/blob/master/database/engineer.db)
|
- [EngineerCMS](https://github.com/3xxx/EngineerCMS): A CMS to manage knowledge for engineers, via direct integration, see: [model](https://github.com/3xxx/EngineerCMS/blob/master/conf/rbac_model.conf), [policy rules (in SQLite)](https://github.com/3xxx/EngineerCMS/blob/master/database/engineer.db)
|
||||||
- [Cyber Auth API](https://github.com/CyberlifeCN/cyber-auth-api): A Golang authentication API project, via direct integration, see: [model](https://github.com/CyberlifeCN/cyber-auth-api/blob/master/conf/authz_model.conf), [policy rules](https://github.com/CyberlifeCN/cyber-auth-api/blob/master/conf/authz_policy.csv)
|
- [Cyber Auth API](https://github.com/CyberlifeCN/cyber-auth-api): A Golang authentication API project, via direct integration, see: [model](https://github.com/CyberlifeCN/cyber-auth-api/blob/master/conf/authz_model.conf), [policy rules](https://github.com/CyberlifeCN/cyber-auth-api/blob/master/conf/authz_policy.csv)
|
||||||
- [IRIS Community](https://github.com/irisnet/iris-community): Website for IRIS Community Activities, via direct integration, see: [model](https://github.com/irisnet/iris-community/blob/master/authz/authz_model.conf), [policy rules](https://github.com/irisnet/iris-community/blob/master/authz/authz_policy.csv)
|
- [IRIS Community](https://github.com/irisnet/iris-community): Website for IRIS Community Activities, via direct integration, see: [model](https://github.com/irisnet/iris-community/blob/master/authz/authz_model.conf), [policy rules](https://github.com/irisnet/iris-community/blob/master/authz/authz_policy.csv)
|
||||||
@ -349,7 +362,7 @@ Priority | [priority_model.conf](https://github.com/casbin/casbin/blob/master/ex
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the [Apache 2.0 license](https://github.com/casbin/casbin/blob/master/LICENSE).
|
This project is licensed under the [Apache 2.0 license](LICENSE).
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
|
||||||
@ -357,10 +370,3 @@ If you have any issues or feature requests, please contact us. PR is welcomed.
|
|||||||
- https://github.com/casbin/casbin/issues
|
- https://github.com/casbin/casbin/issues
|
||||||
- hsluoyz@gmail.com
|
- hsluoyz@gmail.com
|
||||||
- Tencent QQ group: [546057381](//shang.qq.com/wpa/qunwpa?idkey=8ac8b91fc97ace3d383d0035f7aa06f7d670fd8e8d4837347354a31c18fac885)
|
- Tencent QQ group: [546057381](//shang.qq.com/wpa/qunwpa?idkey=8ac8b91fc97ace3d383d0035f7aa06f7d670fd8e8d4837347354a31c18fac885)
|
||||||
|
|
||||||
## Donation
|
|
||||||
|
|
||||||
[![Patreon](https://hsluoyz.github.io/donation/patreon.png)](http://www.patreon.com/yangluo)
|
|
||||||
|
|
||||||
![Alipay](https://hsluoyz.github.io/donation/donate_alipay.png)
|
|
||||||
![Wechat](https://hsluoyz.github.io/donation/donate_weixin.png)
|
|
||||||
|
61
vendor/github.com/casbin/casbin/enforcer.go
generated
vendored
61
vendor/github.com/casbin/casbin/enforcer.go
generated
vendored
@ -19,8 +19,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/Knetic/govaluate"
|
"github.com/Knetic/govaluate"
|
||||||
|
|
||||||
"github.com/casbin/casbin/effect"
|
"github.com/casbin/casbin/effect"
|
||||||
|
"github.com/casbin/casbin/log"
|
||||||
"github.com/casbin/casbin/model"
|
"github.com/casbin/casbin/model"
|
||||||
"github.com/casbin/casbin/persist"
|
"github.com/casbin/casbin/persist"
|
||||||
"github.com/casbin/casbin/persist/file-adapter"
|
"github.com/casbin/casbin/persist/file-adapter"
|
||||||
@ -53,8 +53,6 @@ type Enforcer struct {
|
|||||||
// e := casbin.NewEnforcer("path/to/basic_model.conf", a)
|
// e := casbin.NewEnforcer("path/to/basic_model.conf", a)
|
||||||
func NewEnforcer(params ...interface{}) *Enforcer {
|
func NewEnforcer(params ...interface{}) *Enforcer {
|
||||||
e := &Enforcer{}
|
e := &Enforcer{}
|
||||||
e.rm = defaultrolemanager.NewRoleManager(10)
|
|
||||||
e.eft = effect.NewDefaultEffector()
|
|
||||||
|
|
||||||
parsedParamLen := 0
|
parsedParamLen := 0
|
||||||
if len(params) >= 1 {
|
if len(params) >= 1 {
|
||||||
@ -67,28 +65,28 @@ func NewEnforcer(params ...interface{}) *Enforcer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(params)-parsedParamLen == 2 {
|
if len(params)-parsedParamLen == 2 {
|
||||||
switch params[0].(type) {
|
switch p0 := params[0].(type) {
|
||||||
case string:
|
case string:
|
||||||
switch params[1].(type) {
|
switch p1 := params[1].(type) {
|
||||||
case string:
|
case string:
|
||||||
e.InitWithFile(params[0].(string), params[1].(string))
|
e.InitWithFile(p0, p1)
|
||||||
default:
|
default:
|
||||||
e.InitWithAdapter(params[0].(string), params[1].(persist.Adapter))
|
e.InitWithAdapter(p0, p1.(persist.Adapter))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
switch params[1].(type) {
|
switch params[1].(type) {
|
||||||
case string:
|
case string:
|
||||||
panic("Invalid parameters for enforcer.")
|
panic("Invalid parameters for enforcer.")
|
||||||
default:
|
default:
|
||||||
e.InitWithModelAndAdapter(params[0].(model.Model), params[1].(persist.Adapter))
|
e.InitWithModelAndAdapter(p0.(model.Model), params[1].(persist.Adapter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if len(params)-parsedParamLen == 1 {
|
} else if len(params)-parsedParamLen == 1 {
|
||||||
switch params[0].(type) {
|
switch p0 := params[0].(type) {
|
||||||
case string:
|
case string:
|
||||||
e.InitWithFile(params[0].(string), "")
|
e.InitWithFile(p0, "")
|
||||||
default:
|
default:
|
||||||
e.InitWithModelAndAdapter(params[0].(model.Model), nil)
|
e.InitWithModelAndAdapter(p0.(model.Model), nil)
|
||||||
}
|
}
|
||||||
} else if len(params)-parsedParamLen == 0 {
|
} else if len(params)-parsedParamLen == 0 {
|
||||||
e.InitWithFile("", "")
|
e.InitWithFile("", "")
|
||||||
@ -116,7 +114,6 @@ func (e *Enforcer) InitWithAdapter(modelPath string, adapter persist.Adapter) {
|
|||||||
// InitWithModelAndAdapter initializes an enforcer with a model and a database adapter.
|
// InitWithModelAndAdapter initializes an enforcer with a model and a database adapter.
|
||||||
func (e *Enforcer) InitWithModelAndAdapter(m model.Model, adapter persist.Adapter) {
|
func (e *Enforcer) InitWithModelAndAdapter(m model.Model, adapter persist.Adapter) {
|
||||||
e.adapter = adapter
|
e.adapter = adapter
|
||||||
e.watcher = nil
|
|
||||||
|
|
||||||
e.model = m
|
e.model = m
|
||||||
e.model.PrintModel()
|
e.model.PrintModel()
|
||||||
@ -131,6 +128,10 @@ func (e *Enforcer) InitWithModelAndAdapter(m model.Model, adapter persist.Adapte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *Enforcer) initialize() {
|
func (e *Enforcer) initialize() {
|
||||||
|
e.rm = defaultrolemanager.NewRoleManager(10)
|
||||||
|
e.eft = effect.NewDefaultEffector()
|
||||||
|
e.watcher = nil
|
||||||
|
|
||||||
e.enabled = true
|
e.enabled = true
|
||||||
e.autoSave = true
|
e.autoSave = true
|
||||||
e.autoBuildRoleLinks = true
|
e.autoBuildRoleLinks = true
|
||||||
@ -226,9 +227,9 @@ func (e *Enforcer) LoadFilteredPolicy(filter interface{}) error {
|
|||||||
var filteredAdapter persist.FilteredAdapter
|
var filteredAdapter persist.FilteredAdapter
|
||||||
|
|
||||||
// Attempt to cast the Adapter as a FilteredAdapter
|
// Attempt to cast the Adapter as a FilteredAdapter
|
||||||
switch e.adapter.(type) {
|
switch adapter := e.adapter.(type) {
|
||||||
case persist.FilteredAdapter:
|
case persist.FilteredAdapter:
|
||||||
filteredAdapter = e.adapter.(persist.FilteredAdapter)
|
filteredAdapter = adapter
|
||||||
default:
|
default:
|
||||||
return errors.New("filtered policies are not supported by this adapter")
|
return errors.New("filtered policies are not supported by this adapter")
|
||||||
}
|
}
|
||||||
@ -271,9 +272,9 @@ func (e *Enforcer) EnableEnforce(enable bool) {
|
|||||||
e.enabled = enable
|
e.enabled = enable
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableLog changes whether to print Casbin log to the standard output.
|
// EnableLog changes whether Casbin will log messages to the Logger.
|
||||||
func (e *Enforcer) EnableLog(enable bool) {
|
func (e *Enforcer) EnableLog(enable bool) {
|
||||||
util.EnableLog = enable
|
log.GetLogger().EnableLog(enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableAutoSave controls whether to save a policy rule automatically to the adapter when it is added or removed.
|
// EnableAutoSave controls whether to save a policy rule automatically to the adapter when it is added or removed.
|
||||||
@ -311,7 +312,10 @@ func (e *Enforcer) Enforce(rvals ...interface{}) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expString := e.model["m"]["m"].Value
|
expString := e.model["m"]["m"].Value
|
||||||
expression, _ := govaluate.NewEvaluableExpressionWithFunctions(expString, functions)
|
expression, err := govaluate.NewEvaluableExpressionWithFunctions(expString, functions)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
var policyEffects []effect.Effect
|
var policyEffects []effect.Effect
|
||||||
var matcherResults []float64
|
var matcherResults []float64
|
||||||
@ -320,7 +324,7 @@ func (e *Enforcer) Enforce(rvals ...interface{}) bool {
|
|||||||
matcherResults = make([]float64, policyLen)
|
matcherResults = make([]float64, policyLen)
|
||||||
|
|
||||||
for i, pvals := range e.model["p"]["p"].Policy {
|
for i, pvals := range e.model["p"]["p"].Policy {
|
||||||
// util.LogPrint("Policy Rule: ", pvals)
|
// log.LogPrint("Policy Rule: ", pvals)
|
||||||
|
|
||||||
parameters := make(map[string]interface{}, 8)
|
parameters := make(map[string]interface{}, 8)
|
||||||
for j, token := range e.model["r"]["r"].Tokens {
|
for j, token := range e.model["r"]["r"].Tokens {
|
||||||
@ -331,25 +335,25 @@ func (e *Enforcer) Enforce(rvals ...interface{}) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result, err := expression.Evaluate(parameters)
|
result, err := expression.Evaluate(parameters)
|
||||||
// util.LogPrint("Result: ", result)
|
// log.LogPrint("Result: ", result)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
policyEffects[i] = effect.Indeterminate
|
policyEffects[i] = effect.Indeterminate
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch result.(type) {
|
switch result := result.(type) {
|
||||||
case bool:
|
case bool:
|
||||||
if !result.(bool) {
|
if !result {
|
||||||
policyEffects[i] = effect.Indeterminate
|
policyEffects[i] = effect.Indeterminate
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
case float64:
|
case float64:
|
||||||
if result.(float64) == 0 {
|
if result == 0 {
|
||||||
policyEffects[i] = effect.Indeterminate
|
policyEffects[i] = effect.Indeterminate
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
matcherResults[i] = result.(float64)
|
matcherResults[i] = result
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
panic(errors.New("matcher result should be bool, int or float"))
|
panic(errors.New("matcher result should be bool, int or float"))
|
||||||
@ -385,7 +389,7 @@ func (e *Enforcer) Enforce(rvals ...interface{}) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result, err := expression.Evaluate(parameters)
|
result, err := expression.Evaluate(parameters)
|
||||||
// util.LogPrint("Result: ", result)
|
// log.LogPrint("Result: ", result)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
policyEffects[0] = effect.Indeterminate
|
policyEffects[0] = effect.Indeterminate
|
||||||
@ -399,16 +403,15 @@ func (e *Enforcer) Enforce(rvals ...interface{}) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// util.LogPrint("Rule Results: ", policyEffects)
|
// log.LogPrint("Rule Results: ", policyEffects)
|
||||||
|
|
||||||
result, err := e.eft.MergeEffects(e.model["e"]["e"].Value, policyEffects, matcherResults)
|
result, err := e.eft.MergeEffects(e.model["e"]["e"].Value, policyEffects, matcherResults)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// only generate the request --> result string if the message
|
// Log request.
|
||||||
// is going to be logged.
|
if log.GetLogger().IsEnabled() {
|
||||||
if util.EnableLog {
|
|
||||||
reqStr := "Request: "
|
reqStr := "Request: "
|
||||||
for i, rval := range rvals {
|
for i, rval := range rvals {
|
||||||
if i != len(rvals)-1 {
|
if i != len(rvals)-1 {
|
||||||
@ -418,7 +421,7 @@ func (e *Enforcer) Enforce(rvals ...interface{}) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
reqStr += fmt.Sprintf(" ---> %t", result)
|
reqStr += fmt.Sprintf(" ---> %t", result)
|
||||||
util.LogPrint(reqStr)
|
log.LogPrint(reqStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
42
vendor/github.com/casbin/casbin/log/default_logger.go
generated
vendored
Normal file
42
vendor/github.com/casbin/casbin/log/default_logger.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2018 The casbin Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package log
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
|
// DefaultLogger is the implementation for a Logger using golang log.
|
||||||
|
type DefaultLogger struct {
|
||||||
|
enable bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DefaultLogger) EnableLog(enable bool) {
|
||||||
|
l.enable = enable
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DefaultLogger) IsEnabled() bool {
|
||||||
|
return l.enable
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DefaultLogger) Print(v ...interface{}) {
|
||||||
|
if l.enable {
|
||||||
|
log.Print(v...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DefaultLogger) Printf(format string, v ...interface{}) {
|
||||||
|
if l.enable {
|
||||||
|
log.Printf(format, v...)
|
||||||
|
}
|
||||||
|
}
|
@ -12,23 +12,26 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package util
|
package log
|
||||||
|
|
||||||
import "log"
|
var logger Logger = &DefaultLogger{}
|
||||||
|
|
||||||
// EnableLog controls whether to print log to console.
|
// SetLogger sets the current logger.
|
||||||
var EnableLog = true
|
func SetLogger(l Logger) {
|
||||||
|
logger = l
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLogger returns the current logger.
|
||||||
|
func GetLogger() Logger {
|
||||||
|
return logger
|
||||||
|
}
|
||||||
|
|
||||||
// LogPrint prints the log.
|
// LogPrint prints the log.
|
||||||
func LogPrint(v ...interface{}) {
|
func LogPrint(v ...interface{}) {
|
||||||
if EnableLog {
|
logger.Print(v...)
|
||||||
log.Print(v...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogPrintf prints the log with the format.
|
// LogPrintf prints the log with the format.
|
||||||
func LogPrintf(format string, v ...interface{}) {
|
func LogPrintf(format string, v ...interface{}) {
|
||||||
if EnableLog {
|
logger.Printf(format, v...)
|
||||||
log.Printf(format, v...)
|
|
||||||
}
|
|
||||||
}
|
}
|
30
vendor/github.com/casbin/casbin/log/logger.go
generated
vendored
Normal file
30
vendor/github.com/casbin/casbin/log/logger.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2018 The casbin Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package log
|
||||||
|
|
||||||
|
// Logger is the logging interface implementation.
|
||||||
|
type Logger interface {
|
||||||
|
//EnableLog controls whether print the message.
|
||||||
|
EnableLog(bool)
|
||||||
|
|
||||||
|
//IsEnabled returns if logger is enabled.
|
||||||
|
IsEnabled() bool
|
||||||
|
|
||||||
|
//Print formats using the default formats for its operands and logs the message.
|
||||||
|
Print(...interface{})
|
||||||
|
|
||||||
|
//Printf formats according to a format specifier and logs the message.
|
||||||
|
Printf(string, ...interface{})
|
||||||
|
}
|
4
vendor/github.com/casbin/casbin/model/assertion.go
generated
vendored
4
vendor/github.com/casbin/casbin/model/assertion.go
generated
vendored
@ -18,8 +18,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/casbin/casbin/log"
|
||||||
"github.com/casbin/casbin/rbac"
|
"github.com/casbin/casbin/rbac"
|
||||||
"github.com/casbin/casbin/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Assertion represents an expression in a section of the model.
|
// Assertion represents an expression in a section of the model.
|
||||||
@ -55,6 +55,6 @@ func (ast *Assertion) buildRoleLinks(rm rbac.RoleManager) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
util.LogPrint("Role links for: " + ast.Key)
|
log.LogPrint("Role links for: " + ast.Key)
|
||||||
ast.RM.PrintRoles()
|
ast.RM.PrintRoles()
|
||||||
}
|
}
|
||||||
|
5
vendor/github.com/casbin/casbin/model/model.go
generated
vendored
5
vendor/github.com/casbin/casbin/model/model.go
generated
vendored
@ -19,6 +19,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casbin/casbin/config"
|
"github.com/casbin/casbin/config"
|
||||||
|
"github.com/casbin/casbin/log"
|
||||||
"github.com/casbin/casbin/util"
|
"github.com/casbin/casbin/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -120,10 +121,10 @@ func (model Model) LoadModelFromText(text string) {
|
|||||||
|
|
||||||
// PrintModel prints the model to the log.
|
// PrintModel prints the model to the log.
|
||||||
func (model Model) PrintModel() {
|
func (model Model) PrintModel() {
|
||||||
util.LogPrint("Model:")
|
log.LogPrint("Model:")
|
||||||
for k, v := range model {
|
for k, v := range model {
|
||||||
for i, j := range v {
|
for i, j := range v {
|
||||||
util.LogPrintf("%s.%s: %s", k, i, j.Value)
|
log.LogPrintf("%s.%s: %s", k, i, j.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/casbin/casbin/model/policy.go
generated
vendored
8
vendor/github.com/casbin/casbin/model/policy.go
generated
vendored
@ -15,6 +15,7 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/casbin/casbin/log"
|
||||||
"github.com/casbin/casbin/rbac"
|
"github.com/casbin/casbin/rbac"
|
||||||
"github.com/casbin/casbin/util"
|
"github.com/casbin/casbin/util"
|
||||||
)
|
)
|
||||||
@ -28,13 +29,13 @@ func (model Model) BuildRoleLinks(rm rbac.RoleManager) {
|
|||||||
|
|
||||||
// PrintPolicy prints the policy to log.
|
// PrintPolicy prints the policy to log.
|
||||||
func (model Model) PrintPolicy() {
|
func (model Model) PrintPolicy() {
|
||||||
util.LogPrint("Policy:")
|
log.LogPrint("Policy:")
|
||||||
for key, ast := range model["p"] {
|
for key, ast := range model["p"] {
|
||||||
util.LogPrint(key, ": ", ast.Value, ": ", ast.Policy)
|
log.LogPrint(key, ": ", ast.Value, ": ", ast.Policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, ast := range model["g"] {
|
for key, ast := range model["g"] {
|
||||||
util.LogPrint(key, ": ", ast.Value, ": ", ast.Policy)
|
log.LogPrint(key, ": ", ast.Value, ": ", ast.Policy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +141,6 @@ func (model Model) GetValuesForFieldInPolicy(sec string, ptype string, fieldInde
|
|||||||
}
|
}
|
||||||
|
|
||||||
util.ArrayRemoveDuplicates(&values)
|
util.ArrayRemoveDuplicates(&values)
|
||||||
// sort.Strings(values)
|
|
||||||
|
|
||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
6
vendor/github.com/casbin/casbin/rbac/default-role-manager/role_manager.go
generated
vendored
6
vendor/github.com/casbin/casbin/rbac/default-role-manager/role_manager.go
generated
vendored
@ -18,8 +18,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/casbin/casbin/log"
|
||||||
"github.com/casbin/casbin/rbac"
|
"github.com/casbin/casbin/rbac"
|
||||||
"github.com/casbin/casbin/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// RoleManager provides a default implementation for the RoleManager interface
|
// RoleManager provides a default implementation for the RoleManager interface
|
||||||
@ -123,7 +123,7 @@ func (rm *RoleManager) GetRoles(name string, domain ...string) ([]string, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !rm.hasRole(name) {
|
if !rm.hasRole(name) {
|
||||||
return nil, errors.New("error: name does not exist")
|
return []string{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
roles := rm.createRole(name).getRoles()
|
roles := rm.createRole(name).getRoles()
|
||||||
@ -166,7 +166,7 @@ func (rm *RoleManager) PrintRoles() error {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
util.LogPrint(line)
|
log.LogPrint(line)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
57
vendor/github.com/casbin/casbin/rbac_api.go
generated
vendored
57
vendor/github.com/casbin/casbin/rbac_api.go
generated
vendored
@ -125,3 +125,60 @@ func (e *Enforcer) HasPermissionForUser(user string, permission ...string) bool
|
|||||||
|
|
||||||
return e.HasPolicy(params...)
|
return e.HasPolicy(params...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetImplicitRolesForUser gets implicit roles that a user has.
|
||||||
|
// Compared to GetRolesForUser(), this function retrieves indirect roles besides direct roles.
|
||||||
|
// For example:
|
||||||
|
// g, alice, role:admin
|
||||||
|
// g, role:admin, role:user
|
||||||
|
//
|
||||||
|
// GetRolesForUser("alice") can only get: ["role:admin"].
|
||||||
|
// But GetImplicitRolesForUser("alice") will get: ["role:admin", "role:user"].
|
||||||
|
func (e *Enforcer) GetImplicitRolesForUser(name string) []string {
|
||||||
|
res := []string{}
|
||||||
|
roleSet := make(map[string]bool)
|
||||||
|
roleSet[name] = true
|
||||||
|
|
||||||
|
q := make([]string, 0)
|
||||||
|
q = append(q, name)
|
||||||
|
|
||||||
|
for len(q) > 0 {
|
||||||
|
name := q[0]
|
||||||
|
q = q[1:]
|
||||||
|
|
||||||
|
roles, err := e.rm.GetRoles(name)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for _, r := range roles {
|
||||||
|
if _, ok := roleSet[r]; !ok {
|
||||||
|
res = append(res, r)
|
||||||
|
q = append(q, r)
|
||||||
|
roleSet[r] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetImplicitPermissionsForUser gets implicit permissions for a user or role.
|
||||||
|
// Compared to GetPermissionsForUser(), this function retrieves permissions for inherited roles.
|
||||||
|
// For example:
|
||||||
|
// p, admin, data1, read
|
||||||
|
// p, alice, data2, read
|
||||||
|
// g, alice, admin
|
||||||
|
//
|
||||||
|
// GetPermissionsForUser("alice") can only get: [["alice", "data2", "read"]].
|
||||||
|
// But GetImplicitPermissionsForUser("alice") will get: [["admin", "data1", "read"], ["alice", "data2", "read"]].
|
||||||
|
func (e *Enforcer) GetImplicitPermissionsForUser(user string) [][]string {
|
||||||
|
roles := e.GetImplicitRolesForUser(user)
|
||||||
|
roles = append([]string{user}, roles...)
|
||||||
|
|
||||||
|
res := [][]string{}
|
||||||
|
for _, role := range roles {
|
||||||
|
permissions := e.GetPermissionsForUser(role)
|
||||||
|
res = append(res, permissions...)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
10
vendor/github.com/casbin/casbin/util/builtin_operators.go
generated
vendored
10
vendor/github.com/casbin/casbin/util/builtin_operators.go
generated
vendored
@ -41,7 +41,7 @@ func KeyMatchFunc(args ...interface{}) (interface{}, error) {
|
|||||||
name1 := args[0].(string)
|
name1 := args[0].(string)
|
||||||
name2 := args[1].(string)
|
name2 := args[1].(string)
|
||||||
|
|
||||||
return (bool)(KeyMatch(name1, name2)), nil
|
return bool(KeyMatch(name1, name2)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyMatch2 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
|
// KeyMatch2 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
|
||||||
@ -66,7 +66,7 @@ func KeyMatch2Func(args ...interface{}) (interface{}, error) {
|
|||||||
name1 := args[0].(string)
|
name1 := args[0].(string)
|
||||||
name2 := args[1].(string)
|
name2 := args[1].(string)
|
||||||
|
|
||||||
return (bool)(KeyMatch2(name1, name2)), nil
|
return bool(KeyMatch2(name1, name2)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyMatch3 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
|
// KeyMatch3 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
|
||||||
@ -91,7 +91,7 @@ func KeyMatch3Func(args ...interface{}) (interface{}, error) {
|
|||||||
name1 := args[0].(string)
|
name1 := args[0].(string)
|
||||||
name2 := args[1].(string)
|
name2 := args[1].(string)
|
||||||
|
|
||||||
return (bool)(KeyMatch3(name1, name2)), nil
|
return bool(KeyMatch3(name1, name2)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegexMatch determines whether key1 matches the pattern of key2 in regular expression.
|
// RegexMatch determines whether key1 matches the pattern of key2 in regular expression.
|
||||||
@ -108,7 +108,7 @@ func RegexMatchFunc(args ...interface{}) (interface{}, error) {
|
|||||||
name1 := args[0].(string)
|
name1 := args[0].(string)
|
||||||
name2 := args[1].(string)
|
name2 := args[1].(string)
|
||||||
|
|
||||||
return (bool)(RegexMatch(name1, name2)), nil
|
return bool(RegexMatch(name1, name2)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPMatch determines whether IP address ip1 matches the pattern of IP address ip2, ip2 can be an IP address or a CIDR pattern.
|
// IPMatch determines whether IP address ip1 matches the pattern of IP address ip2, ip2 can be an IP address or a CIDR pattern.
|
||||||
@ -137,7 +137,7 @@ func IPMatchFunc(args ...interface{}) (interface{}, error) {
|
|||||||
ip1 := args[0].(string)
|
ip1 := args[0].(string)
|
||||||
ip2 := args[1].(string)
|
ip2 := args[1].(string)
|
||||||
|
|
||||||
return (bool)(IPMatch(ip1, ip2)), nil
|
return bool(IPMatch(ip1, ip2)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateGFunction is the factory method of the g(_, _) function.
|
// GenerateGFunction is the factory method of the g(_, _) function.
|
||||||
|
1367
vendor/github.com/cloudflare/golz4/src/lz4.c
generated
vendored
1367
vendor/github.com/cloudflare/golz4/src/lz4.c
generated
vendored
File diff suppressed because it is too large
Load Diff
315
vendor/github.com/cloudflare/golz4/src/lz4.h
generated
vendored
315
vendor/github.com/cloudflare/golz4/src/lz4.h
generated
vendored
@ -1,315 +0,0 @@
|
|||||||
/*
|
|
||||||
LZ4 - Fast LZ compression algorithm
|
|
||||||
Header File
|
|
||||||
Copyright (C) 2011-2014, Yann Collet.
|
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
You can contact the author at :
|
|
||||||
- LZ4 source repository : http://code.google.com/p/lz4/
|
|
||||||
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* lz4.h provides raw compression format functions, for optimal performance and integration into programs.
|
|
||||||
* If you need to generate data using an inter-operable format (respecting the framing specification),
|
|
||||||
* please use lz4frame.h instead.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Version
|
|
||||||
**************************************/
|
|
||||||
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
|
|
||||||
#define LZ4_VERSION_MINOR 5 /* for new (non-breaking) interface capabilities */
|
|
||||||
#define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */
|
|
||||||
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
|
|
||||||
int LZ4_versionNumber (void);
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Tuning parameter
|
|
||||||
**************************************/
|
|
||||||
/*
|
|
||||||
* LZ4_MEMORY_USAGE :
|
|
||||||
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
|
|
||||||
* Increasing memory usage improves compression ratio
|
|
||||||
* Reduced memory usage can improve speed, due to cache effect
|
|
||||||
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
|
|
||||||
*/
|
|
||||||
#define LZ4_MEMORY_USAGE 14
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Simple Functions
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
int LZ4_compress (const char* source, char* dest, int sourceSize);
|
|
||||||
int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);
|
|
||||||
|
|
||||||
/*
|
|
||||||
LZ4_compress() :
|
|
||||||
Compresses 'sourceSize' bytes from 'source' into 'dest'.
|
|
||||||
Destination buffer must be already allocated,
|
|
||||||
and must be sized to handle worst cases situations (input data not compressible)
|
|
||||||
Worst case size evaluation is provided by function LZ4_compressBound()
|
|
||||||
inputSize : Max supported value is LZ4_MAX_INPUT_SIZE
|
|
||||||
return : the number of bytes written in buffer dest
|
|
||||||
or 0 if the compression fails
|
|
||||||
|
|
||||||
LZ4_decompress_safe() :
|
|
||||||
compressedSize : is obviously the source size
|
|
||||||
maxDecompressedSize : is the size of the destination buffer, which must be already allocated.
|
|
||||||
return : the number of bytes decompressed into the destination buffer (necessarily <= maxDecompressedSize)
|
|
||||||
If the destination buffer is not large enough, decoding will stop and output an error code (<0).
|
|
||||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
|
||||||
This function is protected against buffer overflow exploits,
|
|
||||||
and never writes outside of output buffer, nor reads outside of input buffer.
|
|
||||||
It is also protected against malicious data packets.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Advanced Functions
|
|
||||||
**************************************/
|
|
||||||
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
|
|
||||||
#define LZ4_COMPRESSBOUND(isize) ((unsigned int)(isize) > (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
|
|
||||||
|
|
||||||
/*
|
|
||||||
LZ4_compressBound() :
|
|
||||||
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
|
|
||||||
This function is primarily useful for memory allocation purposes (output buffer size).
|
|
||||||
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
|
|
||||||
|
|
||||||
isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE
|
|
||||||
return : maximum output size in a "worst case" scenario
|
|
||||||
or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE)
|
|
||||||
*/
|
|
||||||
int LZ4_compressBound(int isize);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
LZ4_compress_limitedOutput() :
|
|
||||||
Compress 'sourceSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
|
|
||||||
If it cannot achieve it, compression will stop, and result of the function will be zero.
|
|
||||||
This saves time and memory on detecting non-compressible (or barely compressible) data.
|
|
||||||
This function never writes outside of provided output buffer.
|
|
||||||
|
|
||||||
sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE
|
|
||||||
maxOutputSize : is the size of the destination buffer (which must be already allocated)
|
|
||||||
return : the number of bytes written in buffer 'dest'
|
|
||||||
or 0 if compression fails
|
|
||||||
*/
|
|
||||||
int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
LZ4_compress_withState() :
|
|
||||||
Same compression functions, but using an externally allocated memory space to store compression state.
|
|
||||||
Use LZ4_sizeofState() to know how much memory must be allocated,
|
|
||||||
and then, provide it as 'void* state' to compression functions.
|
|
||||||
*/
|
|
||||||
int LZ4_sizeofState(void);
|
|
||||||
int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
|
|
||||||
int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
LZ4_decompress_fast() :
|
|
||||||
originalSize : is the original and therefore uncompressed size
|
|
||||||
return : the number of bytes read from the source buffer (in other words, the compressed size)
|
|
||||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
|
||||||
Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes.
|
|
||||||
note : This function fully respect memory boundaries for properly formed compressed data.
|
|
||||||
It is a bit faster than LZ4_decompress_safe().
|
|
||||||
However, it does not provide any protection against intentionally modified data stream (malicious input).
|
|
||||||
Use this function in trusted environment only (data to decode comes from a trusted source).
|
|
||||||
*/
|
|
||||||
int LZ4_decompress_fast (const char* source, char* dest, int originalSize);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
LZ4_decompress_safe_partial() :
|
|
||||||
This function decompress a compressed block of size 'compressedSize' at position 'source'
|
|
||||||
into destination buffer 'dest' of size 'maxDecompressedSize'.
|
|
||||||
The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached,
|
|
||||||
reducing decompression time.
|
|
||||||
return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize)
|
|
||||||
Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller.
|
|
||||||
Always control how many bytes were decoded.
|
|
||||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
|
||||||
This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets
|
|
||||||
*/
|
|
||||||
int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize);
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************
|
|
||||||
Streaming Compression Functions
|
|
||||||
***********************************************/
|
|
||||||
|
|
||||||
#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
|
|
||||||
#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long))
|
|
||||||
/*
|
|
||||||
* LZ4_stream_t
|
|
||||||
* information structure to track an LZ4 stream.
|
|
||||||
* important : init this structure content before first use !
|
|
||||||
* note : only allocated directly the structure if you are statically linking LZ4
|
|
||||||
* If you are using liblz4 as a DLL, please use below construction methods instead.
|
|
||||||
*/
|
|
||||||
typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LZ4_resetStream
|
|
||||||
* Use this function to init an allocated LZ4_stream_t structure
|
|
||||||
*/
|
|
||||||
void LZ4_resetStream (LZ4_stream_t* LZ4_streamPtr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LZ4_createStream will allocate and initialize an LZ4_stream_t structure
|
|
||||||
* LZ4_freeStream releases its memory.
|
|
||||||
* In the context of a DLL (liblz4), please use these methods rather than the static struct.
|
|
||||||
* They are more future proof, in case of a change of LZ4_stream_t size.
|
|
||||||
*/
|
|
||||||
LZ4_stream_t* LZ4_createStream(void);
|
|
||||||
int LZ4_freeStream (LZ4_stream_t* LZ4_streamPtr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LZ4_loadDict
|
|
||||||
* Use this function to load a static dictionary into LZ4_stream.
|
|
||||||
* Any previous data will be forgotten, only 'dictionary' will remain in memory.
|
|
||||||
* Loading a size of 0 is allowed.
|
|
||||||
* Return : dictionary size, in bytes (necessarily <= 64 KB)
|
|
||||||
*/
|
|
||||||
int LZ4_loadDict (LZ4_stream_t* LZ4_streamPtr, const char* dictionary, int dictSize);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LZ4_compress_continue
|
|
||||||
* Compress data block 'source', using blocks compressed before as dictionary to improve compression ratio
|
|
||||||
* Previous data blocks are assumed to still be present at their previous location.
|
|
||||||
*/
|
|
||||||
int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LZ4_compress_limitedOutput_continue
|
|
||||||
* Same as before, but also specify a maximum target compressed size (maxOutputSize)
|
|
||||||
* If objective cannot be met, compression exits, and returns a zero.
|
|
||||||
*/
|
|
||||||
int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LZ4_saveDict
|
|
||||||
* If previously compressed data block is not guaranteed to remain available at its memory location
|
|
||||||
* save it into a safer place (char* safeBuffer)
|
|
||||||
* Note : you don't need to call LZ4_loadDict() afterwards,
|
|
||||||
* dictionary is immediately usable, you can therefore call again LZ4_compress_continue()
|
|
||||||
* Return : dictionary size in bytes, or 0 if error
|
|
||||||
* Note : any dictSize > 64 KB will be interpreted as 64KB.
|
|
||||||
*/
|
|
||||||
int LZ4_saveDict (LZ4_stream_t* LZ4_streamPtr, char* safeBuffer, int dictSize);
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************
|
|
||||||
Streaming Decompression Functions
|
|
||||||
************************************************/
|
|
||||||
|
|
||||||
#define LZ4_STREAMDECODESIZE_U64 4
|
|
||||||
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
|
|
||||||
typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t;
|
|
||||||
/*
|
|
||||||
* LZ4_streamDecode_t
|
|
||||||
* information structure to track an LZ4 stream.
|
|
||||||
* init this structure content using LZ4_setStreamDecode or memset() before first use !
|
|
||||||
*
|
|
||||||
* In the context of a DLL (liblz4) please prefer usage of construction methods below.
|
|
||||||
* They are more future proof, in case of a change of LZ4_streamDecode_t size in the future.
|
|
||||||
* LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure
|
|
||||||
* LZ4_freeStreamDecode releases its memory.
|
|
||||||
*/
|
|
||||||
LZ4_streamDecode_t* LZ4_createStreamDecode(void);
|
|
||||||
int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LZ4_setStreamDecode
|
|
||||||
* Use this function to instruct where to find the dictionary.
|
|
||||||
* Setting a size of 0 is allowed (same effect as reset).
|
|
||||||
* Return : 1 if OK, 0 if error
|
|
||||||
*/
|
|
||||||
int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
|
|
||||||
|
|
||||||
/*
|
|
||||||
*_continue() :
|
|
||||||
These decoding functions allow decompression of multiple blocks in "streaming" mode.
|
|
||||||
Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB)
|
|
||||||
If this condition is not possible, save the relevant part of decoded data into a safe buffer,
|
|
||||||
and indicate where is its new address using LZ4_setStreamDecode()
|
|
||||||
*/
|
|
||||||
int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize);
|
|
||||||
int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Advanced decoding functions :
|
|
||||||
*_usingDict() :
|
|
||||||
These decoding functions work the same as
|
|
||||||
a combination of LZ4_setDictDecode() followed by LZ4_decompress_x_continue()
|
|
||||||
They are stand-alone and don't use nor update an LZ4_streamDecode_t structure.
|
|
||||||
*/
|
|
||||||
int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize);
|
|
||||||
int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Obsolete Functions
|
|
||||||
**************************************/
|
|
||||||
/*
|
|
||||||
Obsolete decompression functions
|
|
||||||
These function names are deprecated and should no longer be used.
|
|
||||||
They are only provided here for compatibility with older user programs.
|
|
||||||
- LZ4_uncompress is the same as LZ4_decompress_fast
|
|
||||||
- LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe
|
|
||||||
These function prototypes are now disabled; uncomment them if you really need them.
|
|
||||||
It is highly recommended to stop using these functions and migrate to newer ones */
|
|
||||||
/* int LZ4_uncompress (const char* source, char* dest, int outputSize); */
|
|
||||||
/* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */
|
|
||||||
|
|
||||||
|
|
||||||
/* Obsolete streaming functions; use new streaming interface whenever possible */
|
|
||||||
void* LZ4_create (const char* inputBuffer);
|
|
||||||
int LZ4_sizeofStreamState(void);
|
|
||||||
int LZ4_resetStreamState(void* state, const char* inputBuffer);
|
|
||||||
char* LZ4_slideInputBuffer (void* state);
|
|
||||||
|
|
||||||
/* Obsolete streaming decoding functions */
|
|
||||||
int LZ4_decompress_safe_withPrefix64k (const char* source, char* dest, int compressedSize, int maxOutputSize);
|
|
||||||
int LZ4_decompress_fast_withPrefix64k (const char* source, char* dest, int originalSize);
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
751
vendor/github.com/cloudflare/golz4/src/lz4hc.c
generated
vendored
751
vendor/github.com/cloudflare/golz4/src/lz4hc.c
generated
vendored
@ -1,751 +0,0 @@
|
|||||||
/*
|
|
||||||
LZ4 HC - High Compression Mode of LZ4
|
|
||||||
Copyright (C) 2011-2014, Yann Collet.
|
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
You can contact the author at :
|
|
||||||
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
|
||||||
- LZ4 source repository : http://code.google.com/p/lz4/
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Tuning Parameter
|
|
||||||
**************************************/
|
|
||||||
static const int LZ4HC_compressionLevel_default = 8;
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Includes
|
|
||||||
**************************************/
|
|
||||||
#include "lz4hc.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Local Compiler Options
|
|
||||||
**************************************/
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
# pragma GCC diagnostic ignored "-Wunused-function"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (__clang__)
|
|
||||||
# pragma clang diagnostic ignored "-Wunused-function"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Common LZ4 definition
|
|
||||||
**************************************/
|
|
||||||
#define LZ4_COMMONDEFS_ONLY
|
|
||||||
#include "lz4.c"
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Local Constants
|
|
||||||
**************************************/
|
|
||||||
#define DICTIONARY_LOGSIZE 16
|
|
||||||
#define MAXD (1<<DICTIONARY_LOGSIZE)
|
|
||||||
#define MAXD_MASK ((U32)(MAXD - 1))
|
|
||||||
|
|
||||||
#define HASH_LOG (DICTIONARY_LOGSIZE-1)
|
|
||||||
#define HASHTABLESIZE (1 << HASH_LOG)
|
|
||||||
#define HASH_MASK (HASHTABLESIZE - 1)
|
|
||||||
|
|
||||||
#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
|
|
||||||
|
|
||||||
static const int g_maxCompressionLevel = 16;
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Local Types
|
|
||||||
**************************************/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
U32 hashTable[HASHTABLESIZE];
|
|
||||||
U16 chainTable[MAXD];
|
|
||||||
const BYTE* end; /* next block here to continue on current prefix */
|
|
||||||
const BYTE* base; /* All index relative to this position */
|
|
||||||
const BYTE* dictBase; /* alternate base for extDict */
|
|
||||||
const BYTE* inputBuffer;/* deprecated */
|
|
||||||
U32 dictLimit; /* below that point, need extDict */
|
|
||||||
U32 lowLimit; /* below that point, no more dict */
|
|
||||||
U32 nextToUpdate;
|
|
||||||
U32 compressionLevel;
|
|
||||||
} LZ4HC_Data_Structure;
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Local Macros
|
|
||||||
**************************************/
|
|
||||||
#define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
|
|
||||||
#define DELTANEXT(p) chainTable[(size_t)(p) & MAXD_MASK]
|
|
||||||
#define GETNEXT(p) ((p) - (size_t)DELTANEXT(p))
|
|
||||||
|
|
||||||
static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
HC Compression
|
|
||||||
**************************************/
|
|
||||||
static void LZ4HC_init (LZ4HC_Data_Structure* hc4, const BYTE* start)
|
|
||||||
{
|
|
||||||
MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));
|
|
||||||
MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
|
|
||||||
hc4->nextToUpdate = 64 KB;
|
|
||||||
hc4->base = start - 64 KB;
|
|
||||||
hc4->inputBuffer = start;
|
|
||||||
hc4->end = start;
|
|
||||||
hc4->dictBase = start - 64 KB;
|
|
||||||
hc4->dictLimit = 64 KB;
|
|
||||||
hc4->lowLimit = 64 KB;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Update chains up to ip (excluded) */
|
|
||||||
FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)
|
|
||||||
{
|
|
||||||
U16* chainTable = hc4->chainTable;
|
|
||||||
U32* HashTable = hc4->hashTable;
|
|
||||||
const BYTE* const base = hc4->base;
|
|
||||||
const U32 target = (U32)(ip - base);
|
|
||||||
U32 idx = hc4->nextToUpdate;
|
|
||||||
|
|
||||||
while(idx < target)
|
|
||||||
{
|
|
||||||
U32 h = LZ4HC_hashPtr(base+idx);
|
|
||||||
size_t delta = idx - HashTable[h];
|
|
||||||
if (delta>MAX_DISTANCE) delta = MAX_DISTANCE;
|
|
||||||
chainTable[idx & 0xFFFF] = (U16)delta;
|
|
||||||
HashTable[h] = idx;
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
hc4->nextToUpdate = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, /* Index table will be updated */
|
|
||||||
const BYTE* ip, const BYTE* const iLimit,
|
|
||||||
const BYTE** matchpos,
|
|
||||||
const int maxNbAttempts)
|
|
||||||
{
|
|
||||||
U16* const chainTable = hc4->chainTable;
|
|
||||||
U32* const HashTable = hc4->hashTable;
|
|
||||||
const BYTE* const base = hc4->base;
|
|
||||||
const BYTE* const dictBase = hc4->dictBase;
|
|
||||||
const U32 dictLimit = hc4->dictLimit;
|
|
||||||
const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1);
|
|
||||||
U32 matchIndex;
|
|
||||||
const BYTE* match;
|
|
||||||
int nbAttempts=maxNbAttempts;
|
|
||||||
size_t ml=0;
|
|
||||||
|
|
||||||
/* HC4 match finder */
|
|
||||||
LZ4HC_Insert(hc4, ip);
|
|
||||||
matchIndex = HashTable[LZ4HC_hashPtr(ip)];
|
|
||||||
|
|
||||||
while ((matchIndex>=lowLimit) && (nbAttempts))
|
|
||||||
{
|
|
||||||
nbAttempts--;
|
|
||||||
if (matchIndex >= dictLimit)
|
|
||||||
{
|
|
||||||
match = base + matchIndex;
|
|
||||||
if (*(match+ml) == *(ip+ml)
|
|
||||||
&& (LZ4_read32(match) == LZ4_read32(ip)))
|
|
||||||
{
|
|
||||||
size_t mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH;
|
|
||||||
if (mlt > ml) { ml = mlt; *matchpos = match; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
match = dictBase + matchIndex;
|
|
||||||
if (LZ4_read32(match) == LZ4_read32(ip))
|
|
||||||
{
|
|
||||||
size_t mlt;
|
|
||||||
const BYTE* vLimit = ip + (dictLimit - matchIndex);
|
|
||||||
if (vLimit > iLimit) vLimit = iLimit;
|
|
||||||
mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH;
|
|
||||||
if ((ip+mlt == vLimit) && (vLimit < iLimit))
|
|
||||||
mlt += LZ4_count(ip+mlt, base+dictLimit, iLimit);
|
|
||||||
if (mlt > ml) { ml = mlt; *matchpos = base + matchIndex; } /* virtual matchpos */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
matchIndex -= chainTable[matchIndex & 0xFFFF];
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int)ml;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (
|
|
||||||
LZ4HC_Data_Structure* hc4,
|
|
||||||
const BYTE* ip,
|
|
||||||
const BYTE* iLowLimit,
|
|
||||||
const BYTE* iHighLimit,
|
|
||||||
int longest,
|
|
||||||
const BYTE** matchpos,
|
|
||||||
const BYTE** startpos,
|
|
||||||
const int maxNbAttempts)
|
|
||||||
{
|
|
||||||
U16* const chainTable = hc4->chainTable;
|
|
||||||
U32* const HashTable = hc4->hashTable;
|
|
||||||
const BYTE* const base = hc4->base;
|
|
||||||
const U32 dictLimit = hc4->dictLimit;
|
|
||||||
const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1);
|
|
||||||
const BYTE* const dictBase = hc4->dictBase;
|
|
||||||
const BYTE* match;
|
|
||||||
U32 matchIndex;
|
|
||||||
int nbAttempts = maxNbAttempts;
|
|
||||||
int delta = (int)(ip-iLowLimit);
|
|
||||||
|
|
||||||
|
|
||||||
/* First Match */
|
|
||||||
LZ4HC_Insert(hc4, ip);
|
|
||||||
matchIndex = HashTable[LZ4HC_hashPtr(ip)];
|
|
||||||
|
|
||||||
while ((matchIndex>=lowLimit) && (nbAttempts))
|
|
||||||
{
|
|
||||||
nbAttempts--;
|
|
||||||
if (matchIndex >= dictLimit)
|
|
||||||
{
|
|
||||||
match = base + matchIndex;
|
|
||||||
if (*(iLowLimit + longest) == *(match - delta + longest))
|
|
||||||
if (LZ4_read32(match) == LZ4_read32(ip))
|
|
||||||
{
|
|
||||||
const BYTE* startt = ip;
|
|
||||||
const BYTE* tmpMatch = match;
|
|
||||||
const BYTE* const matchEnd = ip + MINMATCH + LZ4_count(ip+MINMATCH, match+MINMATCH, iHighLimit);
|
|
||||||
|
|
||||||
while ((startt>iLowLimit) && (tmpMatch > iLowLimit) && (startt[-1] == tmpMatch[-1])) {startt--; tmpMatch--;}
|
|
||||||
|
|
||||||
if ((matchEnd-startt) > longest)
|
|
||||||
{
|
|
||||||
longest = (int)(matchEnd-startt);
|
|
||||||
*matchpos = tmpMatch;
|
|
||||||
*startpos = startt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
match = dictBase + matchIndex;
|
|
||||||
if (LZ4_read32(match) == LZ4_read32(ip))
|
|
||||||
{
|
|
||||||
size_t mlt;
|
|
||||||
int back=0;
|
|
||||||
const BYTE* vLimit = ip + (dictLimit - matchIndex);
|
|
||||||
if (vLimit > iHighLimit) vLimit = iHighLimit;
|
|
||||||
mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH;
|
|
||||||
if ((ip+mlt == vLimit) && (vLimit < iHighLimit))
|
|
||||||
mlt += LZ4_count(ip+mlt, base+dictLimit, iHighLimit);
|
|
||||||
while ((ip+back > iLowLimit) && (matchIndex+back > lowLimit) && (ip[back-1] == match[back-1])) back--;
|
|
||||||
mlt -= back;
|
|
||||||
if ((int)mlt > longest) { longest = (int)mlt; *matchpos = base + matchIndex + back; *startpos = ip+back; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
matchIndex -= chainTable[matchIndex & 0xFFFF];
|
|
||||||
}
|
|
||||||
|
|
||||||
return longest;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive;
|
|
||||||
|
|
||||||
#define LZ4HC_DEBUG 0
|
|
||||||
#if LZ4HC_DEBUG
|
|
||||||
static unsigned debug = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FORCE_INLINE int LZ4HC_encodeSequence (
|
|
||||||
const BYTE** ip,
|
|
||||||
BYTE** op,
|
|
||||||
const BYTE** anchor,
|
|
||||||
int matchLength,
|
|
||||||
const BYTE* const match,
|
|
||||||
limitedOutput_directive limitedOutputBuffer,
|
|
||||||
BYTE* oend)
|
|
||||||
{
|
|
||||||
int length;
|
|
||||||
BYTE* token;
|
|
||||||
|
|
||||||
#if LZ4HC_DEBUG
|
|
||||||
if (debug) printf("literal : %u -- match : %u -- offset : %u\n", (U32)(*ip - *anchor), (U32)matchLength, (U32)(*ip-match));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Encode Literal length */
|
|
||||||
length = (int)(*ip - *anchor);
|
|
||||||
token = (*op)++;
|
|
||||||
if ((limitedOutputBuffer) && ((*op + (length>>8) + length + (2 + 1 + LASTLITERALS)) > oend)) return 1; /* Check output limit */
|
|
||||||
if (length>=(int)RUN_MASK) { int len; *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *(*op)++ = 255; *(*op)++ = (BYTE)len; }
|
|
||||||
else *token = (BYTE)(length<<ML_BITS);
|
|
||||||
|
|
||||||
/* Copy Literals */
|
|
||||||
LZ4_wildCopy(*op, *anchor, (*op) + length);
|
|
||||||
*op += length;
|
|
||||||
|
|
||||||
/* Encode Offset */
|
|
||||||
LZ4_writeLE16(*op, (U16)(*ip-match)); *op += 2;
|
|
||||||
|
|
||||||
/* Encode MatchLength */
|
|
||||||
length = (int)(matchLength-MINMATCH);
|
|
||||||
if ((limitedOutputBuffer) && (*op + (length>>8) + (1 + LASTLITERALS) > oend)) return 1; /* Check output limit */
|
|
||||||
if (length>=(int)ML_MASK) { *token+=ML_MASK; length-=ML_MASK; for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (length > 254) { length-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)length; }
|
|
||||||
else *token += (BYTE)(length);
|
|
||||||
|
|
||||||
/* Prepare next loop */
|
|
||||||
*ip += matchLength;
|
|
||||||
*anchor = *ip;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int LZ4HC_compress_generic (
|
|
||||||
void* ctxvoid,
|
|
||||||
const char* source,
|
|
||||||
char* dest,
|
|
||||||
int inputSize,
|
|
||||||
int maxOutputSize,
|
|
||||||
int compressionLevel,
|
|
||||||
limitedOutput_directive limit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
LZ4HC_Data_Structure* ctx = (LZ4HC_Data_Structure*) ctxvoid;
|
|
||||||
const BYTE* ip = (const BYTE*) source;
|
|
||||||
const BYTE* anchor = ip;
|
|
||||||
const BYTE* const iend = ip + inputSize;
|
|
||||||
const BYTE* const mflimit = iend - MFLIMIT;
|
|
||||||
const BYTE* const matchlimit = (iend - LASTLITERALS);
|
|
||||||
|
|
||||||
BYTE* op = (BYTE*) dest;
|
|
||||||
BYTE* const oend = op + maxOutputSize;
|
|
||||||
|
|
||||||
unsigned maxNbAttempts;
|
|
||||||
int ml, ml2, ml3, ml0;
|
|
||||||
const BYTE* ref=NULL;
|
|
||||||
const BYTE* start2=NULL;
|
|
||||||
const BYTE* ref2=NULL;
|
|
||||||
const BYTE* start3=NULL;
|
|
||||||
const BYTE* ref3=NULL;
|
|
||||||
const BYTE* start0;
|
|
||||||
const BYTE* ref0;
|
|
||||||
|
|
||||||
|
|
||||||
/* init */
|
|
||||||
if (compressionLevel > g_maxCompressionLevel) compressionLevel = g_maxCompressionLevel;
|
|
||||||
if (compressionLevel < 1) compressionLevel = LZ4HC_compressionLevel_default;
|
|
||||||
maxNbAttempts = 1 << (compressionLevel-1);
|
|
||||||
ctx->end += inputSize;
|
|
||||||
|
|
||||||
ip++;
|
|
||||||
|
|
||||||
/* Main Loop */
|
|
||||||
while (ip < mflimit)
|
|
||||||
{
|
|
||||||
ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts);
|
|
||||||
if (!ml) { ip++; continue; }
|
|
||||||
|
|
||||||
/* saved, in case we would skip too much */
|
|
||||||
start0 = ip;
|
|
||||||
ref0 = ref;
|
|
||||||
ml0 = ml;
|
|
||||||
|
|
||||||
_Search2:
|
|
||||||
if (ip+ml < mflimit)
|
|
||||||
ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, &ref2, &start2, maxNbAttempts);
|
|
||||||
else ml2 = ml;
|
|
||||||
|
|
||||||
if (ml2 == ml) /* No better match */
|
|
||||||
{
|
|
||||||
if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start0 < ip)
|
|
||||||
{
|
|
||||||
if (start2 < ip + ml0) /* empirical */
|
|
||||||
{
|
|
||||||
ip = start0;
|
|
||||||
ref = ref0;
|
|
||||||
ml = ml0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Here, start0==ip */
|
|
||||||
if ((start2 - ip) < 3) /* First Match too small : removed */
|
|
||||||
{
|
|
||||||
ml = ml2;
|
|
||||||
ip = start2;
|
|
||||||
ref =ref2;
|
|
||||||
goto _Search2;
|
|
||||||
}
|
|
||||||
|
|
||||||
_Search3:
|
|
||||||
/*
|
|
||||||
* Currently we have :
|
|
||||||
* ml2 > ml1, and
|
|
||||||
* ip1+3 <= ip2 (usually < ip1+ml1)
|
|
||||||
*/
|
|
||||||
if ((start2 - ip) < OPTIMAL_ML)
|
|
||||||
{
|
|
||||||
int correction;
|
|
||||||
int new_ml = ml;
|
|
||||||
if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML;
|
|
||||||
if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH;
|
|
||||||
correction = new_ml - (int)(start2 - ip);
|
|
||||||
if (correction > 0)
|
|
||||||
{
|
|
||||||
start2 += correction;
|
|
||||||
ref2 += correction;
|
|
||||||
ml2 -= correction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */
|
|
||||||
|
|
||||||
if (start2 + ml2 < mflimit)
|
|
||||||
ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts);
|
|
||||||
else ml3 = ml2;
|
|
||||||
|
|
||||||
if (ml3 == ml2) /* No better match : 2 sequences to encode */
|
|
||||||
{
|
|
||||||
/* ip & ref are known; Now for ml */
|
|
||||||
if (start2 < ip+ml) ml = (int)(start2 - ip);
|
|
||||||
/* Now, encode 2 sequences */
|
|
||||||
if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
|
|
||||||
ip = start2;
|
|
||||||
if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start3 < ip+ml+3) /* Not enough space for match 2 : remove it */
|
|
||||||
{
|
|
||||||
if (start3 >= (ip+ml)) /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */
|
|
||||||
{
|
|
||||||
if (start2 < ip+ml)
|
|
||||||
{
|
|
||||||
int correction = (int)(ip+ml - start2);
|
|
||||||
start2 += correction;
|
|
||||||
ref2 += correction;
|
|
||||||
ml2 -= correction;
|
|
||||||
if (ml2 < MINMATCH)
|
|
||||||
{
|
|
||||||
start2 = start3;
|
|
||||||
ref2 = ref3;
|
|
||||||
ml2 = ml3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
|
|
||||||
ip = start3;
|
|
||||||
ref = ref3;
|
|
||||||
ml = ml3;
|
|
||||||
|
|
||||||
start0 = start2;
|
|
||||||
ref0 = ref2;
|
|
||||||
ml0 = ml2;
|
|
||||||
goto _Search2;
|
|
||||||
}
|
|
||||||
|
|
||||||
start2 = start3;
|
|
||||||
ref2 = ref3;
|
|
||||||
ml2 = ml3;
|
|
||||||
goto _Search3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* OK, now we have 3 ascending matches; let's write at least the first one
|
|
||||||
* ip & ref are known; Now for ml
|
|
||||||
*/
|
|
||||||
if (start2 < ip+ml)
|
|
||||||
{
|
|
||||||
if ((start2 - ip) < (int)ML_MASK)
|
|
||||||
{
|
|
||||||
int correction;
|
|
||||||
if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
|
|
||||||
if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
|
|
||||||
correction = ml - (int)(start2 - ip);
|
|
||||||
if (correction > 0)
|
|
||||||
{
|
|
||||||
start2 += correction;
|
|
||||||
ref2 += correction;
|
|
||||||
ml2 -= correction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ml = (int)(start2 - ip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
|
|
||||||
|
|
||||||
ip = start2;
|
|
||||||
ref = ref2;
|
|
||||||
ml = ml2;
|
|
||||||
|
|
||||||
start2 = start3;
|
|
||||||
ref2 = ref3;
|
|
||||||
ml2 = ml3;
|
|
||||||
|
|
||||||
goto _Search3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Encode Last Literals */
|
|
||||||
{
|
|
||||||
int lastRun = (int)(iend - anchor);
|
|
||||||
if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */
|
|
||||||
if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
|
|
||||||
else *op++ = (BYTE)(lastRun<<ML_BITS);
|
|
||||||
memcpy(op, anchor, iend - anchor);
|
|
||||||
op += iend-anchor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* End */
|
|
||||||
return (int) (((char*)op)-dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int LZ4_compressHC2(const char* source, char* dest, int inputSize, int compressionLevel)
|
|
||||||
{
|
|
||||||
LZ4HC_Data_Structure ctx;
|
|
||||||
LZ4HC_init(&ctx, (const BYTE*)source);
|
|
||||||
return LZ4HC_compress_generic (&ctx, source, dest, inputSize, 0, compressionLevel, noLimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
int LZ4_compressHC(const char* source, char* dest, int inputSize) { return LZ4_compressHC2(source, dest, inputSize, 0); }
|
|
||||||
|
|
||||||
int LZ4_compressHC2_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel)
|
|
||||||
{
|
|
||||||
LZ4HC_Data_Structure ctx;
|
|
||||||
LZ4HC_init(&ctx, (const BYTE*)source);
|
|
||||||
return LZ4HC_compress_generic (&ctx, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
int LZ4_compressHC_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize)
|
|
||||||
{
|
|
||||||
return LZ4_compressHC2_limitedOutput(source, dest, inputSize, maxOutputSize, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************
|
|
||||||
* Using external allocation
|
|
||||||
* ***************************/
|
|
||||||
int LZ4_sizeofStateHC(void) { return sizeof(LZ4HC_Data_Structure); }
|
|
||||||
|
|
||||||
|
|
||||||
int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel)
|
|
||||||
{
|
|
||||||
if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */
|
|
||||||
LZ4HC_init ((LZ4HC_Data_Structure*)state, (const BYTE*)source);
|
|
||||||
return LZ4HC_compress_generic (state, source, dest, inputSize, 0, compressionLevel, noLimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize)
|
|
||||||
{ return LZ4_compressHC2_withStateHC (state, source, dest, inputSize, 0); }
|
|
||||||
|
|
||||||
|
|
||||||
int LZ4_compressHC2_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel)
|
|
||||||
{
|
|
||||||
if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */
|
|
||||||
LZ4HC_init ((LZ4HC_Data_Structure*)state, (const BYTE*)source);
|
|
||||||
return LZ4HC_compress_generic (state, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize)
|
|
||||||
{ return LZ4_compressHC2_limitedOutput_withStateHC (state, source, dest, inputSize, maxOutputSize, 0); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
* Streaming Functions
|
|
||||||
* ************************************/
|
|
||||||
/* allocation */
|
|
||||||
LZ4_streamHC_t* LZ4_createStreamHC(void) { return (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t)); }
|
|
||||||
int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) { free(LZ4_streamHCPtr); return 0; }
|
|
||||||
|
|
||||||
|
|
||||||
/* initialization */
|
|
||||||
void LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel)
|
|
||||||
{
|
|
||||||
LZ4_STATIC_ASSERT(sizeof(LZ4HC_Data_Structure) <= LZ4_STREAMHCSIZE); /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
|
|
||||||
((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->base = NULL;
|
|
||||||
((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->compressionLevel = (unsigned)compressionLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize)
|
|
||||||
{
|
|
||||||
LZ4HC_Data_Structure* ctxPtr = (LZ4HC_Data_Structure*) LZ4_streamHCPtr;
|
|
||||||
if (dictSize > 64 KB)
|
|
||||||
{
|
|
||||||
dictionary += dictSize - 64 KB;
|
|
||||||
dictSize = 64 KB;
|
|
||||||
}
|
|
||||||
LZ4HC_init (ctxPtr, (const BYTE*)dictionary);
|
|
||||||
if (dictSize >= 4) LZ4HC_Insert (ctxPtr, (const BYTE*)dictionary +(dictSize-3));
|
|
||||||
ctxPtr->end = (const BYTE*)dictionary + dictSize;
|
|
||||||
return dictSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* compression */
|
|
||||||
|
|
||||||
static void LZ4HC_setExternalDict(LZ4HC_Data_Structure* ctxPtr, const BYTE* newBlock)
|
|
||||||
{
|
|
||||||
if (ctxPtr->end >= ctxPtr->base + 4)
|
|
||||||
LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */
|
|
||||||
/* Only one memory segment for extDict, so any previous extDict is lost at this stage */
|
|
||||||
ctxPtr->lowLimit = ctxPtr->dictLimit;
|
|
||||||
ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base);
|
|
||||||
ctxPtr->dictBase = ctxPtr->base;
|
|
||||||
ctxPtr->base = newBlock - ctxPtr->dictLimit;
|
|
||||||
ctxPtr->end = newBlock;
|
|
||||||
ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */
|
|
||||||
}
|
|
||||||
|
|
||||||
static int LZ4_compressHC_continue_generic (LZ4HC_Data_Structure* ctxPtr,
|
|
||||||
const char* source, char* dest,
|
|
||||||
int inputSize, int maxOutputSize, limitedOutput_directive limit)
|
|
||||||
{
|
|
||||||
/* auto-init if forgotten */
|
|
||||||
if (ctxPtr->base == NULL)
|
|
||||||
LZ4HC_init (ctxPtr, (const BYTE*) source);
|
|
||||||
|
|
||||||
/* Check overflow */
|
|
||||||
if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB)
|
|
||||||
{
|
|
||||||
size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit;
|
|
||||||
if (dictSize > 64 KB) dictSize = 64 KB;
|
|
||||||
|
|
||||||
LZ4_loadDictHC((LZ4_streamHC_t*)ctxPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if blocks follow each other */
|
|
||||||
if ((const BYTE*)source != ctxPtr->end) LZ4HC_setExternalDict(ctxPtr, (const BYTE*)source);
|
|
||||||
|
|
||||||
/* Check overlapping input/dictionary space */
|
|
||||||
{
|
|
||||||
const BYTE* sourceEnd = (const BYTE*) source + inputSize;
|
|
||||||
const BYTE* dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit;
|
|
||||||
const BYTE* dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit;
|
|
||||||
if ((sourceEnd > dictBegin) && ((BYTE*)source < dictEnd))
|
|
||||||
{
|
|
||||||
if (sourceEnd > dictEnd) sourceEnd = dictEnd;
|
|
||||||
ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase);
|
|
||||||
if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return LZ4HC_compress_generic (ctxPtr, source, dest, inputSize, maxOutputSize, ctxPtr->compressionLevel, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize)
|
|
||||||
{
|
|
||||||
return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, 0, noLimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize)
|
|
||||||
{
|
|
||||||
return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, limitedOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* dictionary saving */
|
|
||||||
|
|
||||||
int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize)
|
|
||||||
{
|
|
||||||
LZ4HC_Data_Structure* streamPtr = (LZ4HC_Data_Structure*)LZ4_streamHCPtr;
|
|
||||||
int prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit));
|
|
||||||
if (dictSize > 64 KB) dictSize = 64 KB;
|
|
||||||
if (dictSize < 4) dictSize = 0;
|
|
||||||
if (dictSize > prefixSize) dictSize = prefixSize;
|
|
||||||
memcpy(safeBuffer, streamPtr->end - dictSize, dictSize);
|
|
||||||
{
|
|
||||||
U32 endIndex = (U32)(streamPtr->end - streamPtr->base);
|
|
||||||
streamPtr->end = (const BYTE*)safeBuffer + dictSize;
|
|
||||||
streamPtr->base = streamPtr->end - endIndex;
|
|
||||||
streamPtr->dictLimit = endIndex - dictSize;
|
|
||||||
streamPtr->lowLimit = endIndex - dictSize;
|
|
||||||
if (streamPtr->nextToUpdate < streamPtr->dictLimit) streamPtr->nextToUpdate = streamPtr->dictLimit;
|
|
||||||
}
|
|
||||||
return dictSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************
|
|
||||||
* Deprecated Functions
|
|
||||||
***********************************/
|
|
||||||
int LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; }
|
|
||||||
|
|
||||||
int LZ4_resetStreamStateHC(void* state, const char* inputBuffer)
|
|
||||||
{
|
|
||||||
if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1; /* Error : pointer is not aligned for pointer (32 or 64 bits) */
|
|
||||||
LZ4HC_init((LZ4HC_Data_Structure*)state, (const BYTE*)inputBuffer);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* LZ4_createHC (const char* inputBuffer)
|
|
||||||
{
|
|
||||||
void* hc4 = ALLOCATOR(1, sizeof(LZ4HC_Data_Structure));
|
|
||||||
LZ4HC_init ((LZ4HC_Data_Structure*)hc4, (const BYTE*)inputBuffer);
|
|
||||||
return hc4;
|
|
||||||
}
|
|
||||||
|
|
||||||
int LZ4_freeHC (void* LZ4HC_Data)
|
|
||||||
{
|
|
||||||
FREEMEM(LZ4HC_Data);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
int LZ4_compressHC_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize)
|
|
||||||
{
|
|
||||||
return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, 0, noLimit);
|
|
||||||
}
|
|
||||||
int LZ4_compressHC_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize)
|
|
||||||
{
|
|
||||||
return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, 0, limitedOutput);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel)
|
|
||||||
{
|
|
||||||
return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, compressionLevel, noLimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel)
|
|
||||||
{
|
|
||||||
return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* LZ4_slideInputBufferHC(void* LZ4HC_Data)
|
|
||||||
{
|
|
||||||
LZ4HC_Data_Structure* hc4 = (LZ4HC_Data_Structure*)LZ4HC_Data;
|
|
||||||
int dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB);
|
|
||||||
return (char*)(hc4->inputBuffer + dictSize);
|
|
||||||
}
|
|
174
vendor/github.com/cloudflare/golz4/src/lz4hc.h
generated
vendored
174
vendor/github.com/cloudflare/golz4/src/lz4hc.h
generated
vendored
@ -1,174 +0,0 @@
|
|||||||
/*
|
|
||||||
LZ4 HC - High Compression Mode of LZ4
|
|
||||||
Header File
|
|
||||||
Copyright (C) 2011-2014, Yann Collet.
|
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
You can contact the author at :
|
|
||||||
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
|
||||||
- LZ4 source repository : http://code.google.com/p/lz4/
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
int LZ4_compressHC (const char* source, char* dest, int inputSize);
|
|
||||||
/*
|
|
||||||
LZ4_compressHC :
|
|
||||||
return : the number of bytes in compressed buffer dest
|
|
||||||
or 0 if compression fails.
|
|
||||||
note : destination buffer must be already allocated.
|
|
||||||
To avoid any problem, size it to handle worst cases situations (input data not compressible)
|
|
||||||
Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h")
|
|
||||||
*/
|
|
||||||
|
|
||||||
int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
|
|
||||||
/*
|
|
||||||
LZ4_compress_limitedOutput() :
|
|
||||||
Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
|
|
||||||
If it cannot achieve it, compression will stop, and result of the function will be zero.
|
|
||||||
This function never writes outside of provided output buffer.
|
|
||||||
|
|
||||||
inputSize : Max supported value is 1 GB
|
|
||||||
maxOutputSize : is maximum allowed size into the destination buffer (which must be already allocated)
|
|
||||||
return : the number of output bytes written in buffer 'dest'
|
|
||||||
or 0 if compression fails.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel);
|
|
||||||
int LZ4_compressHC2_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
|
|
||||||
/*
|
|
||||||
Same functions as above, but with programmable 'compressionLevel'.
|
|
||||||
Recommended values are between 4 and 9, although any value between 0 and 16 will work.
|
|
||||||
'compressionLevel'==0 means use default 'compressionLevel' value.
|
|
||||||
Values above 16 behave the same as 16.
|
|
||||||
Equivalent variants exist for all other compression functions below.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Note :
|
|
||||||
Decompression functions are provided within LZ4 source code (see "lz4.h") (BSD license)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Using an external allocation
|
|
||||||
**************************************/
|
|
||||||
int LZ4_sizeofStateHC(void);
|
|
||||||
int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize);
|
|
||||||
int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
|
|
||||||
|
|
||||||
int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel);
|
|
||||||
int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
|
|
||||||
|
|
||||||
/*
|
|
||||||
These functions are provided should you prefer to allocate memory for compression tables with your own allocation methods.
|
|
||||||
To know how much memory must be allocated for the compression tables, use :
|
|
||||||
int LZ4_sizeofStateHC();
|
|
||||||
|
|
||||||
Note that tables must be aligned for pointer (32 or 64 bits), otherwise compression will fail (return code 0).
|
|
||||||
|
|
||||||
The allocated memory can be provided to the compression functions using 'void* state' parameter.
|
|
||||||
LZ4_compress_withStateHC() and LZ4_compress_limitedOutput_withStateHC() are equivalent to previously described functions.
|
|
||||||
They just use the externally allocated memory for state instead of allocating their own (on stack, or on heap).
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
Experimental Streaming Functions
|
|
||||||
**************************************/
|
|
||||||
#define LZ4_STREAMHCSIZE_U64 32774
|
|
||||||
#define LZ4_STREAMHCSIZE (LZ4_STREAMHCSIZE_U64 * sizeof(unsigned long long))
|
|
||||||
typedef struct { unsigned long long table[LZ4_STREAMHCSIZE_U64]; } LZ4_streamHC_t;
|
|
||||||
/*
|
|
||||||
LZ4_streamHC_t
|
|
||||||
This structure allows static allocation of LZ4 HC streaming state.
|
|
||||||
State must then be initialized using LZ4_resetStreamHC() before first use.
|
|
||||||
|
|
||||||
Static allocation should only be used with statically linked library.
|
|
||||||
If you want to use LZ4 as a DLL, please use construction functions below, which are more future-proof.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
LZ4_streamHC_t* LZ4_createStreamHC(void);
|
|
||||||
int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr);
|
|
||||||
/*
|
|
||||||
These functions create and release memory for LZ4 HC streaming state.
|
|
||||||
Newly created states are already initialized.
|
|
||||||
Existing state space can be re-used anytime using LZ4_resetStreamHC().
|
|
||||||
If you use LZ4 as a DLL, please use these functions instead of direct struct allocation,
|
|
||||||
to avoid size mismatch between different versions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel);
|
|
||||||
int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize);
|
|
||||||
|
|
||||||
int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize);
|
|
||||||
int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
|
|
||||||
|
|
||||||
int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int maxDictSize);
|
|
||||||
|
|
||||||
/*
|
|
||||||
These functions compress data in successive blocks of any size, using previous blocks as dictionary.
|
|
||||||
One key assumption is that each previous block will remain read-accessible while compressing next block.
|
|
||||||
|
|
||||||
Before starting compression, state must be properly initialized, using LZ4_resetStreamHC().
|
|
||||||
A first "fictional block" can then be designated as initial dictionary, using LZ4_loadDictHC() (Optional).
|
|
||||||
|
|
||||||
Then, use LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue() to compress each successive block.
|
|
||||||
They work like usual LZ4_compressHC() or LZ4_compressHC_limitedOutput(), but use previous memory blocks to improve compression.
|
|
||||||
Previous memory blocks (including initial dictionary when present) must remain accessible and unmodified during compression.
|
|
||||||
|
|
||||||
If, for any reason, previous data block can't be preserved in memory during next compression block,
|
|
||||||
you must save it to a safer memory space,
|
|
||||||
using LZ4_saveDictHC().
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
* Deprecated Streaming Functions
|
|
||||||
* ************************************/
|
|
||||||
/* Note : these streaming functions follows the older model, and should no longer be used */
|
|
||||||
void* LZ4_createHC (const char* inputBuffer);
|
|
||||||
char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
|
|
||||||
int LZ4_freeHC (void* LZ4HC_Data);
|
|
||||||
|
|
||||||
int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel);
|
|
||||||
int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
|
|
||||||
|
|
||||||
int LZ4_sizeofStreamStateHC(void);
|
|
||||||
int LZ4_resetStreamStateHC(void* state, const char* inputBuffer);
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
11
vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
generated
vendored
11
vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
generated
vendored
@ -1,3 +1,14 @@
|
|||||||
|
## Version 1.4.1 (2018-11-14)
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
|
||||||
|
- Fix TIME format for binary columns (#818)
|
||||||
|
- Fix handling of empty auth plugin names (#835)
|
||||||
|
- Fix caching_sha2_password with empty password (#826)
|
||||||
|
- Fix canceled context broke mysqlConn (#862)
|
||||||
|
- Fix OldAuthSwitchRequest support (#870)
|
||||||
|
- Fix Auth Response packet for cleartext password (#887)
|
||||||
|
|
||||||
## Version 1.4 (2018-06-03)
|
## Version 1.4 (2018-06-03)
|
||||||
|
|
||||||
Changes:
|
Changes:
|
||||||
|
36
vendor/github.com/go-sql-driver/mysql/auth.go
generated
vendored
36
vendor/github.com/go-sql-driver/mysql/auth.go
generated
vendored
@ -234,64 +234,64 @@ func (mc *mysqlConn) sendEncryptedPassword(seed []byte, pub *rsa.PublicKey) erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return mc.writeAuthSwitchPacket(enc, false)
|
return mc.writeAuthSwitchPacket(enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *mysqlConn) auth(authData []byte, plugin string) ([]byte, bool, error) {
|
func (mc *mysqlConn) auth(authData []byte, plugin string) ([]byte, error) {
|
||||||
switch plugin {
|
switch plugin {
|
||||||
case "caching_sha2_password":
|
case "caching_sha2_password":
|
||||||
authResp := scrambleSHA256Password(authData, mc.cfg.Passwd)
|
authResp := scrambleSHA256Password(authData, mc.cfg.Passwd)
|
||||||
return authResp, (authResp == nil), nil
|
return authResp, nil
|
||||||
|
|
||||||
case "mysql_old_password":
|
case "mysql_old_password":
|
||||||
if !mc.cfg.AllowOldPasswords {
|
if !mc.cfg.AllowOldPasswords {
|
||||||
return nil, false, ErrOldPassword
|
return nil, ErrOldPassword
|
||||||
}
|
}
|
||||||
// Note: there are edge cases where this should work but doesn't;
|
// Note: there are edge cases where this should work but doesn't;
|
||||||
// this is currently "wontfix":
|
// this is currently "wontfix":
|
||||||
// https://github.com/go-sql-driver/mysql/issues/184
|
// https://github.com/go-sql-driver/mysql/issues/184
|
||||||
authResp := scrambleOldPassword(authData[:8], mc.cfg.Passwd)
|
authResp := append(scrambleOldPassword(authData[:8], mc.cfg.Passwd), 0)
|
||||||
return authResp, true, nil
|
return authResp, nil
|
||||||
|
|
||||||
case "mysql_clear_password":
|
case "mysql_clear_password":
|
||||||
if !mc.cfg.AllowCleartextPasswords {
|
if !mc.cfg.AllowCleartextPasswords {
|
||||||
return nil, false, ErrCleartextPassword
|
return nil, ErrCleartextPassword
|
||||||
}
|
}
|
||||||
// http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html
|
// http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html
|
||||||
// http://dev.mysql.com/doc/refman/5.7/en/pam-authentication-plugin.html
|
// http://dev.mysql.com/doc/refman/5.7/en/pam-authentication-plugin.html
|
||||||
return []byte(mc.cfg.Passwd), true, nil
|
return append([]byte(mc.cfg.Passwd), 0), nil
|
||||||
|
|
||||||
case "mysql_native_password":
|
case "mysql_native_password":
|
||||||
if !mc.cfg.AllowNativePasswords {
|
if !mc.cfg.AllowNativePasswords {
|
||||||
return nil, false, ErrNativePassword
|
return nil, ErrNativePassword
|
||||||
}
|
}
|
||||||
// https://dev.mysql.com/doc/internals/en/secure-password-authentication.html
|
// https://dev.mysql.com/doc/internals/en/secure-password-authentication.html
|
||||||
// Native password authentication only need and will need 20-byte challenge.
|
// Native password authentication only need and will need 20-byte challenge.
|
||||||
authResp := scramblePassword(authData[:20], mc.cfg.Passwd)
|
authResp := scramblePassword(authData[:20], mc.cfg.Passwd)
|
||||||
return authResp, false, nil
|
return authResp, nil
|
||||||
|
|
||||||
case "sha256_password":
|
case "sha256_password":
|
||||||
if len(mc.cfg.Passwd) == 0 {
|
if len(mc.cfg.Passwd) == 0 {
|
||||||
return nil, true, nil
|
return []byte{0}, nil
|
||||||
}
|
}
|
||||||
if mc.cfg.tls != nil || mc.cfg.Net == "unix" {
|
if mc.cfg.tls != nil || mc.cfg.Net == "unix" {
|
||||||
// write cleartext auth packet
|
// write cleartext auth packet
|
||||||
return []byte(mc.cfg.Passwd), true, nil
|
return append([]byte(mc.cfg.Passwd), 0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
pubKey := mc.cfg.pubKey
|
pubKey := mc.cfg.pubKey
|
||||||
if pubKey == nil {
|
if pubKey == nil {
|
||||||
// request public key from server
|
// request public key from server
|
||||||
return []byte{1}, false, nil
|
return []byte{1}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// encrypted password
|
// encrypted password
|
||||||
enc, err := encryptPassword(mc.cfg.Passwd, authData, pubKey)
|
enc, err := encryptPassword(mc.cfg.Passwd, authData, pubKey)
|
||||||
return enc, false, err
|
return enc, err
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errLog.Print("unknown auth plugin:", plugin)
|
errLog.Print("unknown auth plugin:", plugin)
|
||||||
return nil, false, ErrUnknownPlugin
|
return nil, ErrUnknownPlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,11 +315,11 @@ func (mc *mysqlConn) handleAuthResult(oldAuthData []byte, plugin string) error {
|
|||||||
|
|
||||||
plugin = newPlugin
|
plugin = newPlugin
|
||||||
|
|
||||||
authResp, addNUL, err := mc.auth(authData, plugin)
|
authResp, err := mc.auth(authData, plugin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = mc.writeAuthSwitchPacket(authResp, addNUL); err != nil {
|
if err = mc.writeAuthSwitchPacket(authResp); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +352,7 @@ func (mc *mysqlConn) handleAuthResult(oldAuthData []byte, plugin string) error {
|
|||||||
case cachingSha2PasswordPerformFullAuthentication:
|
case cachingSha2PasswordPerformFullAuthentication:
|
||||||
if mc.cfg.tls != nil || mc.cfg.Net == "unix" {
|
if mc.cfg.tls != nil || mc.cfg.Net == "unix" {
|
||||||
// write cleartext auth packet
|
// write cleartext auth packet
|
||||||
err = mc.writeAuthSwitchPacket([]byte(mc.cfg.Passwd), true)
|
err = mc.writeAuthSwitchPacket(append([]byte(mc.cfg.Passwd), 0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
15
vendor/github.com/go-sql-driver/mysql/connection_go18.go
generated
vendored
15
vendor/github.com/go-sql-driver/mysql/connection_go18.go
generated
vendored
@ -149,22 +149,21 @@ func (mc *mysqlConn) watchCancel(ctx context.Context) error {
|
|||||||
mc.cleanup()
|
mc.cleanup()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// When ctx is already cancelled, don't watch it.
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// When ctx is not cancellable, don't watch it.
|
||||||
if ctx.Done() == nil {
|
if ctx.Done() == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// When watcher is not alive, can't watch it.
|
||||||
mc.watching = true
|
|
||||||
select {
|
|
||||||
default:
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
if mc.watcher == nil {
|
if mc.watcher == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mc.watching = true
|
||||||
mc.watcher <- ctx
|
mc.watcher <- ctx
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
vendor/github.com/go-sql-driver/mysql/driver.go
generated
vendored
9
vendor/github.com/go-sql-driver/mysql/driver.go
generated
vendored
@ -112,20 +112,23 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
|
|||||||
mc.cleanup()
|
mc.cleanup()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if plugin == "" {
|
||||||
|
plugin = defaultAuthPlugin
|
||||||
|
}
|
||||||
|
|
||||||
// Send Client Authentication Packet
|
// Send Client Authentication Packet
|
||||||
authResp, addNUL, err := mc.auth(authData, plugin)
|
authResp, err := mc.auth(authData, plugin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// try the default auth plugin, if using the requested plugin failed
|
// try the default auth plugin, if using the requested plugin failed
|
||||||
errLog.Print("could not use requested auth plugin '"+plugin+"': ", err.Error())
|
errLog.Print("could not use requested auth plugin '"+plugin+"': ", err.Error())
|
||||||
plugin = defaultAuthPlugin
|
plugin = defaultAuthPlugin
|
||||||
authResp, addNUL, err = mc.auth(authData, plugin)
|
authResp, err = mc.auth(authData, plugin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mc.cleanup()
|
mc.cleanup()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin); err != nil {
|
if err = mc.writeHandshakeResponsePacket(authResp, plugin); err != nil {
|
||||||
mc.cleanup()
|
mc.cleanup()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
39
vendor/github.com/go-sql-driver/mysql/packets.go
generated
vendored
39
vendor/github.com/go-sql-driver/mysql/packets.go
generated
vendored
@ -154,15 +154,15 @@ func (mc *mysqlConn) writePacket(data []byte) error {
|
|||||||
|
|
||||||
// Handshake Initialization Packet
|
// Handshake Initialization Packet
|
||||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
|
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
|
||||||
func (mc *mysqlConn) readHandshakePacket() ([]byte, string, error) {
|
func (mc *mysqlConn) readHandshakePacket() (data []byte, plugin string, err error) {
|
||||||
data, err := mc.readPacket()
|
data, err = mc.readPacket()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// for init we can rewrite this to ErrBadConn for sql.Driver to retry, since
|
// for init we can rewrite this to ErrBadConn for sql.Driver to retry, since
|
||||||
// in connection initialization we don't risk retrying non-idempotent actions.
|
// in connection initialization we don't risk retrying non-idempotent actions.
|
||||||
if err == ErrInvalidConn {
|
if err == ErrInvalidConn {
|
||||||
return nil, "", driver.ErrBadConn
|
return nil, "", driver.ErrBadConn
|
||||||
}
|
}
|
||||||
return nil, "", err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if data[0] == iERR {
|
if data[0] == iERR {
|
||||||
@ -198,7 +198,6 @@ func (mc *mysqlConn) readHandshakePacket() ([]byte, string, error) {
|
|||||||
}
|
}
|
||||||
pos += 2
|
pos += 2
|
||||||
|
|
||||||
plugin := ""
|
|
||||||
if len(data) > pos {
|
if len(data) > pos {
|
||||||
// character set [1 byte]
|
// character set [1 byte]
|
||||||
// status flags [2 bytes]
|
// status flags [2 bytes]
|
||||||
@ -236,8 +235,6 @@ func (mc *mysqlConn) readHandshakePacket() ([]byte, string, error) {
|
|||||||
return b[:], plugin, nil
|
return b[:], plugin, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin = defaultAuthPlugin
|
|
||||||
|
|
||||||
// make a memory safe copy of the cipher slice
|
// make a memory safe copy of the cipher slice
|
||||||
var b [8]byte
|
var b [8]byte
|
||||||
copy(b[:], authData)
|
copy(b[:], authData)
|
||||||
@ -246,7 +243,7 @@ func (mc *mysqlConn) readHandshakePacket() ([]byte, string, error) {
|
|||||||
|
|
||||||
// Client Authentication Packet
|
// Client Authentication Packet
|
||||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse
|
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse
|
||||||
func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, addNUL bool, plugin string) error {
|
func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string) error {
|
||||||
// Adjust client flags based on server support
|
// Adjust client flags based on server support
|
||||||
clientFlags := clientProtocol41 |
|
clientFlags := clientProtocol41 |
|
||||||
clientSecureConn |
|
clientSecureConn |
|
||||||
@ -272,7 +269,8 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, addNUL bool,
|
|||||||
|
|
||||||
// encode length of the auth plugin data
|
// encode length of the auth plugin data
|
||||||
var authRespLEIBuf [9]byte
|
var authRespLEIBuf [9]byte
|
||||||
authRespLEI := appendLengthEncodedInteger(authRespLEIBuf[:0], uint64(len(authResp)))
|
authRespLen := len(authResp)
|
||||||
|
authRespLEI := appendLengthEncodedInteger(authRespLEIBuf[:0], uint64(authRespLen))
|
||||||
if len(authRespLEI) > 1 {
|
if len(authRespLEI) > 1 {
|
||||||
// if the length can not be written in 1 byte, it must be written as a
|
// if the length can not be written in 1 byte, it must be written as a
|
||||||
// length encoded integer
|
// length encoded integer
|
||||||
@ -280,9 +278,6 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, addNUL bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pktLen := 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1 + len(authRespLEI) + len(authResp) + 21 + 1
|
pktLen := 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1 + len(authRespLEI) + len(authResp) + 21 + 1
|
||||||
if addNUL {
|
|
||||||
pktLen++
|
|
||||||
}
|
|
||||||
|
|
||||||
// To specify a db name
|
// To specify a db name
|
||||||
if n := len(mc.cfg.DBName); n > 0 {
|
if n := len(mc.cfg.DBName); n > 0 {
|
||||||
@ -353,10 +348,6 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, addNUL bool,
|
|||||||
// Auth Data [length encoded integer]
|
// Auth Data [length encoded integer]
|
||||||
pos += copy(data[pos:], authRespLEI)
|
pos += copy(data[pos:], authRespLEI)
|
||||||
pos += copy(data[pos:], authResp)
|
pos += copy(data[pos:], authResp)
|
||||||
if addNUL {
|
|
||||||
data[pos] = 0x00
|
|
||||||
pos++
|
|
||||||
}
|
|
||||||
|
|
||||||
// Databasename [null terminated string]
|
// Databasename [null terminated string]
|
||||||
if len(mc.cfg.DBName) > 0 {
|
if len(mc.cfg.DBName) > 0 {
|
||||||
@ -367,17 +358,15 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, addNUL bool,
|
|||||||
|
|
||||||
pos += copy(data[pos:], plugin)
|
pos += copy(data[pos:], plugin)
|
||||||
data[pos] = 0x00
|
data[pos] = 0x00
|
||||||
|
pos++
|
||||||
|
|
||||||
// Send Auth packet
|
// Send Auth packet
|
||||||
return mc.writePacket(data)
|
return mc.writePacket(data[:pos])
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
|
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
|
||||||
func (mc *mysqlConn) writeAuthSwitchPacket(authData []byte, addNUL bool) error {
|
func (mc *mysqlConn) writeAuthSwitchPacket(authData []byte) error {
|
||||||
pktLen := 4 + len(authData)
|
pktLen := 4 + len(authData)
|
||||||
if addNUL {
|
|
||||||
pktLen++
|
|
||||||
}
|
|
||||||
data := mc.buf.takeSmallBuffer(pktLen)
|
data := mc.buf.takeSmallBuffer(pktLen)
|
||||||
if data == nil {
|
if data == nil {
|
||||||
// cannot take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
@ -387,10 +376,6 @@ func (mc *mysqlConn) writeAuthSwitchPacket(authData []byte, addNUL bool) error {
|
|||||||
|
|
||||||
// Add the auth data [EOF]
|
// Add the auth data [EOF]
|
||||||
copy(data[4:], authData)
|
copy(data[4:], authData)
|
||||||
if addNUL {
|
|
||||||
data[pktLen-1] = 0x00
|
|
||||||
}
|
|
||||||
|
|
||||||
return mc.writePacket(data)
|
return mc.writePacket(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,7 +467,7 @@ func (mc *mysqlConn) readAuthResult() ([]byte, string, error) {
|
|||||||
return data[1:], "", err
|
return data[1:], "", err
|
||||||
|
|
||||||
case iEOF:
|
case iEOF:
|
||||||
if len(data) < 1 {
|
if len(data) == 1 {
|
||||||
// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest
|
// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest
|
||||||
return nil, "mysql_old_password", nil
|
return nil, "mysql_old_password", nil
|
||||||
}
|
}
|
||||||
@ -1261,7 +1246,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
|||||||
rows.rs.columns[i].decimals,
|
rows.rs.columns[i].decimals,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen, true)
|
dest[i], err = formatBinaryTime(data[pos:pos+int(num)], dstlen)
|
||||||
case rows.mc.parseTime:
|
case rows.mc.parseTime:
|
||||||
dest[i], err = parseBinaryDateTime(num, data[pos:], rows.mc.cfg.Loc)
|
dest[i], err = parseBinaryDateTime(num, data[pos:], rows.mc.cfg.Loc)
|
||||||
default:
|
default:
|
||||||
@ -1281,7 +1266,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen, false)
|
dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
172
vendor/github.com/go-sql-driver/mysql/utils.go
generated
vendored
172
vendor/github.com/go-sql-driver/mysql/utils.go
generated
vendored
@ -14,6 +14,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@ -227,47 +228,64 @@ var zeroDateTime = []byte("0000-00-00 00:00:00.000000")
|
|||||||
const digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
|
const digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
|
||||||
const digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
|
const digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
|
||||||
|
|
||||||
func formatBinaryDateTime(src []byte, length uint8, justTime bool) (driver.Value, error) {
|
func appendMicrosecs(dst, src []byte, decimals int) []byte {
|
||||||
|
if decimals <= 0 {
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
if len(src) == 0 {
|
||||||
|
return append(dst, ".000000"[:decimals+1]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
microsecs := binary.LittleEndian.Uint32(src[:4])
|
||||||
|
p1 := byte(microsecs / 10000)
|
||||||
|
microsecs -= 10000 * uint32(p1)
|
||||||
|
p2 := byte(microsecs / 100)
|
||||||
|
microsecs -= 100 * uint32(p2)
|
||||||
|
p3 := byte(microsecs)
|
||||||
|
|
||||||
|
switch decimals {
|
||||||
|
default:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1], digits01[p1],
|
||||||
|
digits10[p2], digits01[p2],
|
||||||
|
digits10[p3], digits01[p3],
|
||||||
|
)
|
||||||
|
case 1:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1],
|
||||||
|
)
|
||||||
|
case 2:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1], digits01[p1],
|
||||||
|
)
|
||||||
|
case 3:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1], digits01[p1],
|
||||||
|
digits10[p2],
|
||||||
|
)
|
||||||
|
case 4:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1], digits01[p1],
|
||||||
|
digits10[p2], digits01[p2],
|
||||||
|
)
|
||||||
|
case 5:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1], digits01[p1],
|
||||||
|
digits10[p2], digits01[p2],
|
||||||
|
digits10[p3],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatBinaryDateTime(src []byte, length uint8) (driver.Value, error) {
|
||||||
// length expects the deterministic length of the zero value,
|
// length expects the deterministic length of the zero value,
|
||||||
// negative time and 100+ hours are automatically added if needed
|
// negative time and 100+ hours are automatically added if needed
|
||||||
if len(src) == 0 {
|
if len(src) == 0 {
|
||||||
if justTime {
|
|
||||||
return zeroDateTime[11 : 11+length], nil
|
|
||||||
}
|
|
||||||
return zeroDateTime[:length], nil
|
return zeroDateTime[:length], nil
|
||||||
}
|
}
|
||||||
var dst []byte // return value
|
var dst []byte // return value
|
||||||
var pt, p1, p2, p3 byte // current digit pair
|
var p1, p2, p3 byte // current digit pair
|
||||||
var zOffs byte // offset of value in zeroDateTime
|
|
||||||
if justTime {
|
|
||||||
switch length {
|
|
||||||
case
|
|
||||||
8, // time (can be up to 10 when negative and 100+ hours)
|
|
||||||
10, 11, 12, 13, 14, 15: // time with fractional seconds
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("illegal TIME length %d", length)
|
|
||||||
}
|
|
||||||
switch len(src) {
|
|
||||||
case 8, 12:
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid TIME packet length %d", len(src))
|
|
||||||
}
|
|
||||||
// +2 to enable negative time and 100+ hours
|
|
||||||
dst = make([]byte, 0, length+2)
|
|
||||||
if src[0] == 1 {
|
|
||||||
dst = append(dst, '-')
|
|
||||||
}
|
|
||||||
if src[1] != 0 {
|
|
||||||
hour := uint16(src[1])*24 + uint16(src[5])
|
|
||||||
pt = byte(hour / 100)
|
|
||||||
p1 = byte(hour - 100*uint16(pt))
|
|
||||||
dst = append(dst, digits01[pt])
|
|
||||||
} else {
|
|
||||||
p1 = src[5]
|
|
||||||
}
|
|
||||||
zOffs = 11
|
|
||||||
src = src[6:]
|
|
||||||
} else {
|
|
||||||
switch length {
|
switch length {
|
||||||
case 10, 19, 21, 22, 23, 24, 25, 26:
|
case 10, 19, 21, 22, 23, 24, 25, 26:
|
||||||
default:
|
default:
|
||||||
@ -289,7 +307,7 @@ func formatBinaryDateTime(src []byte, length uint8, justTime bool) (driver.Value
|
|||||||
dst = make([]byte, 0, length)
|
dst = make([]byte, 0, length)
|
||||||
// start with the date
|
// start with the date
|
||||||
year := binary.LittleEndian.Uint16(src[:2])
|
year := binary.LittleEndian.Uint16(src[:2])
|
||||||
pt = byte(year / 100)
|
pt := year / 100
|
||||||
p1 = byte(year - 100*uint16(pt))
|
p1 = byte(year - 100*uint16(pt))
|
||||||
p2, p3 = src[2], src[3]
|
p2, p3 = src[2], src[3]
|
||||||
dst = append(dst,
|
dst = append(dst,
|
||||||
@ -307,7 +325,7 @@ func formatBinaryDateTime(src []byte, length uint8, justTime bool) (driver.Value
|
|||||||
dst = append(dst, ' ')
|
dst = append(dst, ' ')
|
||||||
p1 = src[4] // hour
|
p1 = src[4] // hour
|
||||||
src = src[5:]
|
src = src[5:]
|
||||||
}
|
|
||||||
// p1 is 2-digit hour, src is after hour
|
// p1 is 2-digit hour, src is after hour
|
||||||
p2, p3 = src[0], src[1]
|
p2, p3 = src[0], src[1]
|
||||||
dst = append(dst,
|
dst = append(dst,
|
||||||
@ -315,51 +333,49 @@ func formatBinaryDateTime(src []byte, length uint8, justTime bool) (driver.Value
|
|||||||
digits10[p2], digits01[p2], ':',
|
digits10[p2], digits01[p2], ':',
|
||||||
digits10[p3], digits01[p3],
|
digits10[p3], digits01[p3],
|
||||||
)
|
)
|
||||||
if length <= byte(len(dst)) {
|
return appendMicrosecs(dst, src[2:], int(length)-20), nil
|
||||||
return dst, nil
|
}
|
||||||
}
|
|
||||||
src = src[2:]
|
func formatBinaryTime(src []byte, length uint8) (driver.Value, error) {
|
||||||
|
// length expects the deterministic length of the zero value,
|
||||||
|
// negative time and 100+ hours are automatically added if needed
|
||||||
if len(src) == 0 {
|
if len(src) == 0 {
|
||||||
return append(dst, zeroDateTime[19:zOffs+length]...), nil
|
return zeroDateTime[11 : 11+length], nil
|
||||||
}
|
}
|
||||||
microsecs := binary.LittleEndian.Uint32(src[:4])
|
var dst []byte // return value
|
||||||
p1 = byte(microsecs / 10000)
|
|
||||||
microsecs -= 10000 * uint32(p1)
|
switch length {
|
||||||
p2 = byte(microsecs / 100)
|
case
|
||||||
microsecs -= 100 * uint32(p2)
|
8, // time (can be up to 10 when negative and 100+ hours)
|
||||||
p3 = byte(microsecs)
|
10, 11, 12, 13, 14, 15: // time with fractional seconds
|
||||||
switch decimals := zOffs + length - 20; decimals {
|
|
||||||
default:
|
default:
|
||||||
return append(dst, '.',
|
return nil, fmt.Errorf("illegal TIME length %d", length)
|
||||||
digits10[p1], digits01[p1],
|
|
||||||
digits10[p2], digits01[p2],
|
|
||||||
digits10[p3], digits01[p3],
|
|
||||||
), nil
|
|
||||||
case 1:
|
|
||||||
return append(dst, '.',
|
|
||||||
digits10[p1],
|
|
||||||
), nil
|
|
||||||
case 2:
|
|
||||||
return append(dst, '.',
|
|
||||||
digits10[p1], digits01[p1],
|
|
||||||
), nil
|
|
||||||
case 3:
|
|
||||||
return append(dst, '.',
|
|
||||||
digits10[p1], digits01[p1],
|
|
||||||
digits10[p2],
|
|
||||||
), nil
|
|
||||||
case 4:
|
|
||||||
return append(dst, '.',
|
|
||||||
digits10[p1], digits01[p1],
|
|
||||||
digits10[p2], digits01[p2],
|
|
||||||
), nil
|
|
||||||
case 5:
|
|
||||||
return append(dst, '.',
|
|
||||||
digits10[p1], digits01[p1],
|
|
||||||
digits10[p2], digits01[p2],
|
|
||||||
digits10[p3],
|
|
||||||
), nil
|
|
||||||
}
|
}
|
||||||
|
switch len(src) {
|
||||||
|
case 8, 12:
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invalid TIME packet length %d", len(src))
|
||||||
|
}
|
||||||
|
// +2 to enable negative time and 100+ hours
|
||||||
|
dst = make([]byte, 0, length+2)
|
||||||
|
if src[0] == 1 {
|
||||||
|
dst = append(dst, '-')
|
||||||
|
}
|
||||||
|
days := binary.LittleEndian.Uint32(src[1:5])
|
||||||
|
hours := int64(days)*24 + int64(src[5])
|
||||||
|
|
||||||
|
if hours >= 100 {
|
||||||
|
dst = strconv.AppendInt(dst, hours, 10)
|
||||||
|
} else {
|
||||||
|
dst = append(dst, digits10[hours], digits01[hours])
|
||||||
|
}
|
||||||
|
|
||||||
|
min, sec := src[6], src[7]
|
||||||
|
dst = append(dst, ':',
|
||||||
|
digits10[min], digits01[min], ':',
|
||||||
|
digits10[sec], digits01[sec],
|
||||||
|
)
|
||||||
|
return appendMicrosecs(dst, src[8:], int(length)-9), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
9
vendor/golang.org/x/crypto/acme/acme.go
generated
vendored
9
vendor/golang.org/x/crypto/acme/acme.go
generated
vendored
@ -46,8 +46,9 @@ const (
|
|||||||
// ALPNProto is the ALPN protocol name used by a CA server when validating
|
// ALPNProto is the ALPN protocol name used by a CA server when validating
|
||||||
// tls-alpn-01 challenges.
|
// tls-alpn-01 challenges.
|
||||||
//
|
//
|
||||||
// Package users must ensure their servers can negotiate the ACME ALPN
|
// Package users must ensure their servers can negotiate the ACME ALPN in
|
||||||
// in order for tls-alpn-01 challenge verifications to succeed.
|
// order for tls-alpn-01 challenge verifications to succeed.
|
||||||
|
// See the crypto/tls package's Config.NextProtos field.
|
||||||
ALPNProto = "acme-tls/1"
|
ALPNProto = "acme-tls/1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -76,6 +77,10 @@ const (
|
|||||||
type Client struct {
|
type Client struct {
|
||||||
// Key is the account key used to register with a CA and sign requests.
|
// Key is the account key used to register with a CA and sign requests.
|
||||||
// Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey.
|
// Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey.
|
||||||
|
//
|
||||||
|
// The following algorithms are supported:
|
||||||
|
// RS256, ES256, ES384 and ES512.
|
||||||
|
// See RFC7518 for more details about the algorithms.
|
||||||
Key crypto.Signer
|
Key crypto.Signer
|
||||||
|
|
||||||
// HTTPClient optionally specifies an HTTP client to use
|
// HTTPClient optionally specifies an HTTP client to use
|
||||||
|
34
vendor/golang.org/x/crypto/acme/autocert/autocert.go
generated
vendored
34
vendor/golang.org/x/crypto/acme/autocert/autocert.go
generated
vendored
@ -44,7 +44,7 @@ var createCertRetryAfter = time.Minute
|
|||||||
var pseudoRand *lockedMathRand
|
var pseudoRand *lockedMathRand
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
src := mathrand.NewSource(timeNow().UnixNano())
|
src := mathrand.NewSource(time.Now().UnixNano())
|
||||||
pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
|
pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ func HostWhitelist(hosts ...string) HostPolicy {
|
|||||||
}
|
}
|
||||||
return func(_ context.Context, host string) error {
|
return func(_ context.Context, host string) error {
|
||||||
if !whitelist[host] {
|
if !whitelist[host] {
|
||||||
return errors.New("acme/autocert: host not configured")
|
return fmt.Errorf("acme/autocert: host %q not configured in HostWhitelist", host)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -183,6 +183,9 @@ type Manager struct {
|
|||||||
// for tls-alpn.
|
// for tls-alpn.
|
||||||
// The entries are stored for the duration of the authorization flow.
|
// The entries are stored for the duration of the authorization flow.
|
||||||
certTokens map[string]*tls.Certificate
|
certTokens map[string]*tls.Certificate
|
||||||
|
// nowFunc, if not nil, returns the current time. This may be set for
|
||||||
|
// testing purposes.
|
||||||
|
nowFunc func() time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// certKey is the key by which certificates are tracked in state, renewal and cache.
|
// certKey is the key by which certificates are tracked in state, renewal and cache.
|
||||||
@ -223,6 +226,11 @@ func (m *Manager) TLSConfig() *tls.Config {
|
|||||||
// a new cert. A non-nil error returned from m.HostPolicy halts TLS negotiation.
|
// a new cert. A non-nil error returned from m.HostPolicy halts TLS negotiation.
|
||||||
// The error is propagated back to the caller of GetCertificate and is user-visible.
|
// The error is propagated back to the caller of GetCertificate and is user-visible.
|
||||||
// This does not affect cached certs. See HostPolicy field description for more details.
|
// This does not affect cached certs. See HostPolicy field description for more details.
|
||||||
|
//
|
||||||
|
// If GetCertificate is used directly, instead of via Manager.TLSConfig, package users will
|
||||||
|
// also have to add acme.ALPNProto to NextProtos for tls-alpn-01, or use HTTPHandler
|
||||||
|
// for http-01. (The tls-sni-* challenges have been deprecated by popular ACME providers
|
||||||
|
// due to security issues in the ecosystem.)
|
||||||
func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
if m.Prompt == nil {
|
if m.Prompt == nil {
|
||||||
return nil, errors.New("acme/autocert: Manager.Prompt not set")
|
return nil, errors.New("acme/autocert: Manager.Prompt not set")
|
||||||
@ -356,8 +364,8 @@ func supportsECDSA(hello *tls.ClientHelloInfo) bool {
|
|||||||
// Because the fallback handler is run with unencrypted port 80 requests,
|
// Because the fallback handler is run with unencrypted port 80 requests,
|
||||||
// the fallback should not serve TLS-only requests.
|
// the fallback should not serve TLS-only requests.
|
||||||
//
|
//
|
||||||
// If HTTPHandler is never called, the Manager will only use TLS SNI
|
// If HTTPHandler is never called, the Manager will only use the "tls-alpn-01"
|
||||||
// challenges for domain verification.
|
// challenge for domain verification.
|
||||||
func (m *Manager) HTTPHandler(fallback http.Handler) http.Handler {
|
func (m *Manager) HTTPHandler(fallback http.Handler) http.Handler {
|
||||||
m.tokensMu.Lock()
|
m.tokensMu.Lock()
|
||||||
defer m.tokensMu.Unlock()
|
defer m.tokensMu.Unlock()
|
||||||
@ -475,7 +483,7 @@ func (m *Manager) cacheGet(ctx context.Context, ck certKey) (*tls.Certificate, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
// verify and create TLS cert
|
// verify and create TLS cert
|
||||||
leaf, err := validCert(ck, pubDER, privKey)
|
leaf, err := validCert(ck, pubDER, privKey, m.now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ErrCacheMiss
|
return nil, ErrCacheMiss
|
||||||
}
|
}
|
||||||
@ -570,7 +578,7 @@ func (m *Manager) createCert(ctx context.Context, ck certKey) (*tls.Certificate,
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if _, err := validCert(ck, s.cert, s.key); err == nil {
|
if _, err := validCert(ck, s.cert, s.key, m.now()); err == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
delete(m.state, ck)
|
delete(m.state, ck)
|
||||||
@ -639,7 +647,7 @@ func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, ck cert
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
leaf, err = validCert(ck, der, key)
|
leaf, err = validCert(ck, der, key, m.now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -983,6 +991,13 @@ func (m *Manager) renewBefore() time.Duration {
|
|||||||
return 720 * time.Hour // 30 days
|
return 720 * time.Hour // 30 days
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Manager) now() time.Time {
|
||||||
|
if m.nowFunc != nil {
|
||||||
|
return m.nowFunc()
|
||||||
|
}
|
||||||
|
return time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
// certState is ready when its mutex is unlocked for reading.
|
// certState is ready when its mutex is unlocked for reading.
|
||||||
type certState struct {
|
type certState struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
@ -1049,7 +1064,7 @@ func parsePrivateKey(der []byte) (crypto.Signer, error) {
|
|||||||
// are valid. It doesn't do any revocation checking.
|
// are valid. It doesn't do any revocation checking.
|
||||||
//
|
//
|
||||||
// The returned value is the verified leaf cert.
|
// The returned value is the verified leaf cert.
|
||||||
func validCert(ck certKey, der [][]byte, key crypto.Signer) (leaf *x509.Certificate, err error) {
|
func validCert(ck certKey, der [][]byte, key crypto.Signer, now time.Time) (leaf *x509.Certificate, err error) {
|
||||||
// parse public part(s)
|
// parse public part(s)
|
||||||
var n int
|
var n int
|
||||||
for _, b := range der {
|
for _, b := range der {
|
||||||
@ -1066,7 +1081,6 @@ func validCert(ck certKey, der [][]byte, key crypto.Signer) (leaf *x509.Certific
|
|||||||
}
|
}
|
||||||
// verify the leaf is not expired and matches the domain name
|
// verify the leaf is not expired and matches the domain name
|
||||||
leaf = x509Cert[0]
|
leaf = x509Cert[0]
|
||||||
now := timeNow()
|
|
||||||
if now.Before(leaf.NotBefore) {
|
if now.Before(leaf.NotBefore) {
|
||||||
return nil, errors.New("acme/autocert: certificate is not valid yet")
|
return nil, errors.New("acme/autocert: certificate is not valid yet")
|
||||||
}
|
}
|
||||||
@ -1120,8 +1134,6 @@ func (r *lockedMathRand) int63n(max int64) int64 {
|
|||||||
|
|
||||||
// For easier testing.
|
// For easier testing.
|
||||||
var (
|
var (
|
||||||
timeNow = time.Now
|
|
||||||
|
|
||||||
// Called when a state is removed.
|
// Called when a state is removed.
|
||||||
testDidRemoveState = func(certKey) {}
|
testDidRemoveState = func(certKey) {}
|
||||||
)
|
)
|
||||||
|
2
vendor/golang.org/x/crypto/acme/autocert/renewal.go
generated
vendored
2
vendor/golang.org/x/crypto/acme/autocert/renewal.go
generated
vendored
@ -128,7 +128,7 @@ func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (dr *domainRenewal) next(expiry time.Time) time.Duration {
|
func (dr *domainRenewal) next(expiry time.Time) time.Duration {
|
||||||
d := expiry.Sub(timeNow()) - dr.m.renewBefore()
|
d := expiry.Sub(dr.m.now()) - dr.m.renewBefore()
|
||||||
// add a bit of randomness to renew deadline
|
// add a bit of randomness to renew deadline
|
||||||
n := pseudoRand.int63n(int64(renewJitter))
|
n := pseudoRand.int63n(int64(renewJitter))
|
||||||
d -= time.Duration(n)
|
d -= time.Duration(n)
|
||||||
|
29
vendor/golang.org/x/crypto/acme/jws.go
generated
vendored
29
vendor/golang.org/x/crypto/acme/jws.go
generated
vendored
@ -25,7 +25,7 @@ func jwsEncodeJSON(claimset interface{}, key crypto.Signer, nonce string) ([]byt
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
alg, sha := jwsHasher(key)
|
alg, sha := jwsHasher(key.Public())
|
||||||
if alg == "" || !sha.Available() {
|
if alg == "" || !sha.Available() {
|
||||||
return nil, ErrUnsupportedKey
|
return nil, ErrUnsupportedKey
|
||||||
}
|
}
|
||||||
@ -97,13 +97,16 @@ func jwkEncode(pub crypto.PublicKey) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// jwsSign signs the digest using the given key.
|
// jwsSign signs the digest using the given key.
|
||||||
// It returns ErrUnsupportedKey if the key type is unknown.
|
// The hash is unused for ECDSA keys.
|
||||||
// The hash is used only for RSA keys.
|
//
|
||||||
|
// Note: non-stdlib crypto.Signer implementations are expected to return
|
||||||
|
// the signature in the format as specified in RFC7518.
|
||||||
|
// See https://tools.ietf.org/html/rfc7518 for more details.
|
||||||
func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) {
|
func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) {
|
||||||
switch key := key.(type) {
|
if key, ok := key.(*ecdsa.PrivateKey); ok {
|
||||||
case *rsa.PrivateKey:
|
// The key.Sign method of ecdsa returns ASN1-encoded signature.
|
||||||
return key.Sign(rand.Reader, digest, hash)
|
// So, we use the package Sign function instead
|
||||||
case *ecdsa.PrivateKey:
|
// to get R and S values directly and format the result accordingly.
|
||||||
r, s, err := ecdsa.Sign(rand.Reader, key, digest)
|
r, s, err := ecdsa.Sign(rand.Reader, key, digest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -118,18 +121,18 @@ func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error)
|
|||||||
copy(sig[size*2-len(sb):], sb)
|
copy(sig[size*2-len(sb):], sb)
|
||||||
return sig, nil
|
return sig, nil
|
||||||
}
|
}
|
||||||
return nil, ErrUnsupportedKey
|
return key.Sign(rand.Reader, digest, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// jwsHasher indicates suitable JWS algorithm name and a hash function
|
// jwsHasher indicates suitable JWS algorithm name and a hash function
|
||||||
// to use for signing a digest with the provided key.
|
// to use for signing a digest with the provided key.
|
||||||
// It returns ("", 0) if the key is not supported.
|
// It returns ("", 0) if the key is not supported.
|
||||||
func jwsHasher(key crypto.Signer) (string, crypto.Hash) {
|
func jwsHasher(pub crypto.PublicKey) (string, crypto.Hash) {
|
||||||
switch key := key.(type) {
|
switch pub := pub.(type) {
|
||||||
case *rsa.PrivateKey:
|
case *rsa.PublicKey:
|
||||||
return "RS256", crypto.SHA256
|
return "RS256", crypto.SHA256
|
||||||
case *ecdsa.PrivateKey:
|
case *ecdsa.PublicKey:
|
||||||
switch key.Params().Name {
|
switch pub.Params().Name {
|
||||||
case "P-256":
|
case "P-256":
|
||||||
return "ES256", crypto.SHA256
|
return "ES256", crypto.SHA256
|
||||||
case "P-384":
|
case "P-384":
|
||||||
|
13
vendor/modules.txt
vendored
13
vendor/modules.txt
vendored
@ -8,9 +8,10 @@ github.com/beego/x2j
|
|||||||
github.com/belogik/goes
|
github.com/belogik/goes
|
||||||
# github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737
|
# github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737
|
||||||
github.com/bradfitz/gomemcache/memcache
|
github.com/bradfitz/gomemcache/memcache
|
||||||
# github.com/casbin/casbin v1.6.0
|
# github.com/casbin/casbin v1.7.0
|
||||||
github.com/casbin/casbin
|
github.com/casbin/casbin
|
||||||
github.com/casbin/casbin/effect
|
github.com/casbin/casbin/effect
|
||||||
|
github.com/casbin/casbin/log
|
||||||
github.com/casbin/casbin/model
|
github.com/casbin/casbin/model
|
||||||
github.com/casbin/casbin/persist
|
github.com/casbin/casbin/persist
|
||||||
github.com/casbin/casbin/persist/file-adapter
|
github.com/casbin/casbin/persist/file-adapter
|
||||||
@ -34,6 +35,8 @@ github.com/cupcake/rdb/nopdecoder
|
|||||||
github.com/cupcake/rdb/crc64
|
github.com/cupcake/rdb/crc64
|
||||||
# github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712
|
# github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712
|
||||||
github.com/edsrzf/mmap-go
|
github.com/edsrzf/mmap-go
|
||||||
|
# github.com/elazarl/go-bindata-assetfs v0.0.0-20180223110309-38087fe4dafb
|
||||||
|
github.com/elazarl/go-bindata-assetfs
|
||||||
# github.com/go-redis/redis v6.14.2+incompatible
|
# github.com/go-redis/redis v6.14.2+incompatible
|
||||||
github.com/go-redis/redis
|
github.com/go-redis/redis
|
||||||
github.com/go-redis/redis/internal
|
github.com/go-redis/redis/internal
|
||||||
@ -43,7 +46,7 @@ github.com/go-redis/redis/internal/pool
|
|||||||
github.com/go-redis/redis/internal/proto
|
github.com/go-redis/redis/internal/proto
|
||||||
github.com/go-redis/redis/internal/singleflight
|
github.com/go-redis/redis/internal/singleflight
|
||||||
github.com/go-redis/redis/internal/util
|
github.com/go-redis/redis/internal/util
|
||||||
# github.com/go-sql-driver/mysql v1.4.0
|
# github.com/go-sql-driver/mysql v1.4.1
|
||||||
github.com/go-sql-driver/mysql
|
github.com/go-sql-driver/mysql
|
||||||
# github.com/gogo/protobuf v1.1.1
|
# github.com/gogo/protobuf v1.1.1
|
||||||
github.com/gogo/protobuf/proto
|
github.com/gogo/protobuf/proto
|
||||||
@ -97,13 +100,13 @@ github.com/syndtr/goleveldb/leveldb/memdb
|
|||||||
github.com/syndtr/goleveldb/leveldb/table
|
github.com/syndtr/goleveldb/leveldb/table
|
||||||
# github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b
|
# github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b
|
||||||
github.com/wendal/errors
|
github.com/wendal/errors
|
||||||
# golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb
|
# golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869
|
||||||
golang.org/x/crypto/acme/autocert
|
golang.org/x/crypto/acme/autocert
|
||||||
golang.org/x/crypto/acme
|
golang.org/x/crypto/acme
|
||||||
golang.org/x/crypto/pbkdf2
|
golang.org/x/crypto/pbkdf2
|
||||||
# golang.org/x/net v0.0.0-20180906233101-161cd47e91fd
|
# golang.org/x/net v0.0.0-20181114220301-adae6a3d119a
|
||||||
golang.org/x/net/context
|
golang.org/x/net/context
|
||||||
# google.golang.org/appengine v1.1.0
|
# google.golang.org/appengine v1.3.0
|
||||||
google.golang.org/appengine/cloudsql
|
google.golang.org/appengine/cloudsql
|
||||||
# gopkg.in/yaml.v2 v2.2.1
|
# gopkg.in/yaml.v2 v2.2.1
|
||||||
gopkg.in/yaml.v2
|
gopkg.in/yaml.v2
|
||||||
|
Loading…
Reference in New Issue
Block a user