Skip to content

Commit 8d00add

Browse files
authored
Extract option funcs and response types into separate files for clarity (#102)
1 parent 688c562 commit 8d00add

File tree

4 files changed

+163
-155
lines changed

4 files changed

+163
-155
lines changed
File renamed without changes.

httpbin/httpbin.go

+30-155
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package httpbin
22

33
import (
44
"net/http"
5-
"net/url"
65
"time"
76
)
87

@@ -13,77 +12,19 @@ const (
1312
DefaultHostname = "go-httpbin"
1413
)
1514

16-
const (
17-
jsonContentType = "application/json; encoding=utf-8"
18-
htmlContentType = "text/html; charset=utf-8"
19-
)
20-
21-
type headersResponse struct {
22-
Headers http.Header `json:"headers"`
23-
}
24-
25-
type ipResponse struct {
26-
Origin string `json:"origin"`
27-
}
28-
29-
type userAgentResponse struct {
30-
UserAgent string `json:"user-agent"`
31-
}
32-
33-
// A generic response for any incoming request that should not contain a body
34-
// (GET, HEAD, OPTIONS, etc).
35-
type noBodyResponse struct {
36-
Args url.Values `json:"args"`
37-
Headers http.Header `json:"headers"`
38-
Origin string `json:"origin"`
39-
URL string `json:"url"`
40-
41-
Deflated bool `json:"deflated,omitempty"`
42-
Gzipped bool `json:"gzipped,omitempty"`
43-
}
44-
45-
// A generic response for any incoming request that might contain a body (POST,
46-
// PUT, PATCH, etc).
47-
type bodyResponse struct {
48-
Args url.Values `json:"args"`
49-
Headers http.Header `json:"headers"`
50-
Origin string `json:"origin"`
51-
URL string `json:"url"`
52-
53-
Data string `json:"data"`
54-
Files map[string][]string `json:"files"`
55-
Form map[string][]string `json:"form"`
56-
JSON interface{} `json:"json"`
57-
}
58-
59-
type cookiesResponse map[string]string
60-
61-
type authResponse struct {
62-
Authorized bool `json:"authorized"`
63-
User string `json:"user"`
64-
}
65-
66-
// An actual stream response body will be made up of one or more of these
67-
// structs, encoded as JSON and separated by newlines
68-
type streamResponse struct {
69-
ID int `json:"id"`
70-
Args url.Values `json:"args"`
71-
Headers http.Header `json:"headers"`
72-
Origin string `json:"origin"`
73-
URL string `json:"url"`
74-
}
75-
76-
type uuidResponse struct {
77-
UUID string `json:"uuid"`
78-
}
79-
80-
type bearerResponse struct {
81-
Authenticated bool `json:"authenticated"`
82-
Token string `json:"token"`
15+
// DefaultParams defines default parameter values
16+
type DefaultParams struct {
17+
DripDuration time.Duration
18+
DripDelay time.Duration
19+
DripNumBytes int64
8320
}
8421

85-
type hostnameResponse struct {
86-
Hostname string `json:"hostname"`
22+
// DefaultDefaultParams defines the DefaultParams that are used by default. In
23+
// general, these should match the original httpbin.org's defaults.
24+
var DefaultDefaultParams = DefaultParams{
25+
DripDuration: 2 * time.Second,
26+
DripDelay: 2 * time.Second,
27+
DripNumBytes: 10,
8728
}
8829

8930
// HTTPBin contains the business logic
@@ -111,21 +52,29 @@ type HTTPBin struct {
11152
handler http.Handler
11253
}
11354

114-
// DefaultParams defines default parameter values
115-
type DefaultParams struct {
116-
DripDuration time.Duration
117-
DripDelay time.Duration
118-
DripNumBytes int64
55+
// New creates a new HTTPBin instance
56+
func New(opts ...OptionFunc) *HTTPBin {
57+
h := &HTTPBin{
58+
MaxBodySize: DefaultMaxBodySize,
59+
MaxDuration: DefaultMaxDuration,
60+
DefaultParams: DefaultDefaultParams,
61+
hostname: DefaultHostname,
62+
}
63+
for _, opt := range opts {
64+
opt(h)
65+
}
66+
h.handler = h.Handler()
67+
return h
11968
}
12069

121-
// DefaultDefaultParams defines the DefaultParams that are used by default. In
122-
// general, these should match the original httpbin.org's defaults.
123-
var DefaultDefaultParams = DefaultParams{
124-
DripDuration: 2 * time.Second,
125-
DripDelay: 2 * time.Second,
126-
DripNumBytes: 10,
70+
// ServeHTTP implememnts the http.Handler interface.
71+
func (h *HTTPBin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
72+
h.handler.ServeHTTP(w, r)
12773
}
12874

75+
// Assert that HTTPBin implements http.Handler interface
76+
var _ http.Handler = &HTTPBin{}
77+
12978
// Handler returns an http.Handler that exposes all HTTPBin endpoints
13079
func (h *HTTPBin) Handler() http.Handler {
13180
mux := http.NewServeMux()
@@ -227,77 +176,3 @@ func (h *HTTPBin) Handler() http.Handler {
227176

228177
return handler
229178
}
230-
231-
// New creates a new HTTPBin instance
232-
func New(opts ...OptionFunc) *HTTPBin {
233-
h := &HTTPBin{
234-
MaxBodySize: DefaultMaxBodySize,
235-
MaxDuration: DefaultMaxDuration,
236-
DefaultParams: DefaultDefaultParams,
237-
hostname: DefaultHostname,
238-
}
239-
for _, opt := range opts {
240-
opt(h)
241-
}
242-
h.handler = h.Handler()
243-
return h
244-
}
245-
246-
// ServeHTTP implememnts the http.Handler interface.
247-
func (h *HTTPBin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
248-
h.handler.ServeHTTP(w, r)
249-
}
250-
251-
// Assert that HTTPBin implements http.Handler interface
252-
var _ http.Handler = &HTTPBin{}
253-
254-
// OptionFunc uses the "functional options" pattern to customize an HTTPBin
255-
// instance
256-
type OptionFunc func(*HTTPBin)
257-
258-
// WithDefaultParams sets the default params handlers will use
259-
func WithDefaultParams(defaultParams DefaultParams) OptionFunc {
260-
return func(h *HTTPBin) {
261-
h.DefaultParams = defaultParams
262-
}
263-
}
264-
265-
// WithMaxBodySize sets the maximum amount of memory
266-
func WithMaxBodySize(m int64) OptionFunc {
267-
return func(h *HTTPBin) {
268-
h.MaxBodySize = m
269-
}
270-
}
271-
272-
// WithMaxDuration sets the maximum amount of time httpbin may take to respond
273-
func WithMaxDuration(d time.Duration) OptionFunc {
274-
return func(h *HTTPBin) {
275-
h.MaxDuration = d
276-
}
277-
}
278-
279-
// WithHostname sets the hostname to return via the /hostname endpoint.
280-
func WithHostname(s string) OptionFunc {
281-
return func(h *HTTPBin) {
282-
h.hostname = s
283-
}
284-
}
285-
286-
// WithObserver sets the request observer callback
287-
func WithObserver(o Observer) OptionFunc {
288-
return func(h *HTTPBin) {
289-
h.Observer = o
290-
}
291-
}
292-
293-
// WithAllowedRedirectDomains limits the domains to which the /redirect-to
294-
// endpoint will redirect traffic.
295-
func WithAllowedRedirectDomains(hosts []string) OptionFunc {
296-
return func(h *HTTPBin) {
297-
hostSet := make(map[string]struct{}, len(hosts))
298-
for _, host := range hosts {
299-
hostSet[host] = struct{}{}
300-
}
301-
h.AllowedRedirectDomains = hostSet
302-
}
303-
}

httpbin/options.go

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package httpbin
2+
3+
import "time"
4+
5+
// OptionFunc uses the "functional options" pattern to customize an HTTPBin
6+
// instance
7+
type OptionFunc func(*HTTPBin)
8+
9+
// WithDefaultParams sets the default params handlers will use
10+
func WithDefaultParams(defaultParams DefaultParams) OptionFunc {
11+
return func(h *HTTPBin) {
12+
h.DefaultParams = defaultParams
13+
}
14+
}
15+
16+
// WithMaxBodySize sets the maximum amount of memory
17+
func WithMaxBodySize(m int64) OptionFunc {
18+
return func(h *HTTPBin) {
19+
h.MaxBodySize = m
20+
}
21+
}
22+
23+
// WithMaxDuration sets the maximum amount of time httpbin may take to respond
24+
func WithMaxDuration(d time.Duration) OptionFunc {
25+
return func(h *HTTPBin) {
26+
h.MaxDuration = d
27+
}
28+
}
29+
30+
// WithHostname sets the hostname to return via the /hostname endpoint.
31+
func WithHostname(s string) OptionFunc {
32+
return func(h *HTTPBin) {
33+
h.hostname = s
34+
}
35+
}
36+
37+
// WithObserver sets the request observer callback
38+
func WithObserver(o Observer) OptionFunc {
39+
return func(h *HTTPBin) {
40+
h.Observer = o
41+
}
42+
}
43+
44+
// WithAllowedRedirectDomains limits the domains to which the /redirect-to
45+
// endpoint will redirect traffic.
46+
func WithAllowedRedirectDomains(hosts []string) OptionFunc {
47+
return func(h *HTTPBin) {
48+
hostSet := make(map[string]struct{}, len(hosts))
49+
for _, host := range hosts {
50+
hostSet[host] = struct{}{}
51+
}
52+
h.AllowedRedirectDomains = hostSet
53+
}
54+
}

httpbin/responses.go

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package httpbin
2+
3+
import (
4+
"net/http"
5+
"net/url"
6+
)
7+
8+
const (
9+
jsonContentType = "application/json; encoding=utf-8"
10+
htmlContentType = "text/html; charset=utf-8"
11+
)
12+
13+
type headersResponse struct {
14+
Headers http.Header `json:"headers"`
15+
}
16+
17+
type ipResponse struct {
18+
Origin string `json:"origin"`
19+
}
20+
21+
type userAgentResponse struct {
22+
UserAgent string `json:"user-agent"`
23+
}
24+
25+
// A generic response for any incoming request that should not contain a body
26+
// (GET, HEAD, OPTIONS, etc).
27+
type noBodyResponse struct {
28+
Args url.Values `json:"args"`
29+
Headers http.Header `json:"headers"`
30+
Origin string `json:"origin"`
31+
URL string `json:"url"`
32+
33+
Deflated bool `json:"deflated,omitempty"`
34+
Gzipped bool `json:"gzipped,omitempty"`
35+
}
36+
37+
// A generic response for any incoming request that might contain a body (POST,
38+
// PUT, PATCH, etc).
39+
type bodyResponse struct {
40+
Args url.Values `json:"args"`
41+
Headers http.Header `json:"headers"`
42+
Origin string `json:"origin"`
43+
URL string `json:"url"`
44+
45+
Data string `json:"data"`
46+
Files map[string][]string `json:"files"`
47+
Form map[string][]string `json:"form"`
48+
JSON interface{} `json:"json"`
49+
}
50+
51+
type cookiesResponse map[string]string
52+
53+
type authResponse struct {
54+
Authorized bool `json:"authorized"`
55+
User string `json:"user"`
56+
}
57+
58+
// An actual stream response body will be made up of one or more of these
59+
// structs, encoded as JSON and separated by newlines
60+
type streamResponse struct {
61+
ID int `json:"id"`
62+
Args url.Values `json:"args"`
63+
Headers http.Header `json:"headers"`
64+
Origin string `json:"origin"`
65+
URL string `json:"url"`
66+
}
67+
68+
type uuidResponse struct {
69+
UUID string `json:"uuid"`
70+
}
71+
72+
type bearerResponse struct {
73+
Authenticated bool `json:"authenticated"`
74+
Token string `json:"token"`
75+
}
76+
77+
type hostnameResponse struct {
78+
Hostname string `json:"hostname"`
79+
}

0 commit comments

Comments
 (0)