Browse Source

to go modules

master
Morgan Bazalgette 3 months ago
parent
commit
6d4d8f554a
100 changed files with 123 additions and 27492 deletions
  1. +36
    -0
      go.mod
  2. +87
    -0
      go.sum
  3. +0
    -19
      vendor/github.com/DataDog/datadog-go/LICENSE.txt
  4. +0
    -52
      vendor/github.com/DataDog/datadog-go/statsd/README.md
  5. +0
    -577
      vendor/github.com/DataDog/datadog-go/statsd/statsd.go
  6. +0
    -24
      vendor/github.com/buaazp/fasthttprouter/HttpRouterLicense
  7. +0
    -28
      vendor/github.com/buaazp/fasthttprouter/LICENSE
  8. +0
    -216
      vendor/github.com/buaazp/fasthttprouter/README.md
  9. +0
    -123
      vendor/github.com/buaazp/fasthttprouter/path.go
  10. +0
    -374
      vendor/github.com/buaazp/fasthttprouter/router.go
  11. +0
    -643
      vendor/github.com/buaazp/fasthttprouter/tree.go
  12. +0
    -3
      vendor/github.com/certifi/gocertifi/LICENSE
  13. +0
    -60
      vendor/github.com/certifi/gocertifi/README.md
  14. +0
    -5298
      vendor/github.com/certifi/gocertifi/certifi.go
  15. +0
    -20
      vendor/github.com/certifi/gocertifi/tasks.py
  16. +0
    -13
      vendor/github.com/getsentry/raven-go/Dockerfile.test
  17. +0
    -28
      vendor/github.com/getsentry/raven-go/LICENSE
  18. +0
    -13
      vendor/github.com/getsentry/raven-go/README.md
  19. +0
    -799
      vendor/github.com/getsentry/raven-go/client.go
  20. +0
    -41
      vendor/github.com/getsentry/raven-go/exception.go
  21. +0
    -84
      vendor/github.com/getsentry/raven-go/http.go
  22. +0
    -49
      vendor/github.com/getsentry/raven-go/interfaces.go
  23. +0
    -4
      vendor/github.com/getsentry/raven-go/runtests.sh
  24. +0
    -213
      vendor/github.com/getsentry/raven-go/stacktrace.go
  25. +0
    -20
      vendor/github.com/getsentry/raven-go/writer.go
  26. +0
    -57
      vendor/github.com/go-sql-driver/mysql/AUTHORS
  27. +0
    -119
      vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
  28. +0
    -23
      vendor/github.com/go-sql-driver/mysql/CONTRIBUTING.md
  29. +0
    -373
      vendor/github.com/go-sql-driver/mysql/LICENSE
  30. +0
    -443
      vendor/github.com/go-sql-driver/mysql/README.md
  31. +0
    -19
      vendor/github.com/go-sql-driver/mysql/appengine.go
  32. +0
    -147
      vendor/github.com/go-sql-driver/mysql/buffer.go
  33. +0
    -250
      vendor/github.com/go-sql-driver/mysql/collations.go
  34. +0
    -377
      vendor/github.com/go-sql-driver/mysql/connection.go
  35. +0
    -163
      vendor/github.com/go-sql-driver/mysql/const.go
  36. +0
    -183
      vendor/github.com/go-sql-driver/mysql/driver.go
  37. +0
    -548
      vendor/github.com/go-sql-driver/mysql/dsn.go
  38. +0
    -132
      vendor/github.com/go-sql-driver/mysql/errors.go
  39. +0
    -182
      vendor/github.com/go-sql-driver/mysql/infile.go
  40. +0
    -1287
      vendor/github.com/go-sql-driver/mysql/packets.go
  41. +0
    -22
      vendor/github.com/go-sql-driver/mysql/result.go
  42. +0
    -112
      vendor/github.com/go-sql-driver/mysql/rows.go
  43. +0
    -153
      vendor/github.com/go-sql-driver/mysql/statement.go
  44. +0
    -31
      vendor/github.com/go-sql-driver/mysql/transaction.go
  45. +0
    -740
      vendor/github.com/go-sql-driver/mysql/utils.go
  46. +0
    -23
      vendor/github.com/jmoiron/sqlx/LICENSE
  47. +0
    -183
      vendor/github.com/jmoiron/sqlx/README.md
  48. +0
    -186
      vendor/github.com/jmoiron/sqlx/bind.go
  49. +0
    -12
      vendor/github.com/jmoiron/sqlx/doc.go
  50. +0
    -344
      vendor/github.com/jmoiron/sqlx/named.go
  51. +0
    -17
      vendor/github.com/jmoiron/sqlx/reflectx/README.md
  52. +0
    -422
      vendor/github.com/jmoiron/sqlx/reflectx/reflect.go
  53. +0
    -1028
      vendor/github.com/jmoiron/sqlx/sqlx.go
  54. +0
    -27
      vendor/github.com/klauspost/compress/LICENSE
  55. +0
    -32
      vendor/github.com/klauspost/compress/flate/copy.go
  56. +0
    -41
      vendor/github.com/klauspost/compress/flate/crc32_amd64.go
  57. +0
    -213
      vendor/github.com/klauspost/compress/flate/crc32_amd64.s
  58. +0
    -35
      vendor/github.com/klauspost/compress/flate/crc32_noasm.go
  59. +0
    -1353
      vendor/github.com/klauspost/compress/flate/deflate.go
  60. +0
    -184
      vendor/github.com/klauspost/compress/flate/dict_decoder.go
  61. +0
    -265
      vendor/github.com/klauspost/compress/flate/gen.go
  62. +0
    -701
      vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
  63. +0
    -344
      vendor/github.com/klauspost/compress/flate/huffman_code.go
  64. +0
    -846
      vendor/github.com/klauspost/compress/flate/inflate.go
  65. +0
    -48
      vendor/github.com/klauspost/compress/flate/reverse_bits.go
  66. +0
    -900
      vendor/github.com/klauspost/compress/flate/snappy.go
  67. +0
    -115
      vendor/github.com/klauspost/compress/flate/token.go
  68. +0
    -344
      vendor/github.com/klauspost/compress/gzip/gunzip.go
  69. +0
    -251
      vendor/github.com/klauspost/compress/gzip/gzip.go
  70. +0
    -178
      vendor/github.com/klauspost/compress/zlib/reader.go
  71. +0
    -201
      vendor/github.com/klauspost/compress/zlib/writer.go
  72. +0
    -22
      vendor/github.com/klauspost/cpuid/LICENSE
  73. +0
    -145
      vendor/github.com/klauspost/cpuid/README.md
  74. +0
    -1022
      vendor/github.com/klauspost/cpuid/cpuid.go
  75. +0
    -42
      vendor/github.com/klauspost/cpuid/cpuid_386.s
  76. +0
    -42
      vendor/github.com/klauspost/cpuid/cpuid_amd64.s
  77. +0
    -17
      vendor/github.com/klauspost/cpuid/detect_intel.go
  78. +0
    -23
      vendor/github.com/klauspost/cpuid/detect_ref.go
  79. +0
    -3
      vendor/github.com/klauspost/cpuid/generate.go
  80. +0
    -476
      vendor/github.com/klauspost/cpuid/private-gen.go
  81. +0
    -28
      vendor/github.com/klauspost/crc32/LICENSE
  82. +0
    -87
      vendor/github.com/klauspost/crc32/README.md
  83. +0
    -207
      vendor/github.com/klauspost/crc32/crc32.go
  84. +0
    -230
      vendor/github.com/klauspost/crc32/crc32_amd64.go
  85. +0
    -319
      vendor/github.com/klauspost/crc32/crc32_amd64.s
  86. +0
    -43
      vendor/github.com/klauspost/crc32/crc32_amd64p32.go
  87. +0
    -67
      vendor/github.com/klauspost/crc32/crc32_amd64p32.s
  88. +0
    -89
      vendor/github.com/klauspost/crc32/crc32_generic.go
  89. +0
    -15
      vendor/github.com/klauspost/crc32/crc32_otherarch.go
  90. +0
    -91
      vendor/github.com/klauspost/crc32/crc32_s390x.go
  91. +0
    -249
      vendor/github.com/klauspost/crc32/crc32_s390x.s
  92. +0
    -8
      vendor/github.com/leavengood/websocket/AUTHORS
  93. +0
    -22
      vendor/github.com/leavengood/websocket/LICENSE
  94. +0
    -68
      vendor/github.com/leavengood/websocket/README.md
  95. +0
    -420
      vendor/github.com/leavengood/websocket/client.go
  96. +0
    -135
      vendor/github.com/leavengood/websocket/compression.go
  97. +0
    -1055
      vendor/github.com/leavengood/websocket/conn.go
  98. +0
    -18
      vendor/github.com/leavengood/websocket/conn_read.go
  99. +0
    -21
      vendor/github.com/leavengood/websocket/conn_read_legacy.go
  100. +0
    -173
      vendor/github.com/leavengood/websocket/doc.go

+ 36
- 0
go.mod View File

@@ -0,0 +1,36 @@
module zxq.co/ripple/rippleapi

go 1.14

