• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ghettovoice / gosip / 20275641102

16 Dec 2025 04:42PM UTC coverage: 40.889% (-33.6%) from 74.523%
20275641102

push

github

ghettovoice
Refactor SIP stack with transaction/transport layers and improved API

- Implement TransactionLayer with request/response routing and graceful shutdown
- Add TransportLayer for centralized transport management
- Client/server transaction implementation with persistence support
- Add transaction factories and automatic cleanup on termination
- Introduce InboundMessage/OutboundMessage wrappers with type-safe accessors
- Add StatsRecorder interface for transport statistics
- Consolidate Send/Render/NewResponse methods with optional options
- Add log package with context-based logger
- Support compact header rendering
- Message RTT calculation
- Optimization: upgrade abnf lib, fix race conditions, read timeouts
- Improve error handling and validation
- Add comprehensive test coverage

7324 of 19365 new or added lines in 110 files covered. (37.82%)

19 existing lines in 3 files now uncovered.

8439 of 20639 relevant lines covered (40.89%)

8.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

58.18
/header/content_encoding.go
1
package header
2

3
import (
4
        "errors"
5
        "fmt"
6
        "io"
7
        "slices"
8
        "strconv"
9

10
        "braces.dev/errtrace"
11
        "github.com/ghettovoice/abnf"
12

13
        "github.com/ghettovoice/gosip/internal/errorutil"
14
        "github.com/ghettovoice/gosip/internal/grammar"
15
        "github.com/ghettovoice/gosip/internal/ioutil"
16
        "github.com/ghettovoice/gosip/internal/util"
17
)
18

19
type ContentEncoding []Encoding
20

21
func (ContentEncoding) CanonicName() Name { return "Content-Encoding" }
5✔
22

23
func (ContentEncoding) CompactName() Name { return "e" }
1✔
24

25
func (hdr ContentEncoding) RenderTo(w io.Writer, opts *RenderOptions) (num int, err error) {
7✔
26
        if hdr == nil {
8✔
27
                return 0, nil
1✔
28
        }
1✔
29

30
        cw := ioutil.GetCountingWriter(w)
6✔
31
        defer ioutil.FreeCountingWriter(cw)
6✔
32
        cw.Fprint(hdr.name(opts), ": ")
6✔
33
        cw.Call(hdr.renderValueTo)
6✔
34
        return errtrace.Wrap2(cw.Result())
6✔
35
}
36

37
func (hdr ContentEncoding) name(opts *RenderOptions) Name {
6✔
38
        if opts != nil && opts.Compact {
7✔
39
                return hdr.CompactName()
1✔
40
        }
1✔
41
        return hdr.CanonicName()
5✔
42
}
43

44
func (hdr ContentEncoding) renderValueTo(w io.Writer) (num int, err error) {
9✔
45
        return errtrace.Wrap2(renderHdrEntries(w, hdr))
9✔
46
}
9✔
47

48
func (hdr ContentEncoding) Render(opts *RenderOptions) string {
5✔
49
        if hdr == nil {
6✔
50
                return ""
1✔
51
        }
1✔
52

53
        sb := util.GetStringBuilder()
4✔
54
        defer util.FreeStringBuilder(sb)
4✔
55
        hdr.RenderTo(sb, opts) //nolint:errcheck
4✔
56
        return sb.String()
4✔
57
}
58

59
func (hdr ContentEncoding) RenderValue() string {
3✔
60
        sb := util.GetStringBuilder()
3✔
61
        defer util.FreeStringBuilder(sb)
3✔
62
        hdr.renderValueTo(sb) //nolint:errcheck
3✔
63
        return sb.String()
3✔
64
}
3✔
65

66
func (hdr ContentEncoding) String() string { return hdr.RenderValue() }
3✔
67

