Compare commits

..

No commits in common. "5266874bcc79c1afa627e590f982e50f6886f25f" and "ebe5c7af3184d1e8bf3dc441914a6d052f10d135" have entirely different histories.

7 changed files with 43 additions and 86 deletions

View file

@ -1,11 +1,11 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'AFNetworking' s.name = 'AFNetworking'
s.version = '1.3.4' s.version = '1.3.3'
s.license = 'MIT' s.license = 'MIT'
s.summary = 'A delightful iOS and OS X networking framework.' s.summary = 'A delightful iOS and OS X networking framework.'
s.homepage = 'https://github.com/AFNetworking/AFNetworking' s.homepage = 'https://github.com/AFNetworking/AFNetworking'
s.authors = { 'Mattt Thompson' => 'm@mattt.me', 'Scott Raymond' => 'sco@gowalla.com' } s.authors = { 'Mattt Thompson' => 'm@mattt.me', 'Scott Raymond' => 'sco@gowalla.com' }
s.source = { :git => 'https://github.com/AFNetworking/AFNetworking.git', :tag => '1.3.4' } s.source = { :git => 'https://github.com/AFNetworking/AFNetworking.git', :tag => '1.3.3' }
s.source_files = 'AFNetworking' s.source_files = 'AFNetworking'
s.requires_arc = true s.requires_arc = true

View file

