Accessing HTTP Headers From An NSURLRequest

by Dan Grigsby on August 4, 2009 · 9 comments

Rudi Farkas left this comment on my tutorial demonstrating how to use JSON over HTTP on the iPhone:

I would like to get to the HTTP headers that accompanied the response to a query sent via NSURLRequest.

This falls under the easy, but not obvious class of iPhone programming problems. Worthy of a quick post:

The headers for an HTTP connection are included in the NSHTTPURLResponse class. If you have an NSHTTPURLResponse variable you can easily get the headers out as a NSDictionary by sending the allHeaderFields message.

For synchronous requests — not recommended, because they block — it’s easy to populate an NSHTTPURLResponse:

NSURL *url = [NSURL URLWithString:@"http://www.mobileorchard.com"];
NSURLRequest *request = [NSURLRequest requestWithURL: url];
NSHTTPURLResponse *response;
[NSURLConnection sendSynchronousRequest: request returningResponse: &response error: nil];
if ([response respondsToSelector:@selector(allHeaderFields)]) {
	NSDictionary *dictionary = [response allHeaderFields];
	NSLog([dictionary description]);
}

With an asynchronous request you have to do a little more work. When the callback connection:didReceiveResponse: is called, it is passed an NSURLResponse as the second parameter. You can cast it to an NSHTTPURLResponse like so:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
	NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
	if ([response respondsToSelector:@selector(allHeaderFields)]) {
		NSDictionary *dictionary = [httpResponse allHeaderFields];
		NSLog([dictionary description]);
	}
}

Updated based on Ben’s comment. See below for details.

{ 3 trackbacks }

[iPhone] NSURLRequest로 받은 response에서 Http header를 가져오기 – Accessing HTTP Headers From An NSURLRequest | Alones world
08.05.09 at 7:51 pm
links for 2009-08-05 | Alones world
08.05.09 at 8:31 pm
iPhoneGeek 爱疯极客 » 通过NSURLRequest访问HTTP头信息
11.05.09 at 1:08 am

{ 6 comments… read them below or add one }

1

Benjamin Ragheb 08.06.09 at 10:08 am

In both cases you are performing a blind cast: you are assuming that the NSURLResponse is really a NSHTTPURLResponse but if the API returned something else, you’d generate an exception when you try to call allHeaderFields.

Objective-C is not Java. When you write &response you are just passing a memory address with no type information. NSURLConnection does not know that you declared it a NSHTTPURLResponse, and in theory it could return a pointer to any other type of NSURLResponse.

If you want to be really safe, in both cases you need to either check the class of the object or test if it responds to the allHeaderFields selector. For example:

if ([response isKindOfClass:[NSHTTPURLResponse class]]) { …

or

if ([response respondsToSelector:@selector(allHeaderFields)]) { …

Most of the time you’ll get by without the test because you are hard coding HTTP URLs, but if you are accepting URLs from outside sources and/or want your code to be bulletproof, you should always check types before casting.

2

Dan Grigsby 08.06.09 at 9:38 pm

Ben: good input. Updated the post.

3

Rudi Farkas 08.09.09 at 9:01 am

Dan & Ben

After I posted my question, I searched some more, and I found the (easy, but not obvious) solution along these lines.
Thank you for the detailed discussion of the subject, for all interested developers to see.

4

Douglass Turner 09.01.09 at 10:25 am

Hi,

While you’re on the subject of HTTP header hacking, I am in my own personal hell trying to specific the byte-range in the header of an NSMutableURLRequest. I was wondering if anyone would be willing to tell me what I’m doing wrong. I should say at the outset that I have confirmed - via curl - that my server does indeed support requesting a byte range.

The code:

NSMutableURLRequest *request =
[NSMutableURLRequest requestWithURL:url];

[request setHTTPMethod:@"GET"];

// set a byte-range of 2048 bytes.
[request addValue:@"bytes=0-2047" forHTTPHeaderField:@"Range"];

// Confirm the header information
NSLog([[request allHTTPHeaderFields] description]);

No joy at all. When I send this off to my server the entire data payload is returned. Again, and again, and again. I have scoured all the Apple docs. I have pestered the Apple dev. list and StackOverflow. Nuthin’.

Can anyone suggest what I have missed here?

Cheers,
Doug
@dugla

5

roy 03.12.10 at 4:16 pm

I want to suggest this free http testing tool using this tool you can send different http headers and view the Response header from any URL.

6

roy 03.12.10 at 4:17 pm

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Older post: Interview with Rhomobile: GPL3 Cross-Platform Mobile App Development In Ruby

Newer post: 20%/$99 360iDev Discount For OpenGL Workshop Attendees