require (
github.com/DataDog/datadog-go v0.0.0-20161213181837-6ea09a754064
github.com/buaazp/fasthttprouter v0.1.1
github.com/certifi/gocertifi v0.0.0-20160926115448-a61bf5eafa3a // indirect
github.com/getsentry/raven-go v0.0.0-20161115135411-3f7439d3e74d
github.com/go-sql-driver/mysql v1.3.1-0.20161224121019-2e00b5cd7039
github.com/gorilla/websocket v1.4.2 // indirect
github.com/jmoiron/sqlx v0.0.0-20161209024531-cac998c4f095
github.com/klauspost/compress v1.2.2-0.20170114130832-461e8fd8397a // indirect
github.com/klauspost/cpuid v0.0.0-20160302075316-09cded8978dc // indirect
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6 // indirect
github.com/leavengood/websocket v0.0.0-20170104145153-470559ebf58e
github.com/lib/pq v1.3.0 // indirect
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
github.com/onsi/ginkgo v1.12.0 // indirect
github.com/onsi/gomega v1.9.0 // indirect
github.com/rcrowley/goagain v0.0.0-20140424170347-f2f192b5d1a9
github.com/serenize/snaker v0.0.0-20161123064335-543781d2b79b
github.com/thehowl/conf v0.1.1-0.20161010150023-bdfc17531a74
github.com/thehowl/go-osuapi v0.0.0-20161017202541-77ef7867f23c
github.com/tmdvs/Go-Emoji-Utils v1.1.0
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v0.0.0-20170118172047-2ada93a6dff4
gopkg.in/redis.v5 v5.2.1
gopkg.in/thehowl/go-osuapi.v1 v1.0.0-20161017202541-77ef7867f23c
zxq.co/ripple/agplwarning v0.0.0-20180204104638-d3a3d0ee424f
zxq.co/ripple/ocl v0.0.0-20160518155525-b499c4fc6bcd
zxq.co/ripple/playstyle v0.0.0-20200414151848-19a867db35bf
zxq.co/ripple/schiavolib v0.0.0-20161109210250-9cdc674dad07
zxq.co/ripple/semantic-icons-ugc v0.0.0-20161123190331-82d4c266de98
zxq.co/x/getrank v0.0.0-20170418183109-97d2823cf77d
)

+ 87
- 0
go.sum View File

@@ -0,0 +1,87 @@
github.com/DataDog/datadog-go v0.0.0-20161213181837-6ea09a754064 h1:5MHXwwJPoiqDX685FtqzBJzCWNzE+ItHD46BcAQ+eHw=
github.com/DataDog/datadog-go v0.0.0-20161213181837-6ea09a754064/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/buaazp/fasthttprouter v0.1.1 h1:4oAnN0C3xZjylvZJdP35cxfclyn4TYkW6Y+DSvS+h8Q=
github.com/buaazp/fasthttprouter v0.1.1/go.mod h1:h/Ap5oRVLeItGKTVBb+heQPks+HdIUtGmI4H5WCYijM=
github.com/certifi/gocertifi v0.0.0-20160926115448-a61bf5eafa3a h1:zmAIZ9hpjwOsxZ/no776lftrcUR2w0lPiDq3tOBZjh4=
github.com/certifi/gocertifi v0.0.0-20160926115448-a61bf5eafa3a/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/getsentry/raven-go v0.0.0-20161115135411-3f7439d3e74d h1:l+MZegqjcffeVt3U7OldySISIA+wDlizPTz9Ki2u3k4=
github.com/getsentry/raven-go v0.0.0-20161115135411-3f7439d3e74d/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/go-sql-driver/mysql v1.3.1-0.20161224121019-2e00b5cd7039 h1:DK/LMxBX4gKRwnvIzRfjXIhQ62KhiyLoAd7xbGYkBy4=
github.com/go-sql-driver/mysql v1.3.1-0.20161224121019-2e00b5cd7039/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jmoiron/sqlx v0.0.0-20161209024531-cac998c4f095 h1:6uwZHp3lyVH2mZxH/NLFbfBmbra2a2VDMSN2sp5NgGc=
github.com/jmoiron/sqlx v0.0.0-20161209024531-cac998c4f095/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU=
github.com/klauspost/compress v1.2.2-0.20170114130832-461e8fd8397a h1:ecqXXp3gkAsll6ttp8n5lu41qpvA4rA3n34Hxmh3q/k=
github.com/klauspost/compress v1.2.2-0.20170114130832-461e8fd8397a/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v0.0.0-20160302075316-09cded8978dc h1:WW8B7p7QBnFlqRVv/k6ro/S8Z7tCnYjJHcQNScx9YVs=
github.com/klauspost/cpuid v0.0.0-20160302075316-09cded8978dc/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6 h1:KAZ1BW2TCmT6PRihDPpocIy1QTtsAsrx6TneU/4+CMg=
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
github.com/leavengood/websocket v0.0.0-20170104145153-470559ebf58e h1:2JEp+OVtnjlh9y+HBSq3ODkTJRp0JuF9xaXreTHI/Eg=
github.com/leavengood/websocket v0.0.0-20170104145153-470559ebf58e/go.mod h1:JZYtScd6/pBBtSRVS5mVG0PVyY5ucSvSbypyR1iduRY=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/rcrowley/goagain v0.0.0-20140424170347-f2f192b5d1a9 h1:6AeJ2VG7ijbPJPTW2Mq+hCKQsVJBZGzwGJiIm45eHN8=
github.com/rcrowley/goagain v0.0.0-20140424170347-f2f192b5d1a9/go.mod h1:qqlCbG/0ChzjCGcnvB0Q8x3MyrWPqMCVpej81a2QH5k=
github.com/serenize/snaker v0.0.0-20161123064335-543781d2b79b h1:B6dcIy62mIVH3xZ+Alc5J4fLDWthEa1RPzK7L7/glTw=
github.com/serenize/snaker v0.0.0-20161123064335-543781d2b79b/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs=
github.com/thehowl/conf v0.1.1-0.20161010150023-bdfc17531a74 h1:vfl7zJdxxtCqRqPcBsNaM3FCDFd5rOBk7CmdRyBM8wY=
github.com/thehowl/conf v0.1.1-0.20161010150023-bdfc17531a74/go.mod h1:o9YvtFg3Ixu+XsNHEJNYfa+3mLUimgtSruvzx9IHKj8=
github.com/thehowl/go-osuapi v0.0.0-20161017202541-77ef7867f23c h1:XjzqRdiKRat39ILtBy0g602k96az8PuIHzUASgR7gNY=
github.com/thehowl/go-osuapi v0.0.0-20161017202541-77ef7867f23c/go.mod h1:Y+d6hzF4BM2sz5ytQmJLSImHq9dP9JS3dM4xwarFoUQ=
github.com/tmdvs/Go-Emoji-Utils v1.1.0 h1:gtPix7HZPrd49+MNDcuRLvv4xVNxCE5wgjqyuvmbyYg=
github.com/tmdvs/Go-Emoji-Utils v1.1.0/go.mod h1:J82i2WeGn+Kz+T3s5v9+i/OJlvevIVfGZ6qXgqiNWBc=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v0.0.0-20170118172047-2ada93a6dff4 h1:xAKvyhxXh0uBzDEY2hk5i2IfK5wXrh34SDLh4DqNZ7A=
github.com/valyala/fasthttp v0.0.0-20170118172047-2ada93a6dff4/go.mod h1:+g/po7GqyG5E+1CNgquiIxJnsXEi5vwFn5weFujbO78=
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/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/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/redis.v5 v5.2.1 h1:FAJ2+937QQWp5jECvq7X4Qs2Hf04nML5w5Ql44kgz/s=
gopkg.in/redis.v5 v5.2.1/go.mod h1:6gtv0/+A4iM08kdRfocWYB3bLX2tebpNtfKlFT6H4mY=
gopkg.in/thehowl/go-osuapi.v1 v1.0.0-20161017202541-77ef7867f23c h1:QFiP+vB36n+cvo7KfjBqc3eRjfBLV+bPYHfJ4tmtpEQ=
gopkg.in/thehowl/go-osuapi.v1 v1.0.0-20161017202541-77ef7867f23c/go.mod h1:J5HQvzBoBqUS4L0fRGlyTwdj0AMib7hm7vZWnov3QHE=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
zxq.co/ripple/agplwarning v0.0.0-20180204104638-d3a3d0ee424f h1:3mu+sakmZx4sLNo9gBSKcxwKzvpJHHhw7e+Ggbt1VIQ=
zxq.co/ripple/agplwarning v0.0.0-20180204104638-d3a3d0ee424f/go.mod h1:sshTr/Z/WGWO+mj1Q/cCwFXwqa1FlWVGpYe1db98+G0=
zxq.co/ripple/ocl v0.0.0-20160518155525-b499c4fc6bcd h1:jaHPeT0hACc4JyYvvsfcAaVzEt2aa1BNIukQIchWbXU=
zxq.co/ripple/ocl v0.0.0-20160518155525-b499c4fc6bcd/go.mod h1:YagunUAfVRcfr3+9WSusjzwj7qno8fDwan+my3WrGM0=
zxq.co/ripple/playstyle v0.0.0-20200414151848-19a867db35bf h1:237RS2yap+QtOcnfJZ2x79Wq40X8vWAfN4wQTVfAgAE=
zxq.co/ripple/playstyle v0.0.0-20200414151848-19a867db35bf/go.mod h1:ByMeVpw6pHJ7JLr8m/ANnb5uGD5qcO8qwkRdU9vCNrs=
zxq.co/ripple/schiavolib v0.0.0-20161109210250-9cdc674dad07 h1:fQIulgq6BDqgUiRGn1UU29Upms+eAmZxIPuF4KZFNAU=
zxq.co/ripple/schiavolib v0.0.0-20161109210250-9cdc674dad07/go.mod h1:W6Gj7lSJNvs8oFN4bvrzoi+vcjDAEVyMfzguWzUYaok=
zxq.co/ripple/semantic-icons-ugc v0.0.0-20161123190331-82d4c266de98 h1:rAyPOt8C/6Thl7vCFzdmxrIp7hJlFefRXtTlXd7Uef8=
zxq.co/ripple/semantic-icons-ugc v0.0.0-20161123190331-82d4c266de98/go.mod h1:S0iTdeNHcAoRTLk1CC56FzpKNJ3mPhf3BIlz8OJz6SI=
zxq.co/x/getrank v0.0.0-20170418183109-97d2823cf77d h1:VaNJqleeYJFEVgIoPN01HmTDCcjHCypxmGioqmcV7+s=
zxq.co/x/getrank v0.0.0-20170418183109-97d2823cf77d/go.mod h1:F0XQ0fRj05leq/m30CIKrV7VNJFZBfYlAm2KcgzA+Sw=