@ -272,10 +272,9 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) {
if (userAgent) { if (userAgent) {
if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) { if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) {
NSMutableString *mutableUserAgent = [userAgent mutableCopy]; NSMutableString *mutableUserAgent = [userAgent mutableCopy];
if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, kCFStringTransformToLatin, false)) { CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, kCFStringTransformToLatin, false);
userAgent = mutableUserAgent; userAgent = mutableUserAgent;
} }
}
[self setDefaultHeader:@"User-Agent" value:userAgent]; [self setDefaultHeader:@"User-Agent" value:userAgent];
} }
@ -759,22 +758,22 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
#pragma mark - #pragma mark -
static NSString * AFCreateMultipartFormBoundary() { static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY";
return [NSString stringWithFormat:@"Boundary+%08X%08X", arc4random(), arc4random()];
}
static NSString * const kAFMultipartFormCRLF = @"\r\n"; static NSString * const kAFMultipartFormCRLF = @"\r\n";
static inline NSString * AFMultipartFormInitialBoundary(NSString *boundary) { static NSInteger const kAFStreamToStreamBufferSize = 1024 * 1024; //1 meg default
return [NSString stringWithFormat:@"--%@%@", boundary, kAFMultipartFormCRLF];
static inline NSString * AFMultipartFormInitialBoundary() {
return [NSString stringWithFormat:@"--%@%@", kAFMultipartFormBoundary, kAFMultipartFormCRLF];
} }
static inline NSString * AFMultipartFormEncapsulationBoundary(NSString *boundary) { static inline NSString * AFMultipartFormEncapsulationBoundary() {
return [NSString stringWithFormat:@"%@--%@%@", kAFMultipartFormCRLF, boundary, kAFMultipartFormCRLF]; return [NSString stringWithFormat:@"%@--%@%@", kAFMultipartFormCRLF, kAFMultipartFormBoundary, kAFMultipartFormCRLF];
} }
static inline NSString * AFMultipartFormFinalBoundary(NSString *boundary) { static inline NSString * AFMultipartFormFinalBoundary() {
return [NSString stringWithFormat:@"%@--%@--%@", kAFMultipartFormCRLF, boundary, kAFMultipartFormCRLF]; return [NSString stringWithFormat:@"%@--%@--%@", kAFMultipartFormCRLF, kAFMultipartFormBoundary, kAFMultipartFormCRLF];
} }
static inline NSString * AFContentTypeForPathExtension(NSString *extension) { static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
@ -801,7 +800,6 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
@property (nonatomic, assign) unsigned long long bodyContentLength; @property (nonatomic, assign) unsigned long long bodyContentLength;
@property (nonatomic, strong) NSInputStream *inputStream; @property (nonatomic, strong) NSInputStream *inputStream;
@property (nonatomic, copy) NSString *boundary;
@property (nonatomic, assign) BOOL hasInitialBoundary; @property (nonatomic, assign) BOOL hasInitialBoundary;
@property (nonatomic, assign) BOOL hasFinalBoundary; @property (nonatomic, assign) BOOL hasFinalBoundary;
@ -828,7 +826,6 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
@interface AFStreamingMultipartFormData () @interface AFStreamingMultipartFormData ()
@property (readwrite, nonatomic, copy) NSMutableURLRequest *request; @property (readwrite, nonatomic, copy) NSMutableURLRequest *request;
@property (nonatomic, copy) NSString *boundary;
@property (readwrite, nonatomic, strong) AFMultipartBodyStream *bodyStream; @property (readwrite, nonatomic, strong) AFMultipartBodyStream *bodyStream;
@property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding; @property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding;
@end @end
@ -848,7 +845,6 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
self.request = urlRequest; self.request = urlRequest;
self.stringEncoding = encoding; self.stringEncoding = encoding;
self.boundary = AFCreateMultipartFormBoundary();
self.bodyStream = [[AFMultipartBodyStream alloc] initWithStringEncoding:encoding]; self.bodyStream = [[AFMultipartBodyStream alloc] initWithStringEncoding:encoding];
return self; return self;
@ -901,7 +897,6 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init];
bodyPart.stringEncoding = self.stringEncoding; bodyPart.stringEncoding = self.stringEncoding;
bodyPart.headers = mutableHeaders; bodyPart.headers = mutableHeaders;
bodyPart.boundary = self.boundary;
bodyPart.body = fileURL; bodyPart.body = fileURL;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:nil]; NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:nil];
@ -931,7 +926,6 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init];
bodyPart.stringEncoding = self.stringEncoding; bodyPart.stringEncoding = self.stringEncoding;
bodyPart.headers = mutableHeaders; bodyPart.headers = mutableHeaders;
bodyPart.boundary = self.boundary;
bodyPart.body = inputStream; bodyPart.body = inputStream;
bodyPart.bodyContentLength = length; bodyPart.bodyContentLength = length;
@ -974,7 +968,6 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init];
bodyPart.stringEncoding = self.stringEncoding; bodyPart.stringEncoding = self.stringEncoding;
bodyPart.headers = headers; bodyPart.headers = headers;
bodyPart.boundary = self.boundary;
bodyPart.bodyContentLength = [body length]; bodyPart.bodyContentLength = [body length];
bodyPart.body = body; bodyPart.body = body;
@ -996,7 +989,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
// Reset the initial and final boundaries to ensure correct Content-Length // Reset the initial and final boundaries to ensure correct Content-Length
[self.bodyStream setInitialAndFinalBoundaries]; [self.bodyStream setInitialAndFinalBoundaries];
[self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", self.boundary] forHTTPHeaderField:@"Content-Type"]; [self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", kAFMultipartFormBoundary] forHTTPHeaderField:@"Content-Type"];
[self.request setValue:[NSString stringWithFormat:@"%llu", [self.bodyStream contentLength]] forHTTPHeaderField:@"Content-Length"]; [self.request setValue:[NSString stringWithFormat:@"%llu", [self.bodyStream contentLength]] forHTTPHeaderField:@"Content-Length"];
[self.request setHTTPBodyStream:self.bodyStream]; [self.request setHTTPBodyStream:self.bodyStream];
@ -1260,7 +1253,7 @@ typedef enum {
- (unsigned long long)contentLength { - (unsigned long long)contentLength {
unsigned long long length = 0; unsigned long long length = 0;
NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary(self.boundary) : AFMultipartFormEncapsulationBoundary(self.boundary)) dataUsingEncoding:self.stringEncoding]; NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary() : AFMultipartFormEncapsulationBoundary()) dataUsingEncoding:self.stringEncoding];
length += [encapsulationBoundaryData length]; length += [encapsulationBoundaryData length];
NSData *headersData = [[self stringForHeaders] dataUsingEncoding:self.stringEncoding]; NSData *headersData = [[self stringForHeaders] dataUsingEncoding:self.stringEncoding];
@ -1268,7 +1261,7 @@ typedef enum {
length += _bodyContentLength; length += _bodyContentLength;
NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary(self.boundary) dataUsingEncoding:self.stringEncoding] : [NSData data]); NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary() dataUsingEncoding:self.stringEncoding] : [NSData data]);
length += [closingBoundaryData length]; length += [closingBoundaryData length];
return length; return length;
@ -1304,7 +1297,7 @@ typedef enum {
NSUInteger totalNumberOfBytesRead = 0; NSUInteger totalNumberOfBytesRead = 0;
if (_phase == AFEncapsulationBoundaryPhase) { if (_phase == AFEncapsulationBoundaryPhase) {
NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary(self.boundary) : AFMultipartFormEncapsulationBoundary(self.boundary)) dataUsingEncoding:self.stringEncoding]; NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary() : AFMultipartFormEncapsulationBoundary()) dataUsingEncoding:self.stringEncoding];
totalNumberOfBytesRead += [self readData:encapsulationBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; totalNumberOfBytesRead += [self readData:encapsulationBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)];
} }
@ -1329,7 +1322,7 @@ typedef enum {
} }
if (_phase == AFFinalBoundaryPhase) { if (_phase == AFFinalBoundaryPhase) {
NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary(self.boundary) dataUsingEncoding:self.stringEncoding] : [NSData data]); NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary() dataUsingEncoding:self.stringEncoding] : [NSData data]);
totalNumberOfBytesRead += [self readData:closingBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; totalNumberOfBytesRead += [self readData:closingBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)];
} }

