Update dependencies (#1841)

This commit is contained in:
Wim
2022-06-11 23:07:42 +02:00
committed by GitHub
parent 3819062574
commit 8751fb4bb1
188 changed files with 5608 additions and 1334 deletions

View File

@@ -8,7 +8,7 @@ package whatsmeow
import (
"context"
"encoding/base64"
"fmt"
"strconv"
"sync/atomic"
"time"
@@ -27,6 +27,20 @@ func isDisconnectNode(node *waBinary.Node) bool {
return node == xmlStreamEndNode || node.Tag == "stream:error"
}
// isAuthErrorDisconnect checks if the given disconnect node is an error that shouldn't cause retrying.
func isAuthErrorDisconnect(node *waBinary.Node) bool {
if node.Tag != "stream:error" {
return false
}
code, _ := node.Attrs["code"].(string)
conflict, _ := node.GetOptionalChildByTag("conflict")
conflictType := conflict.AttrGetter().OptionalString("type")
if code == "401" || conflictType == "replaced" || conflictType == "device_removed" {
return true
}
return false
}
func (cli *Client) clearResponseWaiters(node *waBinary.Node) {
cli.responseWaitersLock.Lock()
for _, waiter := range cli.responseWaiters {
@@ -88,10 +102,11 @@ type infoQuery struct {
Content interface{}
Timeout time.Duration
NoRetry bool
Context context.Context
}
func (cli *Client) sendIQAsyncDebug(query infoQuery) (<-chan *waBinary.Node, []byte, error) {
func (cli *Client) sendIQAsyncAndGetData(query *infoQuery) (<-chan *waBinary.Node, []byte, error) {
if len(query.ID) == 0 {
query.ID = cli.generateRequestID()
}
@@ -107,7 +122,7 @@ func (cli *Client) sendIQAsyncDebug(query infoQuery) (<-chan *waBinary.Node, []b
if !query.Target.IsEmpty() {
attrs["target"] = query.Target
}
data, err := cli.sendNodeDebug(waBinary.Node{
data, err := cli.sendNodeAndGetData(waBinary.Node{
Tag: "iq",
Attrs: attrs,
Content: query.Content,
@@ -120,12 +135,12 @@ func (cli *Client) sendIQAsyncDebug(query infoQuery) (<-chan *waBinary.Node, []b
}
func (cli *Client) sendIQAsync(query infoQuery) (<-chan *waBinary.Node, error) {
ch, _, err := cli.sendIQAsyncDebug(query)
ch, _, err := cli.sendIQAsyncAndGetData(&query)
return ch, err
}
func (cli *Client) sendIQ(query infoQuery) (*waBinary.Node, error) {
resChan, data, err := cli.sendIQAsyncDebug(query)
resChan, data, err := cli.sendIQAsyncAndGetData(&query)
if err != nil {
return nil, err
}
@@ -138,10 +153,13 @@ func (cli *Client) sendIQ(query infoQuery) (*waBinary.Node, error) {
select {
case res := <-resChan:
if isDisconnectNode(res) {
if cli.DebugDecodeBeforeSend && res.Tag == "stream:error" && res.GetChildByTag("xml-not-well-formed").Tag != "" {
cli.Log.Debugf("Info query that was interrupted by xml-not-well-formed: %s", base64.URLEncoding.EncodeToString(data))
if query.NoRetry {
return nil, &DisconnectedError{Action: "info query", Node: res}
}
res, err = cli.retryFrame("info query", query.ID, data, res, query.Context, query.Timeout)
if err != nil {
return nil, err
}
return nil, &DisconnectedError{Action: "info query", Node: res}
}
resType, _ := res.Attrs["type"].(string)
if res.Tag != "iq" || (resType != "result" && resType != "error") {
@@ -156,3 +174,48 @@ func (cli *Client) sendIQ(query infoQuery) (*waBinary.Node, error) {
return nil, ErrIQTimedOut
}
}
func (cli *Client) retryFrame(reqType, id string, data []byte, origResp *waBinary.Node, ctx context.Context, timeout time.Duration) (*waBinary.Node, error) {
if isAuthErrorDisconnect(origResp) {
cli.Log.Debugf("%s (%s) was interrupted by websocket disconnection (%s), not retrying as it looks like an auth error", id, reqType, origResp.XMLString())
return nil, &DisconnectedError{Action: reqType, Node: origResp}
}
cli.Log.Debugf("%s (%s) was interrupted by websocket disconnection (%s), waiting for reconnect to retry...", id, reqType, origResp.XMLString())
if !cli.WaitForConnection(5 * time.Second) {
cli.Log.Debugf("Websocket didn't reconnect within 5 seconds of failed %s (%s)", reqType, id)
return nil, &DisconnectedError{Action: reqType, Node: origResp}
}
cli.socketLock.RLock()
sock := cli.socket
cli.socketLock.RUnlock()
if sock == nil {
return nil, ErrNotConnected
}
respChan := cli.waitResponse(id)
err := sock.SendFrame(data)
if err != nil {
cli.cancelResponse(id, respChan)
return nil, err
}
var resp *waBinary.Node
if ctx != nil && timeout > 0 {
select {
case resp = <-respChan:
case <-ctx.Done():
return nil, ctx.Err()
case <-time.After(timeout):
// FIXME this error isn't technically correct (but works for now - the ctx and timeout params are only used from sendIQ)
return nil, ErrIQTimedOut
}
} else {
resp = <-respChan
}
if isDisconnectNode(resp) {
cli.Log.Debugf("Retrying %s %s was interrupted by websocket disconnection (%v), not retrying anymore", reqType, id, resp.XMLString())
return nil, &DisconnectedError{Action: fmt.Sprintf("%s (retry)", reqType), Node: resp}
}
return resp, nil
}