{"id":14866855,"url":"https://github.com/weppos/publicsuffix-go","last_synced_at":"2025-05-14T15:06:59.510Z","repository":{"id":39863675,"uuid":"53618789","full_name":"weppos/publicsuffix-go","owner":"weppos","description":"Domain name parser for Go based on the Public Suffix List.","archived":false,"fork":false,"pushed_at":"2025-05-08T09:14:30.000Z","size":1657,"stargazers_count":199,"open_issues_count":2,"forks_count":36,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-08T10:26:53.742Z","etag":null,"topics":["go","golang","psl","publicsuffix"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/weppos.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["weppos"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2016-03-10T21:36:33.000Z","updated_at":"2025-05-08T09:14:33.000Z","dependencies_parsed_at":"2023-10-27T07:32:44.423Z","dependency_job_id":"5f2011eb-46d9-4216-aa52-538e368c196b","html_url":"https://github.com/weppos/publicsuffix-go","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weppos%2Fpublicsuffix-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weppos%2Fpublicsuffix-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weppos%2Fpublicsuffix-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weppos%2Fpublicsuffix-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/weppos","download_url":"https://codeload.github.com/weppos/publicsuffix-go/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254169335,"owners_count":22026211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","psl","publicsuffix"],"created_at":"2024-09-20T04:00:38.883Z","updated_at":"2025-05-14T15:06:59.478Z","avatar_url":"https://github.com/weppos.png","language":"Go","funding_links":["https://github.com/sponsors/weppos"],"categories":["Go"],"sub_categories":[],"readme":"# Public Suffix \u003csmall\u003efor Go\u003c/small\u003e\n\nThe package \u003ctt\u003epublicsuffix\u003c/tt\u003e provides a Go domain name parser based on the [Public Suffix List](http://publicsuffix.org/).\n\n[![Tests](https://github.com/weppos/publicsuffix-go/workflows/Tests/badge.svg)](https://github.com/weppos/publicsuffix-go/actions?query=workflow%3ATests)\n[![GoDoc](https://godoc.org/github.com/weppos/publicsuffix-go/publicsuffix?status.svg)](https://pkg.go.dev/github.com/weppos/publicsuffix-go/publicsuffix)\n\nCurrently, **publicsuffix-go requires Go version 1.21 or greater**. We do our best not to break older versions of Go if we don't have to, but due to tooling constraints, we don't always test older versions.\n\n\n## Getting started\n\nClone the repository [in your workspace](https://golang.org/doc/code.html#Organization) and move into it:\n\n```shell\nmkdir -p $GOPATH/src/github.com/weppos \u0026\u0026 cd $_\ngit clone git@github.com:weppos/publicsuffix-go.git\ncd publicsuffix-go\n```\n\nFetch the dependencies:\n\n```shell\ngo get ./...\n```\n\nRun the test suite.\n\n```shell\ngo test ./...\n```\n\n\n## Testing\n\nThe following command runs the entire test suite.\n\n```shell\ngo test ./...\n```\n\nThere are 3 different test suites built into this library:\n\n- Acceptance: the acceptance test suite contains some high level tests to ensure the library behaves as expected\n- PSL: the PSL test suite runs the library against the [official Public Suffix test cases](https://github.com/publicsuffix/list/blob/master/tests/tests.txt)\n- Unit: the unit test suite stresses the various single components of this package\n\n\n## Installation\n\n```shell\ngo get github.com/weppos/publicsuffix-go\n```\n\n\n## Usage\n\nThis is a simple example that demonstrates how to use the package with the default options and the default Public Suffix list packaged with the library.\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n\n    \"github.com/weppos/publicsuffix-go/publicsuffix\"\n)\n\nfunc main() {\n    // Extract the domain from a string\n    // using the default list\n    fmt.Println(publicsuffix.Domain(\"example.com\"))             // example.com\n    fmt.Println(publicsuffix.Domain(\"www.example.com\"))         // example.com\n    fmt.Println(publicsuffix.Domain(\"example.co.uk\"))           // example.co.uk\n    fmt.Println(publicsuffix.Domain(\"www.example.co.uk\"))       // example.co.uk\n\n    // Parse the domain from a string\n    // using the default list\n    fmt.Println(publicsuffix.Parse(\"example.com\"))             // \u0026DomainName{\"com\", \"example\", \"\"}\n    fmt.Println(publicsuffix.Parse(\"www.example.com\"))         // \u0026DomainName{\"com\", \"example\", \"www\"}\n    fmt.Println(publicsuffix.Parse(\"example.co.uk\"))           // \u0026DomainName{\"co.uk\", \"example\", \"\"}\n    fmt.Println(publicsuffix.Parse(\"www.example.co.uk\"))       // \u0026DomainName{\"co.uk\", \"example\", \"www\"}\n}\n```\n\n#### Ignoring Private Domains\n\nThe PSL is composed by two list of suffixes: IANA suffixes, and Private Domains.\n\nPrivate domains are submitted by private organizations. By default, private domains are not ignored.\nSometimes, you want to ignore these domains and only query against the IANA suffixes. You have two options:\n\n1. Ignore the domains at runtime\n2. Create a custom list without the private domains\n\nIn the first case, the private domains are ignored at runtime: they will still be included in the lists but the lookup will skip them when found.\n\n```go\npublicsuffix.DomainFromListWithOptions(publicsuffix.DefaultList(), \"google.blogspot.com\", nil)\n// google.blogspot.com\n\npublicsuffix.DomainFromListWithOptions(publicsuffix.DefaultList(), \"google.blogspot.com\", \u0026publicsuffix.FindOptions{IgnorePrivate: true})\n// blogspot.com\n\n// Note that the DefaultFindOptions includes the private domains by default\npublicsuffix.DomainFromListWithOptions(publicsuffix.DefaultList(), \"google.blogspot.com\", publicsuffix.DefaultFindOptions)\n// google.blogspot.com\n```\n\nThis solution is easy, but slower. If you find yourself ignoring the private domains in all cases (or in most cases), you may want to create a custom list without the private domains.\n\n```go\nlist := NewListFromFile(\"path/to/list.txt\", \u0026publicsuffix.ParserOption{PrivateDomains: false})\npublicsuffix.DomainFromListWithOptions(list, \"google.blogspot.com\", nil)\n// blogspot.com\n```\n\n## IDN domains, A-labels and U-labels\n\n[A-label and U-label](https://tools.ietf.org/html/rfc5890#section-2.3.2.1) are two different ways to represent IDN domain names. These two encodings are also known as ASCII (A-label) or Pynucode vs Unicode (U-label). Conversions between U-labels and A-labels are performed according to the [\"Punycode\" specification](https://tools.ietf.org/html/rfc3492), adding or removing the ACE prefix as needed.\n\nIDNA-aware applications generally use the A-label form for storing and manipulating data, whereas the U-labels can appear in presentation and user interface forms.\n\nAlthough the PSL list has been traditionally U-label encoded, this library follows the common industry standards and stores the rules in their A-label form. Therefore, unless explicitly mentioned, any method call, comparison or internal representation is expected to be ASCII-compatible encoded (ACE).\n\nPassing Unicode names to the library may either result in error or unexpected behaviors.\n\nIf you are interested in the details of this decision, you can read the full discussion [here](https://github.com/weppos/publicsuffix-go/issues/31).\n\n\n## Differences with `golang.org/x/net/publicsuffix`\n\nThe [`golang.org/x/net/publicsuffix`](https://godoc.org/golang.org/x/net/publicsuffix) is a package part of the Golang `x/net` package, that provides a public suffix list implementation.\n\nThe main difference is that the `x/net` package is optimized for speed, but it's less flexible. The list is compiled and embedded into the package itself. However, this is also the main downside.\nThe [list is not frequently refreshed](https://github.com/letsencrypt/boulder/issues/1374#issuecomment-182429297), hence the results may be inaccurate, in particular if you heavily rely on the private domain section of the list. Changes in the IANA section are less frequent, whereas changes in the Private Domains section happens weekly.\n\nThis package provides the following extra features:\n\n- Ability to load an arbitrary list at runtime (e.g. you can feed your own list, or create multiple lists)\n- Ability to create multiple lists\n- Ability to parse a domain using a previously defined list\n- Ability to add custom rules to an existing list, or merge/load rules from other lists (provided as file or string)\n- Advanced access to the list rules\n- Ability to ignore private domains at runtime, or when the list is parsed\n\nThis package also aims for 100% compatibility with the `x/net` package. A special adapter is provided as a drop-in replacement. Simply change the include statement from\n\n```go\nimport (\n    \"golang.org/x/net/publicsuffix\"\n)\n```\n\nto\n\n```go\nimport (\n    \"github.com/weppos/publicsuffix-go/net/publicsuffix\"\n)\n```\n\nThe `github.com/weppos/publicsuffix-go/net/publicsuffix` package defines the same methods defined in `golang.org/x/net/publicsuffix`, but these methods are implemented using the `github.com/weppos/publicsuffix-go/publicsuffix` package.\n\nNote that the adapter doesn't offer the flexibility of `github.com/weppos/publicsuffix-go/publicsuffix`, such as the ability to use multiple lists or disable private domains at runtime.\n\n\n## `cookiejar.PublicSuffixList` interface\n\nThis package implements the [`cookiejar.PublicSuffixList` interface](https://godoc.org/net/http/cookiejar#PublicSuffixList). It means it can be used as a value for the `PublicSuffixList` option when creating a `net/http/cookiejar`.\n\n```go\nimport (\n    \"net/http/cookiejar\"\n    \"github.com/weppos/publicsuffix-go/publicsuffix\"\n)\n\ndeliciousJar := cookiejar.New(\u0026cookiejar.Options{PublicSuffixList: publicsuffix.CookieJarList})\n```\n\n\n## License\n\nCopyright (c) 2016-2024 Simone Carletti. This is Free Software distributed under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweppos%2Fpublicsuffix-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fweppos%2Fpublicsuffix-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweppos%2Fpublicsuffix-go/lists"}