From 2c349c50c72ad2eb503d08bd59e4fc98b3c7e9a0 Mon Sep 17 00:00:00 2001 From: Joseph Mansy <36427684+yousefmansy1@users.noreply.github.com> Date: Fri, 10 Mar 2023 13:28:32 -0800 Subject: [PATCH 1/8] Support handling delete message from whatsapp. (#1986) --- bridge/whatsappmulti/handlers.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/bridge/whatsappmulti/handlers.go b/bridge/whatsappmulti/handlers.go index b8e78572..d99c6727 100644 --- a/bridge/whatsappmulti/handlers.go +++ b/bridge/whatsappmulti/handlers.go @@ -44,6 +44,8 @@ func (b *Bwhatsapp) handleMessage(message *events.Message) { b.handleDocumentMessage(message) case msg.ImageMessage != nil: b.handleImageMessage(message) + case msg.ProtocolMessage != nil && *msg.ProtocolMessage.Type == proto.ProtocolMessage_REVOKE: + b.handleDelete(msg.ProtocolMessage) } } @@ -359,3 +361,20 @@ func (b *Bwhatsapp) handleDocumentMessage(msg *events.Message) { b.Remote <- rmsg } + +func (b *Bwhatsapp) handleDelete(messageInfo *proto.ProtocolMessage) { + sender, _ := types.ParseJID(*messageInfo.Key.Participant) + + rmsg := config.Message{ + Account: b.Account, + Protocol: b.Protocol, + ID: getMessageIdFormat(sender, *messageInfo.Key.Id), + Event: config.EventMsgDelete, + Text: config.EventMsgDelete, + Channel: *messageInfo.Key.RemoteJid, + } + + b.Log.Debugf("<= Sending message from %s to gateway", b.Account) + b.Log.Debugf("<= Message is %#v", rmsg) + b.Remote <- rmsg +} From 53b63adc71938b020e5003ed29382a14166de1db Mon Sep 17 00:00:00 2001 From: Wim Date: Fri, 10 Mar 2023 22:29:44 +0100 Subject: [PATCH 2/8] Update to actions v3 (#2009) --- .github/workflows/development.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index ff8c1ce4..ed3ac762 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -5,11 +5,11 @@ jobs: name: golangci-lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 20 - name: Run golangci-lint - uses: golangci/golangci-lint-action@v2 + uses: golangci/golangci-lint-action@v3 with: version: latest args: "-v --new-from-rev HEAD~5" @@ -21,12 +21,12 @@ jobs: runs-on: ${{ matrix.platform }} steps: - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: ${{ matrix.go-version }} stable: false - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Test @@ -40,19 +40,19 @@ jobs: CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "-s -X github.com/42wim/matterbridge/version.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.20') - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: matterbridge-linux-64bit path: output/lin - name: Upload windows 64-bit if: startsWith(matrix.go-version,'1.20') - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: matterbridge-windows-64bit path: output/win - name: Upload darwin 64-bit if: startsWith(matrix.go-version,'1.20') - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: matterbridge-darwin-64bit path: output/mac From 544cd5cd9ee8fc48b4056a10316f79d6a96c63bb Mon Sep 17 00:00:00 2001 From: ilmaisin Date: Fri, 10 Mar 2023 23:30:48 +0200 Subject: [PATCH 3/8] Fix Android media download problem (whatsapp) (#2010) --- bridge/whatsappmulti/whatsapp.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bridge/whatsappmulti/whatsapp.go b/bridge/whatsappmulti/whatsapp.go index e943fc86..99e56446 100644 --- a/bridge/whatsappmulti/whatsapp.go +++ b/bridge/whatsappmulti/whatsapp.go @@ -243,6 +243,7 @@ func (b *Bwhatsapp) PostDocumentMessage(msg config.Message, filetype string) (st FileSha256: resp.FileSHA256, FileLength: goproto.Uint64(resp.FileLength), Url: &resp.URL, + DirectPath: &resp.DirectPath, ContextInfo: ctx, } @@ -280,6 +281,7 @@ func (b *Bwhatsapp) PostImageMessage(msg config.Message, filetype string) (strin FileSha256: resp.FileSHA256, FileLength: goproto.Uint64(resp.FileLength), Url: &resp.URL, + DirectPath: &resp.DirectPath, ContextInfo: ctx, } @@ -313,6 +315,7 @@ func (b *Bwhatsapp) PostVideoMessage(msg config.Message, filetype string) (strin FileSha256: resp.FileSHA256, FileLength: goproto.Uint64(resp.FileLength), Url: &resp.URL, + DirectPath: &resp.DirectPath, ContextInfo: ctx, } @@ -345,6 +348,7 @@ func (b *Bwhatsapp) PostAudioMessage(msg config.Message, filetype string) (strin FileSha256: resp.FileSHA256, FileLength: goproto.Uint64(resp.FileLength), Url: &resp.URL, + DirectPath: &resp.DirectPath, ContextInfo: ctx, } From a3deb4872656389425c8d3b9abb7c7d428bb8fe7 Mon Sep 17 00:00:00 2001 From: mvoolt <77506726+mvoolt@users.noreply.github.com> Date: Fri, 10 Mar 2023 23:57:35 +0200 Subject: [PATCH 4/8] Add support for Mumble servers with no message length limit (#2008) * Rename .{jfif,jpe} to .jpg (mumble) * Fix messages not sending in properly if no limit is set (mumble) Co-authored-by: yellows111 * Formatting fix (mumble) --------- Co-authored-by: yellows111 --- bridge/mumble/handlers.go | 10 ++++++++-- bridge/mumble/mumble.go | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/bridge/mumble/handlers.go b/bridge/mumble/handlers.go index 8120159a..830aa5c0 100644 --- a/bridge/mumble/handlers.go +++ b/bridge/mumble/handlers.go @@ -42,7 +42,14 @@ func (b *Bmumble) handleTextMessage(event *gumble.TextMessageEvent) { if part.Image == nil { rmsg.Text = part.Text } else { - fname := b.Account + "_" + strconv.FormatInt(now.UnixNano(), 10) + "_" + strconv.Itoa(i) + part.FileExtension + fileExt := part.FileExtension + if fileExt == ".jfif" { + fileExt = ".jpg" + } + if fileExt == ".jpe" { + fileExt = ".jpg" + } + fname := b.Account + "_" + strconv.FormatInt(now.UnixNano(), 10) + "_" + strconv.Itoa(i) + fileExt rmsg.Extra = make(map[string][]interface{}) if err = helper.HandleDownloadSize(b.Log, &rmsg, fname, int64(len(part.Image)), b.General); err != nil { b.Log.WithError(err).Warn("not including image in message") @@ -62,7 +69,6 @@ func (b *Bmumble) handleConnect(event *gumble.ConnectEvent) { } // No need to talk or listen event.Client.Self.SetSelfDeafened(true) - event.Client.Self.SetSelfMuted(true) // if the Channel variable is set, this is a reconnect -> rejoin channel if b.Channel != nil { if err := b.doJoin(event.Client, *b.Channel); err != nil { diff --git a/bridge/mumble/mumble.go b/bridge/mumble/mumble.go index 945cf559..859ca4ab 100644 --- a/bridge/mumble/mumble.go +++ b/bridge/mumble/mumble.go @@ -250,7 +250,12 @@ func (b *Bmumble) processMessage(msg *config.Message) { // If there is a maximum message length, split and truncate the lines var msgLines []string if maxLength := b.serverConfig.MaximumMessageLength; maxLength != nil { - msgLines = helper.GetSubLines(msg.Text, *maxLength-len(msg.Username), b.GetString("MessageClipped")) + if *maxLength != 0 { // Some servers will have unlimited message lengths. + // Not doing this makes underflows happen. + msgLines = helper.GetSubLines(msg.Text, *maxLength-len(msg.Username), b.GetString("MessageClipped")) + } else { + msgLines = helper.GetSubLines(msg.Text, 0, b.GetString("MessageClipped")) + } } else { msgLines = helper.GetSubLines(msg.Text, 0, b.GetString("MessageClipped")) } From 356ada872c0e1564097e2f8165931fb8c9ee9d23 Mon Sep 17 00:00:00 2001 From: Wim Date: Sat, 11 Mar 2023 17:55:11 +0100 Subject: [PATCH 5/8] Add handlers at the end. Fixes #1988 (discord) (#2011) --- bridge/discord/discord.go | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/bridge/discord/discord.go b/bridge/discord/discord.go index 5ae6c572..51dbe6bc 100644 --- a/bridge/discord/discord.go +++ b/bridge/discord/discord.go @@ -81,17 +81,6 @@ func (b *Bdiscord) Connect() error { return err } b.Log.Info("Connection succeeded") - b.c.AddHandler(b.messageCreate) - b.c.AddHandler(b.messageTyping) - b.c.AddHandler(b.messageUpdate) - b.c.AddHandler(b.messageDelete) - b.c.AddHandler(b.messageDeleteBulk) - b.c.AddHandler(b.memberAdd) - b.c.AddHandler(b.memberRemove) - b.c.AddHandler(b.memberUpdate) - if b.GetInt("debuglevel") == 1 { - b.c.AddHandler(b.messageEvent) - } // 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 | @@ -233,6 +222,19 @@ func (b *Bdiscord) Connect() error { b.nickMemberMap[member.Nick] = member } } + + b.c.AddHandler(b.messageCreate) + b.c.AddHandler(b.messageTyping) + b.c.AddHandler(b.messageUpdate) + b.c.AddHandler(b.messageDelete) + b.c.AddHandler(b.messageDeleteBulk) + b.c.AddHandler(b.memberAdd) + b.c.AddHandler(b.memberRemove) + b.c.AddHandler(b.memberUpdate) + if b.GetInt("debuglevel") == 1 { + b.c.AddHandler(b.messageEvent) + } + return nil } From 89e2dbac1504d6df205938df750fa9eb15996afd Mon Sep 17 00:00:00 2001 From: Wim Date: Sat, 11 Mar 2023 18:14:49 +0100 Subject: [PATCH 6/8] Check client disconnect to exit for loop (api). Fixes #1983 (#2012) Also update to latest melody upstream --- bridge/api/api.go | 19 +- go.mod | 2 +- go.sum | 4 +- .../olahol/melody}/.gitignore | 0 .../olahol/melody}/CHANGELOG.md | 8 + .../olahol/melody}/LICENSE | 0 vendor/github.com/olahol/melody/README.md | 157 +++++++++++++++ .../olahol/melody}/config.go | 0 .../olahol/melody}/doc.go | 8 +- .../olahol/melody}/envelope.go | 0 vendor/github.com/olahol/melody/errors.go | 10 + .../olahol/melody}/hub.go | 11 ++ .../olahol/melody}/melody.go | 40 ++-- .../olahol/melody}/session.go | 72 ++++--- vendor/gopkg.in/olahol/melody.v1/.travis.yml | 10 - vendor/gopkg.in/olahol/melody.v1/README.md | 185 ------------------ vendor/modules.txt | 6 +- 17 files changed, 278 insertions(+), 254 deletions(-) rename vendor/{gopkg.in/olahol/melody.v1 => github.com/olahol/melody}/.gitignore (100%) rename vendor/{gopkg.in/olahol/melody.v1 => github.com/olahol/melody}/CHANGELOG.md (79%) rename vendor/{gopkg.in/olahol/melody.v1 => github.com/olahol/melody}/LICENSE (100%) create mode 100644 vendor/github.com/olahol/melody/README.md rename vendor/{gopkg.in/olahol/melody.v1 => github.com/olahol/melody}/config.go (100%) rename vendor/{gopkg.in/olahol/melody.v1 => github.com/olahol/melody}/doc.go (75%) rename vendor/{gopkg.in/olahol/melody.v1 => github.com/olahol/melody}/envelope.go (100%) create mode 100644 vendor/github.com/olahol/melody/errors.go rename vendor/{gopkg.in/olahol/melody.v1 => github.com/olahol/melody}/hub.go (88%) rename vendor/{gopkg.in/olahol/melody.v1 => github.com/olahol/melody}/melody.go (93%) rename vendor/{gopkg.in/olahol/melody.v1 => github.com/olahol/melody}/session.go (78%) delete mode 100644 vendor/gopkg.in/olahol/melody.v1/.travis.yml delete mode 100644 vendor/gopkg.in/olahol/melody.v1/README.md diff --git a/bridge/api/api.go b/bridge/api/api.go index 515007f0..9e7679d3 100644 --- a/bridge/api/api.go +++ b/bridge/api/api.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "gopkg.in/olahol/melody.v1" + "github.com/olahol/melody" "github.com/42wim/matterbridge/bridge" "github.com/42wim/matterbridge/bridge/config" @@ -166,15 +166,20 @@ func (b *API) handleStream(c echo.Context) error { } c.Response().Flush() for { + select { // TODO: this causes issues, messages should be broadcasted to all connected clients - msg := b.Messages.Dequeue() - if msg != nil { - if err := json.NewEncoder(c.Response()).Encode(msg); err != nil { - return err + default: + msg := b.Messages.Dequeue() + if msg != nil { + if err := json.NewEncoder(c.Response()).Encode(msg); err != nil { + return err + } + c.Response().Flush() } - c.Response().Flush() + time.Sleep(100 * time.Millisecond) + case <-c.Request().Context().Done(): + return nil } - time.Sleep(200 * time.Millisecond) } } diff --git a/go.mod b/go.mod index f4e31db3..e2379e41 100644 --- a/go.mod +++ b/go.mod @@ -34,6 +34,7 @@ require ( github.com/mattn/godown v0.0.1 github.com/mdp/qrterminal v1.0.1 github.com/nelsonken/gomf v0.0.0-20190423072027-c65cc0469e94 + github.com/olahol/melody v1.1.2 github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c github.com/rs/xid v1.4.0 github.com/russross/blackfriday v1.6.0 @@ -53,7 +54,6 @@ require ( golang.org/x/text v0.8.0 gomod.garykim.dev/nc-talk v0.3.0 google.golang.org/protobuf v1.29.0 - gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 layeh.com/gumble v0.0.0-20221205141517-d1df60a3cc14 modernc.org/sqlite v1.21.0 ) diff --git a/go.sum b/go.sum index af479145..ac913120 100644 --- a/go.sum +++ b/go.sum @@ -1246,6 +1246,8 @@ github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olahol/melody v1.1.2 h1:9PZ5kYv/CUy0PRZcJCKja1MUxAh6olVeHkyqaQxO7n0= +github.com/olahol/melody v1.1.2/go.mod h1:GgkTl6Y7yWj/HtfD48Q5vLKPVoZOH+Qqgfa7CvJgJM4= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= 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= @@ -2465,8 +2467,6 @@ gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3M gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 h1:sY2a+y0j4iDrajJcorb+a0hJIQ6uakU5gybjfLWHlXo= -gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376/go.mod h1:BHKOc1m5wm8WwQkMqYBoo4vNxhmF7xg8+xhG8L+Cy3M= gopkg.in/olivere/elastic.v6 v6.2.35/go.mod h1:2cTT8Z+/LcArSWpCgvZqBgt3VOqXiy7v00w12Lz8bd4= gopkg.in/olivere/elastic.v6 v6.2.37/go.mod h1:2cTT8Z+/LcArSWpCgvZqBgt3VOqXiy7v00w12Lz8bd4= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= diff --git a/vendor/gopkg.in/olahol/melody.v1/.gitignore b/vendor/github.com/olahol/melody/.gitignore similarity index 100% rename from vendor/gopkg.in/olahol/melody.v1/.gitignore rename to vendor/github.com/olahol/melody/.gitignore diff --git a/vendor/gopkg.in/olahol/melody.v1/CHANGELOG.md b/vendor/github.com/olahol/melody/CHANGELOG.md similarity index 79% rename from vendor/gopkg.in/olahol/melody.v1/CHANGELOG.md rename to vendor/github.com/olahol/melody/CHANGELOG.md index ff511ddd..e0b19412 100644 --- a/vendor/gopkg.in/olahol/melody.v1/CHANGELOG.md +++ b/vendor/github.com/olahol/melody/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2022-09-12 (v1.1.0) + +* Create Go module. +* Update examples. +* Fix concurrent panic (PR-65). +* Add `Sessions` to get all sessions (PR-53). +* Add `LocalAddr` and `RemoteAddr` (PR-55). + ## 2017-05-18 * Fix `HandleSentMessageBinary`. diff --git a/vendor/gopkg.in/olahol/melody.v1/LICENSE b/vendor/github.com/olahol/melody/LICENSE similarity index 100% rename from vendor/gopkg.in/olahol/melody.v1/LICENSE rename to vendor/github.com/olahol/melody/LICENSE diff --git a/vendor/github.com/olahol/melody/README.md b/vendor/github.com/olahol/melody/README.md new file mode 100644 index 00000000..53196b44 --- /dev/null +++ b/vendor/github.com/olahol/melody/README.md @@ -0,0 +1,157 @@ +# melody + +![Build Status](https://github.com/olahol/melody/actions/workflows/test.yml/badge.svg) +[![Codecov](https://img.shields.io/codecov/c/github/olahol/melody)](https://app.codecov.io/github/olahol/melody) +[![Go Report Card](https://goreportcard.com/badge/github.com/olahol/melody)](https://goreportcard.com/report/github.com/olahol/melody) +[![GoDoc](https://godoc.org/github.com/olahol/melody?status.svg)](https://godoc.org/github.com/olahol/melody) + +> :notes: Minimalist websocket framework for Go. + +Melody is websocket framework based on [github.com/gorilla/websocket](https://github.com/gorilla/websocket) +that abstracts away the tedious parts of handling websockets. It gets out of +your way so you can write real-time apps. Features include: + +* [x] Clear and easy interface similar to `net/http` or Gin. +* [x] A simple way to broadcast to all or selected connected sessions. +* [x] Message buffers making concurrent writing safe. +* [x] Automatic handling of sending ping/pong heartbeats that timeout broken sessions. +* [x] Store data on sessions. + +## Install + +```bash +go get github.com/olahol/melody +``` + +## [Example: chat](https://github.com/olahol/melody/tree/master/examples/chat) + +[![Chat](https://cdn.rawgit.com/olahol/melody/master/examples/chat/demo.gif "Demo")](https://github.com/olahol/melody/tree/master/examples/chat) + +```go +package main + +import ( + "net/http" + + "github.com/olahol/melody" +) + +func main() { + m := melody.New() + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "index.html") + }) + + http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { + m.HandleRequest(w, r) + }) + + m.HandleMessage(func(s *melody.Session, msg []byte) { + m.Broadcast(msg) + }) + + http.ListenAndServe(":5000", nil) +} +``` + +## [Example: gophers](https://github.com/olahol/melody/tree/master/examples/gophers) + +[![Gophers](https://cdn.rawgit.com/olahol/melody/master/examples/gophers/demo.gif "Demo")](https://github.com/olahol/melody/tree/master/examples/gophers) + +```go +package main + +import ( + "net/http" + "strings" + + "github.com/google/uuid" + "github.com/olahol/melody" +) + +type GopherInfo struct { + ID, X, Y string +} + +func main() { + m := melody.New() + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "index.html") + }) + + http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { + m.HandleRequest(w, r) + }) + + m.HandleConnect(func(s *melody.Session) { + ss, _ := m.Sessions() + + for _, o := range ss { + value, exists := o.Get("info") + + if !exists { + continue + } + + info := value.(*GopherInfo) + + s.Write([]byte("set " + info.ID + " " + info.X + " " + info.Y)) + } + + id := uuid.NewString() + s.Set("info", &GopherInfo{id, "0", "0"}) + + s.Write([]byte("iam " + id)) + }) + + m.HandleDisconnect(func(s *melody.Session) { + value, exists := s.Get("info") + + if !exists { + return + } + + info := value.(*GopherInfo) + + m.BroadcastOthers([]byte("dis "+info.ID), s) + }) + + m.HandleMessage(func(s *melody.Session, msg []byte) { + p := strings.Split(string(msg), " ") + value, exists := s.Get("info") + + if len(p) != 2 || !exists { + return + } + + info := value.(*GopherInfo) + info.X = p[0] + info.Y = p[1] + + m.BroadcastOthers([]byte("set "+info.ID+" "+info.X+" "+info.Y), s) + }) + + http.ListenAndServe(":5000", nil) +} +``` + +### [More examples](https://github.com/olahol/melody/tree/master/examples) + +## [Documentation](https://godoc.org/github.com/olahol/melody) + +## Contributors + + + + + +## FAQ + +If you are getting a `403` when trying to connect to your websocket you can [change allow all origin hosts](http://godoc.org/github.com/gorilla/websocket#hdr-Origin_Considerations): + +```go +m := melody.New() +m.Upgrader.CheckOrigin = func(r *http.Request) bool { return true } +``` diff --git a/vendor/gopkg.in/olahol/melody.v1/config.go b/vendor/github.com/olahol/melody/config.go similarity index 100% rename from vendor/gopkg.in/olahol/melody.v1/config.go rename to vendor/github.com/olahol/melody/config.go diff --git a/vendor/gopkg.in/olahol/melody.v1/doc.go b/vendor/github.com/olahol/melody/doc.go similarity index 75% rename from vendor/gopkg.in/olahol/melody.v1/doc.go rename to vendor/github.com/olahol/melody/doc.go index a65aa634..b54b6d4a 100644 --- a/vendor/gopkg.in/olahol/melody.v1/doc.go +++ b/vendor/github.com/olahol/melody/doc.go @@ -9,14 +9,14 @@ // A broadcasting echo server: // // func main() { -// r := gin.Default() // m := melody.New() -// r.GET("/ws", func(c *gin.Context) { -// m.HandleRequest(c.Writer, c.Request) +// http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { +// m.HandleRequest(w, r) // }) // m.HandleMessage(func(s *melody.Session, msg []byte) { // m.Broadcast(msg) // }) -// r.Run(":5000") +// http.ListenAndServe(":5000", nil) // } + package melody diff --git a/vendor/gopkg.in/olahol/melody.v1/envelope.go b/vendor/github.com/olahol/melody/envelope.go similarity index 100% rename from vendor/gopkg.in/olahol/melody.v1/envelope.go rename to vendor/github.com/olahol/melody/envelope.go diff --git a/vendor/github.com/olahol/melody/errors.go b/vendor/github.com/olahol/melody/errors.go new file mode 100644 index 00000000..d8be6157 --- /dev/null +++ b/vendor/github.com/olahol/melody/errors.go @@ -0,0 +1,10 @@ +package melody + +import "errors" + +var ( + ErrClosed = errors.New("melody instance is closed") + ErrSessionClosed = errors.New("session is closed") + ErrWriteClosed = errors.New("tried to write to closed a session") + ErrMessageBufferFull = errors.New("session message buffer is full") +) diff --git a/vendor/gopkg.in/olahol/melody.v1/hub.go b/vendor/github.com/olahol/melody/hub.go similarity index 88% rename from vendor/gopkg.in/olahol/melody.v1/hub.go rename to vendor/github.com/olahol/melody/hub.go index edc6337d..4a8cffac 100644 --- a/vendor/gopkg.in/olahol/melody.v1/hub.go +++ b/vendor/github.com/olahol/melody/hub.go @@ -78,3 +78,14 @@ func (h *hub) len() int { return len(h.sessions) } + +func (h *hub) all() []*Session { + h.rwmutex.RLock() + defer h.rwmutex.RUnlock() + + s := make([]*Session, 0, len(h.sessions)) + for k := range h.sessions { + s = append(s, k) + } + return s +} diff --git a/vendor/gopkg.in/olahol/melody.v1/melody.go b/vendor/github.com/olahol/melody/melody.go similarity index 93% rename from vendor/gopkg.in/olahol/melody.v1/melody.go rename to vendor/github.com/olahol/melody/melody.go index 6e416b15..ca2c5dd1 100644 --- a/vendor/gopkg.in/olahol/melody.v1/melody.go +++ b/vendor/github.com/olahol/melody/melody.go @@ -1,7 +1,6 @@ package melody import ( - "errors" "net/http" "sync" @@ -164,23 +163,24 @@ func (m *Melody) HandleRequest(w http.ResponseWriter, r *http.Request) error { // HandleRequestWithKeys does the same as HandleRequest but populates session.Keys with keys. func (m *Melody) HandleRequestWithKeys(w http.ResponseWriter, r *http.Request, keys map[string]interface{}) error { if m.hub.closed() { - return errors.New("melody instance is closed") + return ErrClosed } - conn, err := m.Upgrader.Upgrade(w, r, nil) + conn, err := m.Upgrader.Upgrade(w, r, w.Header()) if err != nil { return err } session := &Session{ - Request: r, - Keys: keys, - conn: conn, - output: make(chan *envelope, m.Config.MessageBufferSize), - melody: m, - open: true, - rwmutex: &sync.RWMutex{}, + Request: r, + Keys: keys, + conn: conn, + output: make(chan *envelope, m.Config.MessageBufferSize), + outputDone: make(chan struct{}), + melody: m, + open: true, + rwmutex: &sync.RWMutex{}, } m.hub.register <- session @@ -205,7 +205,7 @@ func (m *Melody) HandleRequestWithKeys(w http.ResponseWriter, r *http.Request, k // Broadcast broadcasts a text message to all sessions. func (m *Melody) Broadcast(msg []byte) error { if m.hub.closed() { - return errors.New("melody instance is closed") + return ErrClosed } message := &envelope{t: websocket.TextMessage, msg: msg} @@ -217,7 +217,7 @@ func (m *Melody) Broadcast(msg []byte) error { // BroadcastFilter broadcasts a text message to all sessions that fn returns true for. func (m *Melody) BroadcastFilter(msg []byte, fn func(*Session) bool) error { if m.hub.closed() { - return errors.New("melody instance is closed") + return ErrClosed } message := &envelope{t: websocket.TextMessage, msg: msg, filter: fn} @@ -246,7 +246,7 @@ func (m *Melody) BroadcastMultiple(msg []byte, sessions []*Session) error { // BroadcastBinary broadcasts a binary message to all sessions. func (m *Melody) BroadcastBinary(msg []byte) error { if m.hub.closed() { - return errors.New("melody instance is closed") + return ErrClosed } message := &envelope{t: websocket.BinaryMessage, msg: msg} @@ -258,7 +258,7 @@ func (m *Melody) BroadcastBinary(msg []byte) error { // BroadcastBinaryFilter broadcasts a binary message to all sessions that fn returns true for. func (m *Melody) BroadcastBinaryFilter(msg []byte, fn func(*Session) bool) error { if m.hub.closed() { - return errors.New("melody instance is closed") + return ErrClosed } message := &envelope{t: websocket.BinaryMessage, msg: msg, filter: fn} @@ -274,10 +274,18 @@ func (m *Melody) BroadcastBinaryOthers(msg []byte, s *Session) error { }) } +// Sessions returns all sessions. An error is returned if the melody session is closed. +func (m *Melody) Sessions() ([]*Session, error) { + if m.hub.closed() { + return nil, ErrClosed + } + return m.hub.all(), nil +} + // Close closes the melody instance and all connected sessions. func (m *Melody) Close() error { if m.hub.closed() { - return errors.New("melody instance is already closed") + return ErrClosed } m.hub.exit <- &envelope{t: websocket.CloseMessage, msg: []byte{}} @@ -289,7 +297,7 @@ func (m *Melody) Close() error { // Use the FormatCloseMessage function to format a proper close message payload. func (m *Melody) CloseWithMsg(msg []byte) error { if m.hub.closed() { - return errors.New("melody instance is already closed") + return ErrClosed } m.hub.exit <- &envelope{t: websocket.CloseMessage, msg: msg} diff --git a/vendor/gopkg.in/olahol/melody.v1/session.go b/vendor/github.com/olahol/melody/session.go similarity index 78% rename from vendor/gopkg.in/olahol/melody.v1/session.go rename to vendor/github.com/olahol/melody/session.go index 3997cefe..879a724d 100644 --- a/vendor/gopkg.in/olahol/melody.v1/session.go +++ b/vendor/github.com/olahol/melody/session.go @@ -1,7 +1,7 @@ package melody import ( - "errors" + "net" "net/http" "sync" "time" @@ -11,31 +11,32 @@ import ( // Session wrapper around websocket connections. type Session struct { - Request *http.Request - Keys map[string]interface{} - conn *websocket.Conn - output chan *envelope - melody *Melody - open bool - rwmutex *sync.RWMutex + Request *http.Request + Keys map[string]interface{} + conn *websocket.Conn + output chan *envelope + outputDone chan struct{} + melody *Melody + open bool + rwmutex *sync.RWMutex } func (s *Session) writeMessage(message *envelope) { if s.closed() { - s.melody.errorHandler(s, errors.New("tried to write to closed a session")) + s.melody.errorHandler(s, ErrWriteClosed) return } select { case s.output <- message: default: - s.melody.errorHandler(s, errors.New("session message buffer is full")) + s.melody.errorHandler(s, ErrMessageBufferFull) } } func (s *Session) writeRaw(message *envelope) error { if s.closed() { - return errors.New("tried to write to a closed session") + return ErrWriteClosed } s.conn.SetWriteDeadline(time.Now().Add(s.melody.Config.WriteWait)) @@ -56,12 +57,13 @@ func (s *Session) closed() bool { } func (s *Session) close() { - if !s.closed() { - s.rwmutex.Lock() - s.open = false + s.rwmutex.Lock() + open := s.open + s.open = false + s.rwmutex.Unlock() + if open { s.conn.Close() - close(s.output) - s.rwmutex.Unlock() + close(s.outputDone) } } @@ -76,11 +78,7 @@ func (s *Session) writePump() { loop: for { select { - case msg, ok := <-s.output: - if !ok { - break loop - } - + case msg := <-s.output: err := s.writeRaw(msg) if err != nil { @@ -101,8 +99,14 @@ loop: } case <-ticker.C: s.ping() + case _, ok := <-s.outputDone: + if !ok { + break loop + } } } + + s.close() } func (s *Session) readPump() { @@ -142,7 +146,7 @@ func (s *Session) readPump() { // Write writes message to session. func (s *Session) Write(msg []byte) error { if s.closed() { - return errors.New("session is closed") + return ErrSessionClosed } s.writeMessage(&envelope{t: websocket.TextMessage, msg: msg}) @@ -153,7 +157,7 @@ func (s *Session) Write(msg []byte) error { // WriteBinary writes a binary message to session. func (s *Session) WriteBinary(msg []byte) error { if s.closed() { - return errors.New("session is closed") + return ErrSessionClosed } s.writeMessage(&envelope{t: websocket.BinaryMessage, msg: msg}) @@ -164,7 +168,7 @@ func (s *Session) WriteBinary(msg []byte) error { // Close closes session. func (s *Session) Close() error { if s.closed() { - return errors.New("session is already closed") + return ErrSessionClosed } s.writeMessage(&envelope{t: websocket.CloseMessage, msg: []byte{}}) @@ -176,7 +180,7 @@ func (s *Session) Close() error { // Use the FormatCloseMessage function to format a proper close message payload. func (s *Session) CloseWithMsg(msg []byte) error { if s.closed() { - return errors.New("session is already closed") + return ErrSessionClosed } s.writeMessage(&envelope{t: websocket.CloseMessage, msg: msg}) @@ -184,9 +188,12 @@ func (s *Session) CloseWithMsg(msg []byte) error { return nil } -// Set is used to store a new key/value pair exclusivelly for this session. +// Set is used to store a new key/value pair exclusively for this session. // It also lazy initializes s.Keys if it was not used previously. func (s *Session) Set(key string, value interface{}) { + s.rwmutex.Lock() + defer s.rwmutex.Unlock() + if s.Keys == nil { s.Keys = make(map[string]interface{}) } @@ -197,6 +204,9 @@ func (s *Session) Set(key string, value interface{}) { // Get returns the value for the given key, ie: (value, true). // If the value does not exists it returns (nil, false) func (s *Session) Get(key string) (value interface{}, exists bool) { + s.rwmutex.RLock() + defer s.rwmutex.RUnlock() + if s.Keys != nil { value, exists = s.Keys[key] } @@ -217,3 +227,13 @@ func (s *Session) MustGet(key string) interface{} { func (s *Session) IsClosed() bool { return s.closed() } + +// LocalAddr returns the local addr of the connection. +func (s *Session) LocalAddr() net.Addr { + return s.conn.LocalAddr() +} + +// RemoteAddr returns the remote addr of the connection. +func (s *Session) RemoteAddr() net.Addr { + return s.conn.RemoteAddr() +} diff --git a/vendor/gopkg.in/olahol/melody.v1/.travis.yml b/vendor/gopkg.in/olahol/melody.v1/.travis.yml deleted file mode 100644 index f1a141cd..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: go -sudo: required -go: -- 1.6 -- 1.7 -- 1.8 -install: - - go get github.com/gorilla/websocket -script: - - go test diff --git a/vendor/gopkg.in/olahol/melody.v1/README.md b/vendor/gopkg.in/olahol/melody.v1/README.md deleted file mode 100644 index 67e3ab50..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/README.md +++ /dev/null @@ -1,185 +0,0 @@ -# melody - -[![Build Status](https://travis-ci.org/olahol/melody.svg)](https://travis-ci.org/olahol/melody) -[![Coverage Status](https://img.shields.io/coveralls/olahol/melody.svg?style=flat)](https://coveralls.io/r/olahol/melody) -[![GoDoc](https://godoc.org/github.com/olahol/melody?status.svg)](https://godoc.org/github.com/olahol/melody) - -> :notes: Minimalist websocket framework for Go. - -Melody is websocket framework based on [github.com/gorilla/websocket](https://github.com/gorilla/websocket) -that abstracts away the tedious parts of handling websockets. It gets out of -your way so you can write real-time apps. Features include: - -* [x] Clear and easy interface similar to `net/http` or Gin. -* [x] A simple way to broadcast to all or selected connected sessions. -* [x] Message buffers making concurrent writing safe. -* [x] Automatic handling of ping/pong and session timeouts. -* [x] Store data on sessions. - -## Install - -```bash -go get gopkg.in/olahol/melody.v1 -``` - -## [Example: chat](https://github.com/olahol/melody/tree/master/examples/chat) - -[![Chat](https://cdn.rawgit.com/olahol/melody/master/examples/chat/demo.gif "Demo")](https://github.com/olahol/melody/tree/master/examples/chat) - -Using [Gin](https://github.com/gin-gonic/gin): -```go -package main - -import ( - "github.com/gin-gonic/gin" - "gopkg.in/olahol/melody.v1" - "net/http" -) - -func main() { - r := gin.Default() - m := melody.New() - - r.GET("/", func(c *gin.Context) { - http.ServeFile(c.Writer, c.Request, "index.html") - }) - - r.GET("/ws", func(c *gin.Context) { - m.HandleRequest(c.Writer, c.Request) - }) - - m.HandleMessage(func(s *melody.Session, msg []byte) { - m.Broadcast(msg) - }) - - r.Run(":5000") -} -``` - -Using [Echo](https://github.com/labstack/echo): -```go -package main - -import ( - "github.com/labstack/echo" - "github.com/labstack/echo/engine/standard" - "github.com/labstack/echo/middleware" - "gopkg.in/olahol/melody.v1" - "net/http" -) - -func main() { - e := echo.New() - m := melody.New() - - e.Use(middleware.Logger()) - e.Use(middleware.Recover()) - - e.GET("/", func(c echo.Context) error { - http.ServeFile(c.Response().(*standard.Response).ResponseWriter, c.Request().(*standard.Request).Request, "index.html") - return nil - }) - - e.GET("/ws", func(c echo.Context) error { - m.HandleRequest(c.Response().(*standard.Response).ResponseWriter, c.Request().(*standard.Request).Request) - return nil - }) - - m.HandleMessage(func(s *melody.Session, msg []byte) { - m.Broadcast(msg) - }) - - e.Run(standard.New(":5000")) -} -``` - -## [Example: gophers](https://github.com/olahol/melody/tree/master/examples/gophers) - -[![Gophers](https://cdn.rawgit.com/olahol/melody/master/examples/gophers/demo.gif "Demo")](https://github.com/olahol/melody/tree/master/examples/gophers) - -```go -package main - -import ( - "github.com/gin-gonic/gin" - "gopkg.in/olahol/melody.v1" - "net/http" - "strconv" - "strings" - "sync" -) - -type GopherInfo struct { - ID, X, Y string -} - -func main() { - router := gin.Default() - mrouter := melody.New() - gophers := make(map[*melody.Session]*GopherInfo) - lock := new(sync.Mutex) - counter := 0 - - router.GET("/", func(c *gin.Context) { - http.ServeFile(c.Writer, c.Request, "index.html") - }) - - router.GET("/ws", func(c *gin.Context) { - mrouter.HandleRequest(c.Writer, c.Request) - }) - - mrouter.HandleConnect(func(s *melody.Session) { - lock.Lock() - for _, info := range gophers { - s.Write([]byte("set " + info.ID + " " + info.X + " " + info.Y)) - } - gophers[s] = &GopherInfo{strconv.Itoa(counter), "0", "0"} - s.Write([]byte("iam " + gophers[s].ID)) - counter += 1 - lock.Unlock() - }) - - mrouter.HandleDisconnect(func(s *melody.Session) { - lock.Lock() - mrouter.BroadcastOthers([]byte("dis "+gophers[s].ID), s) - delete(gophers, s) - lock.Unlock() - }) - - mrouter.HandleMessage(func(s *melody.Session, msg []byte) { - p := strings.Split(string(msg), " ") - lock.Lock() - info := gophers[s] - if len(p) == 2 { - info.X = p[0] - info.Y = p[1] - mrouter.BroadcastOthers([]byte("set "+info.ID+" "+info.X+" "+info.Y), s) - } - lock.Unlock() - }) - - router.Run(":5000") -} -``` - -### [More examples](https://github.com/olahol/melody/tree/master/examples) - -## [Documentation](https://godoc.org/github.com/olahol/melody) - -## Contributors - -* Ola Holmström (@olahol) -* Shogo Iwano (@shiwano) -* Matt Caldwell (@mattcaldwell) -* Heikki Uljas (@huljas) -* Robbie Trencheny (@robbiet480) -* yangjinecho (@yangjinecho) - -## FAQ - -If you are getting a `403` when trying to connect to your websocket you can [change allow all origin hosts](http://godoc.org/github.com/gorilla/websocket#hdr-Origin_Considerations): - -```go -m := melody.New() -m.Upgrader.CheckOrigin = func(r *http.Request) bool { return true } -``` diff --git a/vendor/modules.txt b/vendor/modules.txt index 41e2f2e0..1b9fa5bf 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -333,6 +333,9 @@ github.com/mrexodia/wray # github.com/nelsonken/gomf v0.0.0-20190423072027-c65cc0469e94 ## explicit; go 1.12 github.com/nelsonken/gomf +# github.com/olahol/melody v1.1.2 +## explicit; go 1.19 +github.com/olahol/melody # github.com/opentracing/opentracing-go v1.2.0 ## explicit; go 1.14 github.com/opentracing/opentracing-go @@ -698,9 +701,6 @@ gopkg.in/ini.v1 # gopkg.in/natefinch/lumberjack.v2 v2.0.0 ## explicit gopkg.in/natefinch/lumberjack.v2 -# gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 -## explicit -gopkg.in/olahol/melody.v1 # gopkg.in/yaml.v2 v2.4.0 ## explicit; go 1.15 gopkg.in/yaml.v2 From f345eeae55232ddd7cf800c8303b4298fb1b8c52 Mon Sep 17 00:00:00 2001 From: Wim Date: Sat, 11 Mar 2023 18:18:24 +0100 Subject: [PATCH 7/8] Set correct loglevel (whatsapp). Fixes #1980 (#2013) --- bridge/whatsappmulti/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge/whatsappmulti/handlers.go b/bridge/whatsappmulti/handlers.go index d99c6727..ae825f75 100644 --- a/bridge/whatsappmulti/handlers.go +++ b/bridge/whatsappmulti/handlers.go @@ -31,7 +31,7 @@ func (b *Bwhatsapp) handleMessage(message *events.Message) { return } - b.Log.Infof("Receiving message %#v", msg) + b.Log.Debugf("Receiving message %#v", msg) switch { case msg.Conversation != nil || msg.ExtendedTextMessage != nil: From 8587fa85854b8ba14a171edf1c9c7e8f066eb6fb Mon Sep 17 00:00:00 2001 From: Wim Date: Sat, 11 Mar 2023 18:55:29 +0100 Subject: [PATCH 8/8] Fix possible panic in mattermost. (mattermost) Fixes #1947 (#2014) --- bridge/mattermost/mattermost.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge/mattermost/mattermost.go b/bridge/mattermost/mattermost.go index 2b44dcfa..be24ba17 100644 --- a/bridge/mattermost/mattermost.go +++ b/bridge/mattermost/mattermost.go @@ -161,7 +161,7 @@ func (b *Bmattermost) Send(msg config.Message) (string, error) { if err != nil { b.Log.Errorf("getting post %s failed: %s", msg.ParentID, err) } - if post.RootId != "" { + if post != nil && post.RootId != "" { msg.ParentID = post.RootId } }