View file

@ -149,8 +149,8 @@ static void AFSwizzleClassMethodWithClassAndSelectorUsingBlock(Class klass, SEL
[userInfo setValue:self.response forKey:AFNetworkingOperationFailingURLResponseErrorKey]; [userInfo setValue:self.response forKey:AFNetworkingOperationFailingURLResponseErrorKey];
if (![self hasAcceptableStatusCode]) { if (![self hasAcceptableStatusCode]) {
NSInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? [self.response statusCode] : 200; NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200;
[userInfo setValue:[NSString stringWithFormat:NSLocalizedStringFromTable(@"Expected status code in (%@), got %ld", @"AFNetworking", nil), AFStringFromIndexSet([[self class] acceptableStatusCodes]), (long)statusCode] forKey:NSLocalizedDescriptionKey]; [userInfo setValue:[NSString stringWithFormat:NSLocalizedStringFromTable(@"Expected status code in (%@), got %d", @"AFNetworking", nil), AFStringFromIndexSet([[self class] acceptableStatusCodes]), statusCode] forKey:NSLocalizedDescriptionKey];
self.HTTPError = [[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo]; self.HTTPError = [[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo];
} else if (![self hasAcceptableContentType]) { } else if (![self hasAcceptableContentType]) {
// Don't invalidate content type if there is no content // Don't invalidate content type if there is no content

View file

@ -108,13 +108,8 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
static NSData *AFSecKeyGetData(SecKeyRef key) { static NSData *AFSecKeyGetData(SecKeyRef key) {
CFDataRef data = NULL; CFDataRef data = NULL;
#if defined(NS_BLOCK_ASSERTIONS)
SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data);
#else
OSStatus status = SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data); OSStatus status = SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data);
NSCAssert(status == errSecSuccess, @"SecItemExport error: %ld", (long int)status); NSCAssert(status == errSecSuccess, @"SecItemExport error: %ld", (long int)status);
#endif
NSCParameterAssert(data); NSCParameterAssert(data);
return (__bridge_transfer NSData *)data; return (__bridge_transfer NSData *)data;
@ -592,7 +587,6 @@ willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challe
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecPolicyRef policy = SecPolicyCreateBasicX509(); SecPolicyRef policy = SecPolicyCreateBasicX509();
SecTrustEvaluate(serverTrust, NULL);
CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust);
NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:certificateCount]; NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:certificateCount];
@ -739,19 +733,15 @@ didReceiveResponse:(NSURLResponse *)response
while (totalNumberOfBytesWritten < length) { while (totalNumberOfBytesWritten < length) {
numberOfBytesWritten = [self.outputStream write:&dataBuffer[0] maxLength:length]; numberOfBytesWritten = [self.outputStream write:&dataBuffer[0] maxLength:length];
if (numberOfBytesWritten == -1) { if (numberOfBytesWritten == -1) {
break;
}
totalNumberOfBytesWritten += numberOfBytesWritten;
}
break;
}
if (self.outputStream.streamError) {
[self.connection cancel]; [self.connection cancel];
[self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:self.outputStream.streamError]; [self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:self.outputStream.streamError];
return; return;
} else {
totalNumberOfBytesWritten += numberOfBytesWritten;
}
}
break;
} }
} }

28
CHANGES
View file

@ -1,31 +1,3 @@
= 1.3.4 (2014-04-15)
* Fix `AFHTTPMultipartBodyStream` to randomly generate form boundary, to
prevent attack based on a known value (Mathias Bynens, Tom Van Goethem, Mattt
Thompson)
* Fix potential non-terminating loop in `connection:didReceiveData:` (Mattt
Thompson)
* Fix SSL certificate validation to provide a human readable Warning when
SSL Pinning fails (Maximillian Dornseif)
* Fix SSL certificate validation to assert that no impossible pinning
configuration exists (Maximillian Dornseif)
* Fix to check `CFStringTransform()` call for success before using result
(Kevin Cassidy Jr)
* Fix to prevent unused assertion results with macros (Indragie Karunaratne)
* Fix to call call `SecTrustEvaluate` before calling
`SecTrustGetCertificateCount` in SSL certificate validation (Josh Chung)
* Fix to add explicit cast to `NSUInteger` in format string (Alexander
Kempgen)
* Remove unused variable `kAFStreamToStreamBufferSize` (Alexander Kempgen)
= 1.3.3 (2013-09-25) = 1.3.3 (2013-09-25)
* Add stream error handling to `AFMultipartBodyStream` (Nicolas Bachschmidt, * Add stream error handling to `AFMultipartBodyStream` (Nicolas Bachschmidt,

View file

@ -1,4 +1,4 @@
Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com/) Copyright (c) 2011 Gowalla (http://gowalla.com/)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -2,6 +2,8 @@
<img src="https://raw.github.com/AFNetworking/AFNetworking/assets/afnetworking-logo.png" alt="AFNetworking" title="AFNetworking"> <img src="https://raw.github.com/AFNetworking/AFNetworking/assets/afnetworking-logo.png" alt="AFNetworking" title="AFNetworking">
</p> </p>
[![Build Status](https://travis-ci.org/AFNetworking/AFNetworking.png?branch=master)](https://travis-ci.org/AFNetworking/AFNetworking)
AFNetworking is a delightful networking library for iOS and Mac OS X. It's built on top of [NSURLConnection](http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html), [NSOperation](http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html), and other familiar Foundation technologies. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use. For example, here's how easy it is to get JSON from a URL: AFNetworking is a delightful networking library for iOS and Mac OS X. It's built on top of [NSURLConnection](http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html), [NSOperation](http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html), and other familiar Foundation technologies. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use. For example, here's how easy it is to get JSON from a URL:
```objective-c ```objective-c