- 浏览: 772587 次
- 性别:
- 来自: 天堂
文章分类
最新评论
-
xiaozhao-521:
呀呀呀呀呀呀呀
RequestTest222 -
Andy_hyh:
打扰了,问下openmeeting源码可以运行起来吗?
Openmeetings安装 详细步骤 -
qindongliang1922:
擦,现在还行么,厉害
北京免费吃饭的地方 -
minixx77:
...
Openmeetings安装 详细步骤 -
wwwqqqiang:
喜欢楼主分享问题的方式,有思想
UIView 和 CALayer的那点事
首先补充点东西。
main 方法中的[self buildRequestHeaders];
- (void)buildRequestHeaders { if ([self haveBuiltRequestHeaders]) { return; } [self setHaveBuiltRequestHeaders:YES]; if ([self mainRequest]) { for (NSString *header in [[self mainRequest] requestHeaders]) { [self addRequestHeader:header value:[[[self mainRequest] requestHeaders] valueForKey:header]]; } return; } [self applyCookieHeader]; // Build and set the user agent string if the request does not already have a custom user agent specified if (![[self requestHeaders] objectForKey:@"User-Agent"]) { NSString *userAgentString = [ASIHTTPRequest defaultUserAgentString]; if (userAgentString) { [self addRequestHeader:@"User-Agent" value:userAgentString]; } } // Accept a compressed response if ([self allowCompressedResponse]) { [self addRequestHeader:@"Accept-Encoding" value:@"gzip"]; } // Configure a compressed request body if ([self shouldCompressRequestBody]) { [self addRequestHeader:@"Content-Encoding" value:@"gzip"]; } // Should this request resume an existing download? [self updatePartialDownloadSize]; if ([self partialDownloadSize]) { [self addRequestHeader:@"Range" value:[NSString stringWithFormat:@"bytes=%llu-",[self partialDownloadSize]]]; } } - (void)updatePartialDownloadSize { NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease]; if ([self allowResumeForFileDownloads] && [self downloadDestinationPath] && [self temporaryFileDownloadPath] && [fileManager fileExistsAtPath:[self temporaryFileDownloadPath]]) { NSError *err = nil; [self setPartialDownloadSize:[[fileManager attributesOfItemAtPath:[self temporaryFileDownloadPath] error:&err] fileSize]]; if (err) { [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIFileManagementError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Failed to get attributes for file at path '%@'",[self temporaryFileDownloadPath]],NSLocalizedDescriptionKey,error,NSUnderlyingErrorKey,nil]]]; return; } } }
buildRequestHeaders 主要是设置gzip,断点续传
断点续传需要设置的属性如下:
allowResumeForFileDownloads
downloadDestinationPath
temporaryFileDownloadPath
if ([self allowResumeForFileDownloads] && [self downloadDestinationPath] && [self temporaryFileDownloadPath] && [fileManager fileExistsAtPath:[self temporaryFileDownloadPath]]) { NSError *err = nil; [self setPartialDownloadSize:[[fileManager attributesOfItemAtPath:[self temporaryFileDownloadPath] error:&err] fileSize]]; if (err) { [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIFileManagementError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Failed to get attributes for file at path '%@'",[self temporaryFileDownloadPath]],NSLocalizedDescriptionKey,error,NSUnderlyingErrorKey,nil]]]; return; } }
- (void)startRequest { if ([self isCancelled]) { return; } [self performSelectorOnMainThread:@selector(requestStarted) withObject:nil waitUntilDone:[NSThread isMainThread]]; [self setDownloadComplete:NO]; [self setComplete:NO]; [self setTotalBytesRead:0]; [self setLastBytesRead:0]; if ([self redirectCount] == 0) { [self setOriginalURL:[self url]]; } // If we're retrying a request, let's remove any progress we made if ([self lastBytesSent] > 0) { [self removeUploadProgressSoFar]; } [self setLastBytesSent:0]; [self setContentLength:0]; [self setResponseHeaders:nil]; if (![self downloadDestinationPath]) { [self setRawResponseData:[[[NSMutableData alloc] init] autorelease]]; } // // Create the stream for the request // NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease]; [self setReadStreamIsScheduled:NO]; // Do we need to stream the request body from disk if ([self shouldStreamPostDataFromDisk] && [self postBodyFilePath] && [fileManager fileExistsAtPath:[self postBodyFilePath]]) { // Are we gzipping the request body? if ([self compressedPostBodyFilePath] && [fileManager fileExistsAtPath:[self compressedPostBodyFilePath]]) { [self setPostBodyReadStream:[ASIInputStream inputStreamWithFileAtPath:[self compressedPostBodyFilePath] request:self]]; } else { [self setPostBodyReadStream:[ASIInputStream inputStreamWithFileAtPath:[self postBodyFilePath] request:self]]; } [self setReadStream:[(NSInputStream *)CFReadStreamCreateForStreamedHTTPRequest(kCFAllocatorDefault, request,(CFReadStreamRef)[self postBodyReadStream]) autorelease]]; } else { // If we have a request body, we'll stream it from memory using our custom stream, so that we can measure bandwidth use and it can be bandwidth-throttled if necessary if ([self postBody] && [[self postBody] length] > 0) { if ([self shouldCompressRequestBody] && [self compressedPostBody]) { [self setPostBodyReadStream:[ASIInputStream inputStreamWithData:[self compressedPostBody] request:self]]; } else if ([self postBody]) { [self setPostBodyReadStream:[ASIInputStream inputStreamWithData:[self postBody] request:self]]; } [self setReadStream:[(NSInputStream *)CFReadStreamCreateForStreamedHTTPRequest(kCFAllocatorDefault, request,(CFReadStreamRef)[self postBodyReadStream]) autorelease]]; } else { [self setReadStream:[(NSInputStream *)CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request) autorelease]]; } } if (![self readStream]) { [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileBuildingRequestType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Unable to create read stream",NSLocalizedDescriptionKey,nil]]]; return; } // // Handle SSL certificate settings // if([[[[self url] scheme] lowercaseString] isEqualToString:@"https"]) { NSMutableDictionary *sslProperties = [NSMutableDictionary dictionaryWithCapacity:1]; // Tell CFNetwork not to validate SSL certificates if (![self validatesSecureCertificate]) { [sslProperties setObject:(NSString *)kCFBooleanFalse forKey:(NSString *)kCFStreamSSLValidatesCertificateChain]; } // Tell CFNetwork to use a client certificate if (clientCertificateIdentity) { NSMutableArray *certificates = [NSMutableArray arrayWithCapacity:[clientCertificates count]+1]; // The first object in the array is our SecIdentityRef [certificates addObject:(id)clientCertificateIdentity]; // If we've added any additional certificates, add them too for (id cert in clientCertificates) { [certificates addObject:cert]; } [sslProperties setObject:certificates forKey:(NSString *)kCFStreamSSLCertificates]; } CFReadStreamSetProperty((CFReadStreamRef)[self readStream], kCFStreamPropertySSLSettings, sslProperties); } // // Handle proxy settings // if ([self proxyHost] && [self proxyPort]) { NSString *hostKey; NSString *portKey; if (![self proxyType]) { [self setProxyType:(NSString *)kCFProxyTypeHTTP]; } if ([[self proxyType] isEqualToString:(NSString *)kCFProxyTypeSOCKS]) { hostKey = (NSString *)kCFStreamPropertySOCKSProxyHost; portKey = (NSString *)kCFStreamPropertySOCKSProxyPort; } else { hostKey = (NSString *)kCFStreamPropertyHTTPProxyHost; portKey = (NSString *)kCFStreamPropertyHTTPProxyPort; if ([[[[self url] scheme] lowercaseString] isEqualToString:@"https"]) { hostKey = (NSString *)kCFStreamPropertyHTTPSProxyHost; portKey = (NSString *)kCFStreamPropertyHTTPSProxyPort; } } NSMutableDictionary *proxyToUse = [NSMutableDictionary dictionaryWithObjectsAndKeys:[self proxyHost],hostKey,[NSNumber numberWithInt:[self proxyPort]],portKey,nil]; if ([[self proxyType] isEqualToString:(NSString *)kCFProxyTypeSOCKS]) { CFReadStreamSetProperty((CFReadStreamRef)[self readStream], kCFStreamPropertySOCKSProxy, proxyToUse); } else { CFReadStreamSetProperty((CFReadStreamRef)[self readStream], kCFStreamPropertyHTTPProxy, proxyToUse); } } // // Handle persistent connections // [ASIHTTPRequest expirePersistentConnections]; [connectionsLock lock]; if (![[self url] host] || ![[self url] scheme]) { [self setConnectionInfo:nil]; [self setShouldAttemptPersistentConnection:NO]; } // Will store the old stream that was using this connection (if there was one) so we can clean it up once we've opened our own stream NSInputStream *oldStream = nil; // Use a persistent connection if possible if ([self shouldAttemptPersistentConnection]) { // If we are redirecting, we will re-use the current connection only if we are connecting to the same server if ([self connectionInfo]) { if (![[[self connectionInfo] objectForKey:@"host"] isEqualToString:[[self url] host]] || ![[[self connectionInfo] objectForKey:@"scheme"] isEqualToString:[[self url] scheme]] || [(NSNumber *)[[self connectionInfo] objectForKey:@"port"] intValue] != [[[self url] port] intValue]) { [self setConnectionInfo:nil]; // Check if we should have expired this connection } else if ([[[self connectionInfo] objectForKey:@"expires"] timeIntervalSinceNow] < 0) { #if DEBUG_PERSISTENT_CONNECTIONS NSLog(@"Not re-using connection #%i because it has expired",[[[self connectionInfo] objectForKey:@"id"] intValue]); #endif [persistentConnectionsPool removeObject:[self connectionInfo]]; [self setConnectionInfo:nil]; } } if (![self connectionInfo] && [[self url] host] && [[self url] scheme]) { // We must have a proper url with a host and scheme, or this will explode // Look for a connection to the same server in the pool for (NSMutableDictionary *existingConnection in persistentConnectionsPool) { if (![existingConnection objectForKey:@"request"] && [[existingConnection objectForKey:@"host"] isEqualToString:[[self url] host]] && [[existingConnection objectForKey:@"scheme"] isEqualToString:[[self url] scheme]] && [(NSNumber *)[existingConnection objectForKey:@"port"] intValue] == [[[self url] port] intValue]) { [self setConnectionInfo:existingConnection]; } } } if ([[self connectionInfo] objectForKey:@"stream"]) { oldStream = [[[self connectionInfo] objectForKey:@"stream"] retain]; } // No free connection was found in the pool matching the server/scheme/port we're connecting to, we'll need to create a new one if (![self connectionInfo]) { [self setConnectionInfo:[NSMutableDictionary dictionary]]; nextConnectionNumberToCreate++; [[self connectionInfo] setObject:[NSNumber numberWithInt:nextConnectionNumberToCreate] forKey:@"id"]; [[self connectionInfo] setObject:[[self url] host] forKey:@"host"]; [[self connectionInfo] setObject:[NSNumber numberWithInt:[[[self url] port] intValue]] forKey:@"port"]; [[self connectionInfo] setObject:[[self url] scheme] forKey:@"scheme"]; [persistentConnectionsPool addObject:[self connectionInfo]]; } // If we are retrying this request, it will already have a requestID if (![self requestID]) { nextRequestID++; [self setRequestID:[NSNumber numberWithUnsignedInt:nextRequestID]]; } [[self connectionInfo] setObject:[self requestID] forKey:@"request"]; [[self connectionInfo] setObject:[self readStream] forKey:@"stream"]; CFReadStreamSetProperty((CFReadStreamRef)[self readStream], kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue); #if DEBUG_PERSISTENT_CONNECTIONS NSLog(@"Request #%@ will use connection #%i",[self requestID],[[[self connectionInfo] objectForKey:@"id"] intValue]); #endif // Tag the stream with an id that tells it which connection to use behind the scenes // See http://lists.apple.com/archives/macnetworkprog/2008/Dec/msg00001.html for details on this approach CFReadStreamSetProperty((CFReadStreamRef)[self readStream], CFSTR("ASIStreamID"), [[self connectionInfo] objectForKey:@"id"]); } [connectionsLock unlock]; // Schedule the stream if (![self readStreamIsScheduled] && (!throttleWakeUpTime || [throttleWakeUpTime timeIntervalSinceDate:[NSDate date]] < 0)) { [self scheduleReadStream]; } BOOL streamSuccessfullyOpened = NO; // Start the HTTP connection CFStreamClientContext ctxt = {0, self, NULL, NULL, NULL}; if (CFReadStreamSetClient((CFReadStreamRef)[self readStream], kNetworkEvents, ReadStreamClientCallBack, &ctxt)) { if (CFReadStreamOpen((CFReadStreamRef)[self readStream])) { streamSuccessfullyOpened = YES; } } // Here, we'll close the stream that was previously using this connection, if there was one // We've kept it open until now (when we've just opened a new stream) so that the new stream can make use of the old connection // http://lists.apple.com/archives/Macnetworkprog/2006/Mar/msg00119.html if (oldStream) { [oldStream close]; [oldStream release]; oldStream = nil; } if (!streamSuccessfullyOpened) { [self setConnectionCanBeReused:NO]; [self destroyReadStream]; [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileBuildingRequestType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Unable to start HTTP connection",NSLocalizedDescriptionKey,nil]]]; return; } if (![self mainRequest]) { if ([self shouldResetUploadProgress]) { if ([self showAccurateProgress]) { [self incrementUploadSizeBy:[self postLength]]; } else { [self incrementUploadSizeBy:1]; } [ASIHTTPRequest updateProgressIndicator:&uploadProgressDelegate withProgress:0 ofTotal:1]; } if ([self shouldResetDownloadProgress] && ![self partialDownloadSize]) { [ASIHTTPRequest updateProgressIndicator:&downloadProgressDelegate withProgress:0 ofTotal:1]; } } // Record when the request started, so we can timeout if nothing happens [self setLastActivityTime:[NSDate date]]; [self setStatusTimer:[NSTimer timerWithTimeInterval:0.25 target:self selector:@selector(updateStatus:) userInfo:nil repeats:YES]]; [[NSRunLoop currentRunLoop] addTimer:[self statusTimer] forMode:[self runLoopMode]]; }
更新进度条状态
if (![self mainRequest]) {
if ([self shouldResetUploadProgress]) {
if ([self showAccurateProgress]) {
[self incrementUploadSizeBy:[self postLength]];
} else {
[self incrementUploadSizeBy:1];
}
[ASIHTTPRequest updateProgressIndicator:&uploadProgressDelegate withProgress:0 ofTotal:1];
}
if ([self shouldResetDownloadProgress] && ![self partialDownloadSize]) {
[ASIHTTPRequest updateProgressIndicator:&downloadProgressDelegate withProgress:0 ofTotal:1];
}
}
都包含在if (![self mainRequest]) {}中,为什么呢??? 有个注释如下:
//Only update progress if this isn't a HEAD request used to preset the content-length
没有搞明白??????
if (![self downloadDestinationPath]) {
[self setRawResponseData:[[[NSMutableData alloc] init] autorelease]];
}
设置返回结果的存储变量 [self setRawResponseData:[[[NSMutableData alloc] init] autorelease]];
取得返回结果:
主要是从这个变量里rawResponseData
- (NSData *)responseData { if ([self isResponseCompressed] && [self shouldWaitToInflateCompressedResponses]) { return [ASIDataDecompressor uncompressData:[self rawResponseData] error:NULL]; } else { return [self rawResponseData]; } return nil; }
发表评论
-
混编中遇到的搞笑事件
2012-04-10 10:56 2549http://hi.baidu.com/%BD%C7%C2%E ... -
asihttp 源码分析 之四 session
2012-04-09 17:13 1834session 相关的变量 // In memory cac ... -
asihttp 源码分析 之四 cookie
2012-04-09 16:11 3996cookie机制采用的是在客户端保持 HTTP 状态信息的方案 ... -
asihttp 源码分析 之四 获取请求进度
2012-04-09 15:19 1989进度条相关的操作都定义在 ASIProgressDelega ... -
asihttp 源码分析 之三 startRequest 各种回调
2012-04-09 14:34 4070SEL didStartSelector; SEL didR ... -
asihttp 源码分析 之二 main
2012-04-06 15:49 2940一:main main方法中上来就给你锁住了 [[self ... -
asihttp 源码分析
2012-04-06 14:41 5107一:发起一个同步请求 ASIHTTPRequest * ... -
java编程思想笔记
2011-08-19 13:45 908java编程思想笔记 -
iphone releas 后retatincount 为1
2011-07-25 17:34 1111I created a simple program to t ... -
关于uitableview
2011-06-22 16:15 2599一: 问题: 第一次初始化uitablevie ...
相关推荐
综上所述,ASiHTTP.zip的内容可能包括ASiHTTP库的源码和示例,供开发者学习如何在ARC环境下解决兼容性问题,或者如何将其转换为静态库以避免这些问题。对于初学者或有经验的iOS开发者来说,理解ARC的工作原理,以及...
ASIHttp是一个针对iOS平台的网络请求库,基于ASIHttpRequest框架实现。这个框架为开发者提供了强大的网络请求处理能力,包括多任务下载、断点续传等功能,对于构建客户端应用中的网络功能非常有用。以下是对ASIHttp...
2. **设置请求头**:可以添加自定义请求头,例如`[request setHeaderValue:@"application/json" forHTTPHeaderField:@"Content-Type"]`。 3. **发送POST数据**:可以方便地附加POST参数,`[request appendPostData:...
ASIHTTP 是一个已停止维护但在过去非常流行的iOS和Mac OS X平台上的第三方网络库,它为开发者提供了方便的API来处理HTTP请求。这个"ASIHTTP demo"是一个示例项目,展示了如何利用ASIHTTP库进行异步下载图片并显示...
在iOS开发中,实现多个下载任务是常见的需求,特别是在处理数据量大或者用户需要离线浏览的情况下。本项目使用了ASIHTTPRequest库与UITableView相结合来实现这一功能。...而UITableView则是iOS中用于展示列表数据的组件...
4. **处理cookies**:ASIHTTP自动处理服务器返回的cookies,可以通过`- (void)addCookie:(NSHTTPCookie *)cookie`手动添加cookie,或者通过`- (NSArray *)cookies`获取当前请求的所有cookies。 5. **请求队列管理**...
利用ASIHttp第三方库,,获取网络请求,,获得天气预报,,,代码显示天气预报效果默认是河南郑州,,亲们可以自己输入并查询自己想知道的城市天气情况,,堪比真机天气
在iOS开发中,ASIHTTP和JSON是两个非常重要的技术组件,常常用于网络数据的请求与解析,而Google地图API则提供了强大的地图展示功能。在这个"ASIHTTP+JSON+Google地图,多线程实现加载DEMO"中,我们将探讨如何将这些...
ASIHTTPRequest的详细介绍还包括 同步 异步 缓存 请求网络数据与传输数据
request.failureBlock = ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) { NSLog(@"Error: %@", error); // 错误处理逻辑 }; ``` 综上所述,通过ASIHTTPRequest框架,我们可以轻松地...
整理的一些市面上常见的第三方类库,快速集成可以方便开发,这些都是大家常用的。 里面包含: GTM 各种加密 ASIHttp http请求 KissXml xml解析 json oc版 json cpp版 Reachabiliy 网络状态判断 libcurl c语言静态...
ASIHTTP库是一个经典的Objective-C编写的网络请求框架,主要用于iOS和Mac OS X平台。这个库在iOS开发领域曾经非常流行,特别是在HTTP请求处理方面,它提供了简单易用的API,支持GET、POST等多种HTTP方法,同时也包含...
ASIHTTPRequest是一个广泛使用的Objective-C第三方库,专门设计用于简化iOS和macOS平台上的HTTP网络请求。这个库由Sam Soffes开发,它提供了一个简单、直观的接口来发起HTTP请求,处理响应,并管理网络连接。在移动...
1. **获取源码**:可以从GitHub或其他源获取ASIHTTPRequest的源代码压缩包,如"ASIHttpRequest"。 2. **导入项目**:将下载的源代码解压后,将包含的"ASIHTTPRequest"文件夹导入到Xcode工程中。 3. **链接库**:在...
[queue start]; ``` ##### 1.5 在委托方法中处理多个请求的成功和失败 委托方法提供了更细粒度的控制,可以在请求成功或失败时执行特定的操作。 ```objective-c - (void)requestFinished:(ASIHTTPRequest *)...
本文将深入探讨"进入网络请求,对返回的XML数据进行处理"这一主题,包括如何使用ASIHttp进行网络请求以及如何利用XMLParserSDK解析XML数据。 首先,让我们了解网络请求的基础。在网络编程中,HTTP协议是最常用的一...
在iOS开发领域,"中国电视节目查询"这个项目涉及到ASIHttp的使用、XML解析以及自定义Cell这三大关键知识点。接下来,我们将详细探讨这些技术及其在实际应用中的重要性。 首先,ASIHttp是一个广泛使用的Objective-C...
相比于ASIHTTP,NSURLConnection更符合苹果的最新编程指南,但在某些场景下可能需要更多的代码来实现相同的功能。 在WebService开发中,无论是同步还是异步,都应根据实际需求和性能考虑选择合适的策略。对于快速...
ASIHTTPRequest是简单易用的,它封装了CFNetwork API。使得与Web服务器通信变得更简单。它是用Objective-C编写的,可以在MAC OS X和iPhone应用中使用。 ...ASIFormDataRequest子类可以简单的实现提交数据和文件。
这时ios中的使用asihttp类库上传文件到php服务器,关于php服务器接收文件见我的另一篇文章