【问题标题】:Handle HTTP Header Field name on iOS/OSX在 iOS/OSX 上处理 HTTP 标头字段名称
【发布时间】:2013-03-25 09:13:44
【问题描述】:

我们知道 HTTP 标头名称不区分大小写,这在 RFC2616 中指定。

但是我发现所有流行的 iOS/OSX 框架,例如 ASIHTTRequestAFNetworkingRestKit 使用以下代码测试是否存在标头字段。

[[self responseHeaders] objectForKey:@"Keep-Alive"];
[[self responseHeaders] objectForKey:@"Content-Length"];

responseHeaders 只是一个 NSDictionary。我原以为 CFNetwork 层会处理这个问题,但是没有找到任何线索。也许这是现实世界中的约定?

【问题讨论】:

    标签: ios macos asihttprequest restkit afnetworking


    【解决方案1】:

    实际上,-[NSHTTPURLResponse allHeaderFields] 方法返回一个不区分大小写的 NSDictionary 实例。这与 CFNetwork 最新版本中已删除的 _CFCapitalizeHeader 函数无关。不幸的是,它的源代码不再可用。

    这是allHeaderFields 方法的简化调用图(OS X 10.8.3)

    -[NSHTTPURLResponse allHeaderFields] -- Foundation
        CFHTTPMessageCopyAllHeaderFields() -- CFNetwork
            HTTPMessage::copyAllHeaderFields(__CFArray const**)
                MixedDict::copyAsOrdinaryDict(__CFAllocator const*, __CFArray const**) const
                    CFDictionaryCreateMutable()
    

    这个字典最终作为allHeaderFields 方法的结果返回。这是 third parameter 传递给 CFDictionaryCreateMutable 的样子:

    version = 0
    retain = _keyRetain(__CFAllocator const*, void const*) // __ZL10_keyRetainPK13__CFAllocatorPKv
    release = _keyRelease(__CFAllocator const*, void const*) // __ZL11_keyReleasePK13__CFAllocatorPKv
    copyDescription = _keyCopyDescription(void const*) // __ZL19_keyCopyDescriptionPKv
    equal = _keyEqual(void const*, void const*) // __ZL9_keyEqualPKvS0_
    hash = _keyHash(void const*) // __ZL8_keyHashPKv
    

    _keyEqual C++ 方法最终使用kCFCompareCaseInsensitive 选项调用CFStringCompare

    这就是为什么不关心 NSHTTPURLResponse 标头是否区分大小写的原因。

    很遗憾,这种行为没有记录在案。请欺骗雷达#13715902 要求提供文件。

    【讨论】:

    • ASIHTTPRequest 使用 CFNetwork 函数而不是 NSHTTPURLResponse。也许我的回答可以解释这种情况。你的回答解释了 AFNetworking 案例,对吧?
    • ASIHTTPRequest 使用CFHTTPMessageCopyAllHeaderFields,这与-[NSHTTPURLResponse allHeaderFields] 内部使用的函数相同。所以我的回答也适用于 ASIHTTPRequest。并且由于_CFCapitalizeHeader函数已经从CFNetwork中移除,你的回答根本不适用。
    • 我用“nm”打印iOS 6.1 SDK的CFNetwork的符号,没有找到CFCapitalizeHeader。你是对的 !它已被删除。但是,为了改进您的答案,您能否指定 Apple 从哪个版本中删除 __CFCapitalizeHeader ?并为 Apple 改进其文档 +1。
    【解决方案2】:

    我找到了答案。尽管没有关于此的文档。 CFNetwork 层确实对标头字段进行了规范化。 http://www.opensource.apple.com/source/CFNetwork/CFNetwork-129.9/HTTP/CFHTTPMessage.c 工作在函数 __CFCapitalizeHeader 中完成。

    【讨论】:

      【解决方案3】:

      我在我的应用程序中使用以下代码从服务器获取上次修改日期

      lastModifiedStringFromServer = [[responseForDateFromServer allHeaderFields] objectForKey:@"Last-Modified"];
      

      标头字段及其值采用 NSDictionary 格式。因此我们必须使用 objectForKey 来获取值。

      【讨论】:

      • Premsuraj,我想你不明白我的问题。
      猜你喜欢
      • 1970-01-01
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 2017-07-12
      • 1970-01-01
      • 2013-01-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多