+ 0
- 19
vendor/github.com/DataDog/datadog-go/LICENSE.txt View File

@@ -1,19 +0,0 @@
Copyright (c) 2015 Datadog, Inc

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

+ 0
- 52
vendor/github.com/DataDog/datadog-go/statsd/README.md View File

@@ -1,52 +0,0 @@
## Overview

Package `statsd` provides a Go [dogstatsd](http://docs.datadoghq.com/guides/dogstatsd/) client. Dogstatsd extends Statsd, adding tags
and histograms.

## Get the code

$ go get github.com/DataDog/datadog-go/statsd

## Usage

```go
// Create the client
c, err := statsd.New("127.0.0.1:8125")
if err != nil {
log.Fatal(err)
}
// Prefix every metric with the app name
c.Namespace = "flubber."
// Send the EC2 availability zone as a tag with every metric
c.Tags = append(c.Tags, "us-east-1a")

// Do some metrics!
err = c.Gauge("request.queue_depth", 12, nil, 1)
err = c.Timing("request.duration", duration, nil, 1) // Uses a time.Duration!
err = c.TimeInMilliseconds("request", 12, nil, 1)
err = c.Incr("request.count_total", nil, 1)
err = c.Decr("request.count_total", nil, 1)
err = c.Count("request.count_total", 2, nil, 1)
```

## Buffering Client

DogStatsD accepts packets with multiple statsd payloads in them. Using the BufferingClient via `NewBufferingClient` will buffer up commands and send them when the buffer is reached or after 100msec.

## Development

Run the tests with:

$ go test

## Documentation

Please see: http://godoc.org/github.com/DataDog/datadog-go/statsd

## License

go-dogstatsd is released under the [MIT license](http://www.opensource.org/licenses/mit-license.php).

## Credits

Original code by [ooyala](https://github.com/ooyala/go-dogstatsd).

+ 0
- 577
vendor/github.com/DataDog/datadog-go/statsd/statsd.go View File

@@ -1,577 +0,0 @@
// Copyright 2013 Ooyala, Inc.

/*
Package statsd provides a Go dogstatsd client. Dogstatsd extends the popular statsd,
adding tags and histograms and pushing upstream to Datadog.

Refer to http://docs.datadoghq.com/guides/dogstatsd/ for information about DogStatsD.

Example Usage:

// Create the client
c, err := statsd.New("127.0.0.1:8125")
if err != nil {
log.Fatal(err)
}
// Prefix every metric with the app name
c.Namespace = "flubber."
// Send the EC2 availability zone as a tag with every metric
c.Tags = append(c.Tags, "us-east-1a")
err = c.Gauge("request.duration", 1.2, nil, 1)

statsd is based on go-statsd-client.
*/
package statsd

import (
"bytes"
"errors"
"fmt"
"io"
"math/rand"
"net"
"strconv"
"strings"
"sync"
"time"
)

/*
OptimalPayloadSize defines the optimal payload size for a UDP datagram, 1432 bytes
is optimal for regular networks with an MTU of 1500 so datagrams don't get
fragmented. It's generally recommended not to fragment UDP datagrams as losing
a single fragment will cause the entire datagram to be lost.

This can be increased if your network has a greater MTU or you don't mind UDP
datagrams getting fragmented. The practical limit is MaxUDPPayloadSize
*/
const OptimalPayloadSize = 1432

/*
MaxUDPPayloadSize defines the maximum payload size for a UDP datagram.
Its value comes from the calculation: 65535 bytes Max UDP datagram size -
8byte UDP header - 60byte max IP headers
any number greater than that will see frames being cut out.
*/
const MaxUDPPayloadSize = 65467

// A Client is a handle for sending udp messages to dogstatsd. It is safe to
// use one Client from multiple goroutines simultaneously.
type Client struct {
conn net.Conn
// Namespace to prepend to all statsd calls
Namespace string
// Tags are global tags to be added to every statsd call
Tags []string
// BufferLength is the length of the buffer in commands.
bufferLength int
flushTime time.Duration
commands []string
buffer bytes.Buffer
stop bool
sync.Mutex
}

// New returns a pointer to a new Client given an addr in the format "hostname:port".
func New(addr string) (*Client, error) {
udpAddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return nil, err
}
conn, err := net.DialUDP("udp", nil, udpAddr)
if err != nil {
return nil, err
}
client := &Client{conn: conn}
return client, nil
}

// NewBuffered returns a Client that buffers its output and sends it in chunks.
// Buflen is the length of the buffer in number of commands.
func NewBuffered(addr string, buflen int) (*Client, error) {
client, err := New(addr)
if err != nil {
return nil, err
}
client.bufferLength = buflen
client.commands = make([]string, 0, buflen)
client.flushTime = time.Millisecond * 100
go client.watch()
return client, nil
}

// format a message from its name, value, tags and rate. Also adds global
// namespace and tags.
func (c *Client) format(name, value string, tags []string, rate float64) string {
var buf bytes.Buffer
if c.Namespace != "" {
buf.WriteString(c.Namespace)
}
buf.WriteString(name)
buf.WriteString(":")
buf.WriteString(value)
if rate < 1 {
buf.WriteString(`|@`)
buf.WriteString(strconv.FormatFloat(rate, 'f', -1, 64))
}

writeTagString(&buf, c.Tags, tags)

return buf.String()
}

func (c *Client) watch() {
for _ = range time.Tick(c.flushTime) {
if c.stop {
return
}
c.Lock()
if len(c.commands) > 0 {
// FIXME: eating error here
c.flush()
}
c.Unlock()
}
}

func (c *Client) append(cmd string) error {
c.Lock()
defer c.Unlock()
c.commands = append(c.commands, cmd)
// if we should flush, lets do it
if len(c.commands) == c.bufferLength {
if err := c.flush(); err != nil {
return err
}
}
return nil
}

func (c *Client) joinMaxSize(cmds []string, sep string, maxSize int) ([][]byte, []int) {
c.buffer.Reset() //clear buffer

var frames [][]byte
var ncmds []int
sepBytes := []byte(sep)
sepLen := len(sep)

elem := 0
for _, cmd := range cmds {
needed := len(cmd)

if elem != 0 {
needed = needed + sepLen
}

if c.buffer.Len()+needed <= maxSize {
if elem != 0 {
c.buffer.Write(sepBytes)
}
c.buffer.WriteString(cmd)
elem++
} else {
frames = append(frames, copyAndResetBuffer(&c.buffer))
ncmds = append(ncmds, elem)
// if cmd is bigger than maxSize it will get flushed on next loop
c.buffer.WriteString(cmd)
elem = 1
}
}

//add whatever is left! if there's actually something
if c.buffer.Len() > 0 {
frames = append(frames, copyAndResetBuffer(&c.buffer))
ncmds = append(ncmds, elem)
}

return frames, ncmds
}

func copyAndResetBuffer(buf *bytes.Buffer) []byte {
tmpBuf := make([]byte, buf.Len())
copy(tmpBuf, buf.Bytes())
buf.Reset()
return tmpBuf
}

// flush the commands in the buffer. Lock must be held by caller.
func (c *Client) flush() error {
frames, flushable := c.joinMaxSize(c.commands, "\n", OptimalPayloadSize)
var err error
cmdsFlushed := 0
for i, data := range frames {
_, e := c.conn.Write(data)
if e != nil {
err = e
break
}
cmdsFlushed += flushable[i]
}

// clear the slice with a slice op, doesn't realloc
if cmdsFlushed == len(c.commands) {
c.commands = c.commands[:0]
} else {
//this case will cause a future realloc...
// drop problematic command though (sorry).
c.commands = c.commands[cmdsFlushed+1:]
}
return err
}

func (c *Client) sendMsg(msg string) error {
// return an error if message is bigger than MaxUDPPayloadSize
if len(msg) > MaxUDPPayloadSize {
return errors.New("message size exceeds MaxUDPPayloadSize")
}

// if this client is buffered, then we'll just append this
if c.bufferLength > 0 {
return c.append(msg)
}

_, err := c.conn.Write([]byte(msg))
return err
}

// send handles sampling and sends the message over UDP. It also adds global namespace prefixes and tags.
func (c *Client) send(name, value string, tags []string, rate float64) error {
if c == nil {
return nil
}
if rate < 1 && rand.Float64() > rate {
return nil
}
data := c.format(name, value, tags, rate)
return c.sendMsg(data)
}

// Gauge measures the value of a metric at a particular time.
func (c *Client) Gauge(name string, value float64, tags []string, rate float64) error {
stat := fmt.Sprintf("%f|g", value)
return c.send(name, stat, tags, rate)
}

// Count tracks how many times something happened per second.
func (c *Client) Count(name string, value int64, tags []string, rate float64) error {
stat := fmt.Sprintf("%d|c", value)
return c.send(name, stat, tags, rate)
}

// Histogram tracks the statistical distribution of a set of values.
func (c *Client) Histogram(name string, value float64, tags []string, rate float64) error {
stat := fmt.Sprintf("%f|h", value)
return c.send(name, stat, tags, rate)
}

// Decr is just Count of 1
func (c *Client) Decr(name string, tags []string, rate float64) error {
return c.send(name, "-1|c", tags, rate)
}

// Incr is just Count of 1
func (c *Client) Incr(name string, tags []string, rate float64) error {
return c.send(name, "1|c", tags, rate)
}

// Set counts the number of unique elements in a group.
func (c *Client) Set(name string, value string, tags []string, rate float64) error {
stat := fmt.Sprintf("%s|s", value)
return c.send(name, stat, tags, rate)
}

// Timing sends timing information, it is an alias for TimeInMilliseconds
func (c *Client) Timing(name string, value time.Duration, tags []string, rate float64) error {
return c.TimeInMilliseconds(name, value.Seconds()*1000, tags, rate)
}

// TimeInMilliseconds sends timing information in milliseconds.
// It is flushed by statsd with percentiles, mean and other info (https://github.com/etsy/statsd/blob/master/docs/metric_types.md#timing)
func (c *Client) TimeInMilliseconds(name string, value float64, tags []string, rate float64) error {
stat := fmt.Sprintf("%f|ms", value)
return c.send(name, stat, tags, rate)
}

// Event sends the provided Event.
func (c *Client) Event(e *Event) error {
stat, err := e.Encode(c.Tags...)
if err != nil {
return err
}
return c.sendMsg(stat)
}

// SimpleEvent sends an event with the provided title and text.
func (c *Client) SimpleEvent(title, text string) error {
e := NewEvent(title, text)
return c.Event(e)
}

// ServiceCheck sends the provided ServiceCheck.
func (c *Client) ServiceCheck(sc *ServiceCheck) error {
stat, err := sc.Encode(c.Tags...)
if err != nil {
return err
}
return c.sendMsg(stat)
}

// SimpleServiceCheck sends an serviceCheck with the provided name and status.
func (c *Client) SimpleServiceCheck(name string, status ServiceCheckStatus) error {
sc := NewServiceCheck(name, status)
return c.ServiceCheck(sc)
}

// Close the client connection.
func (c *Client) Close() error {
if c == nil {
return nil
}
c.stop = true
return c.conn.Close()
}

// Events support

type eventAlertType string

const (
// Info is the "info" AlertType for events
Info eventAlertType = "info"
// Error is the "error" AlertType for events
Error eventAlertType = "error"
// Warning is the "warning" AlertType for events
Warning eventAlertType = "warning"
// Success is the "success" AlertType for events
Success eventAlertType = "success"
)

type eventPriority string

const (
// Normal is the "normal" Priority for events
Normal eventPriority = "normal"
// Low is the "low" Priority for events
Low eventPriority = "low"
)

// An Event is an object that can be posted to your DataDog event stream.
type Event struct {
// Title of the event. Required.
Title string
// Text is the description of the event. Required.
Text string
// Timestamp is a timestamp for the event. If not provided, the dogstatsd
// server will set this to the current time.
Timestamp time.Time
// Hostname for the event.
Hostname string
// AggregationKey groups this event with others of the same key.
AggregationKey string
// Priority of the event. Can be statsd.Low or statsd.Normal.
Priority eventPriority
// SourceTypeName is a source type for the event.
SourceTypeName string
// AlertType can be statsd.Info, statsd.Error, statsd.Warning, or statsd.Success.
// If absent, the default value applied by the dogstatsd server is Info.
AlertType eventAlertType
// Tags for the event.
Tags []string
}

// NewEvent creates a new event with the given title and text. Error checking
// against these values is done at send-time, or upon running e.Check.
func NewEvent(title, text string) *Event {
return &Event{
Title: title,
Text: text,
}
}

// Check verifies that an event is valid.
func (e Event) Check() error {
if len(e.Title) == 0 {
return fmt.Errorf("statsd.Event title is required")
}
if len(e.Text) == 0 {
return fmt.Errorf("statsd.Event text is required")
}
return nil
}

// Encode returns the dogstatsd wire protocol representation for an event.
// Tags may be passed which will be added to the encoded output but not to
// the Event's list of tags, eg. for default tags.
func (e Event) Encode(tags ...string) (string, error) {
err := e.Check()
if err != nil {
return "", err
}
text := e.escapedText()

var buffer bytes.Buffer
buffer.WriteString("_e{")
buffer.WriteString(strconv.FormatInt(int64(len(e.Title)), 10))
buffer.WriteRune(',')
buffer.WriteString(strconv.FormatInt(int64(len(text)), 10))
buffer.WriteString("}:")
buffer.WriteString(e.Title)
buffer.WriteRune('|')
buffer.WriteString(text)

if !e.Timestamp.IsZero() {
buffer.WriteString("|d:")
buffer.WriteString(strconv.FormatInt(int64(e.Timestamp.Unix()), 10))
}

if len(e.Hostname) != 0 {
buffer.WriteString("|h:")
buffer.WriteString(e.Hostname)
}

if len(e.AggregationKey) != 0 {
buffer.WriteString("|k:")
buffer.WriteString(e.AggregationKey)

}

if len(e.Priority) != 0 {
buffer.WriteString("|p:")
buffer.WriteString(string(e.Priority))
}

if len(e.SourceTypeName) != 0 {
buffer.WriteString("|s:")
buffer.WriteString(e.SourceTypeName)
}

if len(e.AlertType) != 0 {
buffer.WriteString("|t:")
buffer.WriteString(string(e.AlertType))
}

writeTagString(&buffer, tags, e.Tags)

return buffer.String(), nil
}

// ServiceCheck support

type ServiceCheckStatus byte

const (
// Ok is the "ok" ServiceCheck status
Ok ServiceCheckStatus = 0
// Warn is the "warning" ServiceCheck status
Warn ServiceCheckStatus = 1
// Critical is the "critical" ServiceCheck status
Critical ServiceCheckStatus = 2
// Unknown is the "unknown" ServiceCheck status
Unknown ServiceCheckStatus = 3
)

// An ServiceCheck is an object that contains status of DataDog service check.
type ServiceCheck struct {
// Name of the service check. Required.
Name string
// Status of service check. Required.
Status ServiceCheckStatus
// Timestamp is a timestamp for the serviceCheck. If not provided, the dogstatsd
// server will set this to the current time.
Timestamp time.Time
// Hostname for the serviceCheck.
Hostname string
// A message describing the current state of the serviceCheck.
Message string
// Tags for the serviceCheck.
Tags []string
}

// NewServiceCheck creates a new serviceCheck with the given name and status. Error checking
// against these values is done at send-time, or upon running sc.Check.
func NewServiceCheck(name string, status ServiceCheckStatus) *ServiceCheck {
return &ServiceCheck{
Name: name,
Status: status,
}
}

// Check verifies that an event is valid.
func (sc ServiceCheck) Check() error {
if len(sc.Name) == 0 {
return fmt.Errorf("statsd.ServiceCheck name is required")
}
if byte(sc.Status) < 0 || byte(sc.Status) > 3 {
return fmt.Errorf("statsd.ServiceCheck status has invalid value")
}
return nil
}

// Encode returns the dogstatsd wire protocol representation for an serviceCheck.
// Tags may be passed which will be added to the encoded output but not to
// the Event's list of tags, eg. for default tags.
func (sc ServiceCheck) Encode(tags ...string) (string, error) {
err := sc.Check()
if err != nil {
return "", err
}
message := sc.escapedMessage()

var buffer bytes.Buffer
buffer.WriteString("_sc|")
buffer.WriteString(sc.Name)
buffer.WriteRune('|')
buffer.WriteString(strconv.FormatInt(int64(sc.Status), 10))

if !sc.Timestamp.IsZero() {
buffer.WriteString("|d:")
buffer.WriteString(strconv.FormatInt(int64(sc.Timestamp.Unix()), 10))
}

if len(sc.Hostname) != 0 {
buffer.WriteString("|h:")
buffer.WriteString(sc.Hostname)
}

writeTagString(&buffer, tags, sc.Tags)

if len(message) != 0 {
buffer.WriteString("|m:")
buffer.WriteString(message)
}

return buffer.String(), nil
}

func (e Event) escapedText() string {
return strings.Replace(e.Text, "\n", "\\n", -1)
}

func (sc ServiceCheck) escapedMessage() string {
msg := strings.Replace(sc.Message, "\n", "\\n", -1)
return strings.Replace(msg, "m:", `m\:`, -1)
}

func removeNewlines(str string) string {
return strings.Replace(str, "\n", "", -1)
}

func writeTagString(w io.Writer, tagList1, tagList2 []string) {
// the tag lists may be shared with other callers, so we cannot modify
// them in any way (which means we cannot append to them either)
// therefore we must make an entirely separate copy just for this call
totalLen := len(tagList1) + len(tagList2)
if totalLen == 0 {
return
}
tags := make([]string, 0, totalLen)
tags = append(tags, tagList1...)
tags = append(tags, tagList2...)

io.WriteString(w, "|#")
io.WriteString(w, removeNewlines(tags[0]))
for _, tag := range tags[1:] {
io.WriteString(w, ",")
io.WriteString(w, removeNewlines(tag))
}
}

+ 0
- 24
vendor/github.com/buaazp/fasthttprouter/HttpRouterLicense View File

@@ -1,24 +0,0 @@
Copyright (c) 2013 Julien Schmidt. All rights reserved.


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.
* The names of the contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.

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 JULIEN SCHMIDT 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.

+ 0
- 28
vendor/github.com/buaazp/fasthttprouter/LICENSE View File

@@ -1,28 +0,0 @@
Copyright (c) 2015-2016, 招牌疯子
All rights reserved.

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.

* Neither the name of uq nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

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 HOLDER 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.


+ 0
- 216
vendor/github.com/buaazp/fasthttprouter/README.md View File

@@ -1,216 +0,0 @@
# FastHttpRouter
[![Build Status](https://travis-ci.org/buaazp/fasthttprouter.svg?branch=master)](https://travis-ci.org/buaazp/fasthttprouter)
[![Coverage Status](https://coveralls.io/repos/buaazp/fasthttprouter/badge.svg?branch=master&service=github)](https://coveralls.io/github/buaazp/fasthttprouter?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/buaazp/fasthttprouter)](https://goreportcard.com/report/github.com/buaazp/fasthttprouter)
[![GoDoc](http://godoc.org/github.com/buaazp/fasthttprouter?status.svg)](http://godoc.org/github.com/buaazp/fasthttprouter)
[![GitHub release](https://img.shields.io/github/release/buaazp/fasthttprouter.svg)](https://github.com/buaazp/fasthttprouter/releases)

FastHttpRouter is forked from [httprouter](https://github.com/julienschmidt/httprouter) which is a lightweight high performance HTTP request router
(also called *multiplexer* or just *mux* for short) for [fasthttp](https://github.com/valyala/fasthttp).

This router is optimized for high performance and a small memory footprint. It scales well even with very long paths and a large number of routes. A compressing dynamic trie (radix tree) structure is used for efficient matching.

#### License Related

- The author of `httprouter` [@julienschmidt](https://github.com/julienschmidt) did almost all the hard work of this router.
- I respect the laws of open source. So LICENSE of `httprouter` is alway stay here: [HttpRouterLicense](HttpRouterLicense).
- What I do is just fit for `fasthttp`. I have no hope to build a huge but toxic go web framwork like [iris](https://github.com/kataras/iris).
- I fork this repo is just because there is no router for `fasthttp` at that time. And `fasthttprouter` is the FIRST router for `fasthttp`.
- `fasthttprouter` has been used in my online production and processes 17 million requests per day. It is fast and stable, so I decide to release a stable version.

#### Releases

- [2016.10.24] [v0.1.0](https://github.com/buaazp/fasthttprouter/releases/tag/v0.1.0) The first release version of `fasthttprouter`.

## Features

**Best Performance:** FastHttpRouter is **one of the fastest** go web frameworks in the [go-web-framework-benchmark](https://github.com/smallnest/go-web-framework-benchmark). Even faster than httprouter itself.

- Basic Test: The first test case is to mock 0 ms, 10 ms, 100 ms, 500 ms processing time in handlers. The concurrency clients are 5000.

![](http://ww3.sinaimg.cn/large/4c422e03jw1f2p6nyqh9ij20mm0aktbj.jpg)

- Concurrency Test: In 30 ms processing time, the tets result for 100, 1000, 5000 clients is:

![](http://ww4.sinaimg.cn/large/4c422e03jw1f2p6o1cdbij20lk09sack.jpg)

See below for technical details of the implementation.

**Only explicit matches:** With other routers, like [http.ServeMux](http://golang.org/pkg/net/http/#ServeMux),
a requested URL path could match multiple patterns. Therefore they have some
awkward pattern priority rules, like *longest match* or *first registered,
first matched*. By design of this router, a request can only match exactly one
or no route. As a result, there are also no unintended matches, which makes it
great for SEO and improves the user experience.

**Stop caring about trailing slashes:** Choose the URL style you like, the
router automatically redirects the client if a trailing slash is missing or if
there is one extra. Of course it only does so, if the new path has a handler.
If you don't like it, you can [turn off this behavior](http://godoc.org/github.com/buaazp/fasthttprouter#Router.RedirectTrailingSlash).

**Path auto-correction:** Besides detecting the missing or additional trailing
slash at no extra cost, the router can also fix wrong cases and remove
superfluous path elements (like `../` or `//`).
Is [CAPTAIN CAPS LOCK](http://www.urbandictionary.com/define.php?term=Captain+Caps+Lock) one of your users?
FastHttpRouter can help him by making a case-insensitive look-up and redirecting him
to the correct URL.

**Parameters in your routing pattern:** Stop parsing the requested URL path,
just give the path segment a name and the router delivers the dynamic value to
you. Because of the design of the router, path parameters are very cheap.

**Zero Garbage:** The matching and dispatching process generates zero bytes of
garbage. In fact, the only heap allocations that are made, is by building the
slice of the key-value pairs for path parameters. If the request path contains
no parameters, not a single heap allocation is necessary.

**No more server crashes:** You can set a [Panic handler](http://godoc.org/github.com/buaazp/fasthttprouter#Router.PanicHandler) to deal with panics
occurring during handling a HTTP request. The router then recovers and lets the
PanicHandler log what happened and deliver a nice error page.

**Perfect for APIs:** The router design encourages to build sensible, hierarchical
RESTful APIs. Moreover it has builtin native support for [OPTIONS requests](http://zacstewart.com/2012/04/14/http-options-method.html)
and `405 Method Not Allowed` replies.

Of course you can also set **custom [NotFound](http://godoc.org/github.com/buaazp/fasthttprouter#Router.NotFound) and [MethodNotAllowed](http://godoc.org/github.com/buaazp/fasthttprouter#Router.MethodNotAllowed) handlers** and [**serve static files**](http://godoc.org/github.com/buaazp/fasthttprouter#Router.ServeFiles).

## Usage

This is just a quick introduction, view the [GoDoc](http://godoc.org/github.com/buaazp/fasthttprouter) for details:

Let's start with a trivial example:

```go
package main

import (
"fmt"
"log"

"github.com/buaazp/fasthttprouter"
"github.com/valyala/fasthttp"
)

func Index(ctx *fasthttp.RequestCtx) {
fmt.Fprint(ctx, "Welcome!\n")
}

func Hello(ctx *fasthttp.RequestCtx) {
fmt.Fprintf(ctx, "hello, %s!\n", ctx.UserValue("name"))
}

func main() {
router := fasthttprouter.New()
router.GET("/", Index)
router.GET("/hello/:name", Hello)

log.Fatal(fasthttp.ListenAndServe(":8080", router.Handler))
}
```

### Named parameters

As you can see, `:name` is a *named parameter*. The values are accessible via `RequestCtx.UserValues`. You can get the value of a parameter by using the `ctx.UserValue("name")`.

Named parameters only match a single path segment:

```
Pattern: /user/:user

/user/gordon match
/user/you match
/user/gordon/profile no match
/user/ no match
```

**Note:** Since this router has only explicit matches, you can not register static routes and parameters for the same path segment. For example you can not register the patterns `/user/new` and `/user/:user` for the same request method at the same time. The routing of different request methods is independent from each other.

### Catch-All parameters

The second type are *catch-all* parameters and have the form `*name`.
Like the name suggests, they match everything.
Therefore they must always be at the **end** of the pattern:

```
Pattern: /src/*filepath

/src/ match
/src/somefile.go match
/src/subdir/somefile.go match
```

## How does it work?

The router relies on a tree structure which makes heavy use of *common prefixes*, it is basically a *compact* [*prefix tree*](https://en.wikipedia.org/wiki/Trie) (or just [*Radix tree*](https://en.wikipedia.org/wiki/Radix_tree)). Nodes with a common prefix also share a common parent. Here is a short example what the routing tree for the `GET` request method could look like:

```
Priority Path Handle
9 \ *<1>
3 ├s nil
2 |├earch\ *<2>
1 |└upport\ *<3>
2 ├blog\ *<4>
1 | └:post nil
1 | └\ *<5>
2 ├about-us\ *<6>
1 | └team\ *<7>
1 └contact\ *<8>
```

Every `*<num>` represents the memory address of a handler function (a pointer). If you follow a path trough the tree from the root to the leaf, you get the complete route path, e.g `\blog\:post\`, where `:post` is just a placeholder ([*parameter*](#named-parameters)) for an actual post name. Unlike hash-maps, a tree structure also allows us to use dynamic parts like the `:post` parameter, since we actually match against the routing patterns instead of just comparing hashes. [As benchmarks show][benchmark], this works very well and efficient.

Since URL paths have a hierarchical structure and make use only of a limited set of characters (byte values), it is very likely that there are a lot of common prefixes. This allows us to easily reduce the routing into ever smaller problems. Moreover the router manages a separate tree for every request method. For one thing it is more space efficient than holding a method->handle map in every single node, for another thing is also allows us to greatly reduce the routing problem before even starting the look-up in the prefix-tree.

For even better scalability, the child nodes on each tree level are ordered by priority, where the priority is just the number of handles registered in sub nodes (children, grandchildren, and so on..). This helps in two ways:

1. Nodes which are part of the most routing paths are evaluated first. This helps to make as much routes as possible to be reachable as fast as possible.
2. It is some sort of cost compensation. The longest reachable path (highest cost) can always be evaluated first. The following scheme visualizes the tree structure. Nodes are evaluated from top to bottom and from left to right.

```
├------------
├---------
├-----
├----
├--
├--
└-
```

## Why doesn't this work with `http.Handler`?

Becasue fasthttp doesn't provide http.Handler. See this [description](https://github.com/valyala/fasthttp#switching-from-nethttp-to-fasthttp).

Fasthttp works with [RequestHandler](https://godoc.org/github.com/valyala/fasthttp#RequestHandler) functions instead of objects implementing Handler interface. So a FastHttpRouter provides a [Handler](https://godoc.org/github.com/buaazp/fasthttprouter#Router.Handler) interface to implement the fasthttp.ListenAndServe interface.

Just try it out for yourself, the usage of FastHttpRouter is very straightforward. The package is compact and minimalistic, but also probably one of the easiest routers to set up.

## Where can I find Middleware *X*?

This package just provides a very efficient request router with a few extra features. The router is just a [`fasthttp.RequestHandler`](https://godoc.org/github.com/valyala/fasthttp#RequestHandler), you can chain any `fasthttp.RequestHandler` compatible middleware before the router. Or you could [just write your own](https://justinas.org/writing-http-middleware-in-go/), it's very easy!

Have a look at these midware examples:

- [Auth Midware](examples/auth)
- [Multi Hosts Midware](examples/hosts)

## Chaining with the NotFound handler

**NOTE: It might be required to set [Router.HandleMethodNotAllowed](http://godoc.org/github.com/buaazp/fasthttprouter#Router.HandleMethodNotAllowed) to `false` to avoid problems.**

You can use another [http.Handler](http://golang.org/pkg/net/http/#Handler), for example another router, to handle requests which could not be matched by this router by using the [Router.NotFound](http://godoc.org/github.com/buaazp/fasthttprouter#Router.NotFound) handler. This allows chaining.

### Static files
The `NotFound` handler can for example be used to serve static files from the root path `/` (like an index.html file along with other assets):

```go
// Serve static files from the ./public directory
router.NotFound = fasthttp.FSHandler("./public", 0)
```

But this approach sidesteps the strict core rules of this router to avoid routing problems. A cleaner approach is to use a distinct sub-path for serving files, like `/static/*filepath` or `/files/*filepath`.

## Web Frameworks based on FastHttpRouter

If the HttpRouter is a bit too minimalistic for you, you might try one of the following more high-level 3rd-party web frameworks building upon the HttpRouter package:

- Waiting for you to do this...

+ 0
- 123
vendor/github.com/buaazp/fasthttprouter/path.go View File

@@ -1,123 +0,0 @@
// Copyright 2013 Julien Schmidt. All rights reserved.
// Based on the path package, Copyright 2009 The Go Authors.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.

package fasthttprouter

// CleanPath is the URL version of path.Clean, it returns a canonical URL path
// for p, eliminating . and .. elements.
//
// The following rules are applied iteratively until no further processing can
// be done:
// 1. Replace multiple slashes with a single slash.
// 2. Eliminate each . path name element (the current directory).
// 3. Eliminate each inner .. path name element (the parent directory)
// along with the non-.. element that precedes it.
// 4. Eliminate .. elements that begin a rooted path:
// that is, replace "/.." by "/" at the beginning of a path.
//
// If the result of this process is an empty string, "/" is returned
func CleanPath(p string) string {
// Turn empty string into "/"
if p == "" {
return "/"
}

n := len(p)
var buf []byte

// Invariants:
// reading from path; r is index of next byte to process.
// writing to buf; w is index of next byte to write.

// path must start with '/'
r := 1
w := 1

if p[0] != '/' {
r = 0
buf = make([]byte, n+1)
buf[0] = '/'
}

trailing := n > 2 && p[n-1] == '/'

// A bit more clunky without a 'lazybuf' like the path package, but the loop
// gets completely inlined (bufApp). So in contrast to the path package this
// loop has no expensive function calls (except 1x make)

for r < n {
switch {
case p[r] == '/':
// empty path element, trailing slash is added after the end
r++

case p[r] == '.' && r+1 == n:
trailing = true
r++

case p[r] == '.' && p[r+1] == '/':
// . element
r++

case p[r] == '.' && p[r+1] == '.' && (r+2 == n || p[r+2] == '/'):
// .. element: remove to last /
r += 2

if w > 1 {
// can backtrack
w--

if buf == nil {
for w > 1 && p[w] != '/' {
w--
}
} else {
for w > 1 && buf[w] != '/' {
w--
}
}
}

default:
// real path element.
// add slash if needed
if w > 1 {
bufApp(&buf, p, w, '/')
w++
}

// copy element
for r < n && p[r] != '/' {
bufApp(&buf, p, w, p[r])
w++
r++
}
}
}

// re-append trailing slash
if trailing && w > 1 {
bufApp(&buf, p, w, '/')
w++
}

if buf == nil {
return p[:w]
}
return string(buf[:w])
}

// internal helper to lazily create a buffer if necessary
func bufApp(buf *[]byte, s string, w int, c byte) {
if *buf == nil {
if s[w] == c {
return
}

*buf = make([]byte, len(s))
copy(*buf, s[:w])
}
(*buf)[w] = c
}

+ 0
- 374
vendor/github.com/buaazp/fasthttprouter/router.go View File

@@ -1,374 +0,0 @@
// Copyright 2013 Julien Schmidt. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.

// Package fasthttprouter is a trie based high performance HTTP request router.
//
// A trivial example is:
//
// package main

// import (
// "fmt"
// "log"
//
// "github.com/buaazp/fasthttprouter"
// "github.com/valyala/fasthttp"
// )

// func Index(ctx *fasthttp.RequestCtx) {
// fmt.Fprint(ctx, "Welcome!\n")
// }

// func Hello(ctx *fasthttp.RequestCtx) {
// fmt.Fprintf(ctx, "hello, %s!\n", ctx.UserValue("name"))
// }

// func main() {
// router := fasthttprouter.New()
// router.GET("/", Index)
// router.GET("/hello/:name", Hello)

// log.Fatal(fasthttp.ListenAndServe(":8080", router.Handler))
// }
//
// The router matches incoming requests by the request method and the path.
// If a handle is registered for this path and method, the router delegates the
// request to that function.
// For the methods GET, POST, PUT, PATCH and DELETE shortcut functions exist to
// register handles, for all other methods router.Handle can be used.
//
// The registered path, against which the router matches incoming requests, can
// contain two types of parameters:
// Syntax Type
// :name named parameter
// *name catch-all parameter
//
// Named parameters are dynamic path segments. They match anything until the
// next '/' or the path end:
// Path: /blog/:category/:post
//
// Requests:
// /blog/go/request-routers match: category="go", post="request-routers"
// /blog/go/request-routers/ no match, but the router would redirect
// /blog/go/ no match
// /blog/go/request-routers/comments no match
//
// Catch-all parameters match anything until the path end, including the
// directory index (the '/' before the catch-all). Since they match anything
// until the end, catch-all parameters must always be the final path element.
// Path: /files/*filepath
//
// Requests:
// /files/ match: filepath="/"
// /files/LICENSE match: filepath="/LICENSE"
// /files/templates/article.html match: filepath="/templates/article.html"
// /files no match, but the router would redirect
//
// The value of parameters is inside ctx.UserValue
// To retrieve the value of a parameter:
// // use the name of the parameter
// user := ps.UserValue("user")
//

package fasthttprouter

import (
"strings"

"github.com/valyala/fasthttp"
)

var (
defaultContentType = []byte("text/plain; charset=utf-8")
questionMark = []byte("?")
)

// Router is a http.Handler which can be used to dispatch requests to different
// handler functions via configurable routes
type Router struct {
trees map[string]*node

// Enables automatic redirection if the current route can't be matched but a
// handler for the path with (without) the trailing slash exists.
// For example if /foo/ is requested but a route only exists for /foo, the
// client is redirected to /foo with http status code 301 for GET requests
// and 307 for all other request methods.
RedirectTrailingSlash bool

// If enabled, the router tries to fix the current request path, if no
// handle is registered for it.
// First superfluous path elements like ../ or // are removed.
// Afterwards the router does a case-insensitive lookup of the cleaned path.
// If a handle can be found for this route, the router makes a redirection
// to the corrected path with status code 301 for GET requests and 307 for
// all other request methods.
// For example /FOO and /..//Foo could be redirected to /foo.
// RedirectTrailingSlash is independent of this option.
RedirectFixedPath bool

// If enabled, the router checks if another method is allowed for the
// current route, if the current request can not be routed.
// If this is the case, the request is answered with 'Method Not Allowed'
// and HTTP status code 405.
// If no other Method is allowed, the request is delegated to the NotFound
// handler.
HandleMethodNotAllowed bool

// If enabled, the router automatically replies to OPTIONS requests.
// Custom OPTIONS handlers take priority over automatic replies.
HandleOPTIONS bool

// Configurable http.Handler which is called when no matching route is
// found. If it is not set, http.NotFound is used.
NotFound fasthttp.RequestHandler

// Configurable http.Handler which is called when a request
// cannot be routed and HandleMethodNotAllowed is true.
// If it is not set, http.Error with http.StatusMethodNotAllowed is used.
// The "Allow" header with allowed request methods is set before the handler
// is called.
MethodNotAllowed fasthttp.RequestHandler

// Function to handle panics recovered from http handlers.
// It should be used to generate a error page and return the http error code
// 500 (Internal Server Error).
// The handler can be used to keep your server from crashing because of
// unrecovered panics.
PanicHandler func(*fasthttp.RequestCtx, interface{})
}

// New returns a new initialized Router.
// Path auto-correction, including trailing slashes, is enabled by default.
func New() *Router {
return &Router{
RedirectTrailingSlash: true,
RedirectFixedPath: true,
HandleMethodNotAllowed: true,
HandleOPTIONS: true,
}
}

// GET is a shortcut for router.Handle("GET", path, handle)
func (r *Router) GET(path string, handle fasthttp.RequestHandler) {
r.Handle("GET", path, handle)
}

// HEAD is a shortcut for router.Handle("HEAD", path, handle)
func (r *Router) HEAD(path string, handle fasthttp.RequestHandler) {
r.Handle("HEAD", path, handle)
}

// OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle)
func (r *Router) OPTIONS(path string, handle fasthttp.RequestHandler) {
r.Handle("OPTIONS", path, handle)
}

// POST is a shortcut for router.Handle("POST", path, handle)
func (r *Router) POST(path string, handle fasthttp.RequestHandler) {
r.Handle("POST", path, handle)
}

// PUT is a shortcut for router.Handle("PUT", path, handle)
func (r *Router) PUT(path string, handle fasthttp.RequestHandler) {
r.Handle("PUT", path, handle)
}

// PATCH is a shortcut for router.Handle("PATCH", path, handle)
func (r *Router) PATCH(path string, handle fasthttp.RequestHandler) {
r.Handle("PATCH", path, handle)
}

// DELETE is a shortcut for router.Handle("DELETE", path, handle)
func (r *Router) DELETE(path string, handle fasthttp.RequestHandler) {
r.Handle("DELETE", path, handle)
}

// Handle registers a new request handle with the given path and method.
//
// For GET, POST, PUT, PATCH and DELETE requests the respective shortcut
// functions can be used.
//
// This function is intended for bulk loading and to allow the usage of less
// frequently used, non-standardized or custom methods (e.g. for internal
// communication with a proxy).
func (r *Router) Handle(method, path string, handle fasthttp.RequestHandler) {
if path[0] != '/' {
panic("path must begin with '/' in path '" + path + "'")
}

if r.trees == nil {
r.trees = make(map[string]*node)
}

root := r.trees[method]
if root == nil {
root = new(node)
r.trees[method] = root
}

root.addRoute(path, handle)
}

// ServeFiles serves files from the given file system root.
// The path must end with "/*filepath", files are then served from the local
// path /defined/root/dir/*filepath.
// For example if root is "/etc" and *filepath is "passwd", the local file
// "/etc/passwd" would be served.
// Internally a http.FileServer is used, therefore http.NotFound is used instead
// of the Router's NotFound handler.
// router.ServeFiles("/src/*filepath", "/var/www")
func (r *Router) ServeFiles(path string, rootPath string) {
if len(path) < 10 || path[len(path)-10:] != "/*filepath" {
panic("path must end with /*filepath in path '" + path + "'")
}
prefix := path[:len(path)-10]

fileHandler := fasthttp.FSHandler(rootPath, strings.Count(prefix, "/"))

r.GET(path, func(ctx *fasthttp.RequestCtx) {
fileHandler(ctx)
})
}

func (r *Router) recv(ctx *fasthttp.RequestCtx) {
if rcv := recover(); rcv != nil {
r.PanicHandler(ctx, rcv)
}
}

// Lookup allows the manual lookup of a method + path combo.
// This is e.g. useful to build a framework around this router.
// If the path was found, it returns the handle function and the path parameter
// values. Otherwise the third return value indicates whether a redirection to
// the same path with an extra / without the trailing slash should be performed.
func (r *Router) Lookup(method, path string, ctx *fasthttp.RequestCtx) (fasthttp.RequestHandler, bool) {
if root := r.trees[method]; root != nil {
return root.getValue(path, ctx)
}
return nil, false
}

func (r *Router) allowed(path, reqMethod string) (allow string) {
if path == "*" || path == "/*" { // server-wide
for method := range r.trees {
if method == "OPTIONS" {
continue
}

// add request method to list of allowed methods
if len(allow) == 0 {
allow = method
} else {
allow += ", " + method
}
}
} else { // specific path
for method := range r.trees {
// Skip the requested method - we already tried this one
if method == reqMethod || method == "OPTIONS" {
continue
}

handle, _ := r.trees[method].getValue(path, nil)
if handle != nil {
// add request method to list of allowed methods
if len(allow) == 0 {
allow = method
} else {
allow += ", " + method
}
}
}
}
if len(allow) > 0 {
allow += ", OPTIONS"
}
return
}

// Handler makes the router implement the fasthttp.ListenAndServe interface.
func (r *Router) Handler(ctx *fasthttp.RequestCtx) {
if r.PanicHandler != nil {
defer r.recv(ctx)
}

path := string(ctx.Path())
method := string(ctx.Method())
if root := r.trees[method]; root != nil {
if f, tsr := root.getValue(path, ctx); f != nil {
f(ctx)
return
} else if method != "CONNECT" && path != "/" {
code := 301 // Permanent redirect, request with GET method
if method != "GET" {
// Temporary redirect, request with same method
// As of Go 1.3, Go does not support status code 308.
code = 307
}

if tsr && r.RedirectTrailingSlash {
var uri string
if len(path) > 1 && path[len(path)-1] == '/' {
uri = path[:len(path)-1]
} else {
uri = path + "/"
}
ctx.Redirect(uri, code)
return
}

// Try to fix the request path
if r.RedirectFixedPath {
fixedPath, found := root.findCaseInsensitivePath(
CleanPath(path),
r.RedirectTrailingSlash,
)

if found {
queryBuf := ctx.URI().QueryString()
if len(queryBuf) > 0 {
fixedPath = append(fixedPath, questionMark...)
fixedPath = append(fixedPath, queryBuf...)
}
uri := string(fixedPath)
ctx.Redirect(uri, code)
return
}
}
}
}

if method == "OPTIONS" {
// Handle OPTIONS requests
if r.HandleOPTIONS {
if allow := r.allowed(path, method); len(allow) > 0 {
ctx.Response.Header.Set("Allow", allow)
return
}
}
} else {
// Handle 405
if r.HandleMethodNotAllowed {
if allow := r.allowed(path, method); len(allow) > 0 {
ctx.Response.Header.Set("Allow", allow)
if r.MethodNotAllowed != nil {
r.MethodNotAllowed(ctx)
} else {
ctx.SetStatusCode(fasthttp.StatusMethodNotAllowed)
ctx.SetContentTypeBytes(defaultContentType)
ctx.SetBodyString(fasthttp.StatusMessage(fasthttp.StatusMethodNotAllowed))
}
return
}
}
}

// Handle 404
if r.NotFound != nil {
r.NotFound(ctx)
} else {
ctx.Error(fasthttp.StatusMessage(fasthttp.StatusNotFound),
fasthttp.StatusNotFound)
}
}

+ 0
- 643
vendor/github.com/buaazp/fasthttprouter/tree.go View File

@@ -1,643 +0,0 @@
// Copyright 2013 Julien Schmidt. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.

package fasthttprouter

import (
"github.com/valyala/fasthttp"
"strings"
"unicode"
"unicode/utf8"
)

func min(a, b int) int {
if a <= b {
return a
}
return b
}

func countParams(path string) uint8 {
var n uint
for i := 0; i < len(path); i++ {
if path[i] != ':' && path[i] != '*' {
continue
}
n++
}
if n >= 255 {
return 255
}
return uint8(n)
}

type nodeType uint8

const (
static nodeType = iota // default
root
param
catchAll
)

type node struct {
path string
wildChild bool
nType nodeType
maxParams uint8
indices string
children []*node
handle fasthttp.RequestHandler
priority uint32
}

// increments priority of the given child and reorders if necessary
func (n *node) incrementChildPrio(pos int) int {
n.children[pos].priority++
prio := n.children[pos].priority

// adjust position (move to front)
newPos := pos
for newPos > 0 && n.children[newPos-1].priority < prio {
// swap node positions
tmpN := n.children[newPos-1]
n.children[newPos-1] = n.children[newPos]
n.children[newPos] = tmpN

newPos--
}

// build new index char string
if newPos != pos {
n.indices = n.indices[:newPos] + // unchanged prefix, might be empty
n.indices[pos:pos+1] + // the index char we move
n.indices[newPos:pos] + n.indices[pos+1:] // rest without char at 'pos'
}

return newPos
}

// addRoute adds a node with the given handle to the path.
// Not concurrency-safe!
func (n *node) addRoute(path string, handle fasthttp.RequestHandler) {
fullPath := path
n.priority++
numParams := countParams(path)

// non-empty tree
if len(n.path) > 0 || len(n.children) > 0 {
walk:
for {
// Update maxParams of the current node
if numParams > n.maxParams {
n.maxParams = numParams
}

// Find the longest common prefix.
// This also implies that the common prefix contains no ':' or '*'
// since the existing key can't contain those chars.
i := 0
max := min(len(path), len(n.path))
for i < max && path[i] == n.path[i] {
i++
}

// Split edge
if i < len(n.path) {
child := node{
path: n.path[i:],
wildChild: n.wildChild,
nType: static,
indices: n.indices,
children: n.children,
handle: n.handle,
priority: n.priority - 1,
}

// Update maxParams (max of all children)
for i := range child.children {
if child.children[i].maxParams > child.maxParams {
child.maxParams = child.children[i].maxParams
}
}

n.children = []*node{&child}
// []byte for proper unicode char conversion, see #65
n.indices = string([]byte{n.path[i]})
n.path = path[:i]
n.handle = nil
n.wildChild = false
}

// Make new node a child of this node
if i < len(path) {
path = path[i:]

if n.wildChild {
n = n.children[0]
n.priority++

// Update maxParams of the child node
if numParams > n.maxParams {
n.maxParams = numParams
}
numParams--

// Check if the wildcard matches
if len(path) >= len(n.path) && n.path == path[:len(n.path)] &&
// Check for longer wildcard, e.g. :name and :names
(len(n.path) >= len(path) || path[len(n.path)] == '/') {
continue walk
} else {
// Wildcard conflict
pathSeg := strings.SplitN(path, "/", 2)[0]
prefix := fullPath[:strings.Index(fullPath, pathSeg)] + n.path
panic("'" + pathSeg +
"' in new path '" + fullPath +
"' conflicts with existing wildcard '" + n.path +
"' in existing prefix '" + prefix +
"'")
}
}

c := path[0]

// slash after param
if n.nType == param && c == '/' && len(n.children) == 1 {
n = n.children[0]
n.priority++
continue walk
}

// Check if a child with the next path byte exists
for i := 0; i < len(n.indices); i++ {
if c == n.indices[i] {
i = n.incrementChildPrio(i)
n = n.children[i]
continue walk
}
}

// Otherwise insert it
if c != ':' && c != '*' {
// []byte for proper unicode char conversion, see #65
n.indices += string([]byte{c})
child := &node{
maxParams: numParams,
}
n.children = append(n.children, child)
n.incrementChildPrio(len(n.indices) - 1)
n = child
}
n.insertChild(numParams, path, fullPath, handle)
return

} else if i == len(path) { // Make node a (in-path) leaf
if n.handle != nil {
panic("a handle is already registered for path '" + fullPath + "'")
}
n.handle = handle
}
return
}
} else { // Empty tree
n.insertChild(numParams, path, fullPath, handle)
n.nType = root
}
}

func (n *node) insertChild(numParams uint8, path, fullPath string, handle fasthttp.RequestHandler) {
var offset int // already handled bytes of the path

// find prefix until first wildcard (beginning with ':'' or '*'')
for i, max := 0, len(path); numParams > 0; i++ {
c := path[i]
if c != ':' && c != '*' {
continue
}

// find wildcard end (either '/' or path end)
end := i + 1
for end < max && path[end] != '/' {
switch path[end] {
// the wildcard name must not contain ':' and '*'
case ':', '*':
panic("only one wildcard per path segment is allowed, has: '" +
path[i:] + "' in path '" + fullPath + "'")
default:
end++
}
}

// check if this Node existing children which would be
// unreachable if we insert the wildcard here
if len(n.children) > 0 {
panic("wildcard route '" + path[i:end] +
"' conflicts with existing children in path '" + fullPath + "'")
}

// check if the wildcard has a name
if end-i < 2 {
panic("wildcards must be named with a non-empty name in path '" + fullPath + "'")
}

if c == ':' { // param
// split path at the beginning of the wildcard
if i > 0 {
n.path = path[offset:i]
offset = i
}

child := &node{
nType: param,
maxParams: numParams,
}
n.children = []*node{child}
n.wildChild = true
n = child
n.priority++
numParams--

// if the path doesn't end with the wildcard, then there
// will be another non-wildcard subpath starting with '/'
if end < max {
n.path = path[offset:end]
offset = end

child := &node{
maxParams: numParams,
priority: 1,
}
n.children = []*node{child}
n = child
}

} else { // catchAll
if end != max || numParams > 1 {
panic("catch-all routes are only allowed at the end of the path in path '" + fullPath + "'")
}

if len(n.path) > 0 && n.path[len(n.path)-1] == '/' {
panic("catch-all conflicts with existing handle for the path segment root in path '" + fullPath + "'")
}

// currently fixed width 1 for '/'
i--
if path[i] != '/' {
panic("no / before catch-all in path '" + fullPath + "'")
}

n.path = path[offset:i]

// first node: catchAll node with empty path
child := &node{
wildChild: true,
nType: catchAll,
maxParams: 1,
}
n.children = []*node{child}
n.indices = string(path[i])
n = child
n.priority++

// second node: node holding the variable
child = &node{
path: path[i:],
nType: catchAll,
maxParams: 1,
handle: handle,
priority: 1,
}
n.children = []*node{child}

return
}
}

// insert remaining path part and handle to the leaf
n.path = path[offset:]
n.handle = handle
}

// Returns the handle registered with the given path (key). The values of
// wildcards are saved to a map.
// If no handle can be found, a TSR (trailing slash redirect) recommendation is
// made if a handle exists with an extra (without the) trailing slash for the
// given path.
func (n *node) getValue(path string, ctx *fasthttp.RequestCtx) (handle fasthttp.RequestHandler, tsr bool) {
walk: // outer loop for walking the tree
for {
if len(path) > len(n.path) {
if path[:len(n.path)] == n.path {
path = path[len(n.path):]
// If this node does not have a wildcard (param or catchAll)
// child, we can just look up the next child node and continue
// to walk down the tree
if !n.wildChild {
c := path[0]
for i := 0; i < len(n.indices); i++ {
if c == n.indices[i] {
n = n.children[i]
continue walk
}
}

// Nothing found.
// We can recommend to redirect to the same URL without a
// trailing slash if a leaf exists for that path.
tsr = (path == "/" && n.handle != nil)
return

}

// handle wildcard child
n = n.children[0]
switch n.nType {
case param:
// find param end (either '/' or path end)
end := 0
for end < len(path) && path[end] != '/' {
end++
}

// handle calls to Router.allowed method with nil context
if ctx != nil {
ctx.SetUserValue(n.path[1:], path[:end])
}

// we need to go deeper!
if end < len(path) {
if len(n.children) > 0 {
path = path[end:]
n = n.children[0]
continue walk
}

// ... but we can't
tsr = (len(path) == end+1)
return
}

if handle = n.handle; handle != nil {
return
} else if len(n.children) == 1 {
// No handle found. Check if a handle for this path + a
// trailing slash exists for TSR recommendation
n = n.children[0]
tsr = (n.path == "/" && n.handle != nil)
}

return

case catchAll:
if ctx != nil {
// save param value
ctx.SetUserValue(n.path[2:], path)
}
handle = n.handle
return

default:
panic("invalid node type")
}
}
} else if path == n.path {
// We should have reached the node containing the handle.
// Check if this node has a handle registered.
if handle = n.handle; handle != nil {
return
}

if path == "/" && n.wildChild && n.nType != root {
tsr = true
return
}

// No handle found. Check if a handle for this path + a
// trailing slash exists for trailing slash recommendation
for i := 0; i < len(n.indices); i++ {
if n.indices[i] == '/' {
n = n.children[i]
tsr = (len(n.path) == 1 && n.handle != nil) ||
(n.nType == catchAll && n.children[0].handle != nil)
return
}
}

return
}

// Nothing found. We can recommend to redirect to the same URL with an
// extra trailing slash if a leaf exists for that path
tsr = (path == "/") ||
(len(n.path) == len(path)+1 && n.path[len(path)] == '/' &&
path == n.path[:len(n.path)-1] && n.handle != nil)
return
}
}

// Makes a case-insensitive lookup of the given path and tries to find a handler.
// It can optionally also fix trailing slashes.
// It returns the case-corrected path and a bool indicating whether the lookup
// was successful.
func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) ([]byte, bool) {
return n.findCaseInsensitivePathRec(
path,
strings.ToLower(path),
make([]byte, 0, len(path)+1), // preallocate enough memory for new path
[4]byte{}, // empty rune buffer
fixTrailingSlash,
)
}

// shift bytes in array by n bytes left
func shiftNRuneBytes(rb [4]byte, n int) [4]byte {