在iOS / OSX上处理HTTP标头字段名称

时间:2013-03-25 09:13:45

标签: ios macos asihttprequest restkit afnetworking

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

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

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

responseHeaders只是一个NSDictionary。我原本以为CFNetwork层会处理这个问题,但没有发现任何线索。也许这是现实世界的惯例?

3 个答案:

答案 0 :(得分:8)

实际上,-[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 ++方法最终使用CFStringCompare选项调用kCFCompareCaseInsensitive

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

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

答案 1 :(得分:1)

我找到了答案。虽然没有关于此的文档。 CFNetwork层确实标准化了标题字段。 http://www.opensource.apple.com/source/CFNetwork/CFNetwork-129.9/HTTP/CFHTTPMessage.c工作在函数__CFCapitalizeHeader中完成。

答案 2 :(得分:0)

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

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

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