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

nsqio / nsq / 29510824590

16 Jul 2026 03:22PM UTC coverage: 46.746%. First build
29510824590

Pull #1529

github

web-flow
Merge a2df42a80 into 9ea507128
Pull Request #1529: Update go dependencies, coverage, static analysis and lint updates

96 of 459 new or added lines in 36 files covered. (20.92%)

4518 of 9665 relevant lines covered (46.75%)

479.44 hits per line

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

0.0
/internal/http_api/api_request.go
1
package http_api
2

3
import (
4
        "bytes"
5
        "crypto/tls"
6
        "encoding/json"
7
        "fmt"
8
        "io"
9
        "net"
10
        "net/http"
11
        "net/url"
12
        "strconv"
13
        "strings"
14
        "time"
15
)
16

17
// A custom http.Transport with support for deadline timeouts
18
func NewDeadlineTransport(connectTimeout time.Duration, requestTimeout time.Duration) *http.Transport {
×
19
        // arbitrary values copied from http.DefaultTransport
×
20
        transport := &http.Transport{
×
21
                DialContext: (&net.Dialer{
×
22
                        Timeout:   connectTimeout,
×
23
                        KeepAlive: 30 * time.Second,
×
24
                        DualStack: true,
×
25
                }).DialContext,
×
26
                ResponseHeaderTimeout: requestTimeout,
×
27
                MaxIdleConns:          100,
×
28
                IdleConnTimeout:       90 * time.Second,
×
29
                TLSHandshakeTimeout:   10 * time.Second,
×
30
        }
×
31
        return transport
×
32
}
×
33

34
type Client struct {
35
        c *http.Client
36
}
37

38
func NewClient(tlsConfig *tls.Config, connectTimeout time.Duration, requestTimeout time.Duration) *Client {
×
39
        transport := NewDeadlineTransport(connectTimeout, requestTimeout)
×
40
        transport.TLSClientConfig = tlsConfig
×
41
        return &Client{
×
42
                c: &http.Client{
×
43
                        Transport: transport,
×
44
                        Timeout:   requestTimeout,
×
45
                },
×
46
        }
×
47
}
×
48

49
// GETV1 is a helper function to perform a V1 HTTP request
50
// and parse our NSQ daemon's expected response format, with deadlines.
51
func (c *Client) GETV1(endpoint string, v interface{}) error {
×
52
retry:
×
53
        req, err := http.NewRequest("GET", endpoint, nil)
×
54
        if err != nil {
×
55
                return err
×
56
        }
×
57

58
        req.Header.Add("Accept", "application/vnd.nsq; version=1.0")
×
59

×
60
        resp, err := c.c.Do(req)
×
61
        if err != nil {
×
62
                return err
×
63
        }
×
64

65
        body, err := io.ReadAll(resp.Body)
×
NEW
66
        closeErr := resp.Body.Close()
×
67
        if err != nil {
×
68
                return err
×
69
        }
×
NEW
70
        if closeErr != nil {
×
NEW
71
                return closeErr
×
NEW
72
        }
×
73
        if resp.StatusCode != 200 {
×
74
                if resp.StatusCode == 403 && !strings.HasPrefix(endpoint, "https") {
×
75
                        endpoint, err = httpsEndpoint(endpoint, body)
×
76
                        if err != nil {
×
77
                                return err
×
78
                        }
×
79
                        goto retry
×
80
                }
81
                return fmt.Errorf("got response %s %q", resp.Status, body)
×
82
        }
83
        err = json.Unmarshal(body, &v)
×
84
        if err != nil {
×
85
                return err
×
86
        }
×
87

88
        return nil
×
89
}
90

91
// PostV1 is a helper function to perform a V1 HTTP request
92
// and parse our NSQ daemon's expected response format, with deadlines.
93
func (c *Client) POSTV1(endpoint string, data url.Values, v interface{}) error {
×
94
retry:
×
95
        var reqBody io.Reader
×
96
        if data != nil {
×
97
                js, err := json.Marshal(data)
×
98
                if err != nil {
×
99
                        return fmt.Errorf("failed to marshal POST data to endpoint: %v", endpoint)
×
100
                }
×
101
                reqBody = bytes.NewBuffer(js)
×
102
        }
103

104
        req, err := http.NewRequest("POST", endpoint, reqBody)
×
105
        if err != nil {
×
106
                return err
×
107
        }
×
108

109
        req.Header.Add("Accept", "application/vnd.nsq; version=1.0")
×
110
        if reqBody != nil {
×
111
                req.Header.Add("Content-Type", "application/json")
×
112
        }
×
113

114
        resp, err := c.c.Do(req)
×
115
        if err != nil {
×
116
                return err
×
117
        }
×
118

119
        body, err := io.ReadAll(resp.Body)
×
NEW
120
        closeErr := resp.Body.Close()
×
121
        if err != nil {
×
122
                return err
×
123
        }
×
NEW
124
        if closeErr != nil {
×
NEW
125
                return closeErr
×
NEW
126
        }
×
127
        if resp.StatusCode != 200 {
×
128
                if resp.StatusCode == 403 && !strings.HasPrefix(endpoint, "https") {
×
129
                        endpoint, err = httpsEndpoint(endpoint, body)
×
130
                        if err != nil {
×
131
                                return err
×
132
                        }
×
133
                        goto retry
×
134
                }
135
                return fmt.Errorf("got response %s %q", resp.Status, body)
×
136
        }
137

138
        if v != nil {
×
139
                return json.Unmarshal(body, &v)
×
140
        }
×
141

142
        return nil
×
143
}
144

145
func httpsEndpoint(endpoint string, body []byte) (string, error) {
×
146
        var forbiddenResp struct {
×
147
                HTTPSPort int `json:"https_port"`
×
148
        }
×
149
        err := json.Unmarshal(body, &forbiddenResp)
×
150
        if err != nil {
×
151
                return "", err
×
152
        }
×
153

154
        u, err := url.Parse(endpoint)
×
155
        if err != nil {
×
156
                return "", err
×
157
        }
×
158

159
        host, _, err := net.SplitHostPort(u.Host)
×
160
        if err != nil {
×
161
                return "", err
×
162
        }
×
163

164
        u.Scheme = "https"
×
165
        u.Host = net.JoinHostPort(host, strconv.Itoa(forbiddenResp.HTTPSPort))
×
166
        return u.String(), nil
×
167
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc