/
transport.go
84 lines (73 loc) · 2.64 KB
/
transport.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
/*
Copyright 2019 The Pennsylvania State University
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package aleks
import (
"io/ioutil"
"net"
"net/http"
"strings"
"time"
)
// aleksTransport is equivalent to the http.DefaultTransport with
// compression disabled. See https://golang.org/pkg/net/http/#RoundTripper.
func transport() *http.Transport {
return &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
DisableCompression: true,
}
}
// RoundTripper intercepts HTTP calls and alters the request as described
// by the #RoundTrip method.
type RoundTripper struct {
Trans http.RoundTripper
}
// RoundTrip implements https://golang.org/pkg/net/http/#RoundTripper.
// The XML-RPC specification requires the User-Agent and Host headers
// which the kolo/xmlrpc library doesn't honor. Aleks doesn't appear
// to care if they're missing but we're adding them here for completeness.
// More importantly, this intercepter replaces the default transport
// with one that has compression disabled. On the response side, the
// XML-RPC library doesn't deal with string values wrapped in CDATA
// tags so this RoundTripper also strips those tags from the result.
func (rt *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
// Set the headers required by the specification
req.Header["Accept"] = []string{"*/*"}
req.Header["User-Agent"] = []string{"aleks-client"}
host := req.URL.Hostname()
req.Header["Host"] = []string{host}
// Make the call using the customized transport
resp, err := rt.Trans.RoundTrip(req)
if err != nil {
return resp, err
}
// Strip CDATA tags
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return resp, err
}
bodyStr := string(body)
bodyStr = strings.ReplaceAll(bodyStr, "<![CDATA[", "")
bodyStr = strings.ReplaceAll(bodyStr, "]]>", "")
resp.Body = ioutil.NopCloser(strings.NewReader(bodyStr))
return resp, err
}