in EMASCurl/EMASCurlProtocol.m [725:810]
size_t header_cb(char *buffer, size_t size, size_t nitems, void *userdata) {
EMASCurlProtocol *protocol = (__bridge EMASCurlProtocol *)userdata;
size_t totalSize = size * nitems;
NSData *data = [NSData dataWithBytes:buffer length:size * nitems];
NSString *headerLine = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
headerLine = [headerLine stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([headerLine hasPrefix:@"HTTP/"]) {
// 头部首行,标识新的头部开始
[protocol.currentResponse reset];
NSArray<NSString *> *components = [headerLine componentsSeparatedByString:@" "];
if (components.count >= 3) {
protocol.currentResponse.httpVersion = components[0];
protocol.currentResponse.statusCode = [components[1] integerValue];
protocol.currentResponse.reasonPhrase = [[components subarrayWithRange:NSMakeRange(2, components.count - 2)] componentsJoinedByString:@" "];
} else if (components.count == 2) {
protocol.currentResponse.httpVersion = components[0];
protocol.currentResponse.statusCode = [components[1] integerValue];
protocol.currentResponse.reasonPhrase = @"";
}
} else {
NSRange delimiterRange = [headerLine rangeOfString:@": "];
if (delimiterRange.location != NSNotFound) {
NSString *key = [headerLine substringToIndex:delimiterRange.location];
NSString *value = [headerLine substringFromIndex:delimiterRange.location + delimiterRange.length];
// 设置cookie
if ([key caseInsensitiveCompare:@"set-cookie"] == NSOrderedSame) {
EMASCurlCookieStorage *cookieStorage = [EMASCurlCookieStorage sharedStorage];
[cookieStorage setCookieWithString:value forURL:protocol.request.URL];
}
if (protocol.currentResponse.headers[key]) {
NSString *existingValue = protocol.currentResponse.headers[key];
NSString *combinedValue = [existingValue stringByAppendingFormat:@", %@", value];
protocol.currentResponse.headers[key] = combinedValue;
} else {
protocol.currentResponse.headers[key] = value;
}
}
}
if ([headerLine length] == 0) {
// 尾行,标识当前头部读取结束
NSInteger statusCode = protocol.currentResponse.statusCode;
NSString *reasonPhrase = protocol.currentResponse.reasonPhrase;
NSHTTPURLResponse *httpResponse = [[NSHTTPURLResponse alloc] initWithURL:protocol.request.URL
statusCode:protocol.currentResponse.statusCode
HTTPVersion:protocol.currentResponse.httpVersion
headerFields:protocol.currentResponse.headers];
if (isRedirectionStatusCode(statusCode)) {
if (!s_enableBuiltInRedirection) {
// 关闭了重定向支持,则把重定向信息往外传递
__block NSString *location = nil;
[protocol.currentResponse.headers enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {
if ([key caseInsensitiveCompare:@"Location"] == NSOrderedSame) {
location = obj;
*stop = YES;
}
}];
if (location) {
NSURL *locationURL = [NSURL URLWithString:location relativeToURL:protocol.request.URL];
NSMutableURLRequest *redirectedRequest = [protocol.request mutableCopy];
[redirectedRequest setURL:locationURL];
[protocol.client URLProtocol:protocol wasRedirectedToRequest:redirectedRequest redirectResponse:httpResponse];
} else {
}
}
[protocol.currentResponse reset];
} else if (isInformationalStatusCode(statusCode)) {
[protocol.currentResponse reset];
} else if (isConnectEstablishedStatusCode(statusCode, reasonPhrase)) {
[protocol.currentResponse reset];
} else {
[protocol.client URLProtocol:protocol didReceiveResponse:httpResponse cacheStoragePolicy:NSURLCacheStorageAllowed];
protocol.currentResponse.isFinalResponse = YES;
}
}
return totalSize;
}