orator.keyForRequest   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
package client
2
3
import (
4
	"errors"
5
	"fmt"
6
	"net/http"
7
	"sync"
8
)
9
10
var (
11
	// ErrRequestRedundant this error is returned when trying to perform the
12
	// same request (method, host, path) more than one time.
13
	ErrRequestRedundant = errors.New("this request has been made already")
14
)
15
16
func decorateTransportWithRequestCacheDecorator(decorated http.RoundTripper) (*requestCacheTransportDecorator, error) {
17
	if decorated == nil {
18
		return nil, errors.New("decorated round tripper is nil")
19
	}
20
21
	return &requestCacheTransportDecorator{decorated: decorated}, nil
22
}
23
24
type requestCacheTransportDecorator struct {
25
	decorated  http.RoundTripper
26
	requestMap sync.Map
27
}
28
29
func (u *requestCacheTransportDecorator) RoundTrip(r *http.Request) (*http.Response, error) {
30
	key := u.keyForRequest(r)
31
32
	_, found := u.requestMap.Load(key)
33
	if found {
34
		return nil, ErrRequestRedundant
35
	}
36
37
	u.requestMap.Store(key, struct{}{})
38
39
	return u.decorated.RoundTrip(r)
40
}
41
42
func (u *requestCacheTransportDecorator) keyForRequest(r *http.Request) string {
43
	return fmt.Sprintf("%s~%s~%s", r.Method, r.Host, r.URL.Path)
44
}
45