util.go raw
1 package rest
2
3 import (
4 "log"
5 "net/http"
6 "strings"
7 )
8
9 // DoerFunc satisfies Interface. DoerFuncs are useful for adding
10 // logging/instrumentation to the http.Client that is used
11 // within the rest.APIClient.
12 type DoerFunc func(*http.Request) (*http.Response, error)
13
14 // Do is implementation of rest.Doer interface. Calls itself on the
15 // given http.Request.
16 func (f DoerFunc) Do(r *http.Request) (*http.Response, error) {
17 return f(r)
18 }
19
20 // A Decorator wraps a Doer with extra behavior, and doesnt
21 // affect the behavior of other instances of the same type.
22 type Decorator func(Doer) Doer
23
24 // Decorate decorates a Doer c with all the given Decorators, in order.
25 // Core object(Doer instance) that we want to apply layers(Decorator slice) to.
26 func Decorate(d Doer, ds ...Decorator) Doer {
27 decorated := d
28 for _, decorate := range ds {
29 decorated = decorate(decorated)
30 }
31 return decorated
32 }
33
34 // Logging returns a Decorator that logs a Doer's requests.
35 // Dependency injection for the logger instance(inside the closures environment).
36 func Logging(l *log.Logger) Decorator {
37 return func(d Doer) Doer {
38 return DoerFunc(func(r *http.Request) (*http.Response, error) {
39 userAgent := r.UserAgent()
40 escapedUserAgent := strings.Replace(userAgent, "\n", "", -1)
41 escapedUserAgent = strings.Replace(escapedUserAgent, "\r", "", -1)
42 userURL := r.URL.String()
43 escapedURL := strings.Replace(userURL, "\n", "", -1)
44 escapedURL = strings.Replace(escapedURL, "\r", "", -1)
45 l.Printf("%s: %s %s", escapedUserAgent, r.Method, escapedURL)
46 return d.Do(r)
47 })
48 }
49 }
50