1package mask
2
3import (
4	"bytes"
5	"net/url"
6)
7
8// URL will mask the sensitive components in an URL with `[FILTERED]`.
9// This list should maintain parity with the list in
10// GitLab-CE, maintained at https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/application.rb.
11// Based on https://stackoverflow.com/a/52965552/474597.
12func URL(originalURL string) string {
13	u, err := url.Parse(originalURL)
14	if err != nil {
15		return "<invalid URL>"
16	}
17
18	redactionBytes := []byte(RedactionString)
19	buf := bytes.NewBuffer(make([]byte, 0, len(originalURL)))
20
21	for i, queryPart := range bytes.Split([]byte(u.RawQuery), []byte("&")) {
22		if i != 0 {
23			buf.WriteByte('&')
24		}
25
26		splitParam := bytes.SplitN(queryPart, []byte("="), 2)
27
28		if len(splitParam) == 2 {
29			buf.Write(splitParam[0])
30			buf.WriteByte('=')
31
32			if parameterMatcher.Match(splitParam[0]) {
33				buf.Write(redactionBytes)
34			} else {
35				buf.Write(splitParam[1])
36			}
37		} else {
38			buf.Write(queryPart)
39		}
40	}
41	u.RawQuery = buf.String()
42	return u.String()
43}
44