gpt4 book ai didi

swift - 什么样的 URL 不符合 RFC 3986 但符合 RFC 1808、RFC 1738 和 RFC 2732?

转载 作者:可可西里 更新时间:2023-11-01 01:07:23 32 4
gpt4 key购买 nike

URLComponents.init(url:resolvingAgainstBaseURL:) 的文档说:

Returns the initialized URL components object, or nil if the URL could not be parsed.

知道:

我假设当 URL 符合 RFC 1808/1738/2732 但不符合 RFC 3986 时,URLComponents 的初始化将失败。那是什么类型的 URL?有什么例子吗?

到目前为止,我唯一的提示可能与不同的保留字符有关?

最佳答案

因为 Swift Foundation 是开源的,让我们从它的源代码来探索它。

  1. URLComponents 初始化器在 apple/swift – URLComponents.swift 中实现和 apple/swift-corelibs-foundation – URLComponents.swift并简单地调用 NSURLComponents 的初始化程序。

  2. NSURLComponents 初始化器在 apple/swift-corelibs-foundation – NSURL.swift 中实现并简单地调用 _CFURLComponentsCreateWithURL

  3. _CFURLComponentsCreateWithURLapple/swift-corelibs-foundation – CFURLComponents.c 中实现并且:

    • 带有 CFURLCopyAbsoluteURL 的失败副本
    • 使用 _CFURLComponentsCreateWithString 的失败创建调用:
      • _CFURIParserParseURIReference + 一个可失败的_CFURIParserURLStringIsValid
  4. CFURLCopyAbsoluteURLapple/swift-corelibs-foundation – CFURL.c 中实现并且仅在以下情况下失败:

    #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
    if ( base && CFURLIsFileReferenceURL(base) && !CFURLHasDirectoryPath(base) ) {
    // 16695827 - If the base URL is a file reference URL which doesn't end with a slash, we have to convert it to a file path URL before we can make it absolute.
    base = CFURLCreateFilePathURL(alloc, base, NULL);
    if ( !base ) {
    // could not convert file reference URL to file path URL -- fail will NULL
    return NULL;
    }
    }
    #endif

    CFURLCreateFilePathURL 的实现在 opensource.apple.com/source/CF – CFURL.c 中,我的理解是它只会在没有方案或没有路径的情况下失败,这应该是不可能的,因为我们之前使用 CFURLIsFileReferenceURL 测试了文件方案或文件是否存在。

  5. _CFURIParserParseURIReferenceapple/swift-corelibs-foundation – CFURLComponents_URIParser.c 中实现并且仅当 URL 长度超过 2 GB 时才会失败,我认为这与 RFC 规范无关。

  6. _CFURIParserURLStringIsValid本质上将为每个组件调用 _CFURIParserValidateComponent 并因无效字符或转义序列而失败。 这可能是最相关的部分。

现在,通过一些实验,我们知道我们需要一个方案(例如,https:// 或简单的 a://),然后我们使用提出示例的保留字符,例如:

// OK
let url = URL(string: "a://@@")!
// CRASH
let components = URLComponents(url: url, resolvingAgainstBaseURL: true)!

尝试 URLComponents 的替代初始化器也会失败,所以不要试图认为它是不同的:

// CRASH
let components = URLComponents(string: url.absoluteString)!

结论

“a://@@” 是有效 NSURL 但无效 RFC 3986 的示例。


附带说明,一些 Swift 人似乎希望 future 统一对 URL 和 URLComponents 的支持(不再有 RFC 差异)as seen in URL.swift :

// Future implementation note:
// NSURL (really CFURL, which provides its implementation) has quite a few quirks in its processing of some more esoteric (and some not so esoteric) strings. We would like to move much of this over to the more modern NSURLComponents, but binary compat concerns have made this difficult.
// Hopefully soon, we can replace some of the below delegation to NSURL with delegation to NSURLComponents instead. It cannot be done piecemeal, because otherwise we will get inconsistent results from the API.

我不确定他们打算如何执行此操作,因为这意味着要么 URL(string: "a://@@") 会失败,要么 URLComponents(string : "a://@@") 会成功。

关于swift - 什么样的 URL 不符合 RFC 3986 但符合 RFC 1808、RFC 1738 和 RFC 2732?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55609012/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com