NEW
68
func (hdr ContentEncoding) Format(f fmt.State, verb rune) {
×
NEW
69
        switch verb {
×
NEW
70
        case 's':
×
NEW
71
                if f.Flag('+') {
×
NEW
72
                        hdr.RenderTo(f, nil) //nolint:errcheck
×
NEW
73
                        return
×
NEW
74
                }
×
NEW
75
                fmt.Fprint(f, hdr.String())
×
NEW
76
                return
×
NEW
77
        case 'q':
×
NEW
78
                if f.Flag('+') {
×
NEW
79
                        fmt.Fprint(f, strconv.Quote(hdr.Render(nil)))
×
NEW
80
                        return
×
NEW
81
                }
×
NEW
82
                fmt.Fprint(f, strconv.Quote(hdr.String()))
×
NEW
83
                return
×
NEW
84
        default:
×
NEW
85
                type hideMethods ContentEncoding
×
NEW
86
                type ContentEncoding hideMethods
×
NEW
87
                fmt.Fprintf(f, fmt.FormatString(f, verb), ContentEncoding(hdr))
×
NEW
88
                return
×
89
        }
90
}
91

92
func (hdr ContentEncoding) Clone() Header { return slices.Clone(hdr) }
3✔
93

94
func (hdr ContentEncoding) Equal(val any) bool {
19✔
95
        var other ContentEncoding
19✔
96
        switch v := val.(type) {
19✔
97
        case ContentEncoding:
16✔
98
                other = v
16✔
99
        case *ContentEncoding:
2✔
100
                if v == nil {
3✔
101
                        return false
1✔
102
                }
1✔
103
                other = *v
1✔
104
        default:
1✔
105
                return false
1✔
106
        }
107
        return slices.EqualFunc(hdr, other, func(enc1, enc2 Encoding) bool { return enc1.Equal(enc2) })
32✔
108
}
109

110
func (hdr ContentEncoding) IsValid() bool {
4✔
111
        return len(hdr) > 0 && !slices.ContainsFunc(hdr, func(enc Encoding) bool { return !enc.IsValid() })
7✔
112
}
113

NEW
114
func (hdr ContentEncoding) MarshalJSON() ([]byte, error) {
×
NEW
115
        return errtrace.Wrap2(ToJSON(hdr))
×
NEW
116
}
×
117

NEW
118
func (hdr *ContentEncoding) UnmarshalJSON(data []byte) error {
×
NEW
119
        gh, err := FromJSON(data)
×
NEW
120
        if err != nil {
×
NEW
121
                *hdr = nil
×
NEW
122
                if errors.Is(err, errNotHeaderJSON) {
×
NEW
123
                        return nil
×
NEW
124
                }
×
NEW
125
                return errtrace.Wrap(err)
×
126
        }
127

NEW
128
        h, ok := gh.(ContentEncoding)
×
NEW
129
        if !ok {
×
NEW
130
                *hdr = nil
×
NEW
131
                return errtrace.Wrap(errorutil.Errorf("unexpected header: got %T, want %T", gh, *hdr))
×
NEW
132
        }
×
133

NEW
134
        *hdr = h
×
NEW
135
        return nil
×
136
}
137

138
func buildFromContentEncodingNode(node *abnf.Node) ContentEncoding {
2✔
139
        encNodes := node.GetNodes("token")
2✔
140
        h := make(ContentEncoding, len(encNodes))
2✔
141
        for i, encNode := range encNodes {
6✔
142
                h[i] = Encoding(encNode.String())
4✔
143
        }
4✔
144
        return h
2✔
145
}
146

147
type Encoding string
148

149
func (enc Encoding) IsValid() bool { return grammar.IsToken(enc) }
11✔
150

151
func (enc Encoding) Equal(val any) bool {
47✔
152
        var other Encoding
47✔
153
        switch v := val.(type) {
47✔
154
        case Encoding:
47✔
155
                other = v
47✔
NEW
156
        case *Encoding:
×
NEW
157
                if v == nil {
×
NEW
158
                        return false
×
NEW
159
                }
×
NEW
160
                other = *v
×
NEW
161
        default:
×
NEW
162
                return false
×
163
        }
164
        return util.EqFold(enc, other)
47✔
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc