forked from hudl/fargo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rpc.go
128 lines (118 loc) · 3.55 KB
/
rpc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package fargo
// MIT Licensed (see README.md) - Copyright (c) 2013 Hudl <@Hudl>
import (
"bytes"
"io/ioutil"
"net"
"net/http"
"net/url"
"time"
)
var HttpClient = &http.Client{
Transport: transport,
Timeout: 30 * time.Second,
}
var transport = &http.Transport{
Dial: (&net.Dialer{
Timeout: 5 * time.Second,
}).Dial,
ResponseHeaderTimeout: 10 * time.Second,
}
func postBody(reqURL string, reqBody []byte, isJson bool) ([]byte, int, error) {
req, err := http.NewRequest("POST", reqURL, bytes.NewReader(reqBody))
if err != nil {
log.Errorf("Could not create POST %s with body %s, error: %s", reqURL, string(reqBody), err.Error())
return nil, -1, err
}
log.Debugf("postBody: %s %s : %s\n", req.Method, req.URL, string(reqBody))
body, rcode, err := netReqTyped(req, isJson)
if err != nil {
log.Errorf("Could not complete POST %s with body %s, error: %s", reqURL, string(reqBody), err.Error())
return nil, rcode, err
}
//eurekaCache.Flush()
return body, rcode, nil
}
func putKV(reqURL string, pairs map[string]string) ([]byte, int, error) {
params := url.Values{}
for k, v := range pairs {
params.Add(k, v)
}
parameterizedURL := reqURL + "?" + params.Encode()
log.Noticef("Sending KV request with URL %s", parameterizedURL)
req, err := http.NewRequest("PUT", parameterizedURL, nil)
if err != nil {
log.Errorf("Could not create PUT %s, error: %s", reqURL, err.Error())
return nil, -1, err
}
body, rcode, err := netReq(req) // TODO(cq) I think this can just be netReq() since there is no body
if err != nil {
log.Errorf("Could not complete PUT %s, error: %s", reqURL, err.Error())
return nil, rcode, err
}
return body, rcode, nil
}
func getBody(reqURL string, isJson bool) ([]byte, int, error) {
req, err := http.NewRequest("GET", reqURL, nil)
if err != nil {
log.Errorf("Could not create GET %s, error: %s", reqURL, err.Error())
return nil, -1, err
}
body, rcode, err := netReqTyped(req, isJson)
if err != nil {
log.Errorf("Could not complete GET %s, error: %s", reqURL, err.Error())
return nil, rcode, err
}
return body, rcode, nil
}
func deleteReq(reqURL string) (int, error) {
req, err := http.NewRequest("DELETE", reqURL, nil)
if err != nil {
log.Errorf("Could not create DELETE %s, error: %s", reqURL, err.Error())
return -1, err
}
_, rcode, err := netReq(req)
if err != nil {
log.Errorf("Could not complete DELETE %s, error: %s", reqURL, err.Error())
return rcode, err
}
return rcode, nil
}
func netReqTyped(req *http.Request, isJson bool) ([]byte, int, error) {
if isJson {
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
} else {
req.Header.Set("Content-Type", "application/xml")
req.Header.Set("Accept", "application/xml")
}
return netReq(req)
}
func netReq(req *http.Request) ([]byte, int, error) {
var resp *http.Response
var err error
for i := 0; i < 3; i++ {
resp, err = HttpClient.Do(req)
if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
// it's a transient network error so we sleep for a bit and try
// again in case it's a short-lived issue
log.Warningf("Retrying after temporary network failure, error: %s",
nerr.Error())
time.Sleep(10)
} else {
break
}
}
if err != nil {
return nil, -1, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Errorf("Failure reading request body, error: %s", err.Error())
return nil, -1, err
}
// At this point we're done and shit worked, simply return the bytes
log.Infof("Got eureka response from url=%v", req.URL)
return body, resp.StatusCode, nil
}