-
Notifications
You must be signed in to change notification settings - Fork 0
/
http.go
159 lines (115 loc) · 3.09 KB
/
http.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package hkn
import (
"io/ioutil"
"net/http"
"net/url"
"regexp"
"strings"
"time"
)
// Create a new HTTP client with sensible options
func newHTTPClient() *http.Client {
return &http.Client{
// A 10 second timeout
Timeout: time.Second * 10,
// Don't follow 301 redirects
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}
// Perform a GET request and return the response
func get(resource string, cookie *http.Cookie) (*http.Response, error) {
// Build the request
req, err := http.NewRequest("GET", resource, nil)
req.Close = true
if cookie != nil {
req.AddCookie(cookie)
}
if err != nil {
return nil, ErrFetching
}
client := newHTTPClient()
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return resp, nil
}
// Get the content from a http response and close the response
func getContent(resp *http.Response) ([]byte, error) {
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
// Perform a GET request and return the body as a slice of bytes
func getBody(resource string) ([]byte, error) {
resp, err := get(resource, nil)
if err != nil {
return nil, err
}
return getContent(resp)
}
// Perform a GET request with a cookie and return the body as a slice of bytes
func getBodyWithCookie(resource string, cookie *http.Cookie) ([]byte, error) {
resp, err := get(resource, cookie)
if err != nil {
return nil, err
}
return getContent(resp)
}
// Perform a POST request and return the response
func post(resource string, urlEncodedValues url.Values, cookie *http.Cookie) (*http.Response, error) {
req, err := http.NewRequest("POST", resource, strings.NewReader(urlEncodedValues.Encode()))
if err != nil {
return nil, err
}
req.Close = true
if cookie != nil {
req.AddCookie(cookie)
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Access-Control-Allow-Origin", "*")
client := newHTTPClient()
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return resp, nil
}
// Perform a POST request with a cookie
func postWithCookie(resource string, urlEncodedValues url.Values, cookie *http.Cookie) ([]byte, error) {
resp, err := post(resource, urlEncodedValues, cookie)
if err != nil {
return nil, err
}
return getContent(resp)
}
// Perform a POST request and return the first cookie in the response
func postAndGetCookie(resource string, urlEncodedValues url.Values) (*http.Cookie, error) {
resp, err := post(resource, urlEncodedValues, nil)
if err != nil {
return &http.Cookie{}, err
}
defer resp.Body.Close()
cookies := resp.Cookies()
if len(cookies) == 0 {
return &http.Cookie{}, ErrInvalidAuth
}
return cookies[0], nil
}
func matchRegexFromBody(webURL string, regex string, cookie *http.Cookie) (string, error) {
resp, err := getBodyWithCookie(webURL, cookie)
if err != nil {
return "", err
}
r := regexp.MustCompile(regex)
result := r.FindStringSubmatch(string(resp))
if len(result) == 2 {
return result[1], nil
}
return "", ErrFetchingActionURL
}