-
Notifications
You must be signed in to change notification settings - Fork 0
/
http_client.go
115 lines (94 loc) · 2.55 KB
/
http_client.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
package main
import (
"http"
"os"
"log"
"fmt"
)
type HttpClient struct {
client http.Client
}
// Forward a request to another domain
// By design Go doesn't let you define new methods on non-local types
func (this *HttpClient) Forward(req *http.Request, newDomain string) (resp *http.Response, err os.Error){
log.Printf("req host: %v\n", req.Host)
// TODO change the the domain back
for _, cookie := range req.Cookie {
log.Printf("req cookie: %v\n", cookie)
}
var base *http.URL
/*var r *http.Response*/
url := (newDomain + req.URL.RawPath)
log.Printf("forwarding to: " + url)
redirectChecker := this.client.CheckRedirect
if redirectChecker == nil {
redirectChecker = defaultCheckRedirect
}
var via []*http.Request
for redirect := 0; ; redirect++ {
var nReq = http.Request{}
nReq.Method = req.Method
//log.Printf("HTTP method: " + nReq.Method)
nReq.Header = req.Header
//log.Printf("Headers: %v\n", nReq.Header)
if base == nil {
nReq.URL, err = http.ParseURL(url)
} else {
nReq.URL, err = base.ParseURL(url)
}
if err != nil {
break
}
// Set the redirection referer headers
if len(via) > 0 {
// Add the Referer header.
lastReq := via[len(via)-1]
if lastReq.URL.Scheme != "https" {
nReq.Referer = lastReq.URL.String()
}
err = redirectChecker(&nReq, via)
if err != nil {
break
}
}
// TODO support for content in the body if we aren't
// dealing with GET/HEAD requests.
url = nReq.URL.String()
// Wrapped the client so I could do that ...sigh...
// Also, #Do i a wrapper around #send
if resp, err = this.client.Do(&nReq); err != nil {
break
}
if shouldRedirect(resp.StatusCode) {
resp.Body.Close()
if url = resp.Header.Get("Location"); url == "" {
err = os.ErrorString(fmt.Sprintf("%d response missing Location header", resp.StatusCode))
break
}
base = req.URL
via = append(via, &nReq)
continue
}
// log.Printf("final URL: " + url)
return
}
err = &http.URLError{req.Method, url, err}
return
}
// copied over from the http package
func defaultCheckRedirect(req *http.Request, via []*http.Request) os.Error {
if len(via) >= 10 {
return os.ErrorString("stopped after 10 redirects")
}
return nil
}
// copied over from the http package
// True if the specified HTTP status code is one for which the Get utility should
// automatically redirect.
func shouldRedirect(statusCode int) bool {
switch statusCode {
case http.StatusMovedPermanently, http.StatusFound, http.StatusSeeOther, http.StatusTemporaryRedirect:
return true
}
return false
}