Changeset 488 in code for trunk/msgstore.go


Ignore:
Timestamp:
Mar 31, 2021, 3:57:24 PM (4 years ago)
Author:
contact
Message:

Use BARE for internal message IDs

This allows to have shorter and more future-proof IDs. This also
guarantees the IDs will only use reasonable ASCII characters (no
spaces), removing the need to encode them for PING/PONG tokens.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/msgstore.go

    r441 r488  
    22
    33import (
     4        "bytes"
     5        "encoding/base64"
    46        "fmt"
    5         "strconv"
    6         "strings"
    77        "time"
    88
     9        "git.sr.ht/~sircmpwn/go-bare"
    910        "gopkg.in/irc.v3"
    1011)
     
    3031}
    3132
    32 func formatMsgID(netID int64, entity, extra string) string {
    33         return fmt.Sprintf("%v %v %v", netID, entity, extra)
     33type msgIDType uint
     34
     35const (
     36        msgIDNone msgIDType = iota
     37        msgIDMemory
     38        msgIDFS
     39)
     40
     41const msgIDVersion uint = 0
     42
     43type msgIDHeader struct {
     44        Version uint
     45        Network bare.Int
     46        Target  string
     47        Type    msgIDType
    3448}
    3549
    36 func parseMsgID(s string) (netID int64, entity, extra string, err error) {
    37         l := strings.SplitN(s, " ", 3)
    38         if len(l) != 3 {
    39                 return 0, "", "", fmt.Errorf("invalid message ID %q: expected 3 fields", s)
     50type msgIDBody interface {
     51        msgIDType() msgIDType
     52}
     53
     54func formatMsgID(netID int64, target string, body msgIDBody) string {
     55        var buf bytes.Buffer
     56        w := bare.NewWriter(&buf)
     57
     58        header := msgIDHeader{
     59                Version: msgIDVersion,
     60                Network: bare.Int(netID),
     61                Target:  target,
     62                Type:    body.msgIDType(),
    4063        }
    41         netID, err = strconv.ParseInt(l[0], 10, 64)
     64        if err := bare.MarshalWriter(w, &header); err != nil {
     65                panic(err)
     66        }
     67        if err := bare.MarshalWriter(w, body); err != nil {
     68                panic(err)
     69        }
     70        return base64.RawURLEncoding.EncodeToString(buf.Bytes())
     71}
     72
     73func parseMsgID(s string, body msgIDBody) (netID int64, target string, err error) {
     74        b, err := base64.RawURLEncoding.DecodeString(s)
    4275        if err != nil {
    43                 return 0, "", "", fmt.Errorf("invalid message ID %q: %v", s, err)
     76                return 0, "", fmt.Errorf("invalid internal message ID: %v", err)
    4477        }
    45         return netID, l[1], l[2], nil
     78
     79        r := bare.NewReader(bytes.NewReader(b))
     80
     81        var header msgIDHeader
     82        if err := bare.UnmarshalBareReader(r, &header); err != nil {
     83                return 0, "", fmt.Errorf("invalid internal message ID: %v", err)
     84        }
     85
     86        if header.Version != msgIDVersion {
     87                return 0, "", fmt.Errorf("invalid internal message ID: got version %v, want %v", header.Version, msgIDVersion)
     88        }
     89
     90        if body != nil {
     91                typ := body.msgIDType()
     92                if header.Type != typ {
     93                        return 0, "", fmt.Errorf("invalid internal message ID: got type %v, want %v", header.Type, typ)
     94                }
     95
     96                if err := bare.UnmarshalBareReader(r, body); err != nil {
     97                        return 0, "", fmt.Errorf("invalid internal message ID: %v", err)
     98                }
     99        }
     100
     101        return int64(header.Network), header.Target, nil
    46102}
Note: See TracChangeset for help on using the changeset viewer.