A Swift wrapper for [`libpsl`](https://github.com/rockdaboot/libpsl) to work with internet domains in the context of the [Public Suffix List](https://publicsuffix.org/).
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
4.9 KiB
159 lines
4.9 KiB
import psl
|
|
|
|
enum SwiftPSLError : Error {
|
|
case FileNotFound
|
|
case Invalidarg
|
|
case Converter
|
|
case ToUTF16
|
|
case ToLower
|
|
case ToUTF8
|
|
case NoMem
|
|
}
|
|
|
|
public final class SwiftPSL {
|
|
|
|
public let pslVersion = PSL_VERSION
|
|
public let pslVersionMajor = PSL_VERSION_MAJOR
|
|
public let pslVersionMinor = PSL_VERSION_MINOR
|
|
public let pslVersionPatch = PSL_VERSION_PATCH
|
|
|
|
public struct pslType {
|
|
static let ICANN : Int32 = PSL_TYPE_ICANN
|
|
static let NoStarRule : Int32 = PSL_TYPE_NO_STAR_RULE
|
|
static let ANY : Int32 = PSL_TYPE_ANY
|
|
static let Private : Int32 = PSL_TYPE_PRIVATE
|
|
}
|
|
|
|
private var ctx : OpaquePointer? = psl_builtin()
|
|
private var isBuiltin = true
|
|
|
|
// psl_error_t value. PSL_SUCCESS: Success PSL_ERR_INVALID_ARG: str is a NULL value. PSL_ERR_CONVERTER: Failed to open the unicode converter with name encoding PSL_ERR_TO_UTF16: Failed to convert str to unicode PSL_ERR_TO_LOWER: Failed to convert unicode to lowercase PSL_ERR_TO_UTF8: Failed to convert unicode to UTF-8 PSL_ERR_NO_MEM: Failed to allocate memory
|
|
|
|
public func strToUTF8Lower(_ str : String, encoding : String = "utf-8", locale : String = "en") throws -> String? {
|
|
|
|
var lower : UnsafeMutablePointer<Int8>?
|
|
|
|
let ret = psl_str_to_utf8lower(str, encoding, locale, &lower)
|
|
|
|
var dom : String? = nil
|
|
|
|
switch ret {
|
|
case PSL_ERR_INVALID_ARG: throw SwiftPSLError.Invalidarg
|
|
case PSL_ERR_CONVERTER: throw SwiftPSLError.Converter
|
|
case PSL_ERR_TO_UTF16: throw SwiftPSLError.ToUTF16
|
|
case PSL_ERR_TO_LOWER: throw SwiftPSLError.ToLower
|
|
case PSL_ERR_TO_UTF8: throw SwiftPSLError.ToUTF8
|
|
case PSL_ERR_NO_MEM: throw SwiftPSLError.NoMem
|
|
default: dom = String(cString: lower!)
|
|
}
|
|
|
|
psl_free_string(lower)
|
|
|
|
return(dom)
|
|
|
|
}
|
|
|
|
public func publicSuffix(_ domain : String, encoding : String = "utf-8", locale : String = "en") -> String? {
|
|
let psl : OpaquePointer? = ctx
|
|
var lower : UnsafeMutablePointer<Int8>?
|
|
let dom : String? = (psl_str_to_utf8lower(domain, encoding, locale, &lower) == PSL_SUCCESS) ? String(cString: psl_unregistrable_domain(psl, lower)) : nil
|
|
psl_free_string(lower)
|
|
return(dom)
|
|
|
|
}
|
|
|
|
public func apexDomain(_ domain : String, encoding : String = "utf-8", locale : String = "en") -> String? {
|
|
let psl : OpaquePointer? = ctx
|
|
var lower : UnsafeMutablePointer<Int8>?
|
|
let dom : String? = (psl_str_to_utf8lower(domain, encoding, locale, &lower) == PSL_SUCCESS) ? String(cString: psl_registrable_domain(psl, lower)) : nil
|
|
psl_free_string(lower)
|
|
return(dom)
|
|
}
|
|
|
|
public func isPublicSuffix(_ domain : String, encoding : String = "utf-8", locale : String = "en") -> Bool {
|
|
let psl : OpaquePointer? = ctx
|
|
var lower : UnsafeMutablePointer<Int8>?
|
|
let res : Bool = (psl_str_to_utf8lower(domain, encoding, locale, &lower) == PSL_SUCCESS) && (psl_is_public_suffix(psl, lower) == 1)
|
|
psl_free_string(lower)
|
|
return(res)
|
|
}
|
|
|
|
public func isPublicSuffix(_ domain : String, type : Int32, encoding : String = "utf-8", locale : String = "en") -> Bool {
|
|
let psl : OpaquePointer? = ctx
|
|
var lower : UnsafeMutablePointer<Int8>?
|
|
let res : Bool = (psl_str_to_utf8lower(domain, encoding, locale, &lower) == PSL_SUCCESS) && (psl_is_public_suffix2(psl, lower, type) == 1)
|
|
psl_free_string(lower)
|
|
return(res)
|
|
}
|
|
|
|
public func isCookieDomainAcceptable(_ hostname : String, cookieDomain : String) -> Bool {
|
|
|
|
let psl : OpaquePointer? = ctx
|
|
var lower1 : UnsafeMutablePointer<Int8>?
|
|
var lower2 : UnsafeMutablePointer<Int8>?
|
|
|
|
let rc1 = psl_str_to_utf8lower(hostname, "utf-8", "en", &lower1)
|
|
let rc2 = psl_str_to_utf8lower(cookieDomain, "utf-8", "en", &lower2)
|
|
|
|
let res : Bool = (rc1 == PSL_SUCCESS) && (rc2 == PSL_SUCCESS) && (psl_is_cookie_domain_acceptable(psl, lower1, lower2) == 1)
|
|
|
|
psl_free_string(lower1)
|
|
psl_free_string(lower2)
|
|
|
|
return(res)
|
|
|
|
}
|
|
|
|
public init() {}
|
|
|
|
public init(_ path: String) throws {
|
|
ctx = psl_load_file(path)
|
|
if (ctx == nil) { throw SwiftPSLError.FileNotFound }
|
|
isBuiltin = false
|
|
}
|
|
|
|
public func free() {
|
|
if ((!isBuiltin) && (ctx != nil)) {
|
|
psl_free(ctx)
|
|
ctx = nil
|
|
}
|
|
}
|
|
|
|
public func suffixCount() -> Int32 {
|
|
return(psl_suffix_count(ctx))
|
|
}
|
|
|
|
public func suffixWildcardCount() -> Int32 {
|
|
return(psl_suffix_wildcard_count(ctx))
|
|
}
|
|
|
|
public func suffixExceptionCount() -> Int32 {
|
|
return(psl_suffix_exception_count(ctx))
|
|
}
|
|
|
|
public func builtinDistFilename() -> String {
|
|
return(String(cString: psl_dist_filename()))
|
|
}
|
|
|
|
public func builtinFilename() -> String {
|
|
return(String(cString: psl_builtin_filename()))
|
|
}
|
|
|
|
public func builtinSHA1() -> String {
|
|
return(String(cString: psl_builtin_sha1sum()))
|
|
}
|
|
|
|
public func isBuiltinOutdated() -> Bool {
|
|
return(psl_builtin_outdated() == 1)
|
|
}
|
|
|
|
public func builtinTimestamp() -> Int {
|
|
let ft = psl_builtin_file_time()
|
|
return(ft)
|
|
}
|
|
|
|
deinit {
|
|
free()
|
|
}
|
|
|
|
}
|
|
|