Skip to content
This repository

Cannot see Reason-Phrase #544

Closed
kylebrowning opened this Issue September 27, 2012 · 8 comments

5 participants

Kyle Browning Mattt Thompson Stanislaw Pankevich Cédric Luthi Roei
Kyle Browning

Why doesnt AFNetworking let me see the Reason-Phrase.

I can get the response Status Code, but not the actual full header returned. As an example, I get a 401 denied error, and AFNetworking successfully tells me it failed by calling the failure block.

The status returned from the server is this "HTTP/1.1 401 Unauthorized: No OAuth context found"

Why is there no way to get the Reason Phrase?

I cant use localizedStringForStatusCode because that is just a list of strings for certain response codes, and they are hardcoded, read: always the same.

I realize this may be a support issue rather than an actual bug but if this doesnt exist it would be fantastic if it did.

Mattt Thompson
Owner

You can get the reason phrase for an NSHTTPURLResponse with the following code:

NSString *reasonPhrase = (__bridge_transfer NSString *)CFHTTPMessageCopyResponseStatusLine((__bridge CFHTTPMessageRef)response);

Until now, I had honestly forgotten about this part of the HTTP spec. I tried to add it in as an additional key in the HTTP error userInfo dictionary, but CFHTTPMessageCopyResponseStatusLine is part of the CFNetwork framework, which is not a dependency I'd be willing to add just for this. I attempted to add it by wrapping the line in question with #ifdef __CFHTTPMESSAGE__ but that didn't work as expected (apparently the symbol was defined, even though CFNetwork wasn't imported, so the compiler still warned about that missing symbol).

I hope that helps!

Mattt Thompson mattt closed this September 27, 2012
Kyle Browning

Well it compiled fine but I get a big fat NULL :(

Mattt Thompson
Owner

That's a bummer. Sorry to hear that.

Stanislaw Pankevich

The following worked for me, though it is just RFC phrase (no custom phrases) and it is still useless because, yes, AFNetworking does not have CFNetwork in dependencies. So sharing this just to prove the concept.

// http://code.google.com/p/amber-framework/source/browse/trunk/CoreNetworking/AFHTTPMessage.m#120
static inline CFHTTPMessageRef CFHTTPMessageRefForResponse(NSHTTPURLResponse *response) {
    CFHTTPMessageRef message = CFHTTPMessageCreateResponse(kCFAllocatorDefault, [response statusCode], NULL, kCFHTTPVersion1_1);
    // [[response allHeaderFields] enumerateKeysAndObjectsUsingBlock:^ (id key, id obj, BOOL *stop) {
    //    CFHTTPMessageSetHeaderFieldValue(message, (__bridge CFStringRef)key, (__bridge CFStringRef)obj);
    // }];
    return message;
}
NSString *reasonPhrase = (__bridge_transfer NSString *)CFHTTPMessageCopyResponseStatusLine(CFHTTPMessageRefForResponse(operation.response));
Cédric Luthi

@mattt Where did you get the information that CFHTTPMessageRef is toll-free bridged with NSHTTPURLResponse? My testing tends to prove that it’s not and that at best, you get nil, without luck you get a garbage string and at worst you get a crash.

Mattt Thompson
Owner

@0xced That was an incorrect assumption on my part.

Roei

Agreed with @0xced. Tried it with no luck.
I opened an issue to support the HTTP Status Description (#1230), and referenced to this issue, but it seems it does not work as expected (like @0xced mentioned).

I hope it will be added someday. In the meanwhile, if anyone knows of a different working bypass, would be great to know about!

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.