Clean de-duplicates and removes empty entries from the policy.
()
| 54 | |
| 55 | // Clean de-duplicates and removes empty entries from the policy. |
| 56 | func (csp ContentSecurityPolicy) Clean() ContentSecurityPolicy { |
| 57 | cleanDirective := func(contents []string) []string { |
| 58 | added := map[string]struct{}{} |
| 59 | cleanContents := []string{} |
| 60 | for _, entry := range contents { |
| 61 | if entry == "" || strings.HasPrefix(entry, "/") { |
| 62 | continue // Skip empty and relative locations. |
| 63 | } |
| 64 | if strings.HasPrefix(entry, "http://") || strings.HasPrefix(entry, "https://") { |
| 65 | if parsed, err := url.Parse(entry); err == nil { |
| 66 | entry = parsed.Host |
| 67 | } |
| 68 | } |
| 69 | if strings.HasPrefix(entry, "ws://") || strings.HasPrefix(entry, "wss://") { |
| 70 | if parsed, err := url.Parse(entry); err == nil { |
| 71 | parsed.Path, parsed.RawPath = "", "" |
| 72 | entry = parsed.String() |
| 73 | } |
| 74 | } |
| 75 | if _, ok := added[entry]; ok { |
| 76 | continue // Skip already added locations. |
| 77 | } |
| 78 | added[entry] = struct{}{} |
| 79 | cleanContents = append(cleanContents, entry) |
| 80 | } |
| 81 | return cleanContents |
| 82 | } |
| 83 | derived := csp |
| 84 | derived.ConnectionSource = cleanDirective(csp.ConnectionSource) |
| 85 | derived.StyleSource = cleanDirective(csp.StyleSource) |
| 86 | derived.ScriptSource = cleanDirective(csp.ScriptSource) |
| 87 | derived.BaseURI = cleanDirective(csp.BaseURI) |
| 88 | derived.FrameAncestors = cleanDirective(csp.FrameAncestors) |
| 89 | return derived |
| 90 | } |
| 91 | |
| 92 | // Merge merges the provided policies into the existing one. |
| 93 | func (csp ContentSecurityPolicy) Merge(others ...ContentSecurityPolicy) ContentSecurityPolicy { |
no test coverage detected