Files
w4rpservices/vendor/snowplow/referer-parser/go/refererparser.go
T
2019-12-26 05:03:41 +00:00

110 lines
2.5 KiB
Go
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
Package refererparser implements referer extraction using a shared 'database' of known referers found in referers.yml [1].
Links
[1] https://github.com/snowplow/referer-parser/blob/master/referers.yml
*/
package refererparser
import (
"encoding/json"
"net/url"
"strings"
)
type refererData map[string]map[string]map[string][]string
var data refererData
func init() {
data = loadRefererData()
}
// loadRefererData loads and parses the YAML file.
func loadRefererData() refererData {
dat, err := Asset("data/referers.json")
if err != nil {
panic(err)
}
res := make(refererData)
if err := json.Unmarshal(dat, &res); err != nil {
panic(err)
}
return res
}
// RefererResult holds the extracted data
type RefererResult struct {
Known bool
Referer string
Medium string
SearchParameter string
SearchTerm string
URI *url.URL
}
// SetCurrent is used to set the "internal" medium if needed.
func (ref *RefererResult) SetCurrent(curl string) {
purl, _ := url.Parse(curl)
if purl.Host == ref.URI.Host {
ref.Medium = "internal"
}
}
func lookup(uri *url.URL, q string, suffix bool) (refResult *RefererResult) {
refResult = &RefererResult{URI: uri, Medium: "unknown"}
for medium, mediumData := range data {
for refName, refconfig := range mediumData {
for _, domain := range refconfig["domains"] {
if (!suffix && q == domain) || (suffix && (strings.HasSuffix(q, domain) || strings.HasPrefix(q, domain))) {
refResult.Known = true
refResult.Referer = refName
refResult.Medium = medium
params, paramExists := refconfig["parameters"]
if paramExists {
for _, param := range params {
sterm := uri.Query().Get(param)
if sterm != "" {
refResult.SearchParameter = param
refResult.SearchTerm = sterm
}
}
}
return refResult
}
}
}
}
return
}
// Parse an url and extract referer, it returns a RefererResult.
func Parse(uri string) (refResult *RefererResult) {
puri, _ := url.Parse(uri)
// Split before the first dot ".".
parts := strings.SplitAfterN(puri.Host, ".", 2)
rhost := ""
if len(parts) > 1 {
rhost = parts[1]
}
queries := []string{puri.Host + puri.Path, rhost + puri.Path, puri.Host, rhost}
for _, q := range queries {
refResult = lookup(puri, q, false)
if refResult.Known {
return
}
}
if !refResult.Known {
for _, q := range queries {
refResult = lookup(puri, q, true)
if refResult.Known {
return
}
}
}
return
}