cocoahttpserver使用具體解釋(二)
阿新 • • 發佈:2019-04-11
ons track pro 下載 app 實例 添加 == 兩個
.m文件
基本的代碼就在 processDataChunk。我們僅僅須要在這裏面處理數據就可以
接下來,我們接著去學習怎樣去接收處理web上傳的數據1 首先我們創建一個
@interface WTZHTTPConnection : HTTPConnection
在這個類中我們用於處理接受文件並存儲到app文檔
同一時候不要忘記了設置httpserver的Connectio類
[httpServer setConnectionClass:[WTZHTTPConnectionclass]];
所有的代碼例如以下
.h文件
#define UPLOAD_FILE_PROGRESS @"uploadfileprogress" #import <Foundation/Foundation.h> #import "HTTPConnection.h" @interface WTZHTTPConnection : HTTPConnection { int dataStartIndex; NSMutableArray *multipartData; BOOL postHeaderOK; } - (BOOL) isBeginOfOctetStream; @end
.m文件
#import "WTZHTTPConnection.h" @implementation WTZHTTPConnection - (void)dealloc { [multipartData release]; [super dealloc]; } //擴展HTTPServer支持的請求類型,默認支持GET。HEAD。不支持POST - (BOOL)supportsMethod:(NSString *)method atPath:(NSString *)relativePath { if ([@"POST" isEqualToString:method]) { return YES; } return [super supportsMethod:method atPath:relativePath]; } //處量返回的response數據 - (NSObject<HTTPResponse> *)httpResponseForMethod:(NSString *)method URI:(NSString *)path { return [super httpResponseForMethod:method URI:path]; } //處理POST請求提交的數據流(以下方法是改自 Andrew Davidson的類) - (void)processDataChunk:(NSData *)postDataChunk { NSLog(@"processDataChunk function called"); //multipartData初始化不放在init函數中, 當前相似乎不經init函數初始化 if (multipartData == nil) { multipartData = [[NSMutableArray alloc] init]; } //處理multipart/form-data的POST請求中Body數據集中的表單值域並創建文件 if (!postHeaderOK) { //0x0A0D: 換行符 UInt16 separatorBytes = 0x0A0D; NSData* separatorData = [NSData dataWithBytes:&separatorBytes length:2]; int l = (int)[separatorData length]; for (int i = 0; i < [postDataChunk length] - l; i++) { //每次取兩個字節 比對下看看是否是換行 NSRange searchRange = {i, l}; //假設是換行符則進行例如以下處理 if ([[postDataChunk subdataWithRange:searchRange] isEqualToData:separatorData]) { //獲取dataStartIndex標識的上一個換行位置到當前換行符之間的數據的Range NSRange newDataRange = {dataStartIndex, i - dataStartIndex}; //dataStartIndex標識的上一個換行位置到移到當前換行符位置 dataStartIndex = i + l; i += l - 1; //獲取dataStartIndex標識的上一個換行位置到當前換行符之間的數據 NSData *newData = [postDataChunk subdataWithRange:newDataRange]; //假設newData不為空或還沒有處理完multipart/form-data中表單變量值域則繼續處理剩下的表單值域數據 if ([newData length] || ![self isBeginOfOctetStream]) { if ([newData length]) { [multipartData addObject:newData]; } } else { //將標識處理完multipart/form-data中表單變量值域的postHeaderOK變量設置為TRUE; postHeaderOK = TRUE; //這裏臨時寫成硬編碼 弊端:每次添加表單變量都要改這裏的數值 //獲取Content-Disposition: form-data; name="xxx"; filename="xxx" NSString* postInfo = [[NSString alloc] initWithBytes:[[multipartData objectAtIndex:4] bytes] length:[[multipartData objectAtIndex:4] length] encoding:NSUTF8StringEncoding]; NSLog(@"postInfo is:%@", postInfo); NSArray* postInfoComponents = [postInfo componentsSeparatedByString:@"; filename="]; postInfoComponents = [[postInfoComponents lastObject] componentsSeparatedByString:@"\""]; NSLog(@"postInfoComponents0 :%@",postInfoComponents); if ([postInfoComponents count]<2) { return; } postInfoComponents = [[postInfoComponents objectAtIndex:1] componentsSeparatedByString:@"\\"]; NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString* filename = [documentPath stringByAppendingPathComponent:[postInfoComponents lastObject]]; NSLog(@"filename :%@",filename); NSRange fileDataRange = {dataStartIndex, [postDataChunk length] - dataStartIndex}; [[NSFileManager defaultManager] createFileAtPath:filename contents:[postDataChunk subdataWithRange:fileDataRange] attributes:nil]; NSFileHandle *file = [[NSFileHandle fileHandleForUpdatingAtPath:filename] retain]; if (file) { [file seekToEndOfFile]; [multipartData addObject:file]; } [postInfo release]; break; } } } } else //表單值域已經處理過了 這之後的數據全是文件數據流 { [(NSFileHandle*)[multipartData lastObject] writeData:postDataChunk]; } float uploadProgress = (double)requestContentLengthReceived / requestContentLength; //實際應用時 當前類的實例是相當於單例一樣被引用(由於僅僅被實例化一次) if (uploadProgress >= 1.0) { postHeaderOK = NO; [multipartData release]; multipartData = nil; } [[NSNotificationCenter defaultCenter] postNotificationName:UPLOAD_FILE_PROGRESS object:[NSNumber numberWithFloat:uploadProgress] userInfo:nil]; } //檢查是否已經處理完了multipart/form-data表單中的表單變量 - (BOOL) isBeginOfOctetStream { NSString *octetStreamFlag = @"Content-Type: application/octet-stream"; NSString *findData = [[NSString alloc] initWithData:(NSData *)[multipartData lastObject] encoding:NSUTF8StringEncoding]; for (NSData *d in multipartData) { NSString *temp = [[[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding] autorelease] ; NSLog(@"multipartData items: %@", temp); } //假設已經處理完了multipart/form-data表單中的表單變量 if ( findData != nil && [findData length] > 0 ) { NSLog(@"findData is :%@\n octetStreamFlag is :%@", findData, octetStreamFlag); if ([octetStreamFlag isEqualToString:findData]) { NSLog(@"multipart/form-data 變量值域數據處理完成"); [findData release]; return YES; } [findData release]; return NO; } return NO; } @end
基本的代碼就在 processDataChunk。我們僅僅須要在這裏面處理數據就可以
以上代碼主要轉自github上?https://github.com/willonboy/CocoaHTTPServer---multipart-form-data點擊打開鏈接
大家能夠下載源代碼研究
下章將要解說 web js代碼
cocoahttpserver使用具體解釋(二)