-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
103 lines (79 loc) · 2.12 KB
/
main.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
package main
import (
// "errors"
"fmt"
"net/http"
"net/url"
"os"
"github.com/golang-collections/collections/stack"
"github.com/jcelliott/lumber"
"gopkg.in/urfave/cli.v1" // imports as package "cli"
)
var redirectsStack *stack.Stack = stack.New()
type parsedResponse struct {
code int
request string
response string
content string
redirects *stack.Stack
}
func main() {
lumber.Debug("initialized")
app := cli.NewApp()
app.Name = "will_it_redirect"
app.Usage = "test web redirects"
app.Version = "0.1.0"
app.EnableBashCompletion = true
app.Action = func(c *cli.Context) error {
arg := c.Args().Get(0)
resp, err := doAction(arg)
if err != nil {
lumber.Fatal(err.Error())
os.Exit(1)
} else {
err = printResp(resp)
}
return err
}
err := app.Run(os.Args)
if err != nil {
lumber.Fatal(err.Error())
os.Exit(1)
}
}
func doAction(arg string) (parsedResponse, error) {
lumber.Debug("arg: %s\n", arg)
// try to parse the arg as a url
parsedUrl, err := url.Parse(arg)
// if it parses, get it
parsed, err := getUrl(parsedUrl)
return parsed, err
}
func getUrl(u *url.URL) (parsedResponse, error) {
urlString := u.String()
lumber.Info("site: %s\n", urlString)
client := &http.Client{
CheckRedirect: checkRedirect(),
}
req, err := http.NewRequest("GET", urlString, nil)
resp, err := client.Do(req)
code := resp.StatusCode
request := resp.Request.URL.String()
response := resp.Header.Get("location")
content := ""
redirects := redirectsStack
defer resp.Body.Close()
return parsedResponse{code: code, request: request, response:response, content: content, redirects: redirects}, err
}
type checkRedirectFunction func(*http.Request, []*http.Request) error
func checkRedirect() checkRedirectFunction {
return func(req *http.Request, via []*http.Request) error {
lumber.Info("redirect: %s\n", req.URL.String())
redirectsStack.Push(req.URL)
return nil
}
}
func printResp(resp parsedResponse) error {
fmt.Printf("%d\t%s\t%s\t%d\n", resp.code, resp.request, resp.response, resp.redirects.Len())
return nil
}