Skip to content

Commit

Permalink
dcping: correctly switch encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
dennwc committed Mar 13, 2019
1 parent 8a8b8a9 commit b4f3caa
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 74 deletions.
162 changes: 90 additions & 72 deletions nmdc/ping.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package nmdc

import (
"bytes"
"context"
"errors"
"fmt"
Expand Down Expand Up @@ -62,41 +63,6 @@ func (h *HubInfo) decodeWith(enc encoding.Encoding) error {
return nil
}

func (h *HubInfo) decode() error {
if strings.Contains(h.Encoding, "@") {
// YnHub may send an email in the encoding field
if h.Owner == "" {
h.Owner = h.Encoding
}
h.Encoding = ""
return nil
}
code := strings.ToLower(h.Encoding)
// some hubs are misconfigured and send garbage in the encoding field
code = strings.Trim(code, "= ")
if h.Encoding == "" {
return nil
}
if len(code) == 4 {
// some hubs forget the "cp" prefix and just use "1250" as an encoding
if _, err := strconv.Atoi(code); err == nil {
code = "cp" + code
}
}
enc, err := htmlindex.Get(code)
if err != nil {
return nil
}
err = h.decodeWith(enc)
if err != nil {
return nil
}
if code, _ = htmlindex.Name(enc); code != "" {
h.Encoding = code
}
return nil
}

type timeoutErr interface {
Timeout() bool
}
Expand All @@ -117,12 +83,20 @@ func Ping(ctx context.Context, addr string, conf PingConfig) (_ *HubInfo, gerr e
return nil, err
}

var hubInfo []byte
c, err := DialContext(ctx, addr)
if err != nil {
return nil, err
}
defer c.Close()

c.r.OnRawMessage = func(cmd, args []byte) (bool, error) {
if bytes.Equal(cmd, []byte("HubINFO")) {
hubInfo = append([]byte{}, args...)
}
return true, nil
}

// set deadline once
deadline, ok := ctx.Deadline()
if !ok {
Expand Down Expand Up @@ -158,12 +132,6 @@ func Ping(ctx context.Context, addr string, conf PingConfig) (_ *HubInfo, gerr e
}

var hub HubInfo
defer func() {
// make sure to decode the info at the end
if gerr == nil {
gerr = hub.decode()
}
}()

// TODO: check if it's always the case
pk := strings.SplitN(lock.PK, " ", 2)
Expand All @@ -178,6 +146,86 @@ func Ping(ctx context.Context, addr string, conf PingConfig) (_ *HubInfo, gerr e
}
}

setInfo := func(msg *nmdc.HubINFO, enc string) {
if msg.Name != "" {
hub.Name = msg.Name
}
if msg.Desc != "" {
hub.Desc = msg.Desc
}
if msg.Host != "" {
hub.Addr = msg.Host
}
if msg.Soft.Name != "" {
hub.Server.Name = msg.Soft.Name
if msg.Soft.Version != "" {
hub.Server.Version = msg.Soft.Version
} else {
soft := msg.Soft.Name
if i := strings.LastIndex(soft, " "); i > 0 {
hub.Server = dc.Software{
Name: soft[:i],
Version: soft[i+1:],
}
} else if i = strings.LastIndex(soft, "_"); i > 0 {
hub.Server = dc.Software{
Name: soft[:i],
Version: soft[i+1:],
}
}
}
}
if enc != "" {
hub.Encoding = enc
} else {
hub.Encoding = msg.Encoding
}
hub.Owner = msg.Owner
}

switchEncoding := func(msg *nmdc.HubINFO) {
if strings.Contains(hub.Encoding, "@") {
// YnHub may send an email in the encoding field
if msg.Owner == "" {
msg.Owner = msg.Encoding
}
msg.Encoding = ""
setInfo(msg, "")
return
}
code := strings.ToLower(msg.Encoding)
// some hubs are misconfigured and send garbage in the encoding field
code = strings.Trim(code, "= ")
if code == "" {
msg.Encoding = ""
setInfo(msg, "")
return
}
if len(code) == 4 {
// some hubs forget the "cp" prefix and just use "1250" as an encoding
if _, err := strconv.Atoi(code); err == nil {
code = "cp" + code
}
}
enc, err := htmlindex.Get(code)
if err != nil {
setInfo(msg, "")
return
}

var msg2 nmdc.HubINFO
err = msg2.UnmarshalNMDC(enc.NewDecoder(), hubInfo)
if err != nil {
setInfo(msg, "")
return
}
if c, _ := htmlindex.Name(enc); c != "" {
code = c
}
setInfo(&msg2, code)
c.SetEncoding(enc)
}

var (
lastMsg string
listStarted bool
Expand Down Expand Up @@ -286,37 +334,7 @@ func Ping(ctx context.Context, addr string, conf PingConfig) (_ *HubInfo, gerr e
case *nmdc.BotList:
hub.Bots = msg.Names
case *nmdc.HubINFO:
if msg.Name != "" {
hub.Name = msg.Name
}
if msg.Desc != "" {
hub.Desc = msg.Desc
}
if msg.Host != "" {
hub.Addr = msg.Host
}
if msg.Soft.Name != "" {
hub.Server.Name = msg.Soft.Name
if msg.Soft.Version != "" {
hub.Server.Version = msg.Soft.Version
} else {
soft := msg.Soft.Name
if i := strings.LastIndex(soft, " "); i > 0 {
hub.Server = dc.Software{
Name: soft[:i],
Version: soft[i+1:],
}
} else if i = strings.LastIndex(soft, "_"); i > 0 {
hub.Server = dc.Software{
Name: soft[:i],
Version: soft[i+1:],
}
}
}
}
// will be decoded later, see defer
hub.Encoding = msg.Encoding
hub.Owner = msg.Owner
switchEncoding(msg)
case *nmdc.FailOver:
hub.Failover = append(hub.Failover, msg.Host...)
case *nmdc.UserCommand:
Expand Down
2 changes: 1 addition & 1 deletion ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,6 @@ type HubUser struct {
// Software version.
type Software struct {
Name string `json:"name" xml:"Name,attr"`
Version string `json:"vers" xml:"Version,attr"`
Version string `json:"vers,omitempty" xml:"Version,attr,omitempty"`
Ext []string `json:"ext,omitempty" xml:"Ext,attr,omitempty"`
}
2 changes: 1 addition & 1 deletion version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package version

const (
Name = "go-dcpp"
Vers = "0.8.12"
Vers = "0.8.13"
)

0 comments on commit b4f3caa

Please sign in to comment.