3

ご存知のとおり、HTTPヘッダー名では大文字と小文字が区別されません。これはRFC2616で指定されています。

ただし、 ASIHTTRequestAFNetworkingRestKitなどの一般的なiOS / OSXフレームワークはすべて、次のコードを使用してヘッダーフィールドが存在するかどうかをテストすることがわかりました。

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

responseHeadersは単なるNSDictionaryです。CFNetworkレイヤーがこれを処理すると思っていましたが、手がかりは見つかりませんでした。多分これは現実世界の慣習ですか?

4

3 に答える 3

8

実際、この-[NSHTTPURLResponse allHeaderFields]メソッドは大文字と小文字を区別しないNSDictionaryインスタンスを返します。_CFCapitalizeHeaderこれは、CFNetworkの最近のバージョンで削除された機能とは何の関係もありません。残念ながら、そのソースコードはもう利用できません。

allHeaderFieldsこれは、メソッド(OS X 10.8.3)の簡略化されたコールグラフです。

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

allHeaderFieldsこのディクショナリは、メソッドの結果として最終的に返されます。渡される3番目のパラメーター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

_keyEqualC ++メソッドは、最終的にオプションCFStringCompareを使用して呼び出しkCFCompareCaseInsensitiveます。

これが、NSHTTPURLResponseヘッダーの大文字と小文字の区別を気にしない理由です。

ただし、この動作が文書化されていないことは非常に残念です。レーダー#13715902を複製して文書を求めてください。

于 2013-04-23T13:55:27.513 に答える
1

答えが見つかりました。これに関するドキュメントはありませんが。CFNetworkレイヤーはヘッダーフィールドを正規化しました。 http://www.opensource.apple.com/source/CFNetwork/CFNetwork-129.9/HTTP/CFHTTPMessage.c 作業は関数__CFCapitalizeHeaderで行われます。

于 2013-04-02T05:14:24.510 に答える
0

アプリで次のコードを使用して、サーバーから最終変更日を取得しています

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

ヘッダーフィールドとその値はNSDictionary形式です。したがって、値を取得するにはobjectForKeyを使用する必要があります。

于 2013-03-25T09:21:30.587 に答える