forked from lug/matterbridge
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b979aff270 | ||
|
|
b293e3fa75 | ||
|
|
21eb37e471 | ||
|
|
d3b60cc445 | ||
|
|
7466e1d014 | ||
|
|
2a7f28606c | ||
|
|
0450482e6e | ||
|
|
ee5d9b43b5 | ||
|
|
3a8857c8c9 | ||
|
|
be3dfb251d | ||
|
|
4e11e29f70 | ||
|
|
763bb95cea | ||
|
|
668e7407e6 | ||
|
|
c147ba1da1 | ||
|
|
10f044c3dd | ||
|
|
ce5140febd | ||
|
|
858cdc86f5 | ||
|
|
9a25297d51 | ||
|
|
e24f7f5151 | ||
|
|
eff5f1e119 |
15
.github/workflows/development.yml
vendored
15
.github/workflows/development.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
test-build-upload:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.14.x, 1.15.x]
|
||||
go-version: [1.15.x, 1.16.x]
|
||||
platform: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
@@ -24,6 +24,7 @@ jobs:
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
stable: false
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -34,23 +35,23 @@ jobs:
|
||||
run: |
|
||||
mkdir -p output/{win,lin,arm,mac}
|
||||
VERSION=$(git describe --tags)
|
||||
GOOS=linux GOARCH=amd64 go build -mod=vendor -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/lin/matterbridge-$VERSION-linux-amd64
|
||||
GOOS=windows GOARCH=amd64 go build -mod=vendor -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/win/matterbridge-$VERSION-windows-amd64.exe
|
||||
GOOS=darwin GOARCH=amd64 go build -mod=vendor -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/mac/matterbridge-$VERSION-darwin-amd64
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/lin/matterbridge-$VERSION-linux-amd64
|
||||
GOOS=windows GOARCH=amd64 go build -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/win/matterbridge-$VERSION-windows-amd64.exe
|
||||
GOOS=darwin GOARCH=amd64 go build -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/mac/matterbridge-$VERSION-darwin-amd64
|
||||
- name: Upload linux 64-bit
|
||||
if: startsWith(matrix.go-version,'1.15')
|
||||
if: startsWith(matrix.go-version,'1.16')
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: matterbridge-linux-64bit
|
||||
path: output/lin
|
||||
- name: Upload windows 64-bit
|
||||
if: startsWith(matrix.go-version,'1.15')
|
||||
if: startsWith(matrix.go-version,'1.16')
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: matterbridge-windows-64bit
|
||||
path: output/win
|
||||
- name: Upload darwin 64-bit
|
||||
if: startsWith(matrix.go-version,'1.15')
|
||||
if: startsWith(matrix.go-version,'1.16')
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: matterbridge-darwin-64bit
|
||||
|
||||
11
README.md
11
README.md
@@ -110,9 +110,11 @@ And more...
|
||||
### 3rd party via matterbridge api
|
||||
|
||||
- [Discourse](https://github.com/DeclanHoare/matterbabble)
|
||||
- [Facebook messenger](https://github.com/powerjungle/fbridge-asyncio)
|
||||
- [Facebook messenger](https://github.com/VictorNine/fbridge)
|
||||
- [Minecraft](https://github.com/elytra/MatterLink)
|
||||
- [Minecraft](https://github.com/raws/mattercraft)
|
||||
- [Minecraft](https://gitlab.com/Programie/MatterBukkit)
|
||||
- [Reddit](https://github.com/bonehurtingjuice/mattereddit)
|
||||
- [Counter-Strike, half-life and more](https://forums.alliedmods.net/showthread.php?t=319430)
|
||||
- [MatterAMXX](https://github.com/GabeIggy/MatterAMXX)
|
||||
@@ -125,10 +127,12 @@ More info and examples on the [wiki](https://github.com/42wim/matterbridge/wiki/
|
||||
|
||||
Used by the projects below. Feel free to make a PR to add your project to this list.
|
||||
|
||||
- [MatterLink](https://github.com/elytra/MatterLink) (Matterbridge link for Minecraft Server chat)
|
||||
- [Minecraft](https://github.com/raws/mattercraft) (Matterbridge link for Minecraft Server chat)
|
||||
- [MatterLink](https://github.com/elytra/MatterLink) (Matterbridge link for Minecraft Forge server chat, archived)
|
||||
- [MatterCraft](https://github.com/raws/mattercraft) (Matterbridge link for Minecraft Forge server chat)
|
||||
- [MatterBukkit](https://gitlab.com/Programie/MatterBukkit) (Matterbridge link for Minecraft Bukkit/Spigot server chat)
|
||||
- [pyCord](https://github.com/NikkyAI/pyCord) (crossplatform chatbot)
|
||||
- [Mattereddit](https://github.com/bonehurtingjuice/mattereddit) (Reddit chat support)
|
||||
- [fbridge-asyncio](https://github.com/powerjungle/fbridge-asyncio) (Facebook messenger support)
|
||||
- [fbridge](https://github.com/VictorNine/fbridge) (Facebook messenger support)
|
||||
- [matterbabble](https://github.com/DeclanHoare/matterbabble) (Discourse support)
|
||||
- [MatterAMXX](https://forums.alliedmods.net/showthread.php?t=319430) (Counter-Strike, half-life and more via AMXX mod)
|
||||
@@ -159,7 +163,7 @@ See <https://github.com/42wim/matterbridge/wiki>
|
||||
|
||||
### Binaries
|
||||
|
||||
- Latest stable release [v1.22.0](https://github.com/42wim/matterbridge/releases/latest)
|
||||
- Latest stable release [v1.22.1](https://github.com/42wim/matterbridge/releases/latest)
|
||||
- Development releases (follows master) can be downloaded [here](https://github.com/42wim/matterbridge/actions) selecting the latest green build and then artifacts.
|
||||
|
||||
To install or upgrade just download the latest [binary](https://github.com/42wim/matterbridge/releases/latest). On \*nix platforms you may need to make the binary executable - you can do this by running `chmod a+x` on the binary (example: `chmod a+x matterbridge-1.20.0-linux-64bit`). After downloading (and making the binary executable, if necessary), follow the instructions on the [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
|
||||
@@ -168,6 +172,7 @@ To install or upgrade just download the latest [binary](https://github.com/42wim
|
||||
|
||||
- [Overview](https://repology.org/metapackage/matterbridge/versions)
|
||||
- [snap](https://snapcraft.io/matterbridge)
|
||||
- [scoop](https://github.com/42wim/scoop-bucket)
|
||||
|
||||
## Building
|
||||
|
||||
|
||||
@@ -75,6 +75,11 @@ func (b *Bdiscord) Connect() error {
|
||||
b.c.AddHandler(b.messageDeleteBulk)
|
||||
b.c.AddHandler(b.memberAdd)
|
||||
b.c.AddHandler(b.memberRemove)
|
||||
// Add privileged intent for guild member tracking. This is needed to track nicks
|
||||
// for display names and @mention translation
|
||||
b.c.Identify.Intents = discordgo.MakeIntent(discordgo.IntentsAllWithoutPrivileged |
|
||||
discordgo.IntentsGuildMembers)
|
||||
|
||||
err = b.c.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -58,7 +58,7 @@ func New(session *discordgo.Session, guild string, title string, autoCreate bool
|
||||
|
||||
channelWebhooks: make(map[string]*discordgo.Webhook),
|
||||
|
||||
Log: log.NewEntry(nil),
|
||||
Log: log.NewEntry(log.StandardLogger()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,30 @@ func DownloadFileAuth(url string, auth string) (*[]byte, error) {
|
||||
return &data, nil
|
||||
}
|
||||
|
||||
// DownloadFileAuthRocket downloads the given URL using the specified Rocket user ID and authentication token.
|
||||
func DownloadFileAuthRocket(url, token, userID string) (*[]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
client := &http.Client{
|
||||
Timeout: time.Second * 5,
|
||||
}
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
|
||||
req.Header.Add("X-Auth-Token", token)
|
||||
req.Header.Add("X-User-Id", userID)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
_, err = io.Copy(&buf, resp.Body)
|
||||
data := buf.Bytes()
|
||||
return &data, err
|
||||
}
|
||||
|
||||
// GetSubLines splits messages in newline-delimited lines. If maxLineLength is
|
||||
// specified as non-zero GetSubLines will also clip long lines to the maximum
|
||||
// length and insert a warning marker that the line was clipped.
|
||||
@@ -224,35 +248,52 @@ func CanConvertTgsToX() error {
|
||||
// This relies on an external command, which is ugly, but works.
|
||||
func ConvertTgsToX(data *[]byte, outputFormat string, logger *logrus.Entry) error {
|
||||
// lottie can't handle input from a pipe, so write to a temporary file:
|
||||
tmpFile, err := ioutil.TempFile(os.TempDir(), "matterbridge-lottie-*.tgs")
|
||||
tmpInFile, err := ioutil.TempFile(os.TempDir(), "matterbridge-lottie-input-*.tgs")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpFileName := tmpFile.Name()
|
||||
tmpInFileName := tmpInFile.Name()
|
||||
defer func() {
|
||||
if removeErr := os.Remove(tmpFileName); removeErr != nil {
|
||||
logger.Errorf("Could not delete temporary file %s: %v", tmpFileName, removeErr)
|
||||
if removeErr := os.Remove(tmpInFileName); removeErr != nil {
|
||||
logger.Errorf("Could not delete temporary (input) file %s: %v", tmpInFileName, removeErr)
|
||||
}
|
||||
}()
|
||||
// lottie can handle writing to a pipe, but there is no way to do that platform-independently.
|
||||
// "/dev/stdout" won't work on Windows, and "-" upsets Cairo for some reason. So we need another file:
|
||||
tmpOutFile, err := ioutil.TempFile(os.TempDir(), "matterbridge-lottie-output-*.data")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpOutFileName := tmpOutFile.Name()
|
||||
defer func() {
|
||||
if removeErr := os.Remove(tmpOutFileName); removeErr != nil {
|
||||
logger.Errorf("Could not delete temporary (output) file %s: %v", tmpOutFileName, removeErr)
|
||||
}
|
||||
}()
|
||||
|
||||
if _, writeErr := tmpFile.Write(*data); writeErr != nil {
|
||||
if _, writeErr := tmpInFile.Write(*data); writeErr != nil {
|
||||
return writeErr
|
||||
}
|
||||
// Must close before calling lottie to avoid data races:
|
||||
if closeErr := tmpFile.Close(); closeErr != nil {
|
||||
if closeErr := tmpInFile.Close(); closeErr != nil {
|
||||
return closeErr
|
||||
}
|
||||
|
||||
// Call lottie to transform:
|
||||
cmd := exec.Command("lottie_convert.py", "--input-format", "lottie", "--output-format", outputFormat, tmpFileName, "/dev/stdout")
|
||||
cmd := exec.Command("lottie_convert.py", "--input-format", "lottie", "--output-format", outputFormat, tmpInFileName, tmpOutFileName)
|
||||
cmd.Stdout = nil
|
||||
cmd.Stderr = nil
|
||||
// NB: lottie writes progress into to stderr in all cases.
|
||||
stdout, stderr := cmd.Output()
|
||||
_, stderr := cmd.Output()
|
||||
if stderr != nil {
|
||||
// 'stderr' already contains some parts of Stderr, because it was set to 'nil'.
|
||||
return stderr
|
||||
}
|
||||
dataContents, err := ioutil.ReadFile(tmpOutFileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*data = stdout
|
||||
*data = dataContents
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package brocketchat
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/matterbridge/Rocket.Chat.Go.SDK/models"
|
||||
)
|
||||
|
||||
@@ -58,6 +61,7 @@ func (b *Brocketchat) handleStatusEvent(ev models.Message, rmsg *config.Message)
|
||||
|
||||
func (b *Brocketchat) handleRocketClient(messages chan *config.Message) {
|
||||
for message := range b.messageChan {
|
||||
message := message
|
||||
// skip messages with same ID, apparently messages get duplicated for an unknown reason
|
||||
if _, ok := b.cache.Get(message.ID); ok {
|
||||
continue
|
||||
@@ -76,8 +80,11 @@ func (b *Brocketchat) handleRocketClient(messages chan *config.Message) {
|
||||
Account: b.Account,
|
||||
UserID: message.User.ID,
|
||||
ID: message.ID,
|
||||
Extra: make(map[string][]interface{}),
|
||||
}
|
||||
|
||||
b.handleAttachments(&message, rmsg)
|
||||
|
||||
// handleStatusEvent returns false if the message should be dropped
|
||||
// in that case it is probably some modification to the channel we do not want to relay
|
||||
if b.handleStatusEvent(m, rmsg) {
|
||||
@@ -86,6 +93,38 @@ func (b *Brocketchat) handleRocketClient(messages chan *config.Message) {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Brocketchat) handleAttachments(message *models.Message, rmsg *config.Message) {
|
||||
if rmsg.Text == "" {
|
||||
for _, attachment := range message.Attachments {
|
||||
if attachment.Title != "" {
|
||||
rmsg.Text = attachment.Title + "\n"
|
||||
}
|
||||
if attachment.Title != "" && attachment.Text != "" {
|
||||
rmsg.Text += "\n"
|
||||
}
|
||||
if attachment.Text != "" {
|
||||
rmsg.Text += attachment.Text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := range message.Attachments {
|
||||
if err := b.handleDownloadFile(rmsg, &message.Attachments[i]); err != nil {
|
||||
b.Log.Errorf("Could not download incoming file: %#v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Brocketchat) handleDownloadFile(rmsg *config.Message, file *models.Attachment) error {
|
||||
downloadURL := b.GetString("server") + file.TitleLink
|
||||
data, err := helper.DownloadFileAuthRocket(downloadURL, b.user.Token, b.user.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("download %s failed %#v", downloadURL, err)
|
||||
}
|
||||
helper.HandleDownloadData(b.Log, rmsg, file.Title, rmsg.Text, downloadURL, data, b.General)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Brocketchat) handleUploadFile(msg *config.Message) error {
|
||||
for _, f := range msg.Extra["file"] {
|
||||
fi := f.(config.FileInfo)
|
||||
|
||||
@@ -2,7 +2,7 @@ package btelegram
|
||||
|
||||
import (
|
||||
"html"
|
||||
"regexp"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf16"
|
||||
@@ -181,13 +181,15 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) {
|
||||
// sends a EVENT_AVATAR_DOWNLOAD message to the gateway if successful.
|
||||
// logs an error message if it fails
|
||||
func (b *Btelegram) handleDownloadAvatar(userid int, channel string) {
|
||||
rmsg := config.Message{Username: "system",
|
||||
Text: "avatar",
|
||||
Channel: channel,
|
||||
Account: b.Account,
|
||||
UserID: strconv.Itoa(userid),
|
||||
Event: config.EventAvatarDownload,
|
||||
Extra: make(map[string][]interface{})}
|
||||
rmsg := config.Message{
|
||||
Username: "system",
|
||||
Text: "avatar",
|
||||
Channel: channel,
|
||||
Account: b.Account,
|
||||
UserID: strconv.Itoa(userid),
|
||||
Event: config.EventAvatarDownload,
|
||||
Extra: make(map[string][]interface{}),
|
||||
}
|
||||
|
||||
if _, ok := b.avatarMap[strconv.Itoa(userid)]; !ok {
|
||||
photos, err := b.c.GetUserProfilePhotos(tgbotapi.UserProfilePhotosConfig{UserID: userid, Limit: 1})
|
||||
@@ -389,21 +391,32 @@ func (b *Btelegram) handleUploadFile(msg *config.Message, chatid int64) string {
|
||||
Name: fi.Name,
|
||||
Bytes: *fi.Data,
|
||||
}
|
||||
re := regexp.MustCompile(".(jpg|jpe|png)$")
|
||||
if re.MatchString(fi.Name) {
|
||||
c = tgbotapi.NewPhotoUpload(chatid, file)
|
||||
} else {
|
||||
c = tgbotapi.NewDocumentUpload(chatid, file)
|
||||
switch filepath.Ext(fi.Name) {
|
||||
case ".jpg", ".jpe", ".png":
|
||||
pc := tgbotapi.NewPhotoUpload(chatid, file)
|
||||
pc.Caption, pc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
c = pc
|
||||
case ".mp4", ".m4v":
|
||||
vc := tgbotapi.NewVideoUpload(chatid, file)
|
||||
vc.Caption, vc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
c = vc
|
||||
case ".mp3", ".oga":
|
||||
ac := tgbotapi.NewAudioUpload(chatid, file)
|
||||
ac.Caption, ac.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
c = ac
|
||||
case ".ogg":
|
||||
voc := tgbotapi.NewVoiceUpload(chatid, file)
|
||||
voc.Caption, voc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
c = voc
|
||||
default:
|
||||
dc := tgbotapi.NewDocumentUpload(chatid, file)
|
||||
dc.Caption, dc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
c = dc
|
||||
}
|
||||
_, err := b.c.Send(c)
|
||||
if err != nil {
|
||||
b.Log.Errorf("file upload failed: %#v", err)
|
||||
}
|
||||
if fi.Comment != "" {
|
||||
if _, err := b.sendMessage(chatid, msg.Username, fi.Comment); err != nil {
|
||||
b.Log.Errorf("posting file comment %s failed: %s", fi.Comment, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -413,7 +426,7 @@ func (b *Btelegram) handleQuote(message, quoteNick, quoteMessage string) string
|
||||
if format == "" {
|
||||
format = "{MESSAGE} (re @{QUOTENICK}: {QUOTEMESSAGE})"
|
||||
}
|
||||
quoteMessagelength := len(quoteMessage)
|
||||
quoteMessagelength := len([]rune(quoteMessage))
|
||||
if b.GetInt("QuoteLengthLimit") != 0 && quoteMessagelength >= b.GetInt("QuoteLengthLimit") {
|
||||
runes := []rune(quoteMessage)
|
||||
quoteMessage = string(runes[0:b.GetInt("QuoteLengthLimit")])
|
||||
|
||||
@@ -69,6 +69,28 @@ func (b *Btelegram) JoinChannel(channel config.ChannelInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TGGetParseMode(b *Btelegram, username string, text string) (textout string, parsemode string) {
|
||||
textout = username + text
|
||||
if b.GetString("MessageFormat") == HTMLFormat {
|
||||
b.Log.Debug("Using mode HTML")
|
||||
parsemode = tgbotapi.ModeHTML
|
||||
}
|
||||
if b.GetString("MessageFormat") == "Markdown" {
|
||||
b.Log.Debug("Using mode markdown")
|
||||
parsemode = tgbotapi.ModeMarkdown
|
||||
}
|
||||
if b.GetString("MessageFormat") == MarkdownV2 {
|
||||
b.Log.Debug("Using mode MarkdownV2")
|
||||
parsemode = MarkdownV2
|
||||
}
|
||||
if strings.ToLower(b.GetString("MessageFormat")) == HTMLNick {
|
||||
b.Log.Debug("Using mode HTML - nick only")
|
||||
textout = username + html.EscapeString(text)
|
||||
parsemode = tgbotapi.ModeHTML
|
||||
}
|
||||
return textout, parsemode
|
||||
}
|
||||
|
||||
func (b *Btelegram) Send(msg config.Message) (string, error) {
|
||||
b.Log.Debugf("=> Receiving %#v", msg)
|
||||
|
||||
@@ -131,24 +153,7 @@ func (b *Btelegram) getFileDirectURL(id string) string {
|
||||
|
||||
func (b *Btelegram) sendMessage(chatid int64, username, text string) (string, error) {
|
||||
m := tgbotapi.NewMessage(chatid, "")
|
||||
m.Text = username + text
|
||||
if b.GetString("MessageFormat") == HTMLFormat {
|
||||
b.Log.Debug("Using mode HTML")
|
||||
m.ParseMode = tgbotapi.ModeHTML
|
||||
}
|
||||
if b.GetString("MessageFormat") == "Markdown" {
|
||||
b.Log.Debug("Using mode markdown")
|
||||
m.ParseMode = tgbotapi.ModeMarkdown
|
||||
}
|
||||
if b.GetString("MessageFormat") == MarkdownV2 {
|
||||
b.Log.Debug("Using mode MarkdownV2")
|
||||
m.ParseMode = MarkdownV2
|
||||
}
|
||||
if strings.ToLower(b.GetString("MessageFormat")) == HTMLNick {
|
||||
b.Log.Debug("Using mode HTML - nick only")
|
||||
m.Text = username + html.EscapeString(text)
|
||||
m.ParseMode = tgbotapi.ModeHTML
|
||||
}
|
||||
m.Text, m.ParseMode = TGGetParseMode(b, username, text)
|
||||
|
||||
m.DisableWebPagePreview = b.GetBool("DisableWebPagePreview")
|
||||
|
||||
|
||||
@@ -289,6 +289,10 @@ func (b *Bwhatsapp) HandleAudioMessage(message whatsapp.AudioMessage) {
|
||||
return
|
||||
}
|
||||
|
||||
if len(fileExt) == 0 {
|
||||
fileExt = append(fileExt, ".ogg")
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("%v%v", message.Info.Id, fileExt[0])
|
||||
|
||||
b.Log.Debugf("Trying to download %s with size %#v and type %s", filename, message.Length, message.Type)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -157,9 +158,14 @@ func (b *Bxmpp) postSlackCompatibleWebhook(msg config.Message) error {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := http.Post(b.GetString("WebhookURL")+"/"+msg.Channel, "application/json", bytes.NewReader(webhookBody))
|
||||
resp, err := http.Post(b.GetString("WebhookURL")+"/"+url.QueryEscape(msg.Channel), "application/json", bytes.NewReader(webhookBody))
|
||||
if err != nil {
|
||||
b.Log.Errorf("Failed to POST webhook: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
resp.Body.Close()
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bxmpp) createXMPP() error {
|
||||
|
||||
1235
changelog.md
1235
changelog.md
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/d5/tengo/v2"
|
||||
"github.com/d5/tengo/v2/stdlib"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"github.com/matterbridge/emoji"
|
||||
"github.com/kyokomi/emoji/v2"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -127,7 +127,7 @@ func (gw *Gateway) AddConfig(cfg *config.Gateway) error {
|
||||
gw.logger.Errorf("mapChannels() failed: %s", err)
|
||||
}
|
||||
for _, br := range append(gw.MyConfig.In, append(gw.MyConfig.InOut, gw.MyConfig.Out...)...) {
|
||||
br := br //scopelint
|
||||
br := br // scopelint
|
||||
err := gw.AddBridge(&br)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -386,6 +386,7 @@ func (gw *Gateway) modifyMessage(msg *config.Message) {
|
||||
}
|
||||
|
||||
// replace :emoji: to unicode
|
||||
emoji.ReplacePadding = ""
|
||||
msg.Text = emoji.Sprint(msg.Text)
|
||||
|
||||
br := gw.Bridges[msg.Account]
|
||||
@@ -496,7 +497,7 @@ func (gw *Gateway) SendMessage(
|
||||
if mID != "" {
|
||||
gw.logger.Debugf("mID %s: %s", dest.Account, mID)
|
||||
return mID, nil
|
||||
//brMsgIDs = append(brMsgIDs, &BrMsgID{dest, dest.Protocol + " " + mID, channel.ID})
|
||||
// brMsgIDs = append(brMsgIDs, &BrMsgID{dest, dest.Protocol + " " + mID, channel.ID})
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
35
go.mod
35
go.mod
@@ -3,57 +3,56 @@ module github.com/42wim/matterbridge
|
||||
require (
|
||||
github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557
|
||||
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f
|
||||
github.com/Jeffail/gabs v1.4.0 // indirect
|
||||
github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560
|
||||
github.com/Rhymen/go-whatsapp v0.1.2-0.20210126174449-3c094ebae0ce
|
||||
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20200922220614-e4a51dfb52e4 // indirect
|
||||
github.com/SevereCloud/vksdk/v2 v2.9.0
|
||||
github.com/d5/tengo/v2 v2.6.2
|
||||
github.com/d5/tengo/v2 v2.7.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v1.0.1-0.20200524105306-7434b0456e81
|
||||
github.com/gomarkdown/markdown v0.0.0-20201113031856-722100d81a8e
|
||||
github.com/google/gops v0.3.14
|
||||
github.com/gomarkdown/markdown v0.0.0-20210208175418-bda154fe17d8
|
||||
github.com/google/gops v0.3.17
|
||||
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 // indirect
|
||||
github.com/gorilla/schema v1.2.0
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/jpillora/backoff v1.0.0
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20200505163032-5cacf52379da
|
||||
github.com/labstack/echo/v4 v4.1.17
|
||||
github.com/kyokomi/emoji/v2 v2.2.8
|
||||
github.com/labstack/echo/v4 v4.2.1
|
||||
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7
|
||||
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20201206215757-c1d86d75b9f8
|
||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20210403163225-761e8622445d
|
||||
github.com/matterbridge/discordgo v0.21.2-0.20210201201054-fb39a175b4f7
|
||||
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050
|
||||
github.com/matterbridge/gozulipbot v0.0.0-20200820220548-be5824faa913
|
||||
github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba
|
||||
github.com/mattermost/mattermost-server/v5 v5.30.1
|
||||
github.com/mattn/godown v0.0.1
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/missdeer/golib v1.0.4
|
||||
github.com/mitchellh/mapstructure v1.3.3 // indirect
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 // indirect
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d // indirect
|
||||
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect
|
||||
github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9
|
||||
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c
|
||||
github.com/rs/xid v1.2.1
|
||||
github.com/rs/xid v1.3.0
|
||||
github.com/russross/blackfriday v1.6.0
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
|
||||
github.com/shazow/ssh-chat v1.10.1
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
github.com/slack-go/slack v0.8.0
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/slack-go/slack v0.8.2
|
||||
github.com/spf13/afero v1.3.4 // indirect
|
||||
github.com/spf13/cast v1.3.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/viper v1.7.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/vincent-petithory/dataurl v0.0.0-20191104211930-d1553a71de50
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
|
||||
github.com/yaegashi/msgraph.go v0.1.4
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6
|
||||
golang.org/x/oauth2 v0.0.0-20210201163806-010130855d6c
|
||||
github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134
|
||||
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602
|
||||
gomod.garykim.dev/nc-talk v0.1.7
|
||||
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376
|
||||
layeh.com/gumble v0.0.0-20200818122324-146f9205029b
|
||||
|
||||
150
go.sum
150
go.sum
@@ -77,8 +77,6 @@ github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560/go.mod h1:o3
|
||||
github.com/PuerkitoBio/goquery v1.4.1/go.mod h1:T9ezsOHcCrDCgA8aF1Cqr3sSYbO/xgdy8/R/XiIMAhA=
|
||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/Rhymen/go-whatsapp v0.0.0/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA=
|
||||
github.com/Rhymen/go-whatsapp v0.1.2-0.20201226125722-8029c28f5c5a h1:xE1ogaIgFJQbEDoIkiAkMH9wVEAmlKOy/M+kf1xmtCY=
|
||||
github.com/Rhymen/go-whatsapp v0.1.2-0.20201226125722-8029c28f5c5a/go.mod h1:o7jjkvKnigfu432dMbQ/w4PH0Yp5u4Y6ysCNjUlcYCk=
|
||||
github.com/Rhymen/go-whatsapp v0.1.2-0.20210126174449-3c094ebae0ce h1:qitALaMtz6i05smexphqLty1gGc7Viwhn8bdSRmp4UM=
|
||||
github.com/Rhymen/go-whatsapp v0.1.2-0.20210126174449-3c094ebae0ce/go.mod h1:o7jjkvKnigfu432dMbQ/w4PH0Yp5u4Y6ysCNjUlcYCk=
|
||||
github.com/Rhymen/go-whatsapp/examples/echo v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:zgCiQtBtZ4P4gFWvwl9aashsdwOcbb/EHOGRmSzM8ME=
|
||||
@@ -87,14 +85,11 @@ github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf
|
||||
github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:suwzklatySS3Q0+NCxCDh5hYfgXdQUWU1DNcxwAxStM=
|
||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||
github.com/RoaringBitmap/roaring v0.5.1/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20200922220614-e4a51dfb52e4 h1:u7UvmSK6McEMXFZB310/YZ6uvfDaSFrSoqWoy/qaOW0=
|
||||
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20200922220614-e4a51dfb52e4/go.mod h1:wVff6N8s2foRPCYeynerOM/FF44uyI60/HMiboL0SXw=
|
||||
github.com/SevereCloud/vksdk/v2 v2.9.0 h1:39qjzmozK5FDfnDkfA+YN0CtKi4mDrzjPtoT5GN9Xg0=
|
||||
github.com/SevereCloud/vksdk/v2 v2.9.0/go.mod h1:IBmfJ3rs+zDLD9NHCoJEpgg5A4UOoxgUU/g8p5lYb48=
|
||||
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/advancedlogic/GoOse v0.0.0-20191112112754-e742535969c1/go.mod h1:f3HCSN1fBWjcpGtXyM119MJgeQl838v6so/PQOqvE1w=
|
||||
@@ -106,7 +101,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/alexcesaro/log v0.0.0-20150915221235-61e686294e58 h1:MkpmYfld/S8kXqTYI68DfL8/hHXjHogL120Dy00TIxc=
|
||||
github.com/alexcesaro/log v0.0.0-20150915221235-61e686294e58/go.mod h1:YNfsMyWSs+h+PaYkxGeMVmVCX75Zj/pqdjbu12ciCYE=
|
||||
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
@@ -193,8 +187,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
||||
github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/cznic/strutil v0.0.0-20181122101858-275e90344537/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
|
||||
github.com/d5/tengo/v2 v2.6.2 h1:AnPhA/Y5qrNLb5QSWHU9uXq25T3QTTdd2waTgsAHMdc=
|
||||
github.com/d5/tengo/v2 v2.6.2/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
|
||||
github.com/d5/tengo/v2 v2.7.0 h1:oAGQ+gcas0/T0bdqvNxfKzjOJhpQRwceWIF5gldB3aM=
|
||||
github.com/d5/tengo/v2 v2.7.0/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -275,7 +269,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
||||
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-redis/redis/v8 v8.0.0/go.mod h1:isLoQT/NFSP7V67lyvM9GmdvLdyZ7pEhsXvvyQtnQTo=
|
||||
github.com/go-resty/resty/v2 v2.0.0/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
|
||||
@@ -312,7 +305,6 @@ github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
@@ -328,8 +320,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomarkdown/markdown v0.0.0-20201113031856-722100d81a8e h1:/Y3B7hM9H3TOWPhe8eWGBGS4r09pjvS5Z0uoPADyjmU=
|
||||
github.com/gomarkdown/markdown v0.0.0-20201113031856-722100d81a8e/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
|
||||
github.com/gomarkdown/markdown v0.0.0-20210208175418-bda154fe17d8 h1:nWU6p08f1VgIalT6iZyqXi4o5cZsz4X6qa87nusfcsc=
|
||||
github.com/gomarkdown/markdown v0.0.0-20210208175418-bda154fe17d8/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
|
||||
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
@@ -337,19 +329,17 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gops v0.3.14 h1:4Gpv4sABlEsVqrtKxiSynzD0//kzjTIUwUm5UgkGILI=
|
||||
github.com/google/gops v0.3.14/go.mod h1:zjT9F4XsKzazOvdVad3+Zwga79UHKziX3r9TN05rVN8=
|
||||
github.com/google/gops v0.3.17 h1:CguOcnDVYG32soOj2YevV8mW9asrIh1lZw3d7Ovty/o=
|
||||
github.com/google/gops v0.3.17/go.mod h1:Pfp8hWGIFdV/7rY9/O/U5WgdjYQXf/GiEK4NVuVd2ZE=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
@@ -361,7 +351,6 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@@ -371,9 +360,7 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo=
|
||||
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 h1:twflg0XRTjwKpxb/jFExr4HGq6on2dEOmnL6FV+fgPw=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
@@ -406,7 +393,6 @@ github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBt
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -445,7 +431,6 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
@@ -495,7 +480,6 @@ github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6i
|
||||
github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0=
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20200505163032-5cacf52379da h1:LK+8uBG3kNikj664cjFt88RBmuGmonxkXv2rUVfbqz4=
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20200505163032-5cacf52379da/go.mod h1:xJA+X9ZVyT/irGldcb7q1XnJBq5F9s5H9h2L44Y+poY=
|
||||
github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19 h1:WjT3fLi9n8YWh/Ih8Q1LHAPsTqGddPcHqscN+PJ3i68=
|
||||
github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19/go.mod h1:hY+WOq6m2FpbvyrI93sMaypsttvaIL5nhVR92dTMUcQ=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
@@ -514,19 +498,19 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kyokomi/emoji/v2 v2.2.8 h1:jcofPxjHWEkJtkIbcLHvZhxKgCPl6C7MyjTrD4KDqUE=
|
||||
github.com/kyokomi/emoji/v2 v2.2.8/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE=
|
||||
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
||||
github.com/labstack/echo/v4 v4.1.17 h1:PQIBaRplyRy3OjwILGkPg89JRtH2x5bssi59G2EL3fo=
|
||||
github.com/labstack/echo/v4 v4.1.17/go.mod h1:Tn2yRQL/UclUalpb5rPdXDevbkJ+lp/2svdyFBg6CHQ=
|
||||
github.com/labstack/echo/v4 v4.2.1 h1:LF5Iq7t/jrtUuSutNuiEWtB5eiHfZ5gSe2pcu5exjQw=
|
||||
github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
|
||||
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
||||
@@ -548,16 +532,12 @@ github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd h1:xVrqJK3xHREMNjwjljkAUaadalWc0rRbmVuQatzmgwg=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20201206215757-c1d86d75b9f8 h1:2iHni9FGPRRnaZrknLp+Kyr1CWbRIRUjp89TNpkqy3I=
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20201206215757-c1d86d75b9f8/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 h1:ZtO5uywdd5dLDCud4r0r55eP4j9FuUNpl60Gmntcop4=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20210403163225-761e8622445d h1:Csy27nDj00vRGp2+QvwSanaW0RA60SZUHXCk4BBT0AU=
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20210403163225-761e8622445d/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
|
||||
github.com/matterbridge/discordgo v0.21.2-0.20210201201054-fb39a175b4f7 h1:4J2YZuY8dIYrxbLMsWGqPZb/B59ygCwSBkyZHez5PSY=
|
||||
github.com/matterbridge/discordgo v0.21.2-0.20210201201054-fb39a175b4f7/go.mod h1:411nZYv0UMMrtppR5glXop1foboJiFAowy+42U+Ahvw=
|
||||
github.com/matterbridge/discordgo v0.22.1 h1:Wh2NXfvF4egJDxX7jEvtgxJgT/ZOqD/5tfcIsNnHJ9o=
|
||||
github.com/matterbridge/discordgo v0.22.1/go.mod h1:411nZYv0UMMrtppR5glXop1foboJiFAowy+42U+Ahvw=
|
||||
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible h1:oaOqwbg5HxHRxvAbd84ks0Okwoc1ISyUZ87EiVJFhGI=
|
||||
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible/go.mod h1:igE6rUAn3jai2wCdsjFHfhUoekjrFthoEjFObKKwSb4=
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050 h1:kWkP1lXpkvtoNL08jkP3XQH/zvDOEXJpdCJd/DlIvMw=
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
|
||||
github.com/matterbridge/gozulipbot v0.0.0-20200820220548-be5824faa913 h1:5UGr9fLsvAvhjP6i5XJmd0ZIwYVR2gZCzU1lJZ7wfLY=
|
||||
@@ -579,7 +559,6 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
|
||||
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
@@ -596,7 +575,6 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
|
||||
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
@@ -608,8 +586,8 @@ github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpe
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg=
|
||||
github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/mholt/archiver/v3 v3.4.0/go.mod h1:00RcBMhNszoMqnda/5VHHL9+cBoTgj+AkLnmwr3HGrA=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||
@@ -634,8 +612,6 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
|
||||
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
@@ -643,8 +619,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
|
||||
github.com/monaco-io/request v1.0.5 h1:QAJb5m1pCPZUGv3zzTZn7GlQI3q+uJWi7fH9QxDGbm4=
|
||||
github.com/monaco-io/request v1.0.5/go.mod h1:EmggwHktBsbJmCgwZXqy7o0H1NNsAstQBWZrFVd3xtQ=
|
||||
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 h1:oKIteTqeSpenyTrOVj5zkiyCaflLa8B+CD0324otT+o=
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d h1:tLWCMSjfL8XyZwpu1RzI2UpJSPbZCOZ6DVHQFnlpL7A=
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
|
||||
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff h1:HLGD5/9UxxfEuO9DtP8gnTmNtMxbPyhYltfxsITel8g=
|
||||
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff/go.mod h1:B8jLfIIPn2sKyWr0D7cL2v7tnrDD5z291s2Zypdu89E=
|
||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
|
||||
@@ -679,22 +655,17 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v
|
||||
github.com/olekukonko/tablewriter v0.0.0-20180506121414-d4647c9c7a84/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/olivere/elastic v6.2.35+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
|
||||
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.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y=
|
||||
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
|
||||
github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4=
|
||||
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
|
||||
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
@@ -719,11 +690,9 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c h1:P6XGcuPTigoHf4TSu+3D/7QOQ1MbL6alNwrGhcW7sKw=
|
||||
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c/go.mod h1:YnNlZP7l4MhyGQ4CBRwv6ohZTPrUJJZtEv4ZgADkbs4=
|
||||
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
|
||||
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
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.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
@@ -737,7 +706,6 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
|
||||
github.com/pierrec/lz4/v3 v3.3.2/go.mod h1:280XNCGS8jAcG++AHdd6SeWnzyJ1w9oow2vbORyey8Q=
|
||||
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -790,11 +758,11 @@ github.com/rickb777/plural v1.2.0/go.mod h1:UdpyWFCGbo3mvK3f/PfZOAOrkjzJlYN/sD46
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4=
|
||||
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rudderlabs/analytics-go v3.2.1+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30=
|
||||
github.com/russellhaering/goxmldsig v1.1.0/go.mod h1:QK8GhXPB3+AfuCrfo0oRISa9NfzeCpWmxeGnqEpDF9o=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||
@@ -815,8 +783,7 @@ github.com/shazow/rateio v0.0.0-20200113175441-4461efc8bdc4 h1:zwQ1HBo5FYwn1ksMd
|
||||
github.com/shazow/rateio v0.0.0-20200113175441-4461efc8bdc4/go.mod h1:vt2jWY/3Qw1bIzle5thrJWucsLuuX9iUNnp20CqCciI=
|
||||
github.com/shazow/ssh-chat v1.10.1 h1:ePS+ngEYqm+yUuXegDPutysqLV2WoI22XDOeRgI6CE0=
|
||||
github.com/shazow/ssh-chat v1.10.1/go.mod h1:0+7szsKylcre0vljkVnbuI6q7Odtc+QCDHxa+fFNV54=
|
||||
github.com/shirou/gopsutil v2.20.4+incompatible h1:cMT4rxS55zx9NVUnCkrmXCsEB/RNfG9SwHY9evtX8Ng=
|
||||
github.com/shirou/gopsutil v2.20.4+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
|
||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
|
||||
@@ -844,15 +811,13 @@ github.com/simplereach/timeutils v1.2.0/go.mod h1:VVbQDfN/FHRZa1LSqcwo4kNZ62OOyq
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 h1:lpEzuenPuO1XNTeikEmvqYFcU37GVLl8SRNblzyvGBE=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo=
|
||||
github.com/slack-go/slack v0.7.4 h1:Z+7CmUDV+ym4lYLA4NNLFIpr3+nDgViHrx8xsuXgrYs=
|
||||
github.com/slack-go/slack v0.7.4/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM=
|
||||
github.com/slack-go/slack v0.8.0 h1:ANyLY5KHLV+MxLJDQum2IuHTLwbCbDtaWY405X1EU9U=
|
||||
github.com/slack-go/slack v0.8.0/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/slack-go/slack v0.8.2 h1:D7jNu0AInBfdQ4QyKPtVSp+ZxQes3EzWW17RZ/va4JE=
|
||||
github.com/slack-go/slack v0.8.2/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
|
||||
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
@@ -864,11 +829,9 @@ github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJ
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.3.4 h1:8q6vk3hthlpb2SouZcnBVKboxWQWMDNF38bwholZrJc=
|
||||
github.com/spf13/afero v1.3.4/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
@@ -877,10 +840,7 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
@@ -898,14 +858,11 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
|
||||
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
@@ -920,6 +877,8 @@ github.com/throttled/throttled v2.2.5+incompatible/go.mod h1:0BjlrEGQmvxps+HuXLs
|
||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ=
|
||||
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek=
|
||||
github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
@@ -967,7 +926,6 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xlab/treeprint v1.0.0 h1:J0TkWtiuYgtdlrkkrDLISYBQ92M+X5m4LrIIMKrbDTs=
|
||||
github.com/xlab/treeprint v1.0.0/go.mod h1:IoImgRak9i3zJyuxOKUP1v4UZd1tMoKkq/Cimt1uhCg=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM=
|
||||
@@ -982,8 +940,8 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2 h1:UQwvu7FjUEdVYofx0U6bsc5odNE7wa5TSA0fl559GcA=
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2/go.mod h1:0MsIttMJIF/8Y7x0XjonJP7K99t3sR6bjj4m5S4JmqU=
|
||||
github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134 h1:itYC8Ycx8aVBN7a8q1Yr187W5WmQthvYU13+f4rOWkU=
|
||||
github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134/go.mod h1:0MsIttMJIF/8Y7x0XjonJP7K99t3sR6bjj4m5S4JmqU=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
@@ -1001,23 +959,17 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opentelemetry.io/otel v0.11.0/go.mod h1:G8UCk+KooF2HLkgo8RHX9epABH/aRGYET7gQOqBVdB0=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
|
||||
@@ -1040,9 +992,7 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
|
||||
@@ -1063,10 +1013,9 @@ golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMx
|
||||
golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM=
|
||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 h1:nfeHNc1nAqecKCy2FCy4HY+soOOe5sDLJ/gZLbx6GYI=
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk=
|
||||
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -1086,9 +1035,7 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 h1:xUIPaMhvROX9dhPvRCenIJtU78+lbEenGbgqB5hfHCQ=
|
||||
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -1127,9 +1074,7 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
@@ -1138,10 +1083,7 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M=
|
||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -1151,12 +1093,9 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr
|
||||
golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5 h1:Lm4OryKCca1vehdsWogr9N4t7NfZxLbJoc/H0w4K4S4=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210201163806-010130855d6c h1:HiAZXo96zOhVhtFHchj/ojzoxCFiPrp9/j0GtS38V3g=
|
||||
golang.org/x/oauth2 v0.0.0-20210201163806-010130855d6c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
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=
|
||||
@@ -1215,27 +1154,22 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9 h1:YTzHMGlqJu67/uEo1lBv0n3wBXhXNeUbB1XfN2vmTm0=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6 h1:DvY3Zkh7KabQE/kfzMvYvKirSiguP9Q/veMtkYyf0o8=
|
||||
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201007165808-a893ed343c85/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65 h1:Qo9oJ566/Sq7N4hrGftVXs8GI2CXBCuOd4S2wHE/e0M=
|
||||
golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d h1:MiWWjyhUzZ+jvhZvloX6ZrUsdEghn8a64Upd8EMHglE=
|
||||
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210217105451-b926d437f341 h1:2/QtM1mL37YmcsT8HaDNHDgTqqFVw+zr8UzMiBVLzYU=
|
||||
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@@ -1243,6 +1177,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -1293,19 +1229,16 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200529172331-a64b76657301 h1:G6CNEgFU8/XwexSnuFw+Jq/WePjRitgy6ofBcPnAIPo=
|
||||
golang.org/x/tools v0.0.0-20200529172331-a64b76657301/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200731060945-b5fad4ed8dd6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d h1:W07d4xkoAUSNOkOzdzXCdFGxT7o2rW4q8M34tB2i//k=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20201008025239-9df69603baec h1:RY2OghEV/7X1MLaecgm1mwFd3sGvUddm5pGVSxQvX0c=
|
||||
golang.org/x/tools v0.0.0-20201008025239-9df69603baec/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -1338,7 +1271,6 @@ google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
@@ -1409,7 +1341,6 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
@@ -1418,19 +1349,16 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||
@@ -1452,11 +1380,9 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -1468,7 +1394,6 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
@@ -1476,7 +1401,6 @@ layeh.com/gopus v0.0.0-20161224163843-0ebf989153aa/go.mod h1:AOef7vHz0+v4sWwJnr0
|
||||
layeh.com/gumble v0.0.0-20200818122324-146f9205029b h1:Kne6wkHqbqrygRsqs5XUNhSs84DFG5TYMeCkCbM56sY=
|
||||
layeh.com/gumble v0.0.0-20200818122324-146f9205029b/go.mod h1:tWPVA9ZAfImNwabjcd9uDE+Mtz0Hfs7a7G3vxrnrwyc=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/goversion v1.2.0 h1:SPn+NLTiAG7w30IRK/DKp1BjvpWabYgxlLp/+kx5J8w=
|
||||
rsc.io/goversion v1.2.0/go.mod h1:Eih9y/uIBS3ulggl7KNJ09xGSLcuNaLgmvvqa07sgfo=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
version = "1.22.0"
|
||||
version = "1.22.1"
|
||||
githash string
|
||||
|
||||
flagConfig = flag.String("conf", "matterbridge.toml", "config file")
|
||||
|
||||
@@ -1847,7 +1847,7 @@ enable=true
|
||||
# rocketchat | channel | #channel | # is required for private channels too
|
||||
# -------------------------------------------------------------------------------------------------------------------------------------
|
||||
# slack | channel name | general | Do not include the # symbol
|
||||
# | channel id | ID:C123456 | The underlying ID of a channel. This doesn't work with
|
||||
# | channel id | ID:C123456 | The underlying ID of a channel. This doesn't work with webhooks.
|
||||
# -------------------------------------------------------------------------------------------------------------------------------------
|
||||
# steam | chatid | example needed | The number in the URL when you click "enter chat room" in the browser
|
||||
# -------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
69
vendor/github.com/d5/tengo/v2/builtins.go
generated
vendored
69
vendor/github.com/d5/tengo/v2/builtins.go
generated
vendored
@@ -121,6 +121,10 @@ var builtinFuncs = []*BuiltinFunction{
|
||||
Name: "format",
|
||||
Value: builtinFormat,
|
||||
},
|
||||
{
|
||||
Name: "range",
|
||||
Value: builtinRange,
|
||||
},
|
||||
}
|
||||
|
||||
// GetAllBuiltinFunctions returns all builtin function objects.
|
||||
@@ -323,6 +327,71 @@ func builtinLen(args ...Object) (Object, error) {
|
||||
}
|
||||
}
|
||||
|
||||
//range(start, stop[, step])
|
||||
func builtinRange(args ...Object) (Object, error) {
|
||||
numArgs := len(args)
|
||||
if numArgs < 2 || numArgs > 3 {
|
||||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
var start, stop, step *Int
|
||||
|
||||
for i, arg := range args {
|
||||
v, ok := args[i].(*Int)
|
||||
if !ok {
|
||||
var name string
|
||||
switch i {
|
||||
case 0:
|
||||
name = "start"
|
||||
case 1:
|
||||
name = "stop"
|
||||
case 2:
|
||||
name = "step"
|
||||
}
|
||||
|
||||
return nil, ErrInvalidArgumentType{
|
||||
Name: name,
|
||||
Expected: "int",
|
||||
Found: arg.TypeName(),
|
||||
}
|
||||
}
|
||||
if i == 2 && v.Value <= 0 {
|
||||
return nil, ErrInvalidRangeStep
|
||||
}
|
||||
switch i {
|
||||
case 0:
|
||||
start = v
|
||||
case 1:
|
||||
stop = v
|
||||
case 2:
|
||||
step = v
|
||||
}
|
||||
}
|
||||
|
||||
if step == nil {
|
||||
step = &Int{Value: int64(1)}
|
||||
}
|
||||
|
||||
return buildRange(start.Value, stop.Value, step.Value), nil
|
||||
}
|
||||
|
||||
func buildRange(start, stop, step int64) *Array {
|
||||
array := &Array{}
|
||||
if start <= stop {
|
||||
for i := start; i < stop; i += step {
|
||||
array.Value = append(array.Value, &Int{
|
||||
Value: i,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
for i := start; i > stop; i -= step {
|
||||
array.Value = append(array.Value, &Int{
|
||||
Value: i,
|
||||
})
|
||||
}
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
func builtinFormat(args ...Object) (Object, error) {
|
||||
numArgs := len(args)
|
||||
if numArgs == 0 {
|
||||
|
||||
3
vendor/github.com/d5/tengo/v2/errors.go
generated
vendored
3
vendor/github.com/d5/tengo/v2/errors.go
generated
vendored
@@ -49,6 +49,9 @@ var (
|
||||
// ErrNotImplemented is an error where an Object has not implemented a
|
||||
// required method.
|
||||
ErrNotImplemented = errors.New("not implemented")
|
||||
|
||||
// ErrInvalidRangeStep is an error where the step parameter is less than or equal to 0 when using builtin range function.
|
||||
ErrInvalidRangeStep = errors.New("range step must be greater than 0")
|
||||
)
|
||||
|
||||
// ErrInvalidArgumentType represents an invalid argument value type error.
|
||||
|
||||
12
vendor/github.com/gomarkdown/markdown/README.md
generated
vendored
12
vendor/github.com/gomarkdown/markdown/README.md
generated
vendored
@@ -207,6 +207,18 @@ implements the following extensions:
|
||||
Total | 50
|
||||
```
|
||||
|
||||
A cell spanning multiple columns (colspan) is supported, just repeat the pipe symbol:
|
||||
|
||||
```
|
||||
Name | Age
|
||||
--------|------
|
||||
Bob ||
|
||||
Alice | 23
|
||||
========|======
|
||||
Total | 23
|
||||
```
|
||||
|
||||
|
||||
- **Fenced code blocks**. In addition to the normal 4-space
|
||||
indentation to mark code blocks, you can explicitly mark them
|
||||
and supply a language (to make syntax highlighting simple). Just
|
||||
|
||||
1
vendor/github.com/gomarkdown/markdown/ast/node.go
generated
vendored
1
vendor/github.com/gomarkdown/markdown/ast/node.go
generated
vendored
@@ -340,6 +340,7 @@ type TableCell struct {
|
||||
|
||||
IsHeader bool // This tells if it's under the header row
|
||||
Align CellAlignFlags // This holds the value for align attribute
|
||||
ColSpan int // How many columns to span
|
||||
}
|
||||
|
||||
// TableHeader represents markdown table head node
|
||||
|
||||
3
vendor/github.com/gomarkdown/markdown/html/renderer.go
generated
vendored
3
vendor/github.com/gomarkdown/markdown/html/renderer.go
generated
vendored
@@ -952,6 +952,9 @@ func (r *Renderer) TableCell(w io.Writer, tableCell *ast.TableCell, entering boo
|
||||
if align != "" {
|
||||
attrs = append(attrs, fmt.Sprintf(`align="%s"`, align))
|
||||
}
|
||||
if colspan := tableCell.ColSpan; colspan > 0 {
|
||||
attrs = append(attrs, fmt.Sprintf(`colspan="%d"`, colspan))
|
||||
}
|
||||
if ast.GetPrevNode(tableCell) == nil {
|
||||
r.CR(w)
|
||||
}
|
||||
|
||||
31
vendor/github.com/gomarkdown/markdown/parser/block.go
generated
vendored
31
vendor/github.com/gomarkdown/markdown/parser/block.go
generated
vendored
@@ -1204,7 +1204,9 @@ func (p *Parser) tableRow(data []byte, columns []ast.CellAlignFlags, header bool
|
||||
}
|
||||
|
||||
n := len(data)
|
||||
colspans := 0 // keep track of total colspan in this row.
|
||||
for col = 0; col < len(columns) && i < n; col++ {
|
||||
colspan := 0
|
||||
for i < n && data[i] == ' ' {
|
||||
i++
|
||||
}
|
||||
@@ -1218,7 +1220,15 @@ func (p *Parser) tableRow(data []byte, columns []ast.CellAlignFlags, header bool
|
||||
cellEnd := i
|
||||
|
||||
// skip the end-of-cell marker, possibly taking us past end of buffer
|
||||
i++
|
||||
// each _extra_ | means a colspan
|
||||
for data[i] == '|' && !isBackslashEscaped(data, i) {
|
||||
i++
|
||||
colspan++
|
||||
}
|
||||
// only colspan > 1 make sense.
|
||||
if colspan < 2 {
|
||||
colspan = 0
|
||||
}
|
||||
|
||||
for cellEnd > cellStart && cellEnd-1 < n && data[cellEnd-1] == ' ' {
|
||||
cellEnd--
|
||||
@@ -1227,9 +1237,19 @@ func (p *Parser) tableRow(data []byte, columns []ast.CellAlignFlags, header bool
|
||||
block := &ast.TableCell{
|
||||
IsHeader: header,
|
||||
Align: columns[col],
|
||||
ColSpan: colspan,
|
||||
}
|
||||
block.Content = data[cellStart:cellEnd]
|
||||
p.addBlock(block)
|
||||
if cellStart == cellEnd && colspans > 0 {
|
||||
// an empty cell that we should ignore, it exists because of colspan
|
||||
colspans--
|
||||
} else {
|
||||
p.addBlock(block)
|
||||
}
|
||||
|
||||
if colspan > 0 {
|
||||
colspans += colspan - 1
|
||||
}
|
||||
}
|
||||
|
||||
// pad it out with empty columns to get the right number
|
||||
@@ -1247,7 +1267,12 @@ func (p *Parser) tableRow(data []byte, columns []ast.CellAlignFlags, header bool
|
||||
// tableFooter parses the (optional) table footer.
|
||||
func (p *Parser) tableFooter(data []byte) bool {
|
||||
colCount := 1
|
||||
for i := 0; i < len(data) && data[i] != '\n'; i++ {
|
||||
i := 0
|
||||
n := len(data)
|
||||
for i < 3 && i < n && data[i] == ' ' { // ignore up to 3 spaces
|
||||
i++
|
||||
}
|
||||
for ; i < n && data[i] != '\n'; i++ {
|
||||
if data[i] == '|' && !isBackslashEscaped(data, i) {
|
||||
colCount++
|
||||
continue
|
||||
|
||||
3
vendor/github.com/google/gops/agent/agent.go
generated
vendored
3
vendor/github.com/google/gops/agent/agent.go
generated
vendored
@@ -16,6 +16,7 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
gosignal "os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"runtime/pprof"
|
||||
@@ -113,7 +114,7 @@ func Listen(opts Options) error {
|
||||
return err
|
||||
}
|
||||
port := listener.Addr().(*net.TCPAddr).Port
|
||||
portfile = fmt.Sprintf("%s/%d", gopsdir, os.Getpid())
|
||||
portfile = filepath.Join(gopsdir, strconv.Itoa(os.Getpid()))
|
||||
err = ioutil.WriteFile(portfile, []byte(strconv.Itoa(port)), os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -3,19 +3,19 @@ Emoji is a simple golang package.
|
||||
|
||||
[](https://app.wercker.com/project/byKey/7bef60de2c6d3e0e6c13d56b2393c5d8)
|
||||
[](https://coveralls.io/r/kyokomi/emoji?branch=master)
|
||||
[](https://godoc.org/github.com/kyokomi/emoji)
|
||||
[](https://pkg.go.dev/github.com/kyokomi/emoji/v2)
|
||||
|
||||
Get it:
|
||||
|
||||
```
|
||||
go get github.com/kyokomi/emoji
|
||||
go get github.com/kyokomi/emoji/v2
|
||||
```
|
||||
|
||||
Import it:
|
||||
|
||||
```
|
||||
import (
|
||||
"github.com/kyokomi/emoji"
|
||||
"github.com/kyokomi/emoji/v2"
|
||||
)
|
||||
```
|
||||
|
||||
@@ -27,7 +27,7 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kyokomi/emoji"
|
||||
"github.com/kyokomi/emoji/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -46,7 +46,7 @@ func main() {
|
||||
|
||||
## Reference
|
||||
|
||||
- [GitHub EMOJI CHEAT SHEET](http://www.emoji-cheat-sheet.com/)
|
||||
- [unicode Emoji Charts](http://www.unicode.org/emoji/charts/emoji-list.html)
|
||||
|
||||
## License
|
||||
|
||||
@@ -10,23 +10,47 @@ import (
|
||||
"unicode"
|
||||
)
|
||||
|
||||
//go:generate generateEmojiCodeMap -pkg emoji
|
||||
//go:generate generateEmojiCodeMap -pkg emoji -o emoji_codemap.go
|
||||
|
||||
// Replace Padding character for emoji.
|
||||
const (
|
||||
ReplacePadding = ""
|
||||
var (
|
||||
ReplacePadding = " "
|
||||
)
|
||||
|
||||
// CodeMap gets the underlying map of emoji.
|
||||
func CodeMap() map[string]string {
|
||||
return emojiCodeMap
|
||||
return emojiCode()
|
||||
}
|
||||
|
||||
// RevCodeMap gets the underlying map of emoji.
|
||||
func RevCodeMap() map[string][]string {
|
||||
return emojiRevCode()
|
||||
}
|
||||
|
||||
func AliasList(shortCode string) []string {
|
||||
return emojiRevCode()[emojiCode()[shortCode]]
|
||||
}
|
||||
|
||||
// HasAlias flags if the given `shortCode` has multiple aliases with other
|
||||
// codes.
|
||||
func HasAlias(shortCode string) bool {
|
||||
return len(AliasList(shortCode)) > 1
|
||||
}
|
||||
|
||||
// NormalizeShortCode normalizes a given `shortCode` to a deterministic alias.
|
||||
func NormalizeShortCode(shortCode string) string {
|
||||
shortLists := AliasList(shortCode)
|
||||
if len(shortLists) == 0 {
|
||||
return shortCode
|
||||
}
|
||||
return shortLists[0]
|
||||
}
|
||||
|
||||
// regular expression that matches :flag-[countrycode]:
|
||||
var flagRegexp = regexp.MustCompile(":flag-([a-z]{2}):")
|
||||
|
||||
func emojize(x string) string {
|
||||
str, ok := emojiCodeMap[x]
|
||||
str, ok := emojiCode()[x]
|
||||
if ok {
|
||||
return str + ReplacePadding
|
||||
}
|
||||
@@ -99,7 +123,7 @@ func Println(a ...interface{}) (int, error) {
|
||||
|
||||
// Printf is fmt.Printf which supports emoji
|
||||
func Printf(format string, a ...interface{}) (int, error) {
|
||||
return fmt.Printf(compile(fmt.Sprintf(format, a...)))
|
||||
return fmt.Print(compile(fmt.Sprintf(format, a...)))
|
||||
}
|
||||
|
||||
// Fprint is fmt.Fprint which supports emoji
|
||||
7715
vendor/github.com/kyokomi/emoji/v2/emoji_codemap.go
generated
vendored
Normal file
7715
vendor/github.com/kyokomi/emoji/v2/emoji_codemap.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
vendor/github.com/kyokomi/emoji/v2/go.mod
generated
vendored
Normal file
3
vendor/github.com/kyokomi/emoji/v2/go.mod
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module github.com/kyokomi/emoji/v2
|
||||
|
||||
go 1.14
|
||||
@@ -3,9 +3,13 @@ build:
|
||||
steps:
|
||||
- setup-go-workspace
|
||||
- script:
|
||||
name: install goveralls
|
||||
name: go version
|
||||
code: go version
|
||||
- script:
|
||||
name: install tools
|
||||
code: |
|
||||
go get github.com/mattn/goveralls
|
||||
GO111MODULE=on go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
- script:
|
||||
name: go get
|
||||
code: |
|
||||
@@ -14,6 +18,10 @@ build:
|
||||
name: go build
|
||||
code: |
|
||||
go build ./...
|
||||
- script:
|
||||
name: golangci-lint
|
||||
code: |
|
||||
golangci-lint run
|
||||
- script:
|
||||
name: go test
|
||||
code: |
|
||||
1
vendor/github.com/labstack/echo/v4/.gitignore
generated
vendored
1
vendor/github.com/labstack/echo/v4/.gitignore
generated
vendored
@@ -5,3 +5,4 @@ vendor
|
||||
.idea
|
||||
*.iml
|
||||
*.out
|
||||
.vscode
|
||||
|
||||
4
vendor/github.com/labstack/echo/v4/.travis.yml
generated
vendored
4
vendor/github.com/labstack/echo/v4/.travis.yml
generated
vendored
@@ -1,3 +1,7 @@
|
||||
arch:
|
||||
- amd64
|
||||
- ppc64le
|
||||
|
||||
language: go
|
||||
go:
|
||||
- 1.14.x
|
||||
|
||||
95
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
Normal file
95
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
# Changelog
|
||||
|
||||
## v4.2.1 - 2020-03-08
|
||||
|
||||
**Important notes**
|
||||
|
||||
Due to a datarace the config parameters for the newly added timeout middleware required a change.
|
||||
See the [docs](https://echo.labstack.com/middleware/timeout).
|
||||
A performance regression has been fixed, even bringing better performance than before for some routing scenarios.
|
||||
|
||||
**Fixes**
|
||||
|
||||
* Fix performance regression caused by path escaping (#1777, #1798, #1799, aldas)
|
||||
* Avoid context canceled errors (#1789, clwluvw)
|
||||
* Improve router to use on stack backtracking (#1791, aldas, stffabi)
|
||||
* Fix panic in timeout middleware not being not recovered and cause application crash (#1794, aldas)
|
||||
* Fix Echo.Serve() not serving on HTTP port correctly when TLSListener is used (#1785, #1793, aldas)
|
||||
* Apply go fmt (#1788, Le0tk0k)
|
||||
* Uses strings.Equalfold (#1790, rkilingr)
|
||||
* Improve code quality (#1792, withshubh)
|
||||
|
||||
This release was made possible by our **contributors**:
|
||||
aldas, clwluvw, lammel, Le0tk0k, maciej-jezierski, rkilingr, stffabi, withshubh
|
||||
|
||||
## v4.2.0 - 2020-02-11
|
||||
|
||||
**Important notes**
|
||||
|
||||
The behaviour for binding data has been reworked for compatibility with echo before v4.1.11 by
|
||||
enforcing `explicit tagging` for processing parameters. This **may break** your code if you
|
||||
expect combined handling of query/path/form params.
|
||||
Please see the updated documentation for [request](https://echo.labstack.com/guide/request) and [binding](https://echo.labstack.com/guide/request)
|
||||
|
||||
The handling for rewrite rules has been slightly adjusted to expand `*` to a non-greedy `(.*?)` capture group. This is only relevant if multiple asterisks are used in your rules.
|
||||
Please see [rewrite](https://echo.labstack.com/middleware/rewrite) and [proxy](https://echo.labstack.com/middleware/proxy) for details.
|
||||
|
||||
**Security**
|
||||
|
||||
* Fix directory traversal vulnerability for Windows (#1718, little-cui)
|
||||
* Fix open redirect vulnerability with trailing slash (#1771,#1775 aldas,GeoffreyFrogeye)
|
||||
|
||||
**Enhancements**
|
||||
|
||||
* Add Echo#ListenerNetwork as configuration (#1667, pafuent)
|
||||
* Add ability to change the status code using response beforeFuncs (#1706, RashadAnsari)
|
||||
* Echo server startup to allow data race free access to listener address
|
||||
* Binder: Restore pre v4.1.11 behaviour for c.Bind() to use query params only for GET or DELETE methods (#1727, aldas)
|
||||
* Binder: Add separate methods to bind only query params, path params or request body (#1681, aldas)
|
||||
* Binder: New fluent binder for query/path/form parameter binding (#1717, #1736, aldas)
|
||||
* Router: Performance improvements for missed routes (#1689, pafuent)
|
||||
* Router: Improve performance for Real-IP detection using IndexByte instead of Split (#1640, imxyb)
|
||||
* Middleware: Support real regex rules for rewrite and proxy middleware (#1767)
|
||||
* Middleware: New rate limiting middleware (#1724, iambenkay)
|
||||
* Middleware: New timeout middleware implementation for go1.13+ (#1743, )
|
||||
* Middleware: Allow regex pattern for CORS middleware (#1623, KlotzAndrew)
|
||||
* Middleware: Add IgnoreBase parameter to static middleware (#1701, lnenad, iambenkay)
|
||||
* Middleware: Add an optional custom function to CORS middleware to validate origin (#1651, curvegrid)
|
||||
* Middleware: Support form fields in JWT middleware (#1704, rkfg)
|
||||
* Middleware: Use sync.Pool for (de)compress middleware to improve performance (#1699, #1672, pafuent)
|
||||
* Middleware: Add decompress middleware to support gzip compressed requests (#1687, arun0009)
|
||||
* Middleware: Add ErrJWTInvalid for JWT middleware (#1627, juanbelieni)
|
||||
* Middleware: Add SameSite mode for CSRF cookies to support iframes (#1524, pr0head)
|
||||
|
||||
**Fixes**
|
||||
|
||||
* Fix handling of special trailing slash case for partial prefix (#1741, stffabi)
|
||||
* Fix handling of static routes with trailing slash (#1747)
|
||||
* Fix Static files route not working (#1671, pwli0755, lammel)
|
||||
* Fix use of caret(^) in regex for rewrite middleware (#1588, chotow)
|
||||
* Fix Echo#Reverse for Any type routes (#1695, pafuent)
|
||||
* Fix Router#Find panic with infinite loop (#1661, pafuent)
|
||||
* Fix Router#Find panic fails on Param paths (#1659, pafuent)
|
||||
* Fix DefaultHTTPErrorHandler with Debug=true (#1477, lammel)
|
||||
* Fix incorrect CORS headers (#1669, ulasakdeniz)
|
||||
* Fix proxy middleware rewritePath to use url with updated tests (#1630, arun0009)
|
||||
* Fix rewritePath for proxy middleware to use escaped path in (#1628, arun0009)
|
||||
* Remove unless defer (#1656, imxyb)
|
||||
|
||||
**General**
|
||||
|
||||
* New maintainers for Echo: Roland Lammel (@lammel) and Pablo Andres Fuente (@pafuent)
|
||||
* Add GitHub action to compare benchmarks (#1702, pafuent)
|
||||
* Binding query/path params and form fields to struct only works for explicit tags (#1729,#1734, aldas)
|
||||
* Add support for Go 1.15 in CI (#1683, asahasrabuddhe)
|
||||
* Add test for request id to remain unchanged if provided (#1719, iambenkay)
|
||||
* Refactor echo instance listener access and startup to speed up testing (#1735, aldas)
|
||||
* Refactor and improve various tests for binding and routing
|
||||
* Run test workflow only for relevant changes (#1637, #1636, pofl)
|
||||
* Update .travis.yml (#1662, santosh653)
|
||||
* Update README.md with an recents framework benchmark (#1679, pafuent)
|
||||
|
||||
This release was made possible by **over 100 commits** from more than **20 contributors**:
|
||||
asahasrabuddhe, aldas, AndrewKlotz, arun0009, chotow, curvegrid, iambenkay, imxyb,
|
||||
juanbelieni, lammel, little-cui, lnenad, pafuent, pofl, pr0head, pwli, RashadAnsari,
|
||||
rkfg, santosh653, segfiner, stffabi, ulasakdeniz
|
||||
31
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
31
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
@@ -1,3 +1,34 @@
|
||||
PKG := "github.com/labstack/echo"
|
||||
PKG_LIST := $(shell go list ${PKG}/...)
|
||||
|
||||
tag:
|
||||
@git tag `grep -P '^\tversion = ' echo.go|cut -f2 -d'"'`
|
||||
@git tag|grep -v ^v
|
||||
|
||||
.DEFAULT_GOAL := check
|
||||
check: lint vet race ## Check project
|
||||
|
||||
init:
|
||||
@go get -u golang.org/x/lint/golint
|
||||
|
||||
lint: ## Lint the files
|
||||
@golint -set_exit_status ${PKG_LIST}
|
||||
|
||||
vet: ## Vet the files
|
||||
@go vet ${PKG_LIST}
|
||||
|
||||
test: ## Run tests
|
||||
@go test -short ${PKG_LIST}
|
||||
|
||||
race: ## Run tests with data race detector
|
||||
@go test -race ${PKG_LIST}
|
||||
|
||||
benchmark: ## Run benchmarks
|
||||
@go test -run="-" -bench=".*" ${PKG_LIST}
|
||||
|
||||
help: ## Display this help screen
|
||||
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
goversion ?= "1.15"
|
||||
test_version: ## Run tests inside Docker with given version (defaults to 1.15 oldest supported). Example: make test_version goversion=1.15
|
||||
@docker run --rm -it -v $(shell pwd):/project golang:$(goversion) /bin/sh -c "cd /project && make init check"
|
||||
|
||||
13
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
13
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
@@ -1,12 +1,12 @@
|
||||
<a href="https://echo.labstack.com"><img height="80" src="https://cdn.labstack.com/images/echo-logo.svg"></a>
|
||||
|
||||
[](https://sourcegraph.com/github.com/labstack/echo?badge)
|
||||
[](http://godoc.org/github.com/labstack/echo)
|
||||
[](https://pkg.go.dev/github.com/labstack/echo/v4)
|
||||
[](https://goreportcard.com/report/github.com/labstack/echo)
|
||||
[](https://travis-ci.org/labstack/echo)
|
||||
[](https://codecov.io/gh/labstack/echo)
|
||||
[](https://gitter.im/labstack/echo)
|
||||
[](https://forum.labstack.com)
|
||||
[](https://github.com/labstack/echo/discussions)
|
||||
[](https://twitter.com/labstack)
|
||||
[](https://raw.githubusercontent.com/labstack/echo/master/LICENSE)
|
||||
|
||||
@@ -42,11 +42,14 @@ For older versions, please use the latest v3 tag.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Date: 2018/03/15<br>
|
||||
Date: 2020/11/11<br>
|
||||
Source: https://github.com/vishr/web-framework-benchmark<br>
|
||||
Lower is better!
|
||||
|
||||
<img src="https://i.imgur.com/I32VdMJ.png">
|
||||
<img src="https://i.imgur.com/qwPNQbl.png">
|
||||
<img src="https://i.imgur.com/s8yKQjx.png">
|
||||
|
||||
The benchmarks above were run on an Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
|
||||
|
||||
## [Guide](https://echo.labstack.com/guide)
|
||||
|
||||
@@ -91,7 +94,7 @@ func hello(c echo.Context) error {
|
||||
|
||||
## Help
|
||||
|
||||
- [Forum](https://forum.labstack.com)
|
||||
- [Forum](https://github.com/labstack/echo/discussions)
|
||||
- [Chat](https://gitter.im/labstack/echo)
|
||||
|
||||
## Contribute
|
||||
|
||||
61
vendor/github.com/labstack/echo/v4/bind.go
generated
vendored
61
vendor/github.com/labstack/echo/v4/bind.go
generated
vendored
@@ -30,10 +30,8 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
// Bind implements the `Binder#Bind` function.
|
||||
func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
|
||||
req := c.Request()
|
||||
|
||||
// BindPathParams binds path params to bindable object
|
||||
func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error {
|
||||
names := c.ParamNames()
|
||||
values := c.ParamValues()
|
||||
params := map[string][]string{}
|
||||
@@ -43,12 +41,28 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
|
||||
if err := b.bindData(i, params, "param"); err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
if err = b.bindData(i, c.QueryParams(), "query"); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// BindQueryParams binds query params to bindable object
|
||||
func (b *DefaultBinder) BindQueryParams(c Context, i interface{}) error {
|
||||
if err := b.bindData(i, c.QueryParams(), "query"); err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BindBody binds request body contents to bindable object
|
||||
// NB: then binding forms take note that this implementation uses standard library form parsing
|
||||
// which parses form data from BOTH URL and BODY if content type is not MIMEMultipartForm
|
||||
// See non-MIMEMultipartForm: https://golang.org/pkg/net/http/#Request.ParseForm
|
||||
// See MIMEMultipartForm: https://golang.org/pkg/net/http/#Request.ParseMultipartForm
|
||||
func (b *DefaultBinder) BindBody(c Context, i interface{}) (err error) {
|
||||
req := c.Request()
|
||||
if req.ContentLength == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
ctype := req.Header.Get(HeaderContentType)
|
||||
switch {
|
||||
case strings.HasPrefix(ctype, MIMEApplicationJSON):
|
||||
@@ -80,15 +94,35 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
|
||||
default:
|
||||
return ErrUnsupportedMediaType
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag string) error {
|
||||
if ptr == nil || len(data) == 0 {
|
||||
// Bind implements the `Binder#Bind` function.
|
||||
// Binding is done in following order: 1) path params; 2) query params; 3) request body. Each step COULD override previous
|
||||
// step binded values. For single source binding use their own methods BindBody, BindQueryParams, BindPathParams.
|
||||
func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
|
||||
if err := b.BindPathParams(c, i); err != nil {
|
||||
return err
|
||||
}
|
||||
// Issue #1670 - Query params are binded only for GET/DELETE and NOT for usual request with body (POST/PUT/PATCH)
|
||||
// Reasoning here is that parameters in query and bind destination struct could have UNEXPECTED matches and results due that.
|
||||
// i.e. is `&id=1&lang=en` from URL same as `{"id":100,"lang":"de"}` request body and which one should have priority when binding.
|
||||
// This HTTP method check restores pre v4.1.11 behavior and avoids different problems when query is mixed with body
|
||||
if c.Request().Method == http.MethodGet || c.Request().Method == http.MethodDelete {
|
||||
if err = b.BindQueryParams(c, i); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return b.BindBody(c, i)
|
||||
}
|
||||
|
||||
// bindData will bind data ONLY fields in destination struct that have EXPLICIT tag
|
||||
func (b *DefaultBinder) bindData(destination interface{}, data map[string][]string, tag string) error {
|
||||
if destination == nil || len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
typ := reflect.TypeOf(ptr).Elem()
|
||||
val := reflect.ValueOf(ptr).Elem()
|
||||
typ := reflect.TypeOf(destination).Elem()
|
||||
val := reflect.ValueOf(destination).Elem()
|
||||
|
||||
// Map
|
||||
if typ.Kind() == reflect.Map {
|
||||
@@ -113,14 +147,15 @@ func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag
|
||||
inputFieldName := typeField.Tag.Get(tag)
|
||||
|
||||
if inputFieldName == "" {
|
||||
inputFieldName = typeField.Name
|
||||
// If tag is nil, we inspect if the field is a struct.
|
||||
// If tag is nil, we inspect if the field is a not BindUnmarshaler struct and try to bind data into it (might contains fields with tags).
|
||||
// structs that implement BindUnmarshaler are binded only when they have explicit tag
|
||||
if _, ok := structField.Addr().Interface().(BindUnmarshaler); !ok && structFieldKind == reflect.Struct {
|
||||
if err := b.bindData(structField.Addr().Interface(), data, tag); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
// does not have explicit tag and is not an ordinary struct - so move to next field
|
||||
continue
|
||||
}
|
||||
|
||||
inputValue, exists := data[inputFieldName]
|
||||
|
||||
1230
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
Normal file
1230
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
11
vendor/github.com/labstack/echo/v4/codecov.yml
generated
vendored
Normal file
11
vendor/github.com/labstack/echo/v4/codecov.yml
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
threshold: 1%
|
||||
patch:
|
||||
default:
|
||||
threshold: 1%
|
||||
|
||||
comment:
|
||||
require_changes: true
|
||||
34
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
34
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
@@ -246,7 +246,7 @@ func (c *context) IsTLS() bool {
|
||||
|
||||
func (c *context) IsWebSocket() bool {
|
||||
upgrade := c.request.Header.Get(HeaderUpgrade)
|
||||
return strings.ToLower(upgrade) == "websocket"
|
||||
return strings.EqualFold(upgrade, "websocket")
|
||||
}
|
||||
|
||||
func (c *context) Scheme() string {
|
||||
@@ -276,7 +276,11 @@ func (c *context) RealIP() string {
|
||||
}
|
||||
// Fall back to legacy behavior
|
||||
if ip := c.request.Header.Get(HeaderXForwardedFor); ip != "" {
|
||||
return strings.Split(ip, ", ")[0]
|
||||
i := strings.IndexAny(ip, ", ")
|
||||
if i > 0 {
|
||||
return ip[:i]
|
||||
}
|
||||
return ip
|
||||
}
|
||||
if ip := c.request.Header.Get(HeaderXRealIP); ip != "" {
|
||||
return ip
|
||||
@@ -310,7 +314,19 @@ func (c *context) ParamNames() []string {
|
||||
|
||||
func (c *context) SetParamNames(names ...string) {
|
||||
c.pnames = names
|
||||
*c.echo.maxParam = len(names)
|
||||
|
||||
l := len(names)
|
||||
if *c.echo.maxParam < l {
|
||||
*c.echo.maxParam = l
|
||||
}
|
||||
|
||||
if len(c.pvalues) < l {
|
||||
// Keeping the old pvalues just for backward compatibility, but it sounds that doesn't make sense to keep them,
|
||||
// probably those values will be overriden in a Context#SetParamValues
|
||||
newPvalues := make([]string, l)
|
||||
copy(newPvalues, c.pvalues)
|
||||
c.pvalues = newPvalues
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) ParamValues() []string {
|
||||
@@ -318,7 +334,15 @@ func (c *context) ParamValues() []string {
|
||||
}
|
||||
|
||||
func (c *context) SetParamValues(values ...string) {
|
||||
c.pvalues = values
|
||||
// NOTE: Don't just set c.pvalues = values, because it has to have length c.echo.maxParam at all times
|
||||
// It will brake the Router#Find code
|
||||
limit := len(values)
|
||||
if limit > *c.echo.maxParam {
|
||||
limit = *c.echo.maxParam
|
||||
}
|
||||
for i := 0; i < limit; i++ {
|
||||
c.pvalues[i] = values[i]
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) QueryParam(name string) string {
|
||||
@@ -361,7 +385,7 @@ func (c *context) FormFile(name string) (*multipart.FileHeader, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
f.Close()
|
||||
return fh, nil
|
||||
}
|
||||
|
||||
|
||||
135
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
135
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
@@ -49,7 +49,6 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
@@ -68,6 +67,9 @@ type (
|
||||
// Echo is the top-level framework instance.
|
||||
Echo struct {
|
||||
common
|
||||
// startupMutex is mutex to lock Echo instance access during server configuration and startup. Useful for to get
|
||||
// listener address info (on which interface/port was listener binded) without having data races.
|
||||
startupMutex sync.RWMutex
|
||||
StdLogger *stdLog.Logger
|
||||
colorer *color.Color
|
||||
premiddleware []MiddlewareFunc
|
||||
@@ -92,6 +94,7 @@ type (
|
||||
Renderer Renderer
|
||||
Logger Logger
|
||||
IPExtractor IPExtractor
|
||||
ListenerNetwork string
|
||||
}
|
||||
|
||||
// Route contains a handler and information for matching against requests.
|
||||
@@ -231,7 +234,7 @@ const (
|
||||
|
||||
const (
|
||||
// Version of Echo
|
||||
Version = "4.1.17"
|
||||
Version = "4.2.1"
|
||||
website = "https://echo.labstack.com"
|
||||
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
||||
banner = `
|
||||
@@ -281,6 +284,7 @@ var (
|
||||
ErrInvalidRedirectCode = errors.New("invalid redirect status code")
|
||||
ErrCookieNotFound = errors.New("cookie not found")
|
||||
ErrInvalidCertOrKeyType = errors.New("invalid cert or key type, must be string or []byte")
|
||||
ErrInvalidListenerNetwork = errors.New("invalid listener network")
|
||||
)
|
||||
|
||||
// Error handlers
|
||||
@@ -302,9 +306,10 @@ func New() (e *Echo) {
|
||||
AutoTLSManager: autocert.Manager{
|
||||
Prompt: autocert.AcceptTOS,
|
||||
},
|
||||
Logger: log.New("echo"),
|
||||
colorer: color.New(),
|
||||
maxParam: new(int),
|
||||
Logger: log.New("echo"),
|
||||
colorer: color.New(),
|
||||
maxParam: new(int),
|
||||
ListenerNetwork: "tcp",
|
||||
}
|
||||
e.Server.Handler = e
|
||||
e.TLSServer.Handler = e
|
||||
@@ -362,10 +367,12 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
|
||||
// Issue #1426
|
||||
code := he.Code
|
||||
message := he.Message
|
||||
if e.Debug {
|
||||
message = err.Error()
|
||||
} else if m, ok := message.(string); ok {
|
||||
message = Map{"message": m}
|
||||
if m, ok := he.Message.(string); ok {
|
||||
if e.Debug {
|
||||
message = Map{"message": m, "error": err.Error()}
|
||||
} else {
|
||||
message = Map{"message": m}
|
||||
}
|
||||
}
|
||||
|
||||
// Send response
|
||||
@@ -481,7 +488,7 @@ func (common) static(prefix, root string, get func(string, HandlerFunc, ...Middl
|
||||
return err
|
||||
}
|
||||
|
||||
name := filepath.Join(root, path.Clean("/"+p)) // "/"+ for security
|
||||
name := filepath.Join(root, filepath.Clean("/"+p)) // "/"+ for security
|
||||
fi, err := os.Stat(name)
|
||||
if err != nil {
|
||||
// The access path does not exist
|
||||
@@ -496,8 +503,15 @@ func (common) static(prefix, root string, get func(string, HandlerFunc, ...Middl
|
||||
}
|
||||
return c.File(name)
|
||||
}
|
||||
if prefix == "/" {
|
||||
return get(prefix+"*", h)
|
||||
// Handle added routes based on trailing slash:
|
||||
// /prefix => exact route "/prefix" + any route "/prefix/*"
|
||||
// /prefix/ => only any route "/prefix/*"
|
||||
if prefix != "" {
|
||||
if prefix[len(prefix)-1] == '/' {
|
||||
// Only add any route for intentional trailing slash
|
||||
return get(prefix+"*", h)
|
||||
}
|
||||
get(prefix, h)
|
||||
}
|
||||
return get(prefix+"/*", h)
|
||||
}
|
||||
@@ -570,7 +584,7 @@ func (e *Echo) Reverse(name string, params ...interface{}) string {
|
||||
for _, r := range e.router.routes {
|
||||
if r.Name == name {
|
||||
for i, l := 0, len(r.Path); i < l; i++ {
|
||||
if r.Path[i] == ':' && n < ln {
|
||||
if (r.Path[i] == ':' || r.Path[i] == '*') && n < ln {
|
||||
for ; i < l && r.Path[i] != '/'; i++ {
|
||||
}
|
||||
uri.WriteString(fmt.Sprintf("%v", params[n]))
|
||||
@@ -612,7 +626,6 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Acquire context
|
||||
c := e.pool.Get().(*context)
|
||||
c.Reset(r, w)
|
||||
|
||||
h := NotFoundHandler
|
||||
|
||||
if e.premiddleware == nil {
|
||||
@@ -640,21 +653,30 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Start starts an HTTP server.
|
||||
func (e *Echo) Start(address string) error {
|
||||
e.startupMutex.Lock()
|
||||
e.Server.Addr = address
|
||||
return e.StartServer(e.Server)
|
||||
if err := e.configureServer(e.Server); err != nil {
|
||||
e.startupMutex.Unlock()
|
||||
return err
|
||||
}
|
||||
e.startupMutex.Unlock()
|
||||
return e.Server.Serve(e.Listener)
|
||||
}
|
||||
|
||||
// StartTLS starts an HTTPS server.
|
||||
// If `certFile` or `keyFile` is `string` the values are treated as file paths.
|
||||
// If `certFile` or `keyFile` is `[]byte` the values are treated as the certificate or key as-is.
|
||||
func (e *Echo) StartTLS(address string, certFile, keyFile interface{}) (err error) {
|
||||
e.startupMutex.Lock()
|
||||
var cert []byte
|
||||
if cert, err = filepathOrContent(certFile); err != nil {
|
||||
e.startupMutex.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
var key []byte
|
||||
if key, err = filepathOrContent(keyFile); err != nil {
|
||||
e.startupMutex.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -662,10 +684,17 @@ func (e *Echo) StartTLS(address string, certFile, keyFile interface{}) (err erro
|
||||
s.TLSConfig = new(tls.Config)
|
||||
s.TLSConfig.Certificates = make([]tls.Certificate, 1)
|
||||
if s.TLSConfig.Certificates[0], err = tls.X509KeyPair(cert, key); err != nil {
|
||||
e.startupMutex.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
return e.startTLS(address)
|
||||
e.configureTLS(address)
|
||||
if err := e.configureServer(s); err != nil {
|
||||
e.startupMutex.Unlock()
|
||||
return err
|
||||
}
|
||||
e.startupMutex.Unlock()
|
||||
return s.Serve(e.TLSListener)
|
||||
}
|
||||
|
||||
func filepathOrContent(fileOrContent interface{}) (content []byte, err error) {
|
||||
@@ -681,24 +710,45 @@ func filepathOrContent(fileOrContent interface{}) (content []byte, err error) {
|
||||
|
||||
// StartAutoTLS starts an HTTPS server using certificates automatically installed from https://letsencrypt.org.
|
||||
func (e *Echo) StartAutoTLS(address string) error {
|
||||
e.startupMutex.Lock()
|
||||
s := e.TLSServer
|
||||
s.TLSConfig = new(tls.Config)
|
||||
s.TLSConfig.GetCertificate = e.AutoTLSManager.GetCertificate
|
||||
s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, acme.ALPNProto)
|
||||
return e.startTLS(address)
|
||||
|
||||
e.configureTLS(address)
|
||||
if err := e.configureServer(s); err != nil {
|
||||
e.startupMutex.Unlock()
|
||||
return err
|
||||
}
|
||||
e.startupMutex.Unlock()
|
||||
return s.Serve(e.TLSListener)
|
||||
}
|
||||
|
||||
func (e *Echo) startTLS(address string) error {
|
||||
func (e *Echo) configureTLS(address string) {
|
||||
s := e.TLSServer
|
||||
s.Addr = address
|
||||
if !e.DisableHTTP2 {
|
||||
s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "h2")
|
||||
}
|
||||
return e.StartServer(e.TLSServer)
|
||||
}
|
||||
|
||||
// StartServer starts a custom http server.
|
||||
func (e *Echo) StartServer(s *http.Server) (err error) {
|
||||
e.startupMutex.Lock()
|
||||
if err := e.configureServer(s); err != nil {
|
||||
e.startupMutex.Unlock()
|
||||
return err
|
||||
}
|
||||
if s.TLSConfig != nil {
|
||||
e.startupMutex.Unlock()
|
||||
return s.Serve(e.TLSListener)
|
||||
}
|
||||
e.startupMutex.Unlock()
|
||||
return s.Serve(e.Listener)
|
||||
}
|
||||
|
||||
func (e *Echo) configureServer(s *http.Server) (err error) {
|
||||
// Setup
|
||||
e.colorer.SetOutput(e.Logger.Output())
|
||||
s.ErrorLog = e.StdLogger
|
||||
@@ -713,7 +763,7 @@ func (e *Echo) StartServer(s *http.Server) (err error) {
|
||||
|
||||
if s.TLSConfig == nil {
|
||||
if e.Listener == nil {
|
||||
e.Listener, err = newListener(s.Addr)
|
||||
e.Listener, err = newListener(s.Addr, e.ListenerNetwork)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -721,10 +771,10 @@ func (e *Echo) StartServer(s *http.Server) (err error) {
|
||||
if !e.HidePort {
|
||||
e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
||||
}
|
||||
return s.Serve(e.Listener)
|
||||
return nil
|
||||
}
|
||||
if e.TLSListener == nil {
|
||||
l, err := newListener(s.Addr)
|
||||
l, err := newListener(s.Addr, e.ListenerNetwork)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -733,11 +783,32 @@ func (e *Echo) StartServer(s *http.Server) (err error) {
|
||||
if !e.HidePort {
|
||||
e.colorer.Printf("⇨ https server started on %s\n", e.colorer.Green(e.TLSListener.Addr()))
|
||||
}
|
||||
return s.Serve(e.TLSListener)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListenerAddr returns net.Addr for Listener
|
||||
func (e *Echo) ListenerAddr() net.Addr {
|
||||
e.startupMutex.RLock()
|
||||
defer e.startupMutex.RUnlock()
|
||||
if e.Listener == nil {
|
||||
return nil
|
||||
}
|
||||
return e.Listener.Addr()
|
||||
}
|
||||
|
||||
// TLSListenerAddr returns net.Addr for TLSListener
|
||||
func (e *Echo) TLSListenerAddr() net.Addr {
|
||||
e.startupMutex.RLock()
|
||||
defer e.startupMutex.RUnlock()
|
||||
if e.TLSListener == nil {
|
||||
return nil
|
||||
}
|
||||
return e.TLSListener.Addr()
|
||||
}
|
||||
|
||||
// StartH2CServer starts a custom http/2 server with h2c (HTTP/2 Cleartext).
|
||||
func (e *Echo) StartH2CServer(address string, h2s *http2.Server) (err error) {
|
||||
e.startupMutex.Lock()
|
||||
// Setup
|
||||
s := e.Server
|
||||
s.Addr = address
|
||||
@@ -753,20 +824,24 @@ func (e *Echo) StartH2CServer(address string, h2s *http2.Server) (err error) {
|
||||
}
|
||||
|
||||
if e.Listener == nil {
|
||||
e.Listener, err = newListener(s.Addr)
|
||||
e.Listener, err = newListener(s.Addr, e.ListenerNetwork)
|
||||
if err != nil {
|
||||
e.startupMutex.Unlock()
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !e.HidePort {
|
||||
e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
||||
}
|
||||
e.startupMutex.Unlock()
|
||||
return s.Serve(e.Listener)
|
||||
}
|
||||
|
||||
// Close immediately stops the server.
|
||||
// It internally calls `http.Server#Close()`.
|
||||
func (e *Echo) Close() error {
|
||||
e.startupMutex.Lock()
|
||||
defer e.startupMutex.Unlock()
|
||||
if err := e.TLSServer.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -776,6 +851,8 @@ func (e *Echo) Close() error {
|
||||
// Shutdown stops the server gracefully.
|
||||
// It internally calls `http.Server#Shutdown()`.
|
||||
func (e *Echo) Shutdown(ctx stdContext.Context) error {
|
||||
e.startupMutex.Lock()
|
||||
defer e.startupMutex.Unlock()
|
||||
if err := e.TLSServer.Shutdown(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -833,6 +910,9 @@ func WrapMiddleware(m func(http.Handler) http.Handler) MiddlewareFunc {
|
||||
}
|
||||
|
||||
// GetPath returns RawPath, if it's empty returns Path from URL
|
||||
// Difference between RawPath and Path is:
|
||||
// * Path is where request path is stored. Value is stored in decoded form: /%47%6f%2f becomes /Go/.
|
||||
// * RawPath is an optional field which only gets set if the default encoding is different from Path.
|
||||
func GetPath(r *http.Request) string {
|
||||
path := r.URL.RawPath
|
||||
if path == "" {
|
||||
@@ -883,8 +963,11 @@ func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func newListener(address string) (*tcpKeepAliveListener, error) {
|
||||
l, err := net.Listen("tcp", address)
|
||||
func newListener(address, network string) (*tcpKeepAliveListener, error) {
|
||||
if network != "tcp" && network != "tcp4" && network != "tcp6" {
|
||||
return nil, ErrInvalidListenerNetwork
|
||||
}
|
||||
l, err := net.Listen(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
1
vendor/github.com/labstack/echo/v4/go.mod
generated
vendored
1
vendor/github.com/labstack/echo/v4/go.mod
generated
vendored
@@ -12,4 +12,5 @@ require (
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202
|
||||
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6 // indirect
|
||||
golang.org/x/text v0.3.3 // indirect
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324
|
||||
)
|
||||
|
||||
2
vendor/github.com/labstack/echo/v4/go.sum
generated
vendored
2
vendor/github.com/labstack/echo/v4/go.sum
generated
vendored
@@ -46,6 +46,8 @@ 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.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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=
|
||||
|
||||
2
vendor/github.com/labstack/echo/v4/middleware/basic_auth.go
generated
vendored
2
vendor/github.com/labstack/echo/v4/middleware/basic_auth.go
generated
vendored
@@ -73,7 +73,7 @@ func BasicAuthWithConfig(config BasicAuthConfig) echo.MiddlewareFunc {
|
||||
auth := c.Request().Header.Get(echo.HeaderAuthorization)
|
||||
l := len(basic)
|
||||
|
||||
if len(auth) > l+1 && strings.ToLower(auth[:l]) == basic {
|
||||
if len(auth) > l+1 && strings.EqualFold(auth[:l], basic) {
|
||||
b, err := base64.StdEncoding.DecodeString(auth[l+1:])
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
26
vendor/github.com/labstack/echo/v4/middleware/compress.go
generated
vendored
26
vendor/github.com/labstack/echo/v4/middleware/compress.go
generated
vendored
@@ -8,6 +8,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
@@ -58,6 +59,8 @@ func GzipWithConfig(config GzipConfig) echo.MiddlewareFunc {
|
||||
config.Level = DefaultGzipConfig.Level
|
||||
}
|
||||
|
||||
pool := gzipCompressPool(config)
|
||||
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
if config.Skipper(c) {
|
||||
@@ -68,11 +71,13 @@ func GzipWithConfig(config GzipConfig) echo.MiddlewareFunc {
|
||||
res.Header().Add(echo.HeaderVary, echo.HeaderAcceptEncoding)
|
||||
if strings.Contains(c.Request().Header.Get(echo.HeaderAcceptEncoding), gzipScheme) {
|
||||
res.Header().Set(echo.HeaderContentEncoding, gzipScheme) // Issue #806
|
||||
rw := res.Writer
|
||||
w, err := gzip.NewWriterLevel(rw, config.Level)
|
||||
if err != nil {
|
||||
return err
|
||||
i := pool.Get()
|
||||
w, ok := i.(*gzip.Writer)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, i.(error).Error())
|
||||
}
|
||||
rw := res.Writer
|
||||
w.Reset(rw)
|
||||
defer func() {
|
||||
if res.Size == 0 {
|
||||
if res.Header().Get(echo.HeaderContentEncoding) == gzipScheme {
|
||||
@@ -85,6 +90,7 @@ func GzipWithConfig(config GzipConfig) echo.MiddlewareFunc {
|
||||
w.Reset(ioutil.Discard)
|
||||
}
|
||||
w.Close()
|
||||
pool.Put(w)
|
||||
}()
|
||||
grw := &gzipResponseWriter{Writer: w, ResponseWriter: rw}
|
||||
res.Writer = grw
|
||||
@@ -126,3 +132,15 @@ func (w *gzipResponseWriter) Push(target string, opts *http.PushOptions) error {
|
||||
}
|
||||
return http.ErrNotSupported
|
||||
}
|
||||
|
||||
func gzipCompressPool(config GzipConfig) sync.Pool {
|
||||
return sync.Pool{
|
||||
New: func() interface{} {
|
||||
w, err := gzip.NewWriterLevel(ioutil.Discard, config.Level)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return w
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
90
vendor/github.com/labstack/echo/v4/middleware/cors.go
generated
vendored
90
vendor/github.com/labstack/echo/v4/middleware/cors.go
generated
vendored
@@ -2,6 +2,7 @@ package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -18,6 +19,13 @@ type (
|
||||
// Optional. Default value []string{"*"}.
|
||||
AllowOrigins []string `yaml:"allow_origins"`
|
||||
|
||||
// AllowOriginFunc is a custom function to validate the origin. It takes the
|
||||
// origin as an argument and returns true if allowed or false otherwise. If
|
||||
// an error is returned, it is returned by the handler. If this option is
|
||||
// set, AllowOrigins is ignored.
|
||||
// Optional.
|
||||
AllowOriginFunc func(origin string) (bool, error) `yaml:"allow_origin_func"`
|
||||
|
||||
// AllowMethods defines a list methods allowed when accessing the resource.
|
||||
// This is used in response to a preflight request.
|
||||
// Optional. Default value DefaultCORSConfig.AllowMethods.
|
||||
@@ -76,6 +84,15 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
||||
config.AllowMethods = DefaultCORSConfig.AllowMethods
|
||||
}
|
||||
|
||||
allowOriginPatterns := []string{}
|
||||
for _, origin := range config.AllowOrigins {
|
||||
pattern := regexp.QuoteMeta(origin)
|
||||
pattern = strings.Replace(pattern, "\\*", ".*", -1)
|
||||
pattern = strings.Replace(pattern, "\\?", ".", -1)
|
||||
pattern = "^" + pattern + "$"
|
||||
allowOriginPatterns = append(allowOriginPatterns, pattern)
|
||||
}
|
||||
|
||||
allowMethods := strings.Join(config.AllowMethods, ",")
|
||||
allowHeaders := strings.Join(config.AllowHeaders, ",")
|
||||
exposeHeaders := strings.Join(config.ExposeHeaders, ",")
|
||||
@@ -92,25 +109,73 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
||||
origin := req.Header.Get(echo.HeaderOrigin)
|
||||
allowOrigin := ""
|
||||
|
||||
// Check allowed origins
|
||||
for _, o := range config.AllowOrigins {
|
||||
if o == "*" && config.AllowCredentials {
|
||||
allowOrigin = origin
|
||||
break
|
||||
preflight := req.Method == http.MethodOptions
|
||||
res.Header().Add(echo.HeaderVary, echo.HeaderOrigin)
|
||||
|
||||
// No Origin provided
|
||||
if origin == "" {
|
||||
if !preflight {
|
||||
return next(c)
|
||||
}
|
||||
if o == "*" || o == origin {
|
||||
allowOrigin = o
|
||||
break
|
||||
return c.NoContent(http.StatusNoContent)
|
||||
}
|
||||
|
||||
if config.AllowOriginFunc != nil {
|
||||
allowed, err := config.AllowOriginFunc(origin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if matchSubdomain(origin, o) {
|
||||
if allowed {
|
||||
allowOrigin = origin
|
||||
break
|
||||
}
|
||||
} else {
|
||||
// Check allowed origins
|
||||
for _, o := range config.AllowOrigins {
|
||||
if o == "*" && config.AllowCredentials {
|
||||
allowOrigin = origin
|
||||
break
|
||||
}
|
||||
if o == "*" || o == origin {
|
||||
allowOrigin = o
|
||||
break
|
||||
}
|
||||
if matchSubdomain(origin, o) {
|
||||
allowOrigin = origin
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Check allowed origin patterns
|
||||
for _, re := range allowOriginPatterns {
|
||||
if allowOrigin == "" {
|
||||
didx := strings.Index(origin, "://")
|
||||
if didx == -1 {
|
||||
continue
|
||||
}
|
||||
domAuth := origin[didx+3:]
|
||||
// to avoid regex cost by invalid long domain
|
||||
if len(domAuth) > 253 {
|
||||
break
|
||||
}
|
||||
|
||||
if match, _ := regexp.MatchString(re, origin); match {
|
||||
allowOrigin = origin
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Origin not allowed
|
||||
if allowOrigin == "" {
|
||||
if !preflight {
|
||||
return next(c)
|
||||
}
|
||||
return c.NoContent(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// Simple request
|
||||
if req.Method != http.MethodOptions {
|
||||
res.Header().Add(echo.HeaderVary, echo.HeaderOrigin)
|
||||
if !preflight {
|
||||
res.Header().Set(echo.HeaderAccessControlAllowOrigin, allowOrigin)
|
||||
if config.AllowCredentials {
|
||||
res.Header().Set(echo.HeaderAccessControlAllowCredentials, "true")
|
||||
@@ -122,7 +187,6 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
||||
}
|
||||
|
||||
// Preflight request
|
||||
res.Header().Add(echo.HeaderVary, echo.HeaderOrigin)
|
||||
res.Header().Add(echo.HeaderVary, echo.HeaderAccessControlRequestMethod)
|
||||
res.Header().Add(echo.HeaderVary, echo.HeaderAccessControlRequestHeaders)
|
||||
res.Header().Set(echo.HeaderAccessControlAllowOrigin, allowOrigin)
|
||||
|
||||
23
vendor/github.com/labstack/echo/v4/middleware/csrf.go
generated
vendored
23
vendor/github.com/labstack/echo/v4/middleware/csrf.go
generated
vendored
@@ -57,6 +57,10 @@ type (
|
||||
// Indicates if CSRF cookie is HTTP only.
|
||||
// Optional. Default value false.
|
||||
CookieHTTPOnly bool `yaml:"cookie_http_only"`
|
||||
|
||||
// Indicates SameSite mode of the CSRF cookie.
|
||||
// Optional. Default value SameSiteDefaultMode.
|
||||
CookieSameSite http.SameSite `yaml:"cookie_same_site"`
|
||||
}
|
||||
|
||||
// csrfTokenExtractor defines a function that takes `echo.Context` and returns
|
||||
@@ -67,12 +71,13 @@ type (
|
||||
var (
|
||||
// DefaultCSRFConfig is the default CSRF middleware config.
|
||||
DefaultCSRFConfig = CSRFConfig{
|
||||
Skipper: DefaultSkipper,
|
||||
TokenLength: 32,
|
||||
TokenLookup: "header:" + echo.HeaderXCSRFToken,
|
||||
ContextKey: "csrf",
|
||||
CookieName: "_csrf",
|
||||
CookieMaxAge: 86400,
|
||||
Skipper: DefaultSkipper,
|
||||
TokenLength: 32,
|
||||
TokenLookup: "header:" + echo.HeaderXCSRFToken,
|
||||
ContextKey: "csrf",
|
||||
CookieName: "_csrf",
|
||||
CookieMaxAge: 86400,
|
||||
CookieSameSite: http.SameSiteDefaultMode,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -105,6 +110,9 @@ func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc {
|
||||
if config.CookieMaxAge == 0 {
|
||||
config.CookieMaxAge = DefaultCSRFConfig.CookieMaxAge
|
||||
}
|
||||
if config.CookieSameSite == SameSiteNoneMode {
|
||||
config.CookieSecure = true
|
||||
}
|
||||
|
||||
// Initialize
|
||||
parts := strings.Split(config.TokenLookup, ":")
|
||||
@@ -157,6 +165,9 @@ func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc {
|
||||
if config.CookieDomain != "" {
|
||||
cookie.Domain = config.CookieDomain
|
||||
}
|
||||
if config.CookieSameSite != http.SameSiteDefaultMode {
|
||||
cookie.SameSite = config.CookieSameSite
|
||||
}
|
||||
cookie.Expires = time.Now().Add(time.Duration(config.CookieMaxAge) * time.Second)
|
||||
cookie.Secure = config.CookieSecure
|
||||
cookie.HttpOnly = config.CookieHTTPOnly
|
||||
|
||||
12
vendor/github.com/labstack/echo/v4/middleware/csrf_samesite.go
generated
vendored
Normal file
12
vendor/github.com/labstack/echo/v4/middleware/csrf_samesite.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// +build go1.13
|
||||
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
// SameSiteNoneMode required to be redefined for Go 1.12 support (see #1524)
|
||||
SameSiteNoneMode http.SameSite = http.SameSiteNoneMode
|
||||
)
|
||||
12
vendor/github.com/labstack/echo/v4/middleware/csrf_samesite_1.12.go
generated
vendored
Normal file
12
vendor/github.com/labstack/echo/v4/middleware/csrf_samesite_1.12.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// +build !go1.13
|
||||
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
// SameSiteNoneMode required to be redefined for Go 1.12 support (see #1524)
|
||||
SameSiteNoneMode http.SameSite = 4
|
||||
)
|
||||
120
vendor/github.com/labstack/echo/v4/middleware/decompress.go
generated
vendored
Normal file
120
vendor/github.com/labstack/echo/v4/middleware/decompress.go
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
type (
|
||||
// DecompressConfig defines the config for Decompress middleware.
|
||||
DecompressConfig struct {
|
||||
// Skipper defines a function to skip middleware.
|
||||
Skipper Skipper
|
||||
|
||||
// GzipDecompressPool defines an interface to provide the sync.Pool used to create/store Gzip readers
|
||||
GzipDecompressPool Decompressor
|
||||
}
|
||||
)
|
||||
|
||||
//GZIPEncoding content-encoding header if set to "gzip", decompress body contents.
|
||||
const GZIPEncoding string = "gzip"
|
||||
|
||||
// Decompressor is used to get the sync.Pool used by the middleware to get Gzip readers
|
||||
type Decompressor interface {
|
||||
gzipDecompressPool() sync.Pool
|
||||
}
|
||||
|
||||
var (
|
||||
//DefaultDecompressConfig defines the config for decompress middleware
|
||||
DefaultDecompressConfig = DecompressConfig{
|
||||
Skipper: DefaultSkipper,
|
||||
GzipDecompressPool: &DefaultGzipDecompressPool{},
|
||||
}
|
||||
)
|
||||
|
||||
// DefaultGzipDecompressPool is the default implementation of Decompressor interface
|
||||
type DefaultGzipDecompressPool struct {
|
||||
}
|
||||
|
||||
func (d *DefaultGzipDecompressPool) gzipDecompressPool() sync.Pool {
|
||||
return sync.Pool{
|
||||
New: func() interface{} {
|
||||
// create with an empty reader (but with GZIP header)
|
||||
w, err := gzip.NewWriterLevel(ioutil.Discard, gzip.BestSpeed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
w.Reset(b)
|
||||
w.Flush()
|
||||
w.Close()
|
||||
|
||||
r, err := gzip.NewReader(bytes.NewReader(b.Bytes()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//Decompress decompresses request body based if content encoding type is set to "gzip" with default config
|
||||
func Decompress() echo.MiddlewareFunc {
|
||||
return DecompressWithConfig(DefaultDecompressConfig)
|
||||
}
|
||||
|
||||
//DecompressWithConfig decompresses request body based if content encoding type is set to "gzip" with config
|
||||
func DecompressWithConfig(config DecompressConfig) echo.MiddlewareFunc {
|
||||
// Defaults
|
||||
if config.Skipper == nil {
|
||||
config.Skipper = DefaultGzipConfig.Skipper
|
||||
}
|
||||
if config.GzipDecompressPool == nil {
|
||||
config.GzipDecompressPool = DefaultDecompressConfig.GzipDecompressPool
|
||||
}
|
||||
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
pool := config.GzipDecompressPool.gzipDecompressPool()
|
||||
return func(c echo.Context) error {
|
||||
if config.Skipper(c) {
|
||||
return next(c)
|
||||
}
|
||||
switch c.Request().Header.Get(echo.HeaderContentEncoding) {
|
||||
case GZIPEncoding:
|
||||
b := c.Request().Body
|
||||
|
||||
i := pool.Get()
|
||||
gr, ok := i.(*gzip.Reader)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, i.(error).Error())
|
||||
}
|
||||
|
||||
if err := gr.Reset(b); err != nil {
|
||||
pool.Put(gr)
|
||||
if err == io.EOF { //ignore if body is empty
|
||||
return next(c)
|
||||
}
|
||||
return err
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
io.Copy(&buf, gr)
|
||||
|
||||
gr.Close()
|
||||
pool.Put(gr)
|
||||
|
||||
b.Close() // http.Request.Body is closed by the Server, but because we are replacing it, it must be closed here
|
||||
|
||||
r := ioutil.NopCloser(&buf)
|
||||
c.Request().Body = r
|
||||
}
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
19
vendor/github.com/labstack/echo/v4/middleware/jwt.go
generated
vendored
19
vendor/github.com/labstack/echo/v4/middleware/jwt.go
generated
vendored
@@ -57,6 +57,7 @@ type (
|
||||
// - "query:<name>"
|
||||
// - "param:<name>"
|
||||
// - "cookie:<name>"
|
||||
// - "form:<name>"
|
||||
TokenLookup string
|
||||
|
||||
// AuthScheme to be used in the Authorization header.
|
||||
@@ -86,6 +87,7 @@ const (
|
||||
// Errors
|
||||
var (
|
||||
ErrJWTMissing = echo.NewHTTPError(http.StatusBadRequest, "missing or malformed jwt")
|
||||
ErrJWTInvalid = echo.NewHTTPError(http.StatusUnauthorized, "invalid or expired jwt")
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -166,6 +168,8 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
|
||||
extractor = jwtFromParam(parts[1])
|
||||
case "cookie":
|
||||
extractor = jwtFromCookie(parts[1])
|
||||
case "form":
|
||||
extractor = jwtFromForm(parts[1])
|
||||
}
|
||||
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
@@ -213,8 +217,8 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
|
||||
return config.ErrorHandlerWithContext(err, c)
|
||||
}
|
||||
return &echo.HTTPError{
|
||||
Code: http.StatusUnauthorized,
|
||||
Message: "invalid or expired jwt",
|
||||
Code: ErrJWTInvalid.Code,
|
||||
Message: ErrJWTInvalid.Message,
|
||||
Internal: err,
|
||||
}
|
||||
}
|
||||
@@ -265,3 +269,14 @@ func jwtFromCookie(name string) jwtExtractor {
|
||||
return cookie.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
// jwtFromForm returns a `jwtExtractor` that extracts token from the form field.
|
||||
func jwtFromForm(name string) jwtExtractor {
|
||||
return func(c echo.Context) (string, error) {
|
||||
field := c.FormValue(name)
|
||||
if field == "" {
|
||||
return "", ErrJWTMissing
|
||||
}
|
||||
return field, nil
|
||||
}
|
||||
}
|
||||
|
||||
43
vendor/github.com/labstack/echo/v4/middleware/middleware.go
generated
vendored
43
vendor/github.com/labstack/echo/v4/middleware/middleware.go
generated
vendored
@@ -1,6 +1,8 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -32,6 +34,47 @@ func captureTokens(pattern *regexp.Regexp, input string) *strings.Replacer {
|
||||
return strings.NewReplacer(replace...)
|
||||
}
|
||||
|
||||
func rewriteRulesRegex(rewrite map[string]string) map[*regexp.Regexp]string {
|
||||
// Initialize
|
||||
rulesRegex := map[*regexp.Regexp]string{}
|
||||
for k, v := range rewrite {
|
||||
k = regexp.QuoteMeta(k)
|
||||
k = strings.Replace(k, `\*`, "(.*?)", -1)
|
||||
if strings.HasPrefix(k, `\^`) {
|
||||
k = strings.Replace(k, `\^`, "^", -1)
|
||||
}
|
||||
k = k + "$"
|
||||
rulesRegex[regexp.MustCompile(k)] = v
|
||||
}
|
||||
return rulesRegex
|
||||
}
|
||||
|
||||
func rewritePath(rewriteRegex map[*regexp.Regexp]string, req *http.Request) {
|
||||
for k, v := range rewriteRegex {
|
||||
rawPath := req.URL.RawPath
|
||||
if rawPath != "" {
|
||||
// RawPath is only set when there has been escaping done. In that case Path must be deduced from rewritten RawPath
|
||||
// because encoded Path could match rules that RawPath did not
|
||||
if replacer := captureTokens(k, rawPath); replacer != nil {
|
||||
rawPath = replacer.Replace(v)
|
||||
|
||||
req.URL.RawPath = rawPath
|
||||
req.URL.Path, _ = url.PathUnescape(rawPath)
|
||||
|
||||
return // rewrite only once
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if replacer := captureTokens(k, req.URL.Path); replacer != nil {
|
||||
req.URL.Path = replacer.Replace(v)
|
||||
|
||||
return // rewrite only once
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultSkipper returns false which processes the middleware.
|
||||
func DefaultSkipper(echo.Context) bool {
|
||||
return false
|
||||
|
||||
31
vendor/github.com/labstack/echo/v4/middleware/proxy.go
generated
vendored
31
vendor/github.com/labstack/echo/v4/middleware/proxy.go
generated
vendored
@@ -8,7 +8,6 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@@ -37,6 +36,13 @@ type (
|
||||
// "/users/*/orders/*": "/user/$1/order/$2",
|
||||
Rewrite map[string]string
|
||||
|
||||
// RegexRewrite defines rewrite rules using regexp.Rexexp with captures
|
||||
// Every capture group in the values can be retrieved by index e.g. $1, $2 and so on.
|
||||
// Example:
|
||||
// "^/old/[0.9]+/": "/new",
|
||||
// "^/api/.+?/(.*)": "/v2/$1",
|
||||
RegexRewrite map[*regexp.Regexp]string
|
||||
|
||||
// Context key to store selected ProxyTarget into context.
|
||||
// Optional. Default value "target".
|
||||
ContextKey string
|
||||
@@ -47,8 +53,6 @@ type (
|
||||
|
||||
// ModifyResponse defines function to modify response from ProxyTarget.
|
||||
ModifyResponse func(*http.Response) error
|
||||
|
||||
rewriteRegex map[*regexp.Regexp]string
|
||||
}
|
||||
|
||||
// ProxyTarget defines the upstream target.
|
||||
@@ -206,12 +210,14 @@ func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc {
|
||||
if config.Balancer == nil {
|
||||
panic("echo: proxy middleware requires balancer")
|
||||
}
|
||||
config.rewriteRegex = map[*regexp.Regexp]string{}
|
||||
|
||||
// Initialize
|
||||
for k, v := range config.Rewrite {
|
||||
k = strings.Replace(k, "*", "(\\S*)", -1)
|
||||
config.rewriteRegex[regexp.MustCompile(k)] = v
|
||||
if config.Rewrite != nil {
|
||||
if config.RegexRewrite == nil {
|
||||
config.RegexRewrite = make(map[*regexp.Regexp]string)
|
||||
}
|
||||
for k, v := range rewriteRulesRegex(config.Rewrite) {
|
||||
config.RegexRewrite[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
@@ -225,13 +231,8 @@ func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc {
|
||||
tgt := config.Balancer.Next(c)
|
||||
c.Set(config.ContextKey, tgt)
|
||||
|
||||
// Rewrite
|
||||
for k, v := range config.rewriteRegex {
|
||||
replacer := captureTokens(k, echo.GetPath(req))
|
||||
if replacer != nil {
|
||||
req.URL.Path = replacer.Replace(v)
|
||||
}
|
||||
}
|
||||
// Set rewrite path and raw path
|
||||
rewritePath(config.RegexRewrite, req)
|
||||
|
||||
// Fix header
|
||||
// Basically it's not good practice to unconditionally pass incoming x-real-ip header to upstream.
|
||||
|
||||
24
vendor/github.com/labstack/echo/v4/middleware/proxy_1_11.go
generated
vendored
24
vendor/github.com/labstack/echo/v4/middleware/proxy_1_11.go
generated
vendored
@@ -3,13 +3,22 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"strings"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
// StatusCodeContextCanceled is a custom HTTP status code for situations
|
||||
// where a client unexpectedly closed the connection to the server.
|
||||
// As there is no standard error code for "client closed connection", but
|
||||
// various well-known HTTP clients and server implement this HTTP code we use
|
||||
// 499 too instead of the more problematic 5xx, which does not allow to detect this situation
|
||||
const StatusCodeContextCanceled = 499
|
||||
|
||||
func proxyHTTP(tgt *ProxyTarget, c echo.Context, config ProxyConfig) http.Handler {
|
||||
proxy := httputil.NewSingleHostReverseProxy(tgt.URL)
|
||||
proxy.ErrorHandler = func(resp http.ResponseWriter, req *http.Request, err error) {
|
||||
@@ -17,7 +26,20 @@ func proxyHTTP(tgt *ProxyTarget, c echo.Context, config ProxyConfig) http.Handle
|
||||
if tgt.Name != "" {
|
||||
desc = fmt.Sprintf("%s(%s)", tgt.Name, tgt.URL.String())
|
||||
}
|
||||
c.Set("_error", echo.NewHTTPError(http.StatusBadGateway, fmt.Sprintf("remote %s unreachable, could not forward: %v", desc, err)))
|
||||
// If the client canceled the request (usually by closing the connection), we can report a
|
||||
// client error (4xx) instead of a server error (5xx) to correctly identify the situation.
|
||||
// The Go standard library (at of late 2020) wraps the exported, standard
|
||||
// context.Canceled error with unexported garbage value requiring a substring check, see
|
||||
// https://github.com/golang/go/blob/6965b01ea248cabb70c3749fd218b36089a21efb/src/net/net.go#L416-L430
|
||||
if err == context.Canceled || strings.Contains(err.Error(), "operation was canceled") {
|
||||
httpError := echo.NewHTTPError(StatusCodeContextCanceled, fmt.Sprintf("client closed connection: %v", err))
|
||||
httpError.Internal = err
|
||||
c.Set("_error", httpError)
|
||||
} else {
|
||||
httpError := echo.NewHTTPError(http.StatusBadGateway, fmt.Sprintf("remote %s unreachable, could not forward: %v", desc, err))
|
||||
httpError.Internal = err
|
||||
c.Set("_error", httpError)
|
||||
}
|
||||
}
|
||||
proxy.Transport = config.Transport
|
||||
proxy.ModifyResponse = config.ModifyResponse
|
||||
|
||||
266
vendor/github.com/labstack/echo/v4/middleware/rate_limiter.go
generated
vendored
Normal file
266
vendor/github.com/labstack/echo/v4/middleware/rate_limiter.go
generated
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
type (
|
||||
// RateLimiterStore is the interface to be implemented by custom stores.
|
||||
RateLimiterStore interface {
|
||||
// Stores for the rate limiter have to implement the Allow method
|
||||
Allow(identifier string) (bool, error)
|
||||
}
|
||||
)
|
||||
|
||||
type (
|
||||
// RateLimiterConfig defines the configuration for the rate limiter
|
||||
RateLimiterConfig struct {
|
||||
Skipper Skipper
|
||||
BeforeFunc BeforeFunc
|
||||
// IdentifierExtractor uses echo.Context to extract the identifier for a visitor
|
||||
IdentifierExtractor Extractor
|
||||
// Store defines a store for the rate limiter
|
||||
Store RateLimiterStore
|
||||
// ErrorHandler provides a handler to be called when IdentifierExtractor returns an error
|
||||
ErrorHandler func(context echo.Context, err error) error
|
||||
// DenyHandler provides a handler to be called when RateLimiter denies access
|
||||
DenyHandler func(context echo.Context, identifier string, err error) error
|
||||
}
|
||||
// Extractor is used to extract data from echo.Context
|
||||
Extractor func(context echo.Context) (string, error)
|
||||
)
|
||||
|
||||
// errors
|
||||
var (
|
||||
// ErrRateLimitExceeded denotes an error raised when rate limit is exceeded
|
||||
ErrRateLimitExceeded = echo.NewHTTPError(http.StatusTooManyRequests, "rate limit exceeded")
|
||||
// ErrExtractorError denotes an error raised when extractor function is unsuccessful
|
||||
ErrExtractorError = echo.NewHTTPError(http.StatusForbidden, "error while extracting identifier")
|
||||
)
|
||||
|
||||
// DefaultRateLimiterConfig defines default values for RateLimiterConfig
|
||||
var DefaultRateLimiterConfig = RateLimiterConfig{
|
||||
Skipper: DefaultSkipper,
|
||||
IdentifierExtractor: func(ctx echo.Context) (string, error) {
|
||||
id := ctx.RealIP()
|
||||
return id, nil
|
||||
},
|
||||
ErrorHandler: func(context echo.Context, err error) error {
|
||||
return &echo.HTTPError{
|
||||
Code: ErrExtractorError.Code,
|
||||
Message: ErrExtractorError.Message,
|
||||
Internal: err,
|
||||
}
|
||||
},
|
||||
DenyHandler: func(context echo.Context, identifier string, err error) error {
|
||||
return &echo.HTTPError{
|
||||
Code: ErrRateLimitExceeded.Code,
|
||||
Message: ErrRateLimitExceeded.Message,
|
||||
Internal: err,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/*
|
||||
RateLimiter returns a rate limiting middleware
|
||||
|
||||
e := echo.New()
|
||||
|
||||
limiterStore := middleware.NewRateLimiterMemoryStore(20)
|
||||
|
||||
e.GET("/rate-limited", func(c echo.Context) error {
|
||||
return c.String(http.StatusOK, "test")
|
||||
}, RateLimiter(limiterStore))
|
||||
*/
|
||||
func RateLimiter(store RateLimiterStore) echo.MiddlewareFunc {
|
||||
config := DefaultRateLimiterConfig
|
||||
config.Store = store
|
||||
|
||||
return RateLimiterWithConfig(config)
|
||||
}
|
||||
|
||||
/*
|
||||
RateLimiterWithConfig returns a rate limiting middleware
|
||||
|
||||
e := echo.New()
|
||||
|
||||
config := middleware.RateLimiterConfig{
|
||||
Skipper: DefaultSkipper,
|
||||
Store: middleware.NewRateLimiterMemoryStore(
|
||||
middleware.RateLimiterMemoryStoreConfig{Rate: 10, Burst: 30, ExpiresIn: 3 * time.Minute}
|
||||
)
|
||||
IdentifierExtractor: func(ctx echo.Context) (string, error) {
|
||||
id := ctx.RealIP()
|
||||
return id, nil
|
||||
},
|
||||
ErrorHandler: func(context echo.Context, err error) error {
|
||||
return context.JSON(http.StatusTooManyRequests, nil)
|
||||
},
|
||||
DenyHandler: func(context echo.Context, identifier string) error {
|
||||
return context.JSON(http.StatusForbidden, nil)
|
||||
},
|
||||
}
|
||||
|
||||
e.GET("/rate-limited", func(c echo.Context) error {
|
||||
return c.String(http.StatusOK, "test")
|
||||
}, middleware.RateLimiterWithConfig(config))
|
||||
*/
|
||||
func RateLimiterWithConfig(config RateLimiterConfig) echo.MiddlewareFunc {
|
||||
if config.Skipper == nil {
|
||||
config.Skipper = DefaultRateLimiterConfig.Skipper
|
||||
}
|
||||
if config.IdentifierExtractor == nil {
|
||||
config.IdentifierExtractor = DefaultRateLimiterConfig.IdentifierExtractor
|
||||
}
|
||||
if config.ErrorHandler == nil {
|
||||
config.ErrorHandler = DefaultRateLimiterConfig.ErrorHandler
|
||||
}
|
||||
if config.DenyHandler == nil {
|
||||
config.DenyHandler = DefaultRateLimiterConfig.DenyHandler
|
||||
}
|
||||
if config.Store == nil {
|
||||
panic("Store configuration must be provided")
|
||||
}
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
if config.Skipper(c) {
|
||||
return next(c)
|
||||
}
|
||||
if config.BeforeFunc != nil {
|
||||
config.BeforeFunc(c)
|
||||
}
|
||||
|
||||
identifier, err := config.IdentifierExtractor(c)
|
||||
if err != nil {
|
||||
c.Error(config.ErrorHandler(c, err))
|
||||
return nil
|
||||
}
|
||||
|
||||
if allow, err := config.Store.Allow(identifier); !allow {
|
||||
c.Error(config.DenyHandler(c, identifier, err))
|
||||
return nil
|
||||
}
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
// RateLimiterMemoryStore is the built-in store implementation for RateLimiter
|
||||
RateLimiterMemoryStore struct {
|
||||
visitors map[string]*Visitor
|
||||
mutex sync.Mutex
|
||||
rate rate.Limit
|
||||
burst int
|
||||
expiresIn time.Duration
|
||||
lastCleanup time.Time
|
||||
}
|
||||
// Visitor signifies a unique user's limiter details
|
||||
Visitor struct {
|
||||
*rate.Limiter
|
||||
lastSeen time.Time
|
||||
}
|
||||
)
|
||||
|
||||
/*
|
||||
NewRateLimiterMemoryStore returns an instance of RateLimiterMemoryStore with
|
||||
the provided rate (as req/s). Burst and ExpiresIn will be set to default values.
|
||||
|
||||
Example (with 20 requests/sec):
|
||||
|
||||
limiterStore := middleware.NewRateLimiterMemoryStore(20)
|
||||
|
||||
*/
|
||||
func NewRateLimiterMemoryStore(rate rate.Limit) (store *RateLimiterMemoryStore) {
|
||||
return NewRateLimiterMemoryStoreWithConfig(RateLimiterMemoryStoreConfig{
|
||||
Rate: rate,
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
NewRateLimiterMemoryStoreWithConfig returns an instance of RateLimiterMemoryStore
|
||||
with the provided configuration. Rate must be provided. Burst will be set to the value of
|
||||
the configured rate if not provided or set to 0.
|
||||
|
||||
The build-in memory store is usually capable for modest loads. For higher loads other
|
||||
store implementations should be considered.
|
||||
|
||||
Characteristics:
|
||||
* Concurrency above 100 parallel requests may causes measurable lock contention
|
||||
* A high number of different IP addresses (above 16000) may be impacted by the internally used Go map
|
||||
* A high number of requests from a single IP address may cause lock contention
|
||||
|
||||
Example:
|
||||
|
||||
limiterStore := middleware.NewRateLimiterMemoryStoreWithConfig(
|
||||
middleware.RateLimiterMemoryStoreConfig{Rate: 50, Burst: 200, ExpiresIn: 5 * time.Minutes},
|
||||
)
|
||||
*/
|
||||
func NewRateLimiterMemoryStoreWithConfig(config RateLimiterMemoryStoreConfig) (store *RateLimiterMemoryStore) {
|
||||
store = &RateLimiterMemoryStore{}
|
||||
|
||||
store.rate = config.Rate
|
||||
store.burst = config.Burst
|
||||
store.expiresIn = config.ExpiresIn
|
||||
if config.ExpiresIn == 0 {
|
||||
store.expiresIn = DefaultRateLimiterMemoryStoreConfig.ExpiresIn
|
||||
}
|
||||
if config.Burst == 0 {
|
||||
store.burst = int(config.Rate)
|
||||
}
|
||||
store.visitors = make(map[string]*Visitor)
|
||||
store.lastCleanup = now()
|
||||
return
|
||||
}
|
||||
|
||||
// RateLimiterMemoryStoreConfig represents configuration for RateLimiterMemoryStore
|
||||
type RateLimiterMemoryStoreConfig struct {
|
||||
Rate rate.Limit // Rate of requests allowed to pass as req/s
|
||||
Burst int // Burst additionally allows a number of requests to pass when rate limit is reached
|
||||
ExpiresIn time.Duration // ExpiresIn is the duration after that a rate limiter is cleaned up
|
||||
}
|
||||
|
||||
// DefaultRateLimiterMemoryStoreConfig provides default configuration values for RateLimiterMemoryStore
|
||||
var DefaultRateLimiterMemoryStoreConfig = RateLimiterMemoryStoreConfig{
|
||||
ExpiresIn: 3 * time.Minute,
|
||||
}
|
||||
|
||||
// Allow implements RateLimiterStore.Allow
|
||||
func (store *RateLimiterMemoryStore) Allow(identifier string) (bool, error) {
|
||||
store.mutex.Lock()
|
||||
limiter, exists := store.visitors[identifier]
|
||||
if !exists {
|
||||
limiter = new(Visitor)
|
||||
limiter.Limiter = rate.NewLimiter(store.rate, store.burst)
|
||||
store.visitors[identifier] = limiter
|
||||
}
|
||||
limiter.lastSeen = now()
|
||||
if now().Sub(store.lastCleanup) > store.expiresIn {
|
||||
store.cleanupStaleVisitors()
|
||||
}
|
||||
store.mutex.Unlock()
|
||||
return limiter.AllowN(now(), 1), nil
|
||||
}
|
||||
|
||||
/*
|
||||
cleanupStaleVisitors helps manage the size of the visitors map by removing stale records
|
||||
of users who haven't visited again after the configured expiry time has elapsed
|
||||
*/
|
||||
func (store *RateLimiterMemoryStore) cleanupStaleVisitors() {
|
||||
for id, visitor := range store.visitors {
|
||||
if now().Sub(visitor.lastSeen) > store.expiresIn {
|
||||
delete(store.visitors, id)
|
||||
}
|
||||
}
|
||||
store.lastCleanup = now()
|
||||
}
|
||||
|
||||
/*
|
||||
actual time method which is mocked in test file
|
||||
*/
|
||||
var now = time.Now
|
||||
36
vendor/github.com/labstack/echo/v4/middleware/rewrite.go
generated
vendored
36
vendor/github.com/labstack/echo/v4/middleware/rewrite.go
generated
vendored
@@ -2,7 +2,6 @@ package middleware
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
@@ -23,7 +22,12 @@ type (
|
||||
// Required.
|
||||
Rules map[string]string `yaml:"rules"`
|
||||
|
||||
rulesRegex map[*regexp.Regexp]string
|
||||
// RegexRules defines the URL path rewrite rules using regexp.Rexexp with captures
|
||||
// Every capture group in the values can be retrieved by index e.g. $1, $2 and so on.
|
||||
// Example:
|
||||
// "^/old/[0.9]+/": "/new",
|
||||
// "^/api/.+?/(.*)": "/v2/$1",
|
||||
RegexRules map[*regexp.Regexp]string `yaml:"regex_rules"`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -47,20 +51,19 @@ func Rewrite(rules map[string]string) echo.MiddlewareFunc {
|
||||
// See: `Rewrite()`.
|
||||
func RewriteWithConfig(config RewriteConfig) echo.MiddlewareFunc {
|
||||
// Defaults
|
||||
if config.Rules == nil {
|
||||
panic("echo: rewrite middleware requires url path rewrite rules")
|
||||
if config.Rules == nil && config.RegexRules == nil {
|
||||
panic("echo: rewrite middleware requires url path rewrite rules or regex rules")
|
||||
}
|
||||
|
||||
if config.Skipper == nil {
|
||||
config.Skipper = DefaultBodyDumpConfig.Skipper
|
||||
}
|
||||
config.rulesRegex = map[*regexp.Regexp]string{}
|
||||
|
||||
// Initialize
|
||||
for k, v := range config.Rules {
|
||||
k = regexp.QuoteMeta(k)
|
||||
k = strings.Replace(k, `\*`, "(.*)", -1)
|
||||
k = k + "$"
|
||||
config.rulesRegex[regexp.MustCompile(k)] = v
|
||||
if config.RegexRules == nil {
|
||||
config.RegexRules = make(map[*regexp.Regexp]string)
|
||||
}
|
||||
for k, v := range rewriteRulesRegex(config.Rules) {
|
||||
config.RegexRules[k] = v
|
||||
}
|
||||
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
@@ -70,15 +73,8 @@ func RewriteWithConfig(config RewriteConfig) echo.MiddlewareFunc {
|
||||
}
|
||||
|
||||
req := c.Request()
|
||||
|
||||
// Rewrite
|
||||
for k, v := range config.rulesRegex {
|
||||
replacer := captureTokens(k, req.URL.Path)
|
||||
if replacer != nil {
|
||||
req.URL.Path = replacer.Replace(v)
|
||||
break
|
||||
}
|
||||
}
|
||||
// Set rewrite path and raw path
|
||||
rewritePath(config.RegexRules, req)
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
|
||||
13
vendor/github.com/labstack/echo/v4/middleware/slash.go
generated
vendored
13
vendor/github.com/labstack/echo/v4/middleware/slash.go
generated
vendored
@@ -60,7 +60,7 @@ func AddTrailingSlashWithConfig(config TrailingSlashConfig) echo.MiddlewareFunc
|
||||
|
||||
// Redirect
|
||||
if config.RedirectCode != 0 {
|
||||
return c.Redirect(config.RedirectCode, uri)
|
||||
return c.Redirect(config.RedirectCode, sanitizeURI(uri))
|
||||
}
|
||||
|
||||
// Forward
|
||||
@@ -108,7 +108,7 @@ func RemoveTrailingSlashWithConfig(config TrailingSlashConfig) echo.MiddlewareFu
|
||||
|
||||
// Redirect
|
||||
if config.RedirectCode != 0 {
|
||||
return c.Redirect(config.RedirectCode, uri)
|
||||
return c.Redirect(config.RedirectCode, sanitizeURI(uri))
|
||||
}
|
||||
|
||||
// Forward
|
||||
@@ -119,3 +119,12 @@ func RemoveTrailingSlashWithConfig(config TrailingSlashConfig) echo.MiddlewareFu
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sanitizeURI(uri string) string {
|
||||
// double slash `\\`, `//` or even `\/` is absolute uri for browsers and by redirecting request to that uri
|
||||
// we are vulnerable to open redirect attack. so replace all slashes from the beginning with single slash
|
||||
if len(uri) > 1 && (uri[0] == '\\' || uri[0] == '/') && (uri[1] == '\\' || uri[1] == '/') {
|
||||
uri = "/" + strings.TrimLeft(uri, `/\`)
|
||||
}
|
||||
return uri
|
||||
}
|
||||
|
||||
17
vendor/github.com/labstack/echo/v4/middleware/static.go
generated
vendored
17
vendor/github.com/labstack/echo/v4/middleware/static.go
generated
vendored
@@ -36,6 +36,12 @@ type (
|
||||
// Enable directory browsing.
|
||||
// Optional. Default value false.
|
||||
Browse bool `yaml:"browse"`
|
||||
|
||||
// Enable ignoring of the base of the URL path.
|
||||
// Example: when assigning a static middleware to a non root path group,
|
||||
// the filesystem path is not doubled
|
||||
// Optional. Default value false.
|
||||
IgnoreBase bool `yaml:"ignoreBase"`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -161,7 +167,16 @@ func StaticWithConfig(config StaticConfig) echo.MiddlewareFunc {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
name := filepath.Join(config.Root, path.Clean("/"+p)) // "/"+ for security
|
||||
name := filepath.Join(config.Root, filepath.Clean("/"+p)) // "/"+ for security
|
||||
|
||||
if config.IgnoreBase {
|
||||
routePath := path.Base(strings.TrimRight(c.Path(), "/*"))
|
||||
baseURLPath := path.Base(p)
|
||||
if baseURLPath == routePath {
|
||||
i := strings.LastIndex(name, routePath)
|
||||
name = name[:i] + strings.Replace(name[i:], routePath, "", 1)
|
||||
}
|
||||
}
|
||||
|
||||
fi, err := os.Stat(name)
|
||||
if err != nil {
|
||||
|
||||
111
vendor/github.com/labstack/echo/v4/middleware/timeout.go
generated
vendored
Normal file
111
vendor/github.com/labstack/echo/v4/middleware/timeout.go
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
// +build go1.13
|
||||
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
// TimeoutConfig defines the config for Timeout middleware.
|
||||
TimeoutConfig struct {
|
||||
// Skipper defines a function to skip middleware.
|
||||
Skipper Skipper
|
||||
|
||||
// ErrorMessage is written to response on timeout in addition to http.StatusServiceUnavailable (503) status code
|
||||
// It can be used to define a custom timeout error message
|
||||
ErrorMessage string
|
||||
|
||||
// OnTimeoutRouteErrorHandler is an error handler that is executed for error that was returned from wrapped route after
|
||||
// request timeouted and we already had sent the error code (503) and message response to the client.
|
||||
// NB: do not write headers/body inside this handler. The response has already been sent to the client and response writer
|
||||
// will not accept anything no more. If you want to know what actual route middleware timeouted use `c.Path()`
|
||||
OnTimeoutRouteErrorHandler func(err error, c echo.Context)
|
||||
|
||||
// Timeout configures a timeout for the middleware, defaults to 0 for no timeout
|
||||
// NOTE: when difference between timeout duration and handler execution time is almost the same (in range of 100microseconds)
|
||||
// the result of timeout does not seem to be reliable - could respond timeout, could respond handler output
|
||||
// difference over 500microseconds (0.5millisecond) response seems to be reliable
|
||||
Timeout time.Duration
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultTimeoutConfig is the default Timeout middleware config.
|
||||
DefaultTimeoutConfig = TimeoutConfig{
|
||||
Skipper: DefaultSkipper,
|
||||
Timeout: 0,
|
||||
ErrorMessage: "",
|
||||
}
|
||||
)
|
||||
|
||||
// Timeout returns a middleware which recovers from panics anywhere in the chain
|
||||
// and handles the control to the centralized HTTPErrorHandler.
|
||||
func Timeout() echo.MiddlewareFunc {
|
||||
return TimeoutWithConfig(DefaultTimeoutConfig)
|
||||
}
|
||||
|
||||
// TimeoutWithConfig returns a Timeout middleware with config.
|
||||
// See: `Timeout()`.
|
||||
func TimeoutWithConfig(config TimeoutConfig) echo.MiddlewareFunc {
|
||||
// Defaults
|
||||
if config.Skipper == nil {
|
||||
config.Skipper = DefaultTimeoutConfig.Skipper
|
||||
}
|
||||
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
if config.Skipper(c) || config.Timeout == 0 {
|
||||
return next(c)
|
||||
}
|
||||
|
||||
handlerWrapper := echoHandlerFuncWrapper{
|
||||
ctx: c,
|
||||
handler: next,
|
||||
errChan: make(chan error, 1),
|
||||
errHandler: config.OnTimeoutRouteErrorHandler,
|
||||
}
|
||||
handler := http.TimeoutHandler(handlerWrapper, config.Timeout, config.ErrorMessage)
|
||||
handler.ServeHTTP(c.Response().Writer, c.Request())
|
||||
|
||||
select {
|
||||
case err := <-handlerWrapper.errChan:
|
||||
return err
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type echoHandlerFuncWrapper struct {
|
||||
ctx echo.Context
|
||||
handler echo.HandlerFunc
|
||||
errHandler func(err error, c echo.Context)
|
||||
errChan chan error
|
||||
}
|
||||
|
||||
func (t echoHandlerFuncWrapper) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
// replace writer with TimeoutHandler custom one. This will guarantee that
|
||||
// `writes by h to its ResponseWriter will return ErrHandlerTimeout.`
|
||||
originalWriter := t.ctx.Response().Writer
|
||||
t.ctx.Response().Writer = rw
|
||||
|
||||
err := t.handler(t.ctx)
|
||||
if ctxErr := r.Context().Err(); ctxErr == context.DeadlineExceeded {
|
||||
if err != nil && t.errHandler != nil {
|
||||
t.errHandler(err, t.ctx)
|
||||
}
|
||||
return // on timeout we can not send handler error to client because `http.TimeoutHandler` has already sent headers
|
||||
}
|
||||
// we restore original writer only for cases we did not timeout. On timeout we have already sent response to client
|
||||
// and should not anymore send additional headers/data
|
||||
// so on timeout writer stays what http.TimeoutHandler uses and prevents writing headers/body
|
||||
t.ctx.Response().Writer = originalWriter
|
||||
if err != nil {
|
||||
t.errChan <- err
|
||||
}
|
||||
}
|
||||
4
vendor/github.com/labstack/echo/v4/response.go
generated
vendored
4
vendor/github.com/labstack/echo/v4/response.go
generated
vendored
@@ -56,11 +56,11 @@ func (r *Response) WriteHeader(code int) {
|
||||
r.echo.Logger.Warn("response already committed")
|
||||
return
|
||||
}
|
||||
r.Status = code
|
||||
for _, fn := range r.beforeFuncs {
|
||||
fn()
|
||||
}
|
||||
r.Status = code
|
||||
r.Writer.WriteHeader(code)
|
||||
r.Writer.WriteHeader(r.Status)
|
||||
r.Committed = true
|
||||
}
|
||||
|
||||
|
||||
482
vendor/github.com/labstack/echo/v4/router.go
generated
vendored
482
vendor/github.com/labstack/echo/v4/router.go
generated
vendored
@@ -2,7 +2,6 @@ package echo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -14,14 +13,16 @@ type (
|
||||
echo *Echo
|
||||
}
|
||||
node struct {
|
||||
kind kind
|
||||
label byte
|
||||
prefix string
|
||||
parent *node
|
||||
children children
|
||||
ppath string
|
||||
pnames []string
|
||||
methodHandler *methodHandler
|
||||
kind kind
|
||||
label byte
|
||||
prefix string
|
||||
parent *node
|
||||
staticChildren children
|
||||
ppath string
|
||||
pnames []string
|
||||
methodHandler *methodHandler
|
||||
paramChild *node
|
||||
anyChild *node
|
||||
}
|
||||
kind uint8
|
||||
children []*node
|
||||
@@ -41,9 +42,12 @@ type (
|
||||
)
|
||||
|
||||
const (
|
||||
skind kind = iota
|
||||
pkind
|
||||
akind
|
||||
staticKind kind = iota
|
||||
paramKind
|
||||
anyKind
|
||||
|
||||
paramLabel = byte(':')
|
||||
anyLabel = byte('*')
|
||||
)
|
||||
|
||||
// NewRouter returns a new Router instance.
|
||||
@@ -69,120 +73,147 @@ func (r *Router) Add(method, path string, h HandlerFunc) {
|
||||
pnames := []string{} // Param names
|
||||
ppath := path // Pristine path
|
||||
|
||||
for i, l := 0, len(path); i < l; i++ {
|
||||
for i, lcpIndex := 0, len(path); i < lcpIndex; i++ {
|
||||
if path[i] == ':' {
|
||||
j := i + 1
|
||||
|
||||
r.insert(method, path[:i], nil, skind, "", nil)
|
||||
for ; i < l && path[i] != '/'; i++ {
|
||||
r.insert(method, path[:i], nil, staticKind, "", nil)
|
||||
for ; i < lcpIndex && path[i] != '/'; i++ {
|
||||
}
|
||||
|
||||
pnames = append(pnames, path[j:i])
|
||||
path = path[:j] + path[i:]
|
||||
i, l = j, len(path)
|
||||
i, lcpIndex = j, len(path)
|
||||
|
||||
if i == l {
|
||||
r.insert(method, path[:i], h, pkind, ppath, pnames)
|
||||
if i == lcpIndex {
|
||||
r.insert(method, path[:i], h, paramKind, ppath, pnames)
|
||||
} else {
|
||||
r.insert(method, path[:i], nil, pkind, "", nil)
|
||||
r.insert(method, path[:i], nil, paramKind, "", nil)
|
||||
}
|
||||
} else if path[i] == '*' {
|
||||
r.insert(method, path[:i], nil, skind, "", nil)
|
||||
r.insert(method, path[:i], nil, staticKind, "", nil)
|
||||
pnames = append(pnames, "*")
|
||||
r.insert(method, path[:i+1], h, akind, ppath, pnames)
|
||||
r.insert(method, path[:i+1], h, anyKind, ppath, pnames)
|
||||
}
|
||||
}
|
||||
|
||||
r.insert(method, path, h, skind, ppath, pnames)
|
||||
r.insert(method, path, h, staticKind, ppath, pnames)
|
||||
}
|
||||
|
||||
func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string, pnames []string) {
|
||||
// Adjust max param
|
||||
l := len(pnames)
|
||||
if *r.echo.maxParam < l {
|
||||
*r.echo.maxParam = l
|
||||
paramLen := len(pnames)
|
||||
if *r.echo.maxParam < paramLen {
|
||||
*r.echo.maxParam = paramLen
|
||||
}
|
||||
|
||||
cn := r.tree // Current node as root
|
||||
if cn == nil {
|
||||
currentNode := r.tree // Current node as root
|
||||
if currentNode == nil {
|
||||
panic("echo: invalid method")
|
||||
}
|
||||
search := path
|
||||
|
||||
for {
|
||||
sl := len(search)
|
||||
pl := len(cn.prefix)
|
||||
l := 0
|
||||
searchLen := len(search)
|
||||
prefixLen := len(currentNode.prefix)
|
||||
lcpLen := 0
|
||||
|
||||
// LCP
|
||||
max := pl
|
||||
if sl < max {
|
||||
max = sl
|
||||
// LCP - Longest Common Prefix (https://en.wikipedia.org/wiki/LCP_array)
|
||||
max := prefixLen
|
||||
if searchLen < max {
|
||||
max = searchLen
|
||||
}
|
||||
for ; l < max && search[l] == cn.prefix[l]; l++ {
|
||||
for ; lcpLen < max && search[lcpLen] == currentNode.prefix[lcpLen]; lcpLen++ {
|
||||
}
|
||||
|
||||
if l == 0 {
|
||||
if lcpLen == 0 {
|
||||
// At root node
|
||||
cn.label = search[0]
|
||||
cn.prefix = search
|
||||
currentNode.label = search[0]
|
||||
currentNode.prefix = search
|
||||
if h != nil {
|
||||
cn.kind = t
|
||||
cn.addHandler(method, h)
|
||||
cn.ppath = ppath
|
||||
cn.pnames = pnames
|
||||
currentNode.kind = t
|
||||
currentNode.addHandler(method, h)
|
||||
currentNode.ppath = ppath
|
||||
currentNode.pnames = pnames
|
||||
}
|
||||
} else if l < pl {
|
||||
} else if lcpLen < prefixLen {
|
||||
// Split node
|
||||
n := newNode(cn.kind, cn.prefix[l:], cn, cn.children, cn.methodHandler, cn.ppath, cn.pnames)
|
||||
n := newNode(
|
||||
currentNode.kind,
|
||||
currentNode.prefix[lcpLen:],
|
||||
currentNode,
|
||||
currentNode.staticChildren,
|
||||
currentNode.methodHandler,
|
||||
currentNode.ppath,
|
||||
currentNode.pnames,
|
||||
currentNode.paramChild,
|
||||
currentNode.anyChild,
|
||||
)
|
||||
|
||||
// Update parent path for all children to new node
|
||||
for _, child := range cn.children {
|
||||
for _, child := range currentNode.staticChildren {
|
||||
child.parent = n
|
||||
}
|
||||
if currentNode.paramChild != nil {
|
||||
currentNode.paramChild.parent = n
|
||||
}
|
||||
if currentNode.anyChild != nil {
|
||||
currentNode.anyChild.parent = n
|
||||
}
|
||||
|
||||
// Reset parent node
|
||||
cn.kind = skind
|
||||
cn.label = cn.prefix[0]
|
||||
cn.prefix = cn.prefix[:l]
|
||||
cn.children = nil
|
||||
cn.methodHandler = new(methodHandler)
|
||||
cn.ppath = ""
|
||||
cn.pnames = nil
|
||||
currentNode.kind = staticKind
|
||||
currentNode.label = currentNode.prefix[0]
|
||||
currentNode.prefix = currentNode.prefix[:lcpLen]
|
||||
currentNode.staticChildren = nil
|
||||
currentNode.methodHandler = new(methodHandler)
|
||||
currentNode.ppath = ""
|
||||
currentNode.pnames = nil
|
||||
currentNode.paramChild = nil
|
||||
currentNode.anyChild = nil
|
||||
|
||||
cn.addChild(n)
|
||||
// Only Static children could reach here
|
||||
currentNode.addStaticChild(n)
|
||||
|
||||
if l == sl {
|
||||
if lcpLen == searchLen {
|
||||
// At parent node
|
||||
cn.kind = t
|
||||
cn.addHandler(method, h)
|
||||
cn.ppath = ppath
|
||||
cn.pnames = pnames
|
||||
currentNode.kind = t
|
||||
currentNode.addHandler(method, h)
|
||||
currentNode.ppath = ppath
|
||||
currentNode.pnames = pnames
|
||||
} else {
|
||||
// Create child node
|
||||
n = newNode(t, search[l:], cn, nil, new(methodHandler), ppath, pnames)
|
||||
n = newNode(t, search[lcpLen:], currentNode, nil, new(methodHandler), ppath, pnames, nil, nil)
|
||||
n.addHandler(method, h)
|
||||
cn.addChild(n)
|
||||
// Only Static children could reach here
|
||||
currentNode.addStaticChild(n)
|
||||
}
|
||||
} else if l < sl {
|
||||
search = search[l:]
|
||||
c := cn.findChildWithLabel(search[0])
|
||||
} else if lcpLen < searchLen {
|
||||
search = search[lcpLen:]
|
||||
c := currentNode.findChildWithLabel(search[0])
|
||||
if c != nil {
|
||||
// Go deeper
|
||||
cn = c
|
||||
currentNode = c
|
||||
continue
|
||||
}
|
||||
// Create child node
|
||||
n := newNode(t, search, cn, nil, new(methodHandler), ppath, pnames)
|
||||
n := newNode(t, search, currentNode, nil, new(methodHandler), ppath, pnames, nil, nil)
|
||||
n.addHandler(method, h)
|
||||
cn.addChild(n)
|
||||
switch t {
|
||||
case staticKind:
|
||||
currentNode.addStaticChild(n)
|
||||
case paramKind:
|
||||
currentNode.paramChild = n
|
||||
case anyKind:
|
||||
currentNode.anyChild = n
|
||||
}
|
||||
} else {
|
||||
// Node already exists
|
||||
if h != nil {
|
||||
cn.addHandler(method, h)
|
||||
cn.ppath = ppath
|
||||
if len(cn.pnames) == 0 { // Issue #729
|
||||
cn.pnames = pnames
|
||||
currentNode.addHandler(method, h)
|
||||
currentNode.ppath = ppath
|
||||
if len(currentNode.pnames) == 0 { // Issue #729
|
||||
currentNode.pnames = pnames
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,34 +221,27 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
|
||||
}
|
||||
}
|
||||
|
||||
func newNode(t kind, pre string, p *node, c children, mh *methodHandler, ppath string, pnames []string) *node {
|
||||
func newNode(t kind, pre string, p *node, sc children, mh *methodHandler, ppath string, pnames []string, paramChildren, anyChildren *node) *node {
|
||||
return &node{
|
||||
kind: t,
|
||||
label: pre[0],
|
||||
prefix: pre,
|
||||
parent: p,
|
||||
children: c,
|
||||
ppath: ppath,
|
||||
pnames: pnames,
|
||||
methodHandler: mh,
|
||||
kind: t,
|
||||
label: pre[0],
|
||||
prefix: pre,
|
||||
parent: p,
|
||||
staticChildren: sc,
|
||||
ppath: ppath,
|
||||
pnames: pnames,
|
||||
methodHandler: mh,
|
||||
paramChild: paramChildren,
|
||||
anyChild: anyChildren,
|
||||
}
|
||||
}
|
||||
|
||||
func (n *node) addChild(c *node) {
|
||||
n.children = append(n.children, c)
|
||||
func (n *node) addStaticChild(c *node) {
|
||||
n.staticChildren = append(n.staticChildren, c)
|
||||
}
|
||||
|
||||
func (n *node) findChild(l byte, t kind) *node {
|
||||
for _, c := range n.children {
|
||||
if c.label == l && c.kind == t {
|
||||
return c
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *node) findChildWithLabel(l byte) *node {
|
||||
for _, c := range n.children {
|
||||
func (n *node) findStaticChild(l byte) *node {
|
||||
for _, c := range n.staticChildren {
|
||||
if c.label == l {
|
||||
return c
|
||||
}
|
||||
@@ -225,12 +249,18 @@ func (n *node) findChildWithLabel(l byte) *node {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *node) findChildByKind(t kind) *node {
|
||||
for _, c := range n.children {
|
||||
if c.kind == t {
|
||||
func (n *node) findChildWithLabel(l byte) *node {
|
||||
for _, c := range n.staticChildren {
|
||||
if c.label == l {
|
||||
return c
|
||||
}
|
||||
}
|
||||
if l == paramLabel {
|
||||
return n.paramChild
|
||||
}
|
||||
if l == anyLabel {
|
||||
return n.anyChild
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -310,180 +340,152 @@ func (n *node) checkMethodNotAllowed() HandlerFunc {
|
||||
func (r *Router) Find(method, path string, c Context) {
|
||||
ctx := c.(*context)
|
||||
ctx.path = path
|
||||
cn := r.tree // Current node as root
|
||||
currentNode := r.tree // Current node as root
|
||||
|
||||
var (
|
||||
search = path
|
||||
child *node // Child node
|
||||
n int // Param counter
|
||||
nk kind // Next kind
|
||||
nn *node // Next node
|
||||
ns string // Next search
|
||||
pvalues = ctx.pvalues // Use the internal slice so the interface can keep the illusion of a dynamic slice
|
||||
// search stores the remaining path to check for match. By each iteration we move from start of path to end of the path
|
||||
// and search value gets shorter and shorter.
|
||||
search = path
|
||||
searchIndex = 0
|
||||
paramIndex int // Param counter
|
||||
paramValues = ctx.pvalues // Use the internal slice so the interface can keep the illusion of a dynamic slice
|
||||
)
|
||||
|
||||
// Search order static > param > any
|
||||
// Backtracking is needed when a dead end (leaf node) is reached in the router tree.
|
||||
// To backtrack the current node will be changed to the parent node and the next kind for the
|
||||
// router logic will be returned based on fromKind or kind of the dead end node (static > param > any).
|
||||
// For example if there is no static node match we should check parent next sibling by kind (param).
|
||||
// Backtracking itself does not check if there is a next sibling, this is done by the router logic.
|
||||
backtrackToNextNodeKind := func(fromKind kind) (nextNodeKind kind, valid bool) {
|
||||
previous := currentNode
|
||||
currentNode = previous.parent
|
||||
valid = currentNode != nil
|
||||
|
||||
// Next node type by priority
|
||||
// NOTE: With the current implementation we never backtrack from an `any` route, so `previous.kind` is
|
||||
// always `static` or `any`
|
||||
// If this is changed then for any route next kind would be `static` and this statement should be changed
|
||||
nextNodeKind = previous.kind + 1
|
||||
|
||||
if fromKind == staticKind {
|
||||
// when backtracking is done from static kind block we did not change search so nothing to restore
|
||||
return
|
||||
}
|
||||
|
||||
// restore search to value it was before we move to current node we are backtracking from.
|
||||
if previous.kind == staticKind {
|
||||
searchIndex -= len(previous.prefix)
|
||||
} else {
|
||||
paramIndex--
|
||||
// for param/any node.prefix value is always `:` so we can not deduce searchIndex from that and must use pValue
|
||||
// for that index as it would also contain part of path we cut off before moving into node we are backtracking from
|
||||
searchIndex -= len(paramValues[paramIndex])
|
||||
}
|
||||
search = path[searchIndex:]
|
||||
return
|
||||
}
|
||||
|
||||
// Router tree is implemented by longest common prefix array (LCP array) https://en.wikipedia.org/wiki/LCP_array
|
||||
// Tree search is implemented as for loop where one loop iteration is divided into 3 separate blocks
|
||||
// Each of these blocks checks specific kind of node (static/param/any). Order of blocks reflex their priority in routing.
|
||||
// Search order/priority is: static > param > any.
|
||||
//
|
||||
// Note: backtracking in tree is implemented by replacing/switching currentNode to previous node
|
||||
// and hoping to (goto statement) next block by priority to check if it is the match.
|
||||
for {
|
||||
if search == "" {
|
||||
prefixLen := 0 // Prefix length
|
||||
lcpLen := 0 // LCP (longest common prefix) length
|
||||
|
||||
if currentNode.kind == staticKind {
|
||||
searchLen := len(search)
|
||||
prefixLen = len(currentNode.prefix)
|
||||
|
||||
// LCP - Longest Common Prefix (https://en.wikipedia.org/wiki/LCP_array)
|
||||
max := prefixLen
|
||||
if searchLen < max {
|
||||
max = searchLen
|
||||
}
|
||||
for ; lcpLen < max && search[lcpLen] == currentNode.prefix[lcpLen]; lcpLen++ {
|
||||
}
|
||||
}
|
||||
|
||||
if lcpLen != prefixLen {
|
||||
// No matching prefix, let's backtrack to the first possible alternative node of the decision path
|
||||
nk, ok := backtrackToNextNodeKind(staticKind)
|
||||
if !ok {
|
||||
return // No other possibilities on the decision path
|
||||
} else if nk == paramKind {
|
||||
goto Param
|
||||
// NOTE: this case (backtracking from static node to previous any node) can not happen by current any matching logic. Any node is end of search currently
|
||||
//} else if nk == anyKind {
|
||||
// goto Any
|
||||
} else {
|
||||
// Not found (this should never be possible for static node we are looking currently)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// The full prefix has matched, remove the prefix from the remaining search
|
||||
search = search[lcpLen:]
|
||||
searchIndex = searchIndex + lcpLen
|
||||
|
||||
// Finish routing if no remaining search and we are on an leaf node
|
||||
if search == "" && currentNode.ppath != "" {
|
||||
break
|
||||
}
|
||||
|
||||
pl := 0 // Prefix length
|
||||
l := 0 // LCP length
|
||||
|
||||
if cn.label != ':' {
|
||||
sl := len(search)
|
||||
pl = len(cn.prefix)
|
||||
|
||||
// LCP
|
||||
max := pl
|
||||
if sl < max {
|
||||
max = sl
|
||||
}
|
||||
for ; l < max && search[l] == cn.prefix[l]; l++ {
|
||||
}
|
||||
}
|
||||
|
||||
if l == pl {
|
||||
// Continue search
|
||||
search = search[l:]
|
||||
// Finish routing if no remaining search and we are on an leaf node
|
||||
if search == "" && (nn == nil || cn.parent == nil || cn.ppath != "") {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to go back up the tree on no matching prefix or no remaining search
|
||||
if l != pl || search == "" {
|
||||
// Handle special case of trailing slash route with existing any route (see #1526)
|
||||
if path[len(path)-1] == '/' && cn.findChildByKind(akind) != nil {
|
||||
goto Any
|
||||
}
|
||||
if nn == nil { // Issue #1348
|
||||
return // Not found
|
||||
}
|
||||
cn = nn
|
||||
search = ns
|
||||
if nk == pkind {
|
||||
goto Param
|
||||
} else if nk == akind {
|
||||
goto Any
|
||||
}
|
||||
}
|
||||
|
||||
// Static node
|
||||
if child = cn.findChild(search[0], skind); child != nil {
|
||||
// Save next
|
||||
if cn.prefix[len(cn.prefix)-1] == '/' { // Issue #623
|
||||
nk = pkind
|
||||
nn = cn
|
||||
ns = search
|
||||
if search != "" {
|
||||
if child := currentNode.findStaticChild(search[0]); child != nil {
|
||||
currentNode = child
|
||||
continue
|
||||
}
|
||||
cn = child
|
||||
continue
|
||||
}
|
||||
|
||||
Param:
|
||||
// Param node
|
||||
if child = cn.findChildByKind(pkind); child != nil {
|
||||
// Issue #378
|
||||
if len(pvalues) == n {
|
||||
continue
|
||||
}
|
||||
|
||||
// Save next
|
||||
if cn.prefix[len(cn.prefix)-1] == '/' { // Issue #623
|
||||
nk = akind
|
||||
nn = cn
|
||||
ns = search
|
||||
}
|
||||
|
||||
cn = child
|
||||
if child := currentNode.paramChild; search != "" && child != nil {
|
||||
currentNode = child
|
||||
// FIXME: when param node does not have any children then param node should act similarly to any node - consider all remaining search as match
|
||||
i, l := 0, len(search)
|
||||
for ; i < l && search[i] != '/'; i++ {
|
||||
}
|
||||
pvalues[n] = search[:i]
|
||||
n++
|
||||
paramValues[paramIndex] = search[:i]
|
||||
paramIndex++
|
||||
search = search[i:]
|
||||
searchIndex = searchIndex + i
|
||||
continue
|
||||
}
|
||||
|
||||
Any:
|
||||
// Any node
|
||||
if cn = cn.findChildByKind(akind); cn != nil {
|
||||
// If any node is found, use remaining path for pvalues
|
||||
pvalues[len(cn.pnames)-1] = search
|
||||
if child := currentNode.anyChild; child != nil {
|
||||
// If any node is found, use remaining path for paramValues
|
||||
currentNode = child
|
||||
paramValues[len(currentNode.pnames)-1] = search
|
||||
break
|
||||
}
|
||||
|
||||
// No node found, continue at stored next node
|
||||
// or find nearest "any" route
|
||||
if nn != nil {
|
||||
// No next node to go down in routing (issue #954)
|
||||
// Find nearest "any" route going up the routing tree
|
||||
search = ns
|
||||
np := nn.parent
|
||||
// Consider param route one level up only
|
||||
if cn = nn.findChildByKind(pkind); cn != nil {
|
||||
pos := strings.IndexByte(ns, '/')
|
||||
if pos == -1 {
|
||||
// If no slash is remaining in search string set param value
|
||||
pvalues[len(cn.pnames)-1] = search
|
||||
break
|
||||
} else if pos > 0 {
|
||||
// Otherwise continue route processing with restored next node
|
||||
cn = nn
|
||||
nn = nil
|
||||
ns = ""
|
||||
goto Param
|
||||
}
|
||||
}
|
||||
// No param route found, try to resolve nearest any route
|
||||
for {
|
||||
np = nn.parent
|
||||
if cn = nn.findChildByKind(akind); cn != nil {
|
||||
break
|
||||
}
|
||||
if np == nil {
|
||||
break // no further parent nodes in tree, abort
|
||||
}
|
||||
var str strings.Builder
|
||||
str.WriteString(nn.prefix)
|
||||
str.WriteString(search)
|
||||
search = str.String()
|
||||
nn = np
|
||||
}
|
||||
if cn != nil { // use the found "any" route and update path
|
||||
pvalues[len(cn.pnames)-1] = search
|
||||
break
|
||||
}
|
||||
}
|
||||
return // Not found
|
||||
|
||||
}
|
||||
|
||||
ctx.handler = cn.findHandler(method)
|
||||
ctx.path = cn.ppath
|
||||
ctx.pnames = cn.pnames
|
||||
|
||||
// NOTE: Slow zone...
|
||||
if ctx.handler == nil {
|
||||
ctx.handler = cn.checkMethodNotAllowed()
|
||||
|
||||
// Dig further for any, might have an empty value for *, e.g.
|
||||
// serving a directory. Issue #207.
|
||||
if cn = cn.findChildByKind(akind); cn == nil {
|
||||
// Let's backtrack to the first possible alternative node of the decision path
|
||||
nk, ok := backtrackToNextNodeKind(anyKind)
|
||||
if !ok {
|
||||
return // No other possibilities on the decision path
|
||||
} else if nk == paramKind {
|
||||
goto Param
|
||||
} else if nk == anyKind {
|
||||
goto Any
|
||||
} else {
|
||||
// Not found
|
||||
return
|
||||
}
|
||||
if h := cn.findHandler(method); h != nil {
|
||||
ctx.handler = h
|
||||
} else {
|
||||
ctx.handler = cn.checkMethodNotAllowed()
|
||||
}
|
||||
ctx.path = cn.ppath
|
||||
ctx.pnames = cn.pnames
|
||||
pvalues[len(cn.pnames)-1] = ""
|
||||
}
|
||||
|
||||
ctx.handler = currentNode.findHandler(method)
|
||||
ctx.path = currentNode.ppath
|
||||
ctx.pnames = currentNode.pnames
|
||||
|
||||
if ctx.handler == nil {
|
||||
ctx.handler = currentNode.checkMethodNotAllowed()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
4
vendor/github.com/matrix-org/gomatrix/.gitignore
generated
vendored
4
vendor/github.com/matrix-org/gomatrix/.gitignore
generated
vendored
@@ -2,6 +2,7 @@
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.out
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
@@ -22,3 +23,6 @@ _testmain.go
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
# test editor files
|
||||
*.swp
|
||||
|
||||
1
vendor/github.com/matrix-org/gomatrix/CHANGELOG.md
generated
vendored
Normal file
1
vendor/github.com/matrix-org/gomatrix/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
## Release 0.1.0 (UNRELEASED)
|
||||
65
vendor/github.com/matrix-org/gomatrix/README.md
generated
vendored
65
vendor/github.com/matrix-org/gomatrix/README.md
generated
vendored
@@ -4,3 +4,68 @@
|
||||
A Golang Matrix client.
|
||||
|
||||
**THIS IS UNDER ACTIVE DEVELOPMENT: BREAKING CHANGES ARE FREQUENT.**
|
||||
|
||||
# Contributing
|
||||
|
||||
All contributions are greatly appreciated!
|
||||
|
||||
## How to report issues
|
||||
|
||||
Please check the current open issues for similar reports
|
||||
in order to avoid duplicates.
|
||||
|
||||
Some general guidelines:
|
||||
|
||||
- Include a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) when possible.
|
||||
- Describe the expected behaviour and what actually happened
|
||||
including a full trace-back in case of exceptions.
|
||||
- Make sure to list details about your environment
|
||||
|
||||
## Setting up your environment
|
||||
|
||||
If you intend to contribute to gomatrix you'll first need Go installed on your machine (version 1.12+ is required). Also, make sure to have golangci-lint properly set up since we use it for pre-commit hooks (for instructions on how to install it, check the [official docs](https://golangci-lint.run/usage/install/#local-installation)).
|
||||
|
||||
- Fork gomatrix to your GitHub account by clicking the [Fork](https://github.com/matrix-org/gomatrix/fork) button.
|
||||
- [Clone](https://help.github.com/en/articles/fork-a-repo#step-2-create-a-local-clone-of-your-fork) the main repository (not your fork) to your local machine.
|
||||
|
||||
|
||||
$ git clone https://github.com/matrix-org/gomatrix
|
||||
$ cd gomatrix
|
||||
|
||||
|
||||
- Add your fork as a remote to push your contributions.Replace
|
||||
``{username}`` with your username.
|
||||
|
||||
git remote add fork https://github.com/{username}/gomatrix
|
||||
|
||||
- Create a new branch to identify what feature you are working on.
|
||||
|
||||
$ git fetch origin
|
||||
$ git checkout -b your-branch-name origin/master
|
||||
|
||||
|
||||
- Make your changes, including tests that cover any code changes you make, and run them as described below.
|
||||
|
||||
- Execute pre-commit hooks by running
|
||||
|
||||
<gomatrix dir>/hooks/pre-commit
|
||||
|
||||
- Push your changes to your fork and [create a pull request](https://help.github.com/en/articles/creating-a-pull-request) describing your changes.
|
||||
|
||||
$ git push --set-upstream fork your-branch-name
|
||||
|
||||
- Finally, create a [pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests)
|
||||
|
||||
## How to run tests
|
||||
|
||||
You can run the test suite and example code with `$ go test -v`
|
||||
|
||||
# Running Coverage
|
||||
|
||||
To run coverage, first generate the coverage report using `go test`
|
||||
|
||||
go test -v -cover -coverprofile=coverage.out
|
||||
|
||||
You can now show the generated report as a html page with `go tool`
|
||||
|
||||
go tool cover -html=coverage.out
|
||||
|
||||
23
vendor/github.com/matrix-org/gomatrix/client.go
generated
vendored
23
vendor/github.com/matrix-org/gomatrix/client.go
generated
vendored
@@ -53,13 +53,13 @@ func (e HTTPError) Error() string {
|
||||
return fmt.Sprintf("contents=%v msg=%s code=%d wrapped=%s", e.Contents, e.Message, e.Code, wrappedErrMsg)
|
||||
}
|
||||
|
||||
// BuildURL builds a URL with the Client's homserver/prefix/access_token set already.
|
||||
// BuildURL builds a URL with the Client's homeserver/prefix set already.
|
||||
func (cli *Client) BuildURL(urlPath ...string) string {
|
||||
ps := append([]string{cli.Prefix}, urlPath...)
|
||||
return cli.BuildBaseURL(ps...)
|
||||
}
|
||||
|
||||
// BuildBaseURL builds a URL with the Client's homeserver/access_token set already. You must
|
||||
// BuildBaseURL builds a URL with the Client's homeserver set already. You must
|
||||
// supply the prefix in the path.
|
||||
func (cli *Client) BuildBaseURL(urlPath ...string) string {
|
||||
// copy the URL. Purposefully ignore error as the input is from a valid URL already
|
||||
@@ -72,9 +72,6 @@ func (cli *Client) BuildBaseURL(urlPath ...string) string {
|
||||
hsURL.Path = hsURL.Path + "/"
|
||||
}
|
||||
query := hsURL.Query()
|
||||
if cli.AccessToken != "" {
|
||||
query.Set("access_token", cli.AccessToken)
|
||||
}
|
||||
if cli.AppServiceUserID != "" {
|
||||
query.Set("user_id", cli.AppServiceUserID)
|
||||
}
|
||||
@@ -82,7 +79,7 @@ func (cli *Client) BuildBaseURL(urlPath ...string) string {
|
||||
return hsURL.String()
|
||||
}
|
||||
|
||||
// BuildURLWithQuery builds a URL with query parameters in addition to the Client's homeserver/prefix/access_token set already.
|
||||
// BuildURLWithQuery builds a URL with query parameters in addition to the Client's homeserver/prefix set already.
|
||||
func (cli *Client) BuildURLWithQuery(urlPath []string, urlQuery map[string]string) string {
|
||||
u, _ := url.Parse(cli.BuildURL(urlPath...))
|
||||
q := u.Query()
|
||||
@@ -203,7 +200,13 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
if cli.AccessToken != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+cli.AccessToken)
|
||||
}
|
||||
|
||||
res, err := cli.Client.Do(req)
|
||||
if res != nil {
|
||||
defer res.Body.Close()
|
||||
@@ -687,15 +690,21 @@ func (cli *Client) UploadToContentRepo(content io.Reader, contentType string, co
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
req.Header.Set("Authorization", "Bearer "+cli.AccessToken)
|
||||
|
||||
req.ContentLength = contentLength
|
||||
|
||||
res, err := cli.Client.Do(req)
|
||||
if res != nil {
|
||||
defer res.Body.Close()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if res.StatusCode != 200 {
|
||||
contents, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
@@ -710,10 +719,12 @@ func (cli *Client) UploadToContentRepo(content io.Reader, contentType string, co
|
||||
Code: res.StatusCode,
|
||||
}
|
||||
}
|
||||
|
||||
var m RespMediaUpload
|
||||
if err := json.NewDecoder(res.Body).Decode(&m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
|
||||
18
vendor/github.com/matterbridge/Rocket.Chat.Go.SDK/models/message.go
generated
vendored
18
vendor/github.com/matterbridge/Rocket.Chat.Go.SDK/models/message.go
generated
vendored
@@ -77,8 +77,8 @@ type Attachment struct {
|
||||
// https://rocket.chat/docs/developer-guides/rest-api/chat/postmessage/
|
||||
type AttachmentField struct {
|
||||
Short bool `json:"short"`
|
||||
Title string `json:"title"`
|
||||
Value string `json:"value"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
type AttachmentActionType string
|
||||
@@ -89,15 +89,15 @@ const (
|
||||
|
||||
// AttachmentAction are action buttons on message attachments
|
||||
type AttachmentAction struct {
|
||||
Type AttachmentActionType `json:"type"`
|
||||
Text string `json:"text"`
|
||||
Url string `json:"url"`
|
||||
ImageURL string `json:"image_url"`
|
||||
Type AttachmentActionType `json:"type,omitempty"`
|
||||
Text string `json:"text,omitempty"`
|
||||
Url string `json:"url,omitempty"`
|
||||
ImageURL string `json:"image_url,omitempty"`
|
||||
IsWebView bool `json:"is_webview"`
|
||||
WebviewHeightRatio string `json:"webview_height_ratio"`
|
||||
Msg string `json:"msg"`
|
||||
WebviewHeightRatio string `json:"webview_height_ratio,omitempty"`
|
||||
Msg string `json:"msg,omitempty"`
|
||||
MsgInChatWindow bool `json:"msg_in_chat_window"`
|
||||
MsgProcessingType MessageProcessingType `json:"msg_processing_type"`
|
||||
MsgProcessingType MessageProcessingType `json:"msg_processing_type,omitempty"`
|
||||
}
|
||||
|
||||
// AttachmentActionButtonAlignment configures how the actions buttons will be aligned
|
||||
|
||||
41
vendor/github.com/matterbridge/Rocket.Chat.Go.SDK/rest/channels.go
generated
vendored
41
vendor/github.com/matterbridge/Rocket.Chat.Go.SDK/rest/channels.go
generated
vendored
@@ -19,6 +19,17 @@ type ChannelResponse struct {
|
||||
Channel models.Channel `json:"channel"`
|
||||
}
|
||||
|
||||
type GroupsResponse struct {
|
||||
Status
|
||||
models.Pagination
|
||||
Groups []models.Channel `json:"groups"`
|
||||
}
|
||||
|
||||
type GroupResponse struct {
|
||||
Status
|
||||
Group models.Channel `json:"group"`
|
||||
}
|
||||
|
||||
// GetPublicChannels returns all channels that can be seen by the logged in user.
|
||||
//
|
||||
// https://rocket.chat/docs/developer-guides/rest-api/channels/list
|
||||
@@ -31,6 +42,19 @@ func (c *Client) GetPublicChannels() (*ChannelsResponse, error) {
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// GetPrivateGroups returns all channels that can be seen by the logged in user.
|
||||
//
|
||||
// https://rocket.chat/docs/developer-guides/rest-api/groups/list
|
||||
func (c *Client) GetPrivateGroups() (*GroupsResponse, error) {
|
||||
response := new(GroupsResponse)
|
||||
if err := c.Get("groups.list", nil, response); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
|
||||
// GetJoinedChannels returns all channels that the user has joined.
|
||||
//
|
||||
// https://rocket.chat/docs/developer-guides/rest-api/channels/list-joined
|
||||
@@ -70,3 +94,20 @@ func (c *Client) GetChannelInfo(channel *models.Channel) (*models.Channel, error
|
||||
return &response.Channel, nil
|
||||
}
|
||||
|
||||
// GetGroupInfo get information about a group. That might be useful to update the usernames.
|
||||
//
|
||||
// https://rocket.chat/docs/developer-guides/rest-api/groups/info
|
||||
func (c *Client) GetGroupInfo(channel *models.Channel) (*models.Channel, error) {
|
||||
response := new(GroupResponse)
|
||||
switch {
|
||||
case channel.Name != "" && channel.ID == "":
|
||||
if err := c.Get("groups.info", url.Values{"roomName": []string{channel.Name}}, response); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
if err := c.Get("groups.info", url.Values{"roomId": []string{channel.ID}}, response); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &response.Group, nil
|
||||
}
|
||||
|
||||
4114
vendor/github.com/matterbridge/emoji/emoji_codemap.go
generated
vendored
4114
vendor/github.com/matterbridge/emoji/emoji_codemap.go
generated
vendored
File diff suppressed because it is too large
Load Diff
2
vendor/github.com/mgutz/ansi/README.md
generated
vendored
2
vendor/github.com/mgutz/ansi/README.md
generated
vendored
@@ -34,6 +34,7 @@ Other examples
|
||||
|
||||
```go
|
||||
Color(s, "red") // red
|
||||
Color(s, "red+d") // red dim
|
||||
Color(s, "red+b") // red bold
|
||||
Color(s, "red+B") // red blinking
|
||||
Color(s, "red+u") // red underline
|
||||
@@ -73,6 +74,7 @@ Foreground Attributes
|
||||
* B = Blink
|
||||
* b = bold
|
||||
* h = high intensity (bright)
|
||||
* d = dim
|
||||
* i = inverse
|
||||
* s = strikethrough
|
||||
* u = underline
|
||||
|
||||
8
vendor/github.com/mgutz/ansi/ansi.go
generated
vendored
8
vendor/github.com/mgutz/ansi/ansi.go
generated
vendored
@@ -24,9 +24,11 @@ const (
|
||||
highIntensityBG = 100
|
||||
|
||||
start = "\033["
|
||||
normal = "0;"
|
||||
bold = "1;"
|
||||
blink = "5;"
|
||||
dim = "2;"
|
||||
underline = "4;"
|
||||
blink = "5;"
|
||||
inverse = "7;"
|
||||
strikethrough = "9;"
|
||||
|
||||
@@ -164,10 +166,14 @@ func colorCode(style string) *bytes.Buffer {
|
||||
|
||||
buf.WriteString(start)
|
||||
base := normalIntensityFG
|
||||
buf.WriteString(normal) // reset any previous style
|
||||
if len(fgStyle) > 0 {
|
||||
if strings.Contains(fgStyle, "b") {
|
||||
buf.WriteString(bold)
|
||||
}
|
||||
if strings.Contains(fgStyle, "d") {
|
||||
buf.WriteString(dim)
|
||||
}
|
||||
if strings.Contains(fgStyle, "B") {
|
||||
buf.WriteString(blink)
|
||||
}
|
||||
|
||||
1
vendor/github.com/mgutz/ansi/doc.go
generated
vendored
1
vendor/github.com/mgutz/ansi/doc.go
generated
vendored
@@ -58,6 +58,7 @@ Attributes
|
||||
B = Blink foreground
|
||||
u = underline foreground
|
||||
h = high intensity (bright) foreground, background
|
||||
d = dim foreground
|
||||
i = inverse
|
||||
|
||||
Wikipedia ANSI escape codes [Colors](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors)
|
||||
|
||||
3
vendor/github.com/mitchellh/mapstructure/.travis.yml
generated
vendored
3
vendor/github.com/mitchellh/mapstructure/.travis.yml
generated
vendored
@@ -1,9 +1,8 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- "1.14.x"
|
||||
- "1.11.x"
|
||||
- tip
|
||||
|
||||
script:
|
||||
- go test
|
||||
- go test -bench . -benchmem
|
||||
|
||||
40
vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
generated
vendored
40
vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
generated
vendored
@@ -1,43 +1,3 @@
|
||||
## 1.3.3
|
||||
|
||||
* Decoding maps from maps creates a settable value for decode hooks [GH-203]
|
||||
|
||||
## 1.3.2
|
||||
|
||||
* Decode into interface type with a struct value is supported [GH-187]
|
||||
|
||||
## 1.3.1
|
||||
|
||||
* Squash should only squash embedded structs. [GH-194]
|
||||
|
||||
## 1.3.0
|
||||
|
||||
* Added `",omitempty"` support. This will ignore zero values in the source
|
||||
structure when encoding. [GH-145]
|
||||
|
||||
## 1.2.3
|
||||
|
||||
* Fix duplicate entries in Keys list with pointer values. [GH-185]
|
||||
|
||||
## 1.2.2
|
||||
|
||||
* Do not add unsettable (unexported) values to the unused metadata key
|
||||
or "remain" value. [GH-150]
|
||||
|
||||
## 1.2.1
|
||||
|
||||
* Go modules checksum mismatch fix
|
||||
|
||||
## 1.2.0
|
||||
|
||||
* Added support to capture unused values in a field using the `",remain"` value
|
||||
in the mapstructure tag. There is an example to showcase usage.
|
||||
* Added `DecoderConfig` option to always squash embedded structs
|
||||
* `json.Number` can decode into `uint` types
|
||||
* Empty slices are preserved and not replaced with nil slices
|
||||
* Fix panic that can occur in when decoding a map into a nil slice of structs
|
||||
* Improved package documentation for godoc
|
||||
|
||||
## 1.1.2
|
||||
|
||||
* Fix error when decode hook decodes interface implementation into interface
|
||||
|
||||
2
vendor/github.com/mitchellh/mapstructure/go.mod
generated
vendored
2
vendor/github.com/mitchellh/mapstructure/go.mod
generated
vendored
@@ -1,3 +1 @@
|
||||
module github.com/mitchellh/mapstructure
|
||||
|
||||
go 1.14
|
||||
|
||||
364
vendor/github.com/mitchellh/mapstructure/mapstructure.go
generated
vendored
364
vendor/github.com/mitchellh/mapstructure/mapstructure.go
generated
vendored
@@ -1,150 +1,10 @@
|
||||
// Package mapstructure exposes functionality to convert one arbitrary
|
||||
// Go type into another, typically to convert a map[string]interface{}
|
||||
// into a native Go structure.
|
||||
// Package mapstructure exposes functionality to convert an arbitrary
|
||||
// map[string]interface{} into a native Go structure.
|
||||
//
|
||||
// The Go structure can be arbitrarily complex, containing slices,
|
||||
// other structs, etc. and the decoder will properly decode nested
|
||||
// maps and so on into the proper structures in the native Go struct.
|
||||
// See the examples to see what the decoder is capable of.
|
||||
//
|
||||
// The simplest function to start with is Decode.
|
||||
//
|
||||
// Field Tags
|
||||
//
|
||||
// When decoding to a struct, mapstructure will use the field name by
|
||||
// default to perform the mapping. For example, if a struct has a field
|
||||
// "Username" then mapstructure will look for a key in the source value
|
||||
// of "username" (case insensitive).
|
||||
//
|
||||
// type User struct {
|
||||
// Username string
|
||||
// }
|
||||
//
|
||||
// You can change the behavior of mapstructure by using struct tags.
|
||||
// The default struct tag that mapstructure looks for is "mapstructure"
|
||||
// but you can customize it using DecoderConfig.
|
||||
//
|
||||
// Renaming Fields
|
||||
//
|
||||
// To rename the key that mapstructure looks for, use the "mapstructure"
|
||||
// tag and set a value directly. For example, to change the "username" example
|
||||
// above to "user":
|
||||
//
|
||||
// type User struct {
|
||||
// Username string `mapstructure:"user"`
|
||||
// }
|
||||
//
|
||||
// Embedded Structs and Squashing
|
||||
//
|
||||
// Embedded structs are treated as if they're another field with that name.
|
||||
// By default, the two structs below are equivalent when decoding with
|
||||
// mapstructure:
|
||||
//
|
||||
// type Person struct {
|
||||
// Name string
|
||||
// }
|
||||
//
|
||||
// type Friend struct {
|
||||
// Person
|
||||
// }
|
||||
//
|
||||
// type Friend struct {
|
||||
// Person Person
|
||||
// }
|
||||
//
|
||||
// This would require an input that looks like below:
|
||||
//
|
||||
// map[string]interface{}{
|
||||
// "person": map[string]interface{}{"name": "alice"},
|
||||
// }
|
||||
//
|
||||
// If your "person" value is NOT nested, then you can append ",squash" to
|
||||
// your tag value and mapstructure will treat it as if the embedded struct
|
||||
// were part of the struct directly. Example:
|
||||
//
|
||||
// type Friend struct {
|
||||
// Person `mapstructure:",squash"`
|
||||
// }
|
||||
//
|
||||
// Now the following input would be accepted:
|
||||
//
|
||||
// map[string]interface{}{
|
||||
// "name": "alice",
|
||||
// }
|
||||
//
|
||||
// DecoderConfig has a field that changes the behavior of mapstructure
|
||||
// to always squash embedded structs.
|
||||
//
|
||||
// Remainder Values
|
||||
//
|
||||
// If there are any unmapped keys in the source value, mapstructure by
|
||||
// default will silently ignore them. You can error by setting ErrorUnused
|
||||
// in DecoderConfig. If you're using Metadata you can also maintain a slice
|
||||
// of the unused keys.
|
||||
//
|
||||
// You can also use the ",remain" suffix on your tag to collect all unused
|
||||
// values in a map. The field with this tag MUST be a map type and should
|
||||
// probably be a "map[string]interface{}" or "map[interface{}]interface{}".
|
||||
// See example below:
|
||||
//
|
||||
// type Friend struct {
|
||||
// Name string
|
||||
// Other map[string]interface{} `mapstructure:",remain"`
|
||||
// }
|
||||
//
|
||||
// Given the input below, Other would be populated with the other
|
||||
// values that weren't used (everything but "name"):
|
||||
//
|
||||
// map[string]interface{}{
|
||||
// "name": "bob",
|
||||
// "address": "123 Maple St.",
|
||||
// }
|
||||
//
|
||||
// Omit Empty Values
|
||||
//
|
||||
// When decoding from a struct to any other value, you may use the
|
||||
// ",omitempty" suffix on your tag to omit that value if it equates to
|
||||
// the zero value. The zero value of all types is specified in the Go
|
||||
// specification.
|
||||
//
|
||||
// For example, the zero type of a numeric type is zero ("0"). If the struct
|
||||
// field value is zero and a numeric type, the field is empty, and it won't
|
||||
// be encoded into the destination type.
|
||||
//
|
||||
// type Source {
|
||||
// Age int `mapstructure:",omitempty"`
|
||||
// }
|
||||
//
|
||||
// Unexported fields
|
||||
//
|
||||
// Since unexported (private) struct fields cannot be set outside the package
|
||||
// where they are defined, the decoder will simply skip them.
|
||||
//
|
||||
// For this output type definition:
|
||||
//
|
||||
// type Exported struct {
|
||||
// private string // this unexported field will be skipped
|
||||
// Public string
|
||||
// }
|
||||
//
|
||||
// Using this map as input:
|
||||
//
|
||||
// map[string]interface{}{
|
||||
// "private": "I will be ignored",
|
||||
// "Public": "I made it through!",
|
||||
// }
|
||||
//
|
||||
// The following struct will be decoded:
|
||||
//
|
||||
// type Exported struct {
|
||||
// private: "" // field is left with an empty string (zero value)
|
||||
// Public: "I made it through!"
|
||||
// }
|
||||
//
|
||||
// Other Configuration
|
||||
//
|
||||
// mapstructure is highly configurable. See the DecoderConfig struct
|
||||
// for other features and options that are supported.
|
||||
package mapstructure
|
||||
|
||||
import (
|
||||
@@ -220,14 +80,6 @@ type DecoderConfig struct {
|
||||
//
|
||||
WeaklyTypedInput bool
|
||||
|
||||
// Squash will squash embedded structs. A squash tag may also be
|
||||
// added to an individual struct field using a tag. For example:
|
||||
//
|
||||
// type Parent struct {
|
||||
// Child `mapstructure:",squash"`
|
||||
// }
|
||||
Squash bool
|
||||
|
||||
// Metadata is the struct that will contain extra metadata about
|
||||
// the decoding. If this is nil, then no metadata will be tracked.
|
||||
Metadata *Metadata
|
||||
@@ -419,7 +271,6 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
|
||||
|
||||
var err error
|
||||
outputKind := getKind(outVal)
|
||||
addMetaKey := true
|
||||
switch outputKind {
|
||||
case reflect.Bool:
|
||||
err = d.decodeBool(name, input, outVal)
|
||||
@@ -438,7 +289,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
|
||||
case reflect.Map:
|
||||
err = d.decodeMap(name, input, outVal)
|
||||
case reflect.Ptr:
|
||||
addMetaKey, err = d.decodePtr(name, input, outVal)
|
||||
err = d.decodePtr(name, input, outVal)
|
||||
case reflect.Slice:
|
||||
err = d.decodeSlice(name, input, outVal)
|
||||
case reflect.Array:
|
||||
@@ -452,7 +303,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
|
||||
|
||||
// If we reached here, then we successfully decoded SOMETHING, so
|
||||
// mark the key as used if we're tracking metainput.
|
||||
if addMetaKey && d.config.Metadata != nil && name != "" {
|
||||
if d.config.Metadata != nil && name != "" {
|
||||
d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
|
||||
}
|
||||
|
||||
@@ -463,34 +314,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
|
||||
// value to "data" of that type.
|
||||
func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
|
||||
if val.IsValid() && val.Elem().IsValid() {
|
||||
elem := val.Elem()
|
||||
|
||||
// If we can't address this element, then its not writable. Instead,
|
||||
// we make a copy of the value (which is a pointer and therefore
|
||||
// writable), decode into that, and replace the whole value.
|
||||
copied := false
|
||||
if !elem.CanAddr() {
|
||||
copied = true
|
||||
|
||||
// Make *T
|
||||
copy := reflect.New(elem.Type())
|
||||
|
||||
// *T = elem
|
||||
copy.Elem().Set(elem)
|
||||
|
||||
// Set elem so we decode into it
|
||||
elem = copy
|
||||
}
|
||||
|
||||
// Decode. If we have an error then return. We also return right
|
||||
// away if we're not a copy because that means we decoded directly.
|
||||
if err := d.decode(name, data, elem); err != nil || !copied {
|
||||
return err
|
||||
}
|
||||
|
||||
// If we're a copy, we need to set te final result
|
||||
val.Set(elem.Elem())
|
||||
return nil
|
||||
return d.decode(name, data, val.Elem())
|
||||
}
|
||||
|
||||
dataVal := reflect.ValueOf(data)
|
||||
@@ -614,7 +438,6 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er
|
||||
func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
|
||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
||||
dataKind := getKind(dataVal)
|
||||
dataType := dataVal.Type()
|
||||
|
||||
switch {
|
||||
case dataKind == reflect.Int:
|
||||
@@ -646,18 +469,6 @@ func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) e
|
||||
} else {
|
||||
return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
|
||||
}
|
||||
case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
|
||||
jn := data.(json.Number)
|
||||
i, err := jn.Int64()
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"error decoding json.Number into %s: %s", name, err)
|
||||
}
|
||||
if i < 0 && !d.config.WeaklyTypedInput {
|
||||
return fmt.Errorf("cannot parse '%s', %d overflows uint",
|
||||
name, i)
|
||||
}
|
||||
val.SetUint(uint64(i))
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
||||
@@ -867,31 +678,27 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
|
||||
}
|
||||
|
||||
tagValue := f.Tag.Get(d.config.TagName)
|
||||
keyName := f.Name
|
||||
tagParts := strings.Split(tagValue, ",")
|
||||
|
||||
// If Squash is set in the config, we squash the field down.
|
||||
squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous
|
||||
// Determine the name of the key in the map
|
||||
if index := strings.Index(tagValue, ","); index != -1 {
|
||||
if tagValue[:index] == "-" {
|
||||
continue
|
||||
}
|
||||
// If "omitempty" is specified in the tag, it ignores empty values.
|
||||
if strings.Index(tagValue[index+1:], "omitempty") != -1 && isEmptyValue(v) {
|
||||
keyName := f.Name
|
||||
if tagParts[0] != "" {
|
||||
if tagParts[0] == "-" {
|
||||
continue
|
||||
}
|
||||
keyName = tagParts[0]
|
||||
}
|
||||
|
||||
// If "squash" is specified in the tag, we squash the field down.
|
||||
squash = !squash && strings.Index(tagValue[index+1:], "squash") != -1
|
||||
if squash && v.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
|
||||
// If "squash" is specified in the tag, we squash the field down.
|
||||
squash := false
|
||||
for _, tag := range tagParts[1:] {
|
||||
if tag == "squash" {
|
||||
squash = true
|
||||
break
|
||||
}
|
||||
keyName = tagValue[:index]
|
||||
} else if len(tagValue) > 0 {
|
||||
if tagValue == "-" {
|
||||
continue
|
||||
}
|
||||
keyName = tagValue
|
||||
}
|
||||
if squash && v.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
|
||||
}
|
||||
|
||||
switch v.Kind() {
|
||||
@@ -906,22 +713,11 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
|
||||
mType := reflect.MapOf(vKeyType, vElemType)
|
||||
vMap := reflect.MakeMap(mType)
|
||||
|
||||
// Creating a pointer to a map so that other methods can completely
|
||||
// overwrite the map if need be (looking at you decodeMapFromMap). The
|
||||
// indirection allows the underlying map to be settable (CanSet() == true)
|
||||
// where as reflect.MakeMap returns an unsettable map.
|
||||
addrVal := reflect.New(vMap.Type())
|
||||
reflect.Indirect(addrVal).Set(vMap)
|
||||
|
||||
err := d.decode(keyName, x.Interface(), reflect.Indirect(addrVal))
|
||||
err := d.decode(keyName, x.Interface(), vMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// the underlying map may have been completely overwritten so pull
|
||||
// it indirectly out of the enclosing value.
|
||||
vMap = reflect.Indirect(addrVal)
|
||||
|
||||
if squash {
|
||||
for _, k := range vMap.MapKeys() {
|
||||
valMap.SetMapIndex(k, vMap.MapIndex(k))
|
||||
@@ -942,7 +738,7 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) (bool, error) {
|
||||
func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error {
|
||||
// If the input data is nil, then we want to just set the output
|
||||
// pointer to be nil as well.
|
||||
isNil := data == nil
|
||||
@@ -963,7 +759,7 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) (b
|
||||
val.Set(nilValue)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create an element of the concrete (non pointer) type and decode
|
||||
@@ -977,16 +773,16 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) (b
|
||||
}
|
||||
|
||||
if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
|
||||
return false, err
|
||||
return err
|
||||
}
|
||||
|
||||
val.Set(realVal)
|
||||
} else {
|
||||
if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
|
||||
return false, err
|
||||
return err
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
|
||||
@@ -1009,8 +805,8 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
|
||||
valElemType := valType.Elem()
|
||||
sliceType := reflect.SliceOf(valElemType)
|
||||
|
||||
// If we have a non array/slice type then we first attempt to convert.
|
||||
if dataValKind != reflect.Array && dataValKind != reflect.Slice {
|
||||
valSlice := val
|
||||
if valSlice.IsNil() || d.config.ZeroFields {
|
||||
if d.config.WeaklyTypedInput {
|
||||
switch {
|
||||
// Slice and array we use the normal logic
|
||||
@@ -1037,17 +833,18 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf(
|
||||
"'%s': source data must be an array or slice, got %s", name, dataValKind)
|
||||
}
|
||||
// Check input type
|
||||
if dataValKind != reflect.Array && dataValKind != reflect.Slice {
|
||||
return fmt.Errorf(
|
||||
"'%s': source data must be an array or slice, got %s", name, dataValKind)
|
||||
|
||||
// If the input value is nil, then don't allocate since empty != nil
|
||||
if dataVal.IsNil() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// If the input value is empty, then don't allocate since non-nil != nil
|
||||
if dataVal.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
valSlice := val
|
||||
if valSlice.IsNil() || d.config.ZeroFields {
|
||||
// Make a new slice to hold our result, same size as the original data.
|
||||
valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
|
||||
}
|
||||
@@ -1165,23 +962,13 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
|
||||
// Not the most efficient way to do this but we can optimize later if
|
||||
// we want to. To convert from struct to struct we go to map first
|
||||
// as an intermediary.
|
||||
|
||||
// Make a new map to hold our result
|
||||
mapType := reflect.TypeOf((map[string]interface{})(nil))
|
||||
mval := reflect.MakeMap(mapType)
|
||||
|
||||
// Creating a pointer to a map so that other methods can completely
|
||||
// overwrite the map if need be (looking at you decodeMapFromMap). The
|
||||
// indirection allows the underlying map to be settable (CanSet() == true)
|
||||
// where as reflect.MakeMap returns an unsettable map.
|
||||
addrVal := reflect.New(mval.Type())
|
||||
|
||||
reflect.Indirect(addrVal).Set(mval)
|
||||
if err := d.decodeMapFromStruct(name, dataVal, reflect.Indirect(addrVal), mval); err != nil {
|
||||
m := make(map[string]interface{})
|
||||
mval := reflect.Indirect(reflect.ValueOf(&m))
|
||||
if err := d.decodeMapFromStruct(name, dataVal, mval, mval); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result := d.decodeStructFromMap(name, reflect.Indirect(addrVal), val)
|
||||
result := d.decodeStructFromMap(name, mval, val)
|
||||
return result
|
||||
|
||||
default:
|
||||
@@ -1218,11 +1005,6 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||
field reflect.StructField
|
||||
val reflect.Value
|
||||
}
|
||||
|
||||
// remainField is set to a valid field set with the "remain" tag if
|
||||
// we are keeping track of remaining values.
|
||||
var remainField *field
|
||||
|
||||
fields := []field{}
|
||||
for len(structs) > 0 {
|
||||
structVal := structs[0]
|
||||
@@ -1235,21 +1017,13 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||
fieldKind := fieldType.Type.Kind()
|
||||
|
||||
// If "squash" is specified in the tag, we squash the field down.
|
||||
squash := d.config.Squash && fieldKind == reflect.Struct && fieldType.Anonymous
|
||||
remain := false
|
||||
|
||||
// We always parse the tags cause we're looking for other tags too
|
||||
squash := false
|
||||
tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
|
||||
for _, tag := range tagParts[1:] {
|
||||
if tag == "squash" {
|
||||
squash = true
|
||||
break
|
||||
}
|
||||
|
||||
if tag == "remain" {
|
||||
remain = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if squash {
|
||||
@@ -1262,13 +1036,8 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||
continue
|
||||
}
|
||||
|
||||
// Build our field
|
||||
if remain {
|
||||
remainField = &field{fieldType, structVal.Field(i)}
|
||||
} else {
|
||||
// Normal struct field, store it away
|
||||
fields = append(fields, field{fieldType, structVal.Field(i)})
|
||||
}
|
||||
// Normal struct field, store it away
|
||||
fields = append(fields, field{fieldType, structVal.Field(i)})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1309,6 +1078,9 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the key we're using from the unused map so we stop tracking
|
||||
delete(dataValKeysUnused, rawMapKey.Interface())
|
||||
|
||||
if !fieldValue.IsValid() {
|
||||
// This should never happen
|
||||
panic("field is not valid")
|
||||
@@ -1320,9 +1092,6 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||
continue
|
||||
}
|
||||
|
||||
// Delete the key we're using from the unused map so we stop tracking
|
||||
delete(dataValKeysUnused, rawMapKey.Interface())
|
||||
|
||||
// If the name is empty string, then we're at the root, and we
|
||||
// don't dot-join the fields.
|
||||
if name != "" {
|
||||
@@ -1334,25 +1103,6 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a "remain"-tagged field and we have unused keys then
|
||||
// we put the unused keys directly into the remain field.
|
||||
if remainField != nil && len(dataValKeysUnused) > 0 {
|
||||
// Build a map of only the unused values
|
||||
remain := map[interface{}]interface{}{}
|
||||
for key := range dataValKeysUnused {
|
||||
remain[key] = dataVal.MapIndex(reflect.ValueOf(key)).Interface()
|
||||
}
|
||||
|
||||
// Decode it as-if we were just decoding this map onto our map.
|
||||
if err := d.decodeMap(name, remain, remainField.val); err != nil {
|
||||
errors = appendErrors(errors, err)
|
||||
}
|
||||
|
||||
// Set the map to nil so we have none so that the next check will
|
||||
// not error (ErrorUnused)
|
||||
dataValKeysUnused = nil
|
||||
}
|
||||
|
||||
if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
|
||||
keys := make([]string, 0, len(dataValKeysUnused))
|
||||
for rawKey := range dataValKeysUnused {
|
||||
@@ -1383,24 +1133,6 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func isEmptyValue(v reflect.Value) bool {
|
||||
switch getKind(v) {
|
||||
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||
return v.Len() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
return v.IsNil()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getKind(val reflect.Value) reflect.Kind {
|
||||
kind := val.Kind()
|
||||
|
||||
|
||||
5
vendor/github.com/mreiferson/go-httpclient/.travis.yml
generated
vendored
5
vendor/github.com/mreiferson/go-httpclient/.travis.yml
generated
vendored
@@ -1,6 +1,9 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.1
|
||||
- '1.x'
|
||||
arch:
|
||||
- amd64
|
||||
- ppc64le
|
||||
install:
|
||||
- go get github.com/bmizerany/assert
|
||||
script:
|
||||
|
||||
13
vendor/github.com/rs/xid/README.md
generated
vendored
13
vendor/github.com/rs/xid/README.md
generated
vendored
@@ -2,9 +2,9 @@
|
||||
|
||||
[](https://godoc.org/github.com/rs/xid) [](https://raw.githubusercontent.com/rs/xid/master/LICENSE) [](https://travis-ci.org/rs/xid) [](http://gocover.io/github.com/rs/xid)
|
||||
|
||||
Package xid is a globally unique id generator library, ready to be used safely directly in your server code.
|
||||
Package xid is a globally unique id generator library, ready to safely be used directly in your server code.
|
||||
|
||||
Xid is using Mongo Object ID algorithm to generate globally unique ids with a different serialization (base64) to make it shorter when transported as a string:
|
||||
Xid uses the Mongo Object ID algorithm to generate globally unique ids with a different serialization (base64) to make it shorter when transported as a string:
|
||||
https://docs.mongodb.org/manual/reference/object-id/
|
||||
|
||||
- 4-byte value representing the seconds since the Unix epoch,
|
||||
@@ -33,7 +33,7 @@ is required so it can be used directly in server's code.
|
||||
|-------------|-------------|----------------|----------------
|
||||
| [UUID] | 16 bytes | 36 chars | configuration free, not sortable
|
||||
| [shortuuid] | 16 bytes | 22 chars | configuration free, not sortable
|
||||
| [Snowflake] | 8 bytes | up to 20 chars | needs machin/DC configuration, needs central server, sortable
|
||||
| [Snowflake] | 8 bytes | up to 20 chars | needs machine/DC configuration, needs central server, sortable
|
||||
| [MongoID] | 12 bytes | 24 chars | configuration free, sortable
|
||||
| xid | 12 bytes | 20 chars | configuration free, sortable
|
||||
|
||||
@@ -57,7 +57,7 @@ Best used with [zerolog](https://github.com/rs/zerolog)'s
|
||||
|
||||
Notes:
|
||||
|
||||
- Xid is dependent on the system time, a monotonic counter and so is not cryptographically secure. If unpredictability of IDs is important, you should not use Xids. It is worth noting that most of the other UUID like implementations are also not cryptographically secure. You shoud use libraries that rely on cryptographically secure sources (like /dev/urandom on unix, crypto/rand in golang), if you want a truly random ID generator.
|
||||
- Xid is dependent on the system time, a monotonic counter and so is not cryptographically secure. If unpredictability of IDs is important, you should not use Xids. It is worth noting that most other UUID-like implementations are also not cryptographically secure. You should use libraries that rely on cryptographically secure sources (like /dev/urandom on unix, crypto/rand in golang), if you want a truly random ID generator.
|
||||
|
||||
References:
|
||||
|
||||
@@ -66,6 +66,9 @@ References:
|
||||
- https://blog.twitter.com/2010/announcing-snowflake
|
||||
- Python port by [Graham Abbott](https://github.com/graham): https://github.com/graham/python_xid
|
||||
- Scala port by [Egor Kolotaev](https://github.com/kolotaev): https://github.com/kolotaev/ride
|
||||
- Rust port by [Jérôme Renard](https://github.com/jeromer/): https://github.com/jeromer/libxid
|
||||
- Ruby port by [Valar](https://github.com/valarpirai/): https://github.com/valarpirai/ruby_xid
|
||||
- Java port by [0xShamil](https://github.com/0xShamil/): https://github.com/0xShamil/java-xid
|
||||
|
||||
## Install
|
||||
|
||||
@@ -105,7 +108,7 @@ BenchmarkUUIDv4-2 1000000 1427 ns/op 64 B/op 2 allocs/op
|
||||
BenchmarkUUIDv4-4 1000000 1452 ns/op 64 B/op 2 allocs/op
|
||||
```
|
||||
|
||||
Note: UUIDv1 requires a global lock, hence the performence degrading as we add more CPUs.
|
||||
Note: UUIDv1 requires a global lock, hence the performance degradation as we add more CPUs.
|
||||
|
||||
## Licenses
|
||||
|
||||
|
||||
2
vendor/github.com/rs/xid/go.mod
generated
vendored
2
vendor/github.com/rs/xid/go.mod
generated
vendored
@@ -1 +1,3 @@
|
||||
module github.com/rs/xid
|
||||
|
||||
go 1.12
|
||||
|
||||
5
vendor/github.com/rs/xid/hostid_linux.go
generated
vendored
5
vendor/github.com/rs/xid/hostid_linux.go
generated
vendored
@@ -5,6 +5,9 @@ package xid
|
||||
import "io/ioutil"
|
||||
|
||||
func readPlatformMachineID() (string, error) {
|
||||
b, err := ioutil.ReadFile("/sys/class/dmi/id/product_uuid")
|
||||
b, err := ioutil.ReadFile("/etc/machine-id")
|
||||
if err != nil || len(b) == 0 {
|
||||
b, err = ioutil.ReadFile("/sys/class/dmi/id/product_uuid")
|
||||
}
|
||||
return string(b), err
|
||||
}
|
||||
|
||||
81
vendor/github.com/rs/xid/id.go
generated
vendored
81
vendor/github.com/rs/xid/id.go
generated
vendored
@@ -55,6 +55,7 @@ import (
|
||||
"sort"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Code inspired from mgo/bson ObjectId
|
||||
@@ -177,7 +178,13 @@ func FromString(id string) (ID, error) {
|
||||
func (id ID) String() string {
|
||||
text := make([]byte, encodedLen)
|
||||
encode(text, id[:])
|
||||
return string(text)
|
||||
return *(*string)(unsafe.Pointer(&text))
|
||||
}
|
||||
|
||||
// Encode encodes the id using base32 encoding, writing 20 bytes to dst and return it.
|
||||
func (id ID) Encode(dst []byte) []byte {
|
||||
encode(dst, id[:])
|
||||
return dst
|
||||
}
|
||||
|
||||
// MarshalText implements encoding/text TextMarshaler interface
|
||||
@@ -192,32 +199,37 @@ func (id ID) MarshalJSON() ([]byte, error) {
|
||||
if id.IsNil() {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
text, err := id.MarshalText()
|
||||
return []byte(`"` + string(text) + `"`), err
|
||||
text := make([]byte, encodedLen+2)
|
||||
encode(text[1:encodedLen+1], id[:])
|
||||
text[0], text[encodedLen+1] = '"', '"'
|
||||
return text, nil
|
||||
}
|
||||
|
||||
// encode by unrolling the stdlib base32 algorithm + removing all safe checks
|
||||
func encode(dst, id []byte) {
|
||||
dst[0] = encoding[id[0]>>3]
|
||||
dst[1] = encoding[(id[1]>>6)&0x1F|(id[0]<<2)&0x1F]
|
||||
dst[2] = encoding[(id[1]>>1)&0x1F]
|
||||
dst[3] = encoding[(id[2]>>4)&0x1F|(id[1]<<4)&0x1F]
|
||||
dst[4] = encoding[id[3]>>7|(id[2]<<1)&0x1F]
|
||||
dst[5] = encoding[(id[3]>>2)&0x1F]
|
||||
dst[6] = encoding[id[4]>>5|(id[3]<<3)&0x1F]
|
||||
dst[7] = encoding[id[4]&0x1F]
|
||||
dst[8] = encoding[id[5]>>3]
|
||||
dst[9] = encoding[(id[6]>>6)&0x1F|(id[5]<<2)&0x1F]
|
||||
dst[10] = encoding[(id[6]>>1)&0x1F]
|
||||
dst[11] = encoding[(id[7]>>4)&0x1F|(id[6]<<4)&0x1F]
|
||||
dst[12] = encoding[id[8]>>7|(id[7]<<1)&0x1F]
|
||||
dst[13] = encoding[(id[8]>>2)&0x1F]
|
||||
dst[14] = encoding[(id[9]>>5)|(id[8]<<3)&0x1F]
|
||||
dst[15] = encoding[id[9]&0x1F]
|
||||
dst[16] = encoding[id[10]>>3]
|
||||
dst[17] = encoding[(id[11]>>6)&0x1F|(id[10]<<2)&0x1F]
|
||||
dst[18] = encoding[(id[11]>>1)&0x1F]
|
||||
_ = dst[19]
|
||||
_ = id[11]
|
||||
|
||||
dst[19] = encoding[(id[11]<<4)&0x1F]
|
||||
dst[18] = encoding[(id[11]>>1)&0x1F]
|
||||
dst[17] = encoding[(id[11]>>6)&0x1F|(id[10]<<2)&0x1F]
|
||||
dst[16] = encoding[id[10]>>3]
|
||||
dst[15] = encoding[id[9]&0x1F]
|
||||
dst[14] = encoding[(id[9]>>5)|(id[8]<<3)&0x1F]
|
||||
dst[13] = encoding[(id[8]>>2)&0x1F]
|
||||
dst[12] = encoding[id[8]>>7|(id[7]<<1)&0x1F]
|
||||
dst[11] = encoding[(id[7]>>4)&0x1F|(id[6]<<4)&0x1F]
|
||||
dst[10] = encoding[(id[6]>>1)&0x1F]
|
||||
dst[9] = encoding[(id[6]>>6)&0x1F|(id[5]<<2)&0x1F]
|
||||
dst[8] = encoding[id[5]>>3]
|
||||
dst[7] = encoding[id[4]&0x1F]
|
||||
dst[6] = encoding[id[4]>>5|(id[3]<<3)&0x1F]
|
||||
dst[5] = encoding[(id[3]>>2)&0x1F]
|
||||
dst[4] = encoding[id[3]>>7|(id[2]<<1)&0x1F]
|
||||
dst[3] = encoding[(id[2]>>4)&0x1F|(id[1]<<4)&0x1F]
|
||||
dst[2] = encoding[(id[1]>>1)&0x1F]
|
||||
dst[1] = encoding[(id[1]>>6)&0x1F|(id[0]<<2)&0x1F]
|
||||
dst[0] = encoding[id[0]>>3]
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding/text TextUnmarshaler interface
|
||||
@@ -246,18 +258,21 @@ func (id *ID) UnmarshalJSON(b []byte) error {
|
||||
|
||||
// decode by unrolling the stdlib base32 algorithm + removing all safe checks
|
||||
func decode(id *ID, src []byte) {
|
||||
id[0] = dec[src[0]]<<3 | dec[src[1]]>>2
|
||||
id[1] = dec[src[1]]<<6 | dec[src[2]]<<1 | dec[src[3]]>>4
|
||||
id[2] = dec[src[3]]<<4 | dec[src[4]]>>1
|
||||
id[3] = dec[src[4]]<<7 | dec[src[5]]<<2 | dec[src[6]]>>3
|
||||
id[4] = dec[src[6]]<<5 | dec[src[7]]
|
||||
id[5] = dec[src[8]]<<3 | dec[src[9]]>>2
|
||||
id[6] = dec[src[9]]<<6 | dec[src[10]]<<1 | dec[src[11]]>>4
|
||||
id[7] = dec[src[11]]<<4 | dec[src[12]]>>1
|
||||
id[8] = dec[src[12]]<<7 | dec[src[13]]<<2 | dec[src[14]]>>3
|
||||
id[9] = dec[src[14]]<<5 | dec[src[15]]
|
||||
id[10] = dec[src[16]]<<3 | dec[src[17]]>>2
|
||||
_ = src[19]
|
||||
_ = id[11]
|
||||
|
||||
id[11] = dec[src[17]]<<6 | dec[src[18]]<<1 | dec[src[19]]>>4
|
||||
id[10] = dec[src[16]]<<3 | dec[src[17]]>>2
|
||||
id[9] = dec[src[14]]<<5 | dec[src[15]]
|
||||
id[8] = dec[src[12]]<<7 | dec[src[13]]<<2 | dec[src[14]]>>3
|
||||
id[7] = dec[src[11]]<<4 | dec[src[12]]>>1
|
||||
id[6] = dec[src[9]]<<6 | dec[src[10]]<<1 | dec[src[11]]>>4
|
||||
id[5] = dec[src[8]]<<3 | dec[src[9]]>>2
|
||||
id[4] = dec[src[6]]<<5 | dec[src[7]]
|
||||
id[3] = dec[src[4]]<<7 | dec[src[5]]<<2 | dec[src[6]]>>3
|
||||
id[2] = dec[src[3]]<<4 | dec[src[4]]>>1
|
||||
id[1] = dec[src[1]]<<6 | dec[src[2]]<<1 | dec[src[3]]>>4
|
||||
id[0] = dec[src[0]]<<3 | dec[src[1]]>>2
|
||||
}
|
||||
|
||||
// Time returns the timestamp part of the id.
|
||||
|
||||
14
vendor/github.com/sirupsen/logrus/.travis.yml
generated
vendored
14
vendor/github.com/sirupsen/logrus/.travis.yml
generated
vendored
@@ -4,14 +4,12 @@ git:
|
||||
depth: 1
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
go: [1.13.x, 1.14.x]
|
||||
os: [linux, osx]
|
||||
go: 1.15.x
|
||||
os: linux
|
||||
install:
|
||||
- ./travis/install.sh
|
||||
script:
|
||||
- ./travis/cross_build.sh
|
||||
- ./travis/lint.sh
|
||||
- export GOMAXPROCS=4
|
||||
- export GORACE=halt_on_error=1
|
||||
- go test -race -v ./...
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then go test -race -v -tags appengine ./... ; fi
|
||||
- cd ci
|
||||
- go run mage.go -v -w ../ crossBuild
|
||||
- go run mage.go -v -w ../ lint
|
||||
- go run mage.go -v -w ../ test
|
||||
|
||||
36
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
36
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
@@ -1,3 +1,39 @@
|
||||
# 1.8.1
|
||||
Code quality:
|
||||
* move magefile in its own subdir/submodule to remove magefile dependency on logrus consumer
|
||||
* improve timestamp format documentation
|
||||
|
||||
Fixes:
|
||||
* fix race condition on logger hooks
|
||||
|
||||
|
||||
# 1.8.0
|
||||
|
||||
Correct versioning number replacing v1.7.1.
|
||||
|
||||
# 1.7.1
|
||||
|
||||
Beware this release has introduced a new public API and its semver is therefore incorrect.
|
||||
|
||||
Code quality:
|
||||
* use go 1.15 in travis
|
||||
* use magefile as task runner
|
||||
|
||||
Fixes:
|
||||
* small fixes about new go 1.13 error formatting system
|
||||
* Fix for long time race condiction with mutating data hooks
|
||||
|
||||
Features:
|
||||
* build support for zos
|
||||
|
||||
# 1.7.0
|
||||
Fixes:
|
||||
* the dependency toward a windows terminal library has been removed
|
||||
|
||||
Features:
|
||||
* a new buffer pool management API has been added
|
||||
* a set of `<LogLevel>Fn()` functions have been added
|
||||
|
||||
# 1.6.0
|
||||
Fixes:
|
||||
* end of line cleanup
|
||||
|
||||
2
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
2
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
@@ -402,7 +402,7 @@ func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
// source of the official loggers.
|
||||
serialized, err := json.Marshal(entry.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %w", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
||||
|
||||
75
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
75
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
@@ -78,6 +78,14 @@ func NewEntry(logger *Logger) *Entry {
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Dup() *Entry {
|
||||
data := make(Fields, len(entry.Data))
|
||||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
}
|
||||
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, Context: entry.Context, err: entry.err}
|
||||
}
|
||||
|
||||
// Returns the bytes representation of this entry from the formatter.
|
||||
func (entry *Entry) Bytes() ([]byte, error) {
|
||||
return entry.Logger.Formatter.Format(entry)
|
||||
@@ -123,11 +131,9 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
|
||||
for k, v := range fields {
|
||||
isErrField := false
|
||||
if t := reflect.TypeOf(v); t != nil {
|
||||
switch t.Kind() {
|
||||
case reflect.Func:
|
||||
switch {
|
||||
case t.Kind() == reflect.Func, t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Func:
|
||||
isErrField = true
|
||||
case reflect.Ptr:
|
||||
isErrField = t.Elem().Kind() == reflect.Func
|
||||
}
|
||||
}
|
||||
if isErrField {
|
||||
@@ -212,68 +218,72 @@ func (entry Entry) HasCaller() (has bool) {
|
||||
entry.Caller != nil
|
||||
}
|
||||
|
||||
// This function is not declared with a pointer value because otherwise
|
||||
// race conditions will occur when using multiple goroutines
|
||||
func (entry Entry) log(level Level, msg string) {
|
||||
func (entry *Entry) log(level Level, msg string) {
|
||||
var buffer *bytes.Buffer
|
||||
|
||||
// Default to now, but allow users to override if they want.
|
||||
//
|
||||
// We don't have to worry about polluting future calls to Entry#log()
|
||||
// with this assignment because this function is declared with a
|
||||
// non-pointer receiver.
|
||||
if entry.Time.IsZero() {
|
||||
entry.Time = time.Now()
|
||||
newEntry := entry.Dup()
|
||||
|
||||
if newEntry.Time.IsZero() {
|
||||
newEntry.Time = time.Now()
|
||||
}
|
||||
|
||||
entry.Level = level
|
||||
entry.Message = msg
|
||||
entry.Logger.mu.Lock()
|
||||
if entry.Logger.ReportCaller {
|
||||
entry.Caller = getCaller()
|
||||
}
|
||||
entry.Logger.mu.Unlock()
|
||||
newEntry.Level = level
|
||||
newEntry.Message = msg
|
||||
|
||||
entry.fireHooks()
|
||||
newEntry.Logger.mu.Lock()
|
||||
reportCaller := newEntry.Logger.ReportCaller
|
||||
newEntry.Logger.mu.Unlock()
|
||||
|
||||
if reportCaller {
|
||||
newEntry.Caller = getCaller()
|
||||
}
|
||||
|
||||
newEntry.fireHooks()
|
||||
|
||||
buffer = getBuffer()
|
||||
defer func() {
|
||||
entry.Buffer = nil
|
||||
newEntry.Buffer = nil
|
||||
putBuffer(buffer)
|
||||
}()
|
||||
buffer.Reset()
|
||||
entry.Buffer = buffer
|
||||
newEntry.Buffer = buffer
|
||||
|
||||
entry.write()
|
||||
newEntry.write()
|
||||
|
||||
entry.Buffer = nil
|
||||
newEntry.Buffer = nil
|
||||
|
||||
// To avoid Entry#log() returning a value that only would make sense for
|
||||
// panic() to use in Entry#Panic(), we avoid the allocation by checking
|
||||
// directly here.
|
||||
if level <= PanicLevel {
|
||||
panic(&entry)
|
||||
panic(newEntry)
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) fireHooks() {
|
||||
var tmpHooks LevelHooks
|
||||
entry.Logger.mu.Lock()
|
||||
defer entry.Logger.mu.Unlock()
|
||||
err := entry.Logger.Hooks.Fire(entry.Level, entry)
|
||||
tmpHooks = make(LevelHooks, len(entry.Logger.Hooks))
|
||||
for k, v := range entry.Logger.Hooks {
|
||||
tmpHooks[k] = v
|
||||
}
|
||||
entry.Logger.mu.Unlock()
|
||||
|
||||
err := tmpHooks.Fire(entry.Level, entry)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) write() {
|
||||
entry.Logger.mu.Lock()
|
||||
defer entry.Logger.mu.Unlock()
|
||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
||||
return
|
||||
}
|
||||
if _, err = entry.Logger.Out.Write(serialized); err != nil {
|
||||
entry.Logger.mu.Lock()
|
||||
defer entry.Logger.mu.Unlock()
|
||||
if _, err := entry.Logger.Out.Write(serialized); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||
}
|
||||
}
|
||||
@@ -319,7 +329,6 @@ func (entry *Entry) Fatal(args ...interface{}) {
|
||||
|
||||
func (entry *Entry) Panic(args ...interface{}) {
|
||||
entry.Log(PanicLevel, args...)
|
||||
panic(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
// Entry Printf family functions
|
||||
|
||||
2
vendor/github.com/sirupsen/logrus/go.sum
generated
vendored
2
vendor/github.com/sirupsen/logrus/go.sum
generated
vendored
@@ -4,7 +4,5 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
5
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
5
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
@@ -23,6 +23,9 @@ func (f FieldMap) resolve(key fieldKey) string {
|
||||
// JSONFormatter formats logs into parsable json
|
||||
type JSONFormatter struct {
|
||||
// TimestampFormat sets the format used for marshaling timestamps.
|
||||
// The format to use is the same than for time.Format or time.Parse from the standard
|
||||
// library.
|
||||
// The standard Library already provides a set of predefined format.
|
||||
TimestampFormat string
|
||||
|
||||
// DisableTimestamp allows disabling automatic timestamps in output
|
||||
@@ -118,7 +121,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
encoder.SetIndent("", " ")
|
||||
}
|
||||
if err := encoder.Encode(data); err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal fields to JSON, %v", err)
|
||||
return nil, fmt.Errorf("failed to marshal fields to JSON, %w", err)
|
||||
}
|
||||
|
||||
return b.Bytes(), nil
|
||||
|
||||
2
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
2
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
@@ -12,7 +12,7 @@ import (
|
||||
// LogFunction For big messages, it can be more efficient to pass a function
|
||||
// and only call it if the log level is actually enables rather than
|
||||
// generating the log message and then checking if the level is enabled
|
||||
type LogFunction func()[]interface{}
|
||||
type LogFunction func() []interface{}
|
||||
|
||||
type Logger struct {
|
||||
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
|
||||
|
||||
2
vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
2
vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// +build linux aix
|
||||
// +build linux aix zos
|
||||
// +build !js
|
||||
|
||||
package logrus
|
||||
|
||||
7
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
7
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
@@ -53,7 +53,10 @@ type TextFormatter struct {
|
||||
// the time passed since beginning of execution.
|
||||
FullTimestamp bool
|
||||
|
||||
// TimestampFormat to use for display when a full timestamp is printed
|
||||
// TimestampFormat to use for display when a full timestamp is printed.
|
||||
// The format to use is the same than for time.Format or time.Parse from the standard
|
||||
// library.
|
||||
// The standard Library already provides a set of predefined format.
|
||||
TimestampFormat string
|
||||
|
||||
// The fields are sorted by default for a consistent output. For applications
|
||||
@@ -235,6 +238,8 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
|
||||
levelColor = yellow
|
||||
case ErrorLevel, FatalLevel, PanicLevel:
|
||||
levelColor = red
|
||||
case InfoLevel:
|
||||
levelColor = blue
|
||||
default:
|
||||
levelColor = blue
|
||||
}
|
||||
|
||||
2
vendor/github.com/slack-go/slack/README.md
generated
vendored
2
vendor/github.com/slack-go/slack/README.md
generated
vendored
@@ -1,6 +1,6 @@
|
||||
Slack API in Go [](https://godoc.org/github.com/slack-go/slack) [](https://travis-ci.org/slack-go/slack)
|
||||
===============
|
||||
This is the original Slack library for Go created by Norberto Lopez, transferred to a Github organization.
|
||||
This is the original Slack library for Go created by Norberto Lopes, transferred to a Github organization.
|
||||
|
||||
[](https://gitter.im/go-slack/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
|
||||
5
vendor/github.com/slack-go/slack/attachments.go
generated
vendored
5
vendor/github.com/slack-go/slack/attachments.go
generated
vendored
@@ -80,6 +80,11 @@ type Attachment struct {
|
||||
ImageURL string `json:"image_url,omitempty"`
|
||||
ThumbURL string `json:"thumb_url,omitempty"`
|
||||
|
||||
ServiceName string `json:"service_name,omitempty"`
|
||||
ServiceIcon string `json:"service_icon,omitempty"`
|
||||
FromURL string `json:"from_url,omitempty"`
|
||||
OriginalURL string `json:"original_url,omitempty"`
|
||||
|
||||
Fields []AttachmentField `json:"fields,omitempty"`
|
||||
Actions []AttachmentAction `json:"actions,omitempty"`
|
||||
MarkdownIn []string `json:"mrkdwn_in,omitempty"`
|
||||
|
||||
1
vendor/github.com/slack-go/slack/block_element.go
generated
vendored
1
vendor/github.com/slack-go/slack/block_element.go
generated
vendored
@@ -268,6 +268,7 @@ type MultiSelectBlockElement struct {
|
||||
InitialConversations []string `json:"initial_conversations,omitempty"`
|
||||
InitialChannels []string `json:"initial_channels,omitempty"`
|
||||
MinQueryLength *int `json:"min_query_length,omitempty"`
|
||||
MaxSelectedItems *int `json:"max_selected_items,omitempty"`
|
||||
Confirm *ConfirmationBlockObject `json:"confirm,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
13
vendor/github.com/slack-go/slack/block_input.go
generated
vendored
13
vendor/github.com/slack-go/slack/block_input.go
generated
vendored
@@ -4,12 +4,13 @@ package slack
|
||||
//
|
||||
// More Information: https://api.slack.com/reference/block-kit/blocks#input
|
||||
type InputBlock struct {
|
||||
Type MessageBlockType `json:"type"`
|
||||
BlockID string `json:"block_id,omitempty"`
|
||||
Label *TextBlockObject `json:"label"`
|
||||
Element BlockElement `json:"element"`
|
||||
Hint *TextBlockObject `json:"hint,omitempty"`
|
||||
Optional bool `json:"optional,omitempty"`
|
||||
Type MessageBlockType `json:"type"`
|
||||
BlockID string `json:"block_id,omitempty"`
|
||||
Label *TextBlockObject `json:"label"`
|
||||
Element BlockElement `json:"element"`
|
||||
Hint *TextBlockObject `json:"hint,omitempty"`
|
||||
Optional bool `json:"optional,omitempty"`
|
||||
DispatchAction bool `json:"dispatch_action,omitempty"`
|
||||
}
|
||||
|
||||
// BlockType returns the type of the block
|
||||
|
||||
15
vendor/github.com/slack-go/slack/block_object.go
generated
vendored
15
vendor/github.com/slack-go/slack/block_object.go
generated
vendored
@@ -2,6 +2,7 @@ package slack
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// Block Objects are also known as Composition Objects
|
||||
@@ -135,6 +136,20 @@ func (s TextBlockObject) MixedElementType() MixedElementType {
|
||||
return MixedElementText
|
||||
}
|
||||
|
||||
// Validate checks if TextBlockObject has valid values
|
||||
func (s TextBlockObject) Validate() error {
|
||||
if s.Type != "plain_text" && s.Type != "mrkdwn" {
|
||||
return errors.New("type must be either of plain_text or mrkdwn")
|
||||
}
|
||||
|
||||
// https://github.com/slack-go/slack/issues/881
|
||||
if s.Type == "mrkdwn" && s.Emoji {
|
||||
return errors.New("emoji cannot be true in mrkdown")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewTextBlockObject returns an instance of a new Text Block Object
|
||||
func NewTextBlockObject(elementType, text string, emoji, verbatim bool) *TextBlockObject {
|
||||
return &TextBlockObject{
|
||||
|
||||
4
vendor/github.com/slack-go/slack/reminders.go
generated
vendored
4
vendor/github.com/slack-go/slack/reminders.go
generated
vendored
@@ -22,7 +22,7 @@ type reminderResp struct {
|
||||
|
||||
type remindersResp struct {
|
||||
SlackResponse
|
||||
Reminders []Reminder `json:"reminders"`
|
||||
Reminders []*Reminder `json:"reminders"`
|
||||
}
|
||||
|
||||
func (api *Client) doReminder(ctx context.Context, path string, values url.Values) (*Reminder, error) {
|
||||
@@ -42,7 +42,7 @@ func (api *Client) doReminders(ctx context.Context, path string, values url.Valu
|
||||
// create an array of pointers to reminders
|
||||
var reminders = make([]*Reminder, 0, len(response.Reminders))
|
||||
for _, reminder := range response.Reminders {
|
||||
reminders = append(reminders, &reminder)
|
||||
reminders = append(reminders, reminder)
|
||||
}
|
||||
|
||||
return reminders, response.Err()
|
||||
|
||||
5
vendor/github.com/slack-go/slack/users.go
generated
vendored
5
vendor/github.com/slack-go/slack/users.go
generated
vendored
@@ -644,10 +644,13 @@ type getUserProfileResponse struct {
|
||||
|
||||
// GetUserProfileContext retrieves a user's profile information with a context.
|
||||
func (api *Client) GetUserProfileContext(ctx context.Context, userID string, includeLabels bool) (*UserProfile, error) {
|
||||
values := url.Values{"token": {api.token}, "user": {userID}}
|
||||
values := url.Values{"token": {api.token}}
|
||||
if includeLabels {
|
||||
values.Add("include_labels", "true")
|
||||
}
|
||||
if userID != "" {
|
||||
values.Add("user", userID)
|
||||
}
|
||||
resp := &getUserProfileResponse{}
|
||||
|
||||
err := api.postMethod(ctx, "users.profile.get", values, &resp)
|
||||
|
||||
1
vendor/github.com/slack-go/slack/websocket_internals.go
generated
vendored
1
vendor/github.com/slack-go/slack/websocket_internals.go
generated
vendored
@@ -94,6 +94,7 @@ func (i *IncomingEventError) Error() string {
|
||||
// AckErrorEvent i
|
||||
type AckErrorEvent struct {
|
||||
ErrorObj error
|
||||
ReplyTo int
|
||||
}
|
||||
|
||||
func (a *AckErrorEvent) Error() string {
|
||||
|
||||
7
vendor/github.com/slack-go/slack/websocket_managed_conn.go
generated
vendored
7
vendor/github.com/slack-go/slack/websocket_managed_conn.go
generated
vendored
@@ -91,6 +91,7 @@ func (rtm *RTM) connect(connectionCount int, useRTMStart bool) (*Info, *websocke
|
||||
errInvalidAuth = "invalid_auth"
|
||||
errInactiveAccount = "account_inactive"
|
||||
errMissingAuthToken = "not_authed"
|
||||
errTokenRevoked = "token_revoked"
|
||||
)
|
||||
|
||||
// used to provide exponential backoff wait time with jitter before trying
|
||||
@@ -118,7 +119,7 @@ func (rtm *RTM) connect(connectionCount int, useRTMStart bool) (*Info, *websocke
|
||||
|
||||
// check for fatal errors
|
||||
switch err.Error() {
|
||||
case errInvalidAuth, errInactiveAccount, errMissingAuthToken:
|
||||
case errInvalidAuth, errInactiveAccount, errMissingAuthToken, errTokenRevoked:
|
||||
rtm.Debugf("invalid auth when connecting with RTM: %s", err)
|
||||
rtm.IncomingEvents <- RTMEvent{"invalid_auth", &InvalidAuthEvent{}}
|
||||
return nil, nil, err
|
||||
@@ -438,10 +439,10 @@ func (rtm *RTM) handleAck(event json.RawMessage) {
|
||||
if ack.RTMResponse.Error.Code == -1 && ack.RTMResponse.Error.Msg == "slow down, too many messages..." {
|
||||
rtm.IncomingEvents <- RTMEvent{"ack_error", &RateLimitEvent{}}
|
||||
} else {
|
||||
rtm.IncomingEvents <- RTMEvent{"ack_error", &AckErrorEvent{ack.Error}}
|
||||
rtm.IncomingEvents <- RTMEvent{"ack_error", &AckErrorEvent{ack.Error, ack.ReplyTo}}
|
||||
}
|
||||
} else {
|
||||
rtm.IncomingEvents <- RTMEvent{"ack_error", &AckErrorEvent{fmt.Errorf("ack decode failure")}}
|
||||
rtm.IncomingEvents <- RTMEvent{"ack_error", &AckErrorEvent{ErrorObj: fmt.Errorf("ack decode failure")}}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/spf13/jwalterweatherman/.gitignore
generated
vendored
2
vendor/github.com/spf13/jwalterweatherman/.gitignore
generated
vendored
@@ -20,5 +20,3 @@ _cgo_export.*
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.bench
|
||||
go.sum
|
||||
30
vendor/github.com/spf13/jwalterweatherman/default_notepad.go
generated
vendored
30
vendor/github.com/spf13/jwalterweatherman/default_notepad.go
generated
vendored
@@ -64,13 +64,6 @@ func SetStdoutThreshold(threshold Threshold) {
|
||||
reloadDefaultNotepad()
|
||||
}
|
||||
|
||||
// SetStdoutOutput set the stdout output for the default notepad. Default is stdout.
|
||||
func SetStdoutOutput(handle io.Writer) {
|
||||
defaultNotepad.outHandle = handle
|
||||
defaultNotepad.init()
|
||||
reloadDefaultNotepad()
|
||||
}
|
||||
|
||||
// SetPrefix set the prefix for the default logger. Empty by default.
|
||||
func SetPrefix(prefix string) {
|
||||
defaultNotepad.SetPrefix(prefix)
|
||||
@@ -83,13 +76,6 @@ func SetFlags(flags int) {
|
||||
reloadDefaultNotepad()
|
||||
}
|
||||
|
||||
// SetLogListeners configures the default logger with one or more log listeners.
|
||||
func SetLogListeners(l ...LogListener) {
|
||||
defaultNotepad.logListeners = l
|
||||
defaultNotepad.init()
|
||||
reloadDefaultNotepad()
|
||||
}
|
||||
|
||||
// Level returns the current global log threshold.
|
||||
func LogThreshold() Threshold {
|
||||
return defaultNotepad.logThreshold
|
||||
@@ -109,3 +95,19 @@ func GetLogThreshold() Threshold {
|
||||
func GetStdoutThreshold() Threshold {
|
||||
return defaultNotepad.GetStdoutThreshold()
|
||||
}
|
||||
|
||||
// LogCountForLevel returns the number of log invocations for a given threshold.
|
||||
func LogCountForLevel(l Threshold) uint64 {
|
||||
return defaultNotepad.LogCountForLevel(l)
|
||||
}
|
||||
|
||||
// LogCountForLevelsGreaterThanorEqualTo returns the number of log invocations
|
||||
// greater than or equal to a given threshold.
|
||||
func LogCountForLevelsGreaterThanorEqualTo(threshold Threshold) uint64 {
|
||||
return defaultNotepad.LogCountForLevelsGreaterThanorEqualTo(threshold)
|
||||
}
|
||||
|
||||
// ResetLogCounters resets the invocation counters for all levels.
|
||||
func ResetLogCounters() {
|
||||
defaultNotepad.ResetLogCounters()
|
||||
}
|
||||
|
||||
6
vendor/github.com/spf13/jwalterweatherman/go.mod
generated
vendored
6
vendor/github.com/spf13/jwalterweatherman/go.mod
generated
vendored
@@ -1,7 +1 @@
|
||||
module github.com/spf13/jwalterweatherman
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.2.2
|
||||
)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user