| skipped 1 lines |
2 | 2 | | |
3 | 3 | | import ( |
4 | 4 | | "crypto/tls" |
| 5 | + | "io" |
5 | 6 | | "net" |
6 | 7 | | "net/http" |
7 | 8 | | "regexp" |
8 | 9 | | "strings" |
9 | 10 | | "time" |
| 11 | + | |
| 12 | + | "golang.org/x/net/html" |
10 | 13 | | ) |
11 | 14 | | |
12 | 15 | | const ( |
| skipped 16 lines |
29 | 32 | | |
30 | 33 | | defer resp.Body.Close() |
31 | 34 | | |
32 | | - | headerCSP = parseCSPHeader(resp.Header.Get("Content-Security-Policy"), r) |
33 | | - | if len(headerCSP) != 0 { |
34 | | - | bodyCSP = parseCSPBody("") |
| 35 | + | headerCSP = parseCSP(resp.Header.Get("Content-Security-Policy"), r) |
| 36 | + | if len(headerCSP) == 0 { |
| 37 | + | bodyCSP, err = parseCSPBody(resp.Body, r) |
| 38 | + | if err != nil { |
| 39 | + | return result, nil |
| 40 | + | } |
35 | 41 | | } |
36 | 42 | | |
37 | 43 | | result = append(result, headerCSP...) |
| skipped 2 lines |
40 | 46 | | return result, nil |
41 | 47 | | } |
42 | 48 | | |
43 | | - | func parseCSPHeader(input string, r *regexp.Regexp) []string { |
| 49 | + | func parseCSP(input string, r *regexp.Regexp) []string { |
44 | 50 | | result := []string{} |
45 | 51 | | |
46 | 52 | | splitted := strings.Split(input, ";") |
| skipped 10 lines |
57 | 63 | | return result |
58 | 64 | | } |
59 | 65 | | |
60 | | - | func parseCSPBody(input string) []string { |
| 66 | + | func parseCSPBody(input io.ReadCloser, r *regexp.Regexp) ([]string, error) { |
61 | 67 | | result := []string{} |
62 | 68 | | |
63 | | - | return result |
| 69 | + | doc, err := html.Parse(input) |
| 70 | + | if err != nil { |
| 71 | + | return result, err |
| 72 | + | } |
| 73 | + | |
| 74 | + | bodyString, err := io.ReadAll(input) |
| 75 | + | if err != nil { |
| 76 | + | return result, err |
| 77 | + | } |
| 78 | + | |
| 79 | + | if strings.Contains(string(bodyString), `http-equiv="Content-Security-Policy"`) { |
| 80 | + | // Recursively visit nodes in the parse tree |
| 81 | + | var f func(*html.Node) |
| 82 | + | f = func(n *html.Node) { |
| 83 | + | if n.Data == "meta" { |
| 84 | + | for _, a := range n.Attr { |
| 85 | + | if a.Key == "content" { |
| 86 | + | result = parseCSP(a.Val, r) |
| 87 | + | break |
| 88 | + | } |
| 89 | + | } |
| 90 | + | } |
| 91 | + | |
| 92 | + | for c := n.FirstChild; c != nil; c = c.NextSibling { |
| 93 | + | f(c) |
| 94 | + | } |
| 95 | + | } |
| 96 | + | f(doc) |
| 97 | + | } |
| 98 | + | |
| 99 | + | return result, nil |
64 | 100 | | } |
65 | 101 | | |
66 | 102 | | func customClient(timeout int) *http.Client { |
| skipped 27 lines |