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

nsqio / nsq / 29509145787

16 Jul 2026 03:00PM UTC coverage: 46.89%. First build
29509145787

Pull #1529

github

web-flow
Merge 0d9213362 into 9ea507128
Pull Request #1529: Go: update dependencies

99 of 457 new or added lines in 36 files covered. (21.66%)

4531 of 9663 relevant lines covered (46.89%)

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

87
        return nil
×
88
}
89

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

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

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

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

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

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

140
        return nil
×
141
}
142

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

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

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

162
        u.Scheme = "https"
×
163
        u.Host = net.JoinHostPort(host, strconv.Itoa(forbiddenResp.HTTPSPort))
×
164
        return u.String(), nil
×
165
}
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