Cannot see Reason-Phrase #544

Closed
kylebrowning opened this Issue Sep 27, 2012 · 7 comments

Comments

Projects
None yet
5 participants
@kylebrowning

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

This comment has been minimized.

Show comment
Hide comment
@mattt

mattt Sep 27, 2012

Contributor

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!

Contributor

mattt commented Sep 27, 2012

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 mattt closed this Sep 27, 2012

@kylebrowning

This comment has been minimized.

Show comment
Hide comment
@kylebrowning

kylebrowning Sep 27, 2012

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

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

@mattt

This comment has been minimized.

Show comment
Hide comment
@mattt

mattt Sep 27, 2012

Contributor

That's a bummer. Sorry to hear that.

Contributor

mattt commented Sep 27, 2012

That's a bummer. Sorry to hear that.

@stanislaw

This comment has been minimized.

Show comment
Hide comment
@stanislaw

stanislaw Aug 14, 2013

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));

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));
@0xced

This comment has been minimized.

Show comment
Hide comment
@0xced

0xced Aug 20, 2013

Collaborator

@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.

Collaborator

0xced commented Aug 20, 2013

@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

This comment has been minimized.

Show comment
Hide comment
@mattt

mattt Aug 20, 2013

Contributor

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

Contributor

mattt commented Aug 20, 2013

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

@roeioved

This comment has been minimized.

Show comment
Hide comment
@roeioved

roeioved Aug 21, 2013

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!

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!

@Cheesebaron Cheesebaron referenced this issue in paulcbetts/ModernHttpClient Apr 3, 2015

Closed

ReasonPhrase not returned properly on iOS #135

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment