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

nsqio / nsq / 29756879699

20 Jul 2026 03:49PM UTC coverage: 46.849%. First build
29756879699

Pull #1529

github

web-flow
Merge 208325a67 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%)

4528 of 9665 relevant lines covered (46.85%)

477.4 hits per line

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

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

3
import (
4
        "encoding/json"
5
        "fmt"
6
        "io"
7
        "net/http"
8
        "time"
9

10
        "github.com/julienschmidt/httprouter"
11
        "github.com/nsqio/nsq/internal/lg"
12
)
13

14
type Decorator func(APIHandler) APIHandler
15

16
type APIHandler func(http.ResponseWriter, *http.Request, httprouter.Params) (interface{}, error)
17

18
type Err struct {
19
        Code int
20
        Text string
21
}
22

23
func (e Err) Error() string {
×
24
        return e.Text
×
25
}
×
26

27
func PlainText(f APIHandler) APIHandler {
×
28
        return func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) (interface{}, error) {
×
29
                code := 200
×
30
                data, err := f(w, req, ps)
×
31
                if err != nil {
×
32
                        code = err.(Err).Code
×
33
                        data = err.Error()
×
34
                }
×
35
                switch d := data.(type) {
×
36
                case string:
×
37
                        w.WriteHeader(code)
×
NEW
38
                        if _, err := io.WriteString(w, d); err != nil {
×
NEW
39
                                return nil, err
×
NEW
40
                        }
×
41
                case []byte:
×
42
                        w.WriteHeader(code)
×
NEW
43
                        if _, err := w.Write(d); err != nil {
×
NEW
44
                                return nil, err
×
NEW
45
                        }
×
46
                default:
×
47
                        panic(fmt.Sprintf("unknown response type %T", data))
×
48
                }
49
                return nil, nil
×
50
        }
51
}
52

53
func V1(f APIHandler) APIHandler {
×
54
        return func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) (interface{}, error) {
×
55
                data, err := f(w, req, ps)
×
56
                if err != nil {
×
57
                        RespondV1(w, err.(Err).Code, err)
×
58
                        return nil, nil
×
59
                }
×
60
                RespondV1(w, 200, data)
×
61
                return nil, nil
×
62
        }
63
}
64

65
func RespondV1(w http.ResponseWriter, code int, data interface{}) {
×
66
        var response []byte
×
67
        var err error
×
68
        var isJSON bool
×
69

×
70
        if code == 200 {
×
71
                switch data := data.(type) {
×
72
                case string:
×
73
                        response = []byte(data)
×
74
                case []byte:
×
75
                        response = data
×
76
                case nil:
×
77
                        response = []byte{}
×
78
                default:
×
79
                        isJSON = true
×
80
                        response, err = json.Marshal(data)
×
81
                        if err != nil {
×
82
                                code = 500
×
NEW
83
                                response, _ = json.Marshal(struct {
×
NEW
84
                                        Message string `json:"message"`
×
NEW
85
                                }{err.Error()})
×
86
                        }
×
87
                }
88
        }
89

90
        if code != 200 {
×
91
                isJSON = true
×
92
                response, _ = json.Marshal(struct {
×
93
                        Message string `json:"message"`
×
94
                }{fmt.Sprintf("%s", data)})
×
95
        }
×
96

97
        if isJSON {
×
98
                w.Header().Set("Content-Type", "application/json; charset=utf-8")
×
99
        }
×
100
        w.Header().Set("X-NSQ-Content-Type", "nsq; version=1.0")
×
101
        w.WriteHeader(code)
×
NEW
102
        _, _ = w.Write(response)
×
103
}
104

105
func Decorate(f APIHandler, ds ...Decorator) httprouter.Handle {
×
106
        decorated := f
×
107
        for _, decorate := range ds {
×
108
                decorated = decorate(decorated)
×
109
        }
×
110
        return func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
×
NEW
111
                _, _ = decorated(w, req, ps)
×
112
        }
×
113
}
114

115
func Log(logf lg.AppLogFunc) Decorator {
×
116
        return func(f APIHandler) APIHandler {
×
117
                return func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) (interface{}, error) {
×
118
                        start := time.Now()
×
119
                        response, err := f(w, req, ps)
×
120
                        elapsed := time.Since(start)
×
121
                        status := 200
×
122
                        if e, ok := err.(Err); ok {
×
123
                                status = e.Code
×
124
                        }
×
125
                        logf(lg.INFO, "%d %s %s (%s) %s",
×
126
                                status, req.Method, req.URL.RequestURI(), req.RemoteAddr, elapsed)
×
127
                        return response, err
×
128
                }
129
        }
130
}
131

132
func LogPanicHandler(logf lg.AppLogFunc) func(w http.ResponseWriter, req *http.Request, p interface{}) {
×
133
        return func(w http.ResponseWriter, req *http.Request, p interface{}) {
×
134
                logf(lg.ERROR, "panic in HTTP handler - %s", p)
×
135
                Decorate(func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) (interface{}, error) {
×
136
                        return nil, Err{500, "INTERNAL_ERROR"}
×
137
                }, Log(logf), V1)(w, req, nil)
×
138
        }
139
}
140

141
func LogNotFoundHandler(logf lg.AppLogFunc) http.Handler {
×
142
        return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
×
143
                Decorate(func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) (interface{}, error) {
×
144
                        return nil, Err{404, "NOT_FOUND"}
×
145
                }, Log(logf), V1)(w, req, nil)
×
146
        })
147
}
148

149
func LogMethodNotAllowedHandler(logf lg.AppLogFunc) http.Handler {
×
150
        return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
×
151
                Decorate(func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) (interface{}, error) {
×
152
                        return nil, Err{405, "METHOD_NOT_ALLOWED"}
×
153
                }, Log(logf), V1)(w, req, nil)
×
154
        })
155
}
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