HTTPAuthenticationRequest.m
上传用户:kc0325
上传日期:2020-06-20
资源大小:204k
文件大小:6k
源码类别:

iPhone

开发平台:

Objective-C

  1. #import "HTTPAuthenticationRequest.h"
  2. @interface HTTPAuthenticationRequest (PrivateAPI)
  3. - (NSString *)quotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header;
  4. - (NSString *)nonquotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header;
  5. @end
  6. @implementation HTTPAuthenticationRequest
  7. - (id)initWithRequest:(CFHTTPMessageRef)request
  8. {
  9. if(self = [super init])
  10. {
  11. NSString *authInfo = (NSString *)CFHTTPMessageCopyHeaderFieldValue(request, CFSTR("Authorization"));
  12. isBasic = NO;
  13. if([authInfo length] >= 6)
  14. {
  15. isBasic = [[authInfo substringToIndex:6] caseInsensitiveCompare:@"Basic "] == NSOrderedSame;
  16. }
  17. isDigest = NO;
  18. if([authInfo length] >= 7)
  19. {
  20. isDigest = [[authInfo substringToIndex:7] caseInsensitiveCompare:@"Digest "] == NSOrderedSame;
  21. }
  22. if(isBasic)
  23. {
  24. NSMutableString *temp = [[[authInfo substringFromIndex:6] mutableCopy] autorelease];
  25. CFStringTrimWhitespace((CFMutableStringRef)temp);
  26. base64Credentials = [temp copy];
  27. }
  28. if(isDigest)
  29. {
  30. username = [[self quotedSubHeaderFieldValue:@"username" fromHeaderFieldValue:authInfo] retain];
  31. realm    = [[self quotedSubHeaderFieldValue:@"realm" fromHeaderFieldValue:authInfo] retain];
  32. nonce    = [[self quotedSubHeaderFieldValue:@"nonce" fromHeaderFieldValue:authInfo] retain];
  33. uri      = [[self quotedSubHeaderFieldValue:@"uri" fromHeaderFieldValue:authInfo] retain];
  34. // It appears from RFC 2617 that the qop is to be given unquoted
  35. // Tests show that Firefox performs this way, but Safari does not
  36. // Thus we'll attempt to retrieve the value as nonquoted, but we'll verify it doesn't start with a quote
  37. qop      = [self nonquotedSubHeaderFieldValue:@"qop" fromHeaderFieldValue:authInfo];
  38. if(qop && ([qop characterAtIndex:0] == '"'))
  39. {
  40. qop  = [self quotedSubHeaderFieldValue:@"qop" fromHeaderFieldValue:authInfo];
  41. }
  42. [qop retain];
  43. nc       = [[self nonquotedSubHeaderFieldValue:@"nc" fromHeaderFieldValue:authInfo] retain];
  44. cnonce   = [[self quotedSubHeaderFieldValue:@"cnonce" fromHeaderFieldValue:authInfo] retain];
  45. response = [[self quotedSubHeaderFieldValue:@"response" fromHeaderFieldValue:authInfo] retain];
  46. }
  47. // Remember, if using garbage collection:
  48. // Core foundation objects must be released using CFRelease, as [id release] is a no-op.
  49. if(authInfo) CFRelease((CFStringRef)authInfo);
  50. }
  51. return self;
  52. }
  53. - (void)dealloc
  54. {
  55. [base64Credentials release];
  56. [username release];
  57. [realm release];
  58. [nonce release];
  59. [uri release];
  60. [qop release];
  61. [nc release];
  62. [cnonce release];
  63. [response release];
  64. [super dealloc];
  65. }
  66. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  67. #pragma mark Accessors:
  68. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. - (BOOL)isBasic {
  70. return isBasic;
  71. }
  72. - (BOOL)isDigest {
  73. return isDigest;
  74. }
  75. - (NSString *)base64Credentials {
  76. return base64Credentials;
  77. }
  78. - (NSString *)username {
  79. return username;
  80. }
  81. - (NSString *)realm {
  82. return realm;
  83. }
  84. - (NSString *)nonce {
  85. return nonce;
  86. }
  87. - (NSString *)uri {
  88. return uri;
  89. }
  90. - (NSString *)qop {
  91. return qop;
  92. }
  93. - (NSString *)nc {
  94. return nc;
  95. }
  96. - (NSString *)cnonce {
  97. return cnonce;
  98. }
  99. - (NSString *)response {
  100. return response;
  101. }
  102. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  103. #pragma mark Private API:
  104. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  105. /**
  106.  * Retrieves a "Sub Header Field Value" from a given header field value.
  107.  * The sub header field is expected to be quoted.
  108.  * 
  109.  * In the following header field:
  110.  * Authorization: Digest username="Mufasa", qop=auth, response="6629fae4939"
  111.  * The sub header field titled 'username' is quoted, and this method would return the value @"Mufasa".
  112. **/
  113. - (NSString *)quotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header
  114. {
  115. NSRange startRange = [header rangeOfString:[NSString stringWithFormat:@"%@="", param]];
  116. if(startRange.location == NSNotFound)
  117. {
  118. // The param was not found anywhere in the header
  119. return nil;
  120. }
  121. int postStartRangeLocation = startRange.location + startRange.length;
  122. int postStartRangeLength = [header length] - postStartRangeLocation;
  123. NSRange postStartRange = NSMakeRange(postStartRangeLocation, postStartRangeLength);
  124. NSRange endRange = [header rangeOfString:@""" options:0 range:postStartRange];
  125. if(endRange.location == NSNotFound)
  126. {
  127. // The ending double-quote was not found anywhere in the header
  128. return nil;
  129. }
  130. NSRange subHeaderRange = NSMakeRange(postStartRangeLocation, endRange.location - postStartRangeLocation);
  131. return [header substringWithRange:subHeaderRange];
  132. }
  133. /**
  134.  * Retrieves a "Sub Header Field Value" from a given header field value.
  135.  * The sub header field is expected to not be quoted.
  136.  * 
  137.  * In the following header field:
  138.  * Authorization: Digest username="Mufasa", qop=auth, response="6629fae4939"
  139.  * The sub header field titled 'qop' is nonquoted, and this method would return the value @"auth".
  140. **/
  141. - (NSString *)nonquotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header
  142. {
  143. NSRange startRange = [header rangeOfString:[NSString stringWithFormat:@"%@=", param]];
  144. if(startRange.location == NSNotFound)
  145. {
  146. // The param was not found anywhere in the header
  147. return nil;
  148. }
  149. int postStartRangeLocation = startRange.location + startRange.length;
  150. int postStartRangeLength = [header length] - postStartRangeLocation;
  151. NSRange postStartRange = NSMakeRange(postStartRangeLocation, postStartRangeLength);
  152. NSRange endRange = [header rangeOfString:@"," options:0 range:postStartRange];
  153. if(endRange.location == NSNotFound)
  154. {
  155. // The ending comma was not found anywhere in the header
  156. // However, if the nonquoted param is at the end of the string, there would be no comma
  157. // This is only possible if there are no spaces anywhere
  158. NSRange endRange2 = [header rangeOfString:@" " options:0 range:postStartRange];
  159. if(endRange2.location != NSNotFound)
  160. {
  161. return nil;
  162. }
  163. else
  164. {
  165. return [header substringWithRange:postStartRange];
  166. }
  167. }
  168. else
  169. {
  170. NSRange subHeaderRange = NSMakeRange(postStartRangeLocation, endRange.location - postStartRangeLocation);
  171. return [header substringWithRange:subHeaderRange];
  172. }
  173. }
  174. @end