zoukankan      html  css  js  c++  java
  • 断点续传队列和本地持久化(iOS源码)

    //
    //  ASIFormDataRequest.m
    //  Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
    //
    //  Created by Ben Copsey on 07/11/2008.
    //  Copyright 2008-2009 All-Seeing Interactive. All rights reserved.
    //
    
    #import "ASIFormDataRequest.h"
    
    
    // Private stuff
    @interface ASIFormDataRequest ()
    - (void)buildMultipartFormDataPostBody;
    - (void)buildURLEncodedPostBody;
    - (void)appendPostString:(NSString *)string;
    
    @property (retain) NSMutableArray *postData;
    @property (retain) NSMutableArray *fileData;
    
    #if DEBUG_FORM_DATA_REQUEST
    - (void)addToDebugBody:(NSString *)string;
    @property (retain, nonatomic) NSString *debugBodyString;
    #endif
    
    @end
    
    @implementation ASIFormDataRequest
    
    #pragma mark utilities
    - (NSString*)encodeURL:(NSString *)string
    {
        NSString *newString = [NSMakeCollectable(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, CFSTR(":/?#[]@!$ &'()*+,;="<>%{}|\^~`"), CFStringConvertNSStringEncodingToEncoding([self stringEncoding]))) autorelease];
        if (newString) {
            return newString;
        }
        return @"";
    }
    
    #pragma mark init / dealloc
    
    + (id)requestWithURL:(NSURL *)newURL
    {
        return [[[self alloc] initWithURL:newURL] autorelease];
    }
    
    - (id)initWithURL:(NSURL *)newURL
    {
        self = [super initWithURL:newURL];
        [self setPostFormat:ASIURLEncodedPostFormat];
        [self setStringEncoding:NSUTF8StringEncoding];
            [self setRequestMethod:@"POST"];
        return self;
    }
    
    - (void)dealloc
    {
    #if DEBUG_FORM_DATA_REQUEST
        [debugBodyString release]; 
    #endif
        
        [postData release];
        [fileData release];
        [super dealloc];
    }
    
    #pragma mark setup request
    
    - (void)addPostValue:(id <NSObject>)value forKey:(NSString *)key
    {
        if (!key) {
            return;
        }
        if (![self postData]) {
            [self setPostData:[NSMutableArray array]];
        }
        NSMutableDictionary *keyValuePair = [NSMutableDictionary dictionaryWithCapacity:2];
        [keyValuePair setValue:key forKey:@"key"];
        [keyValuePair setValue:[value description] forKey:@"value"];
        [[self postData] addObject:keyValuePair];
    }
    
    - (void)setPostValue:(id <NSObject>)value forKey:(NSString *)key
    {
        // Remove any existing value
        NSUInteger i;
        for (i=0; i<[[self postData] count]; i++) {
            NSDictionary *val = [[self postData] objectAtIndex:i];
            if ([[val objectForKey:@"key"] isEqualToString:key]) {
                [[self postData] removeObjectAtIndex:i];
                i--;
            }
        }
        [self addPostValue:value forKey:key];
    }
    
    
    - (void)addFile:(NSString *)filePath forKey:(NSString *)key
    {
        [self addFile:filePath withFileName:nil andContentType:nil forKey:key];
    }
    
    - (void)addFile:(NSString *)filePath withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key
    {
        BOOL isDirectory = NO;
        BOOL fileExists = [[[[NSFileManager alloc] init] autorelease] fileExistsAtPath:filePath isDirectory:&isDirectory];
        if (!fileExists || isDirectory) {
            [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileBuildingRequestType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"No file exists at %@",filePath],NSLocalizedDescriptionKey,nil]]];
        }
    
        // If the caller didn't specify a custom file name, we'll use the file name of the file we were passed
        if (!fileName) {
            fileName = [filePath lastPathComponent];
        }
    
        // If we were given the path to a file, and the user didn't specify a mime type, we can detect it from the file extension
        if (!contentType) {
            contentType = [ASIHTTPRequest mimeTypeForFileAtPath:filePath];
        }
        [self addData:filePath withFileName:fileName andContentType:contentType forKey:key];
    }
    
    - (void)setFile:(NSString *)filePath forKey:(NSString *)key
    {
        [self setFile:filePath withFileName:nil andContentType:nil forKey:key];
    }
    
    - (void)setFile:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key
    {
        // Remove any existing value
        NSUInteger i;
        for (i=0; i<[[self fileData] count]; i++) {
            NSDictionary *val = [[self fileData] objectAtIndex:i];
            if ([[val objectForKey:@"key"] isEqualToString:key]) {
                [[self fileData] removeObjectAtIndex:i];
                i--;
            }
        }
        [self addFile:data withFileName:fileName andContentType:contentType forKey:key];
    }
    
    - (void)addData:(NSData *)data forKey:(NSString *)key
    {
        [self addData:data withFileName:@"file" andContentType:nil forKey:key];
    }
    
    - (void)addData:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key
    {
        if (![self fileData]) {
            [self setFileData:[NSMutableArray array]];
        }
        if (!contentType) {
            contentType = @"application/octet-stream";
        }
    
        NSMutableDictionary *fileInfo = [NSMutableDictionary dictionaryWithCapacity:4];
        [fileInfo setValue:key forKey:@"key"];
        [fileInfo setValue:fileName forKey:@"fileName"];
        [fileInfo setValue:contentType forKey:@"contentType"];
        [fileInfo setValue:data forKey:@"data"];
    
        [[self fileData] addObject:fileInfo];
    }
    
    - (void)setData:(NSData *)data forKey:(NSString *)key
    {
        [self setData:data withFileName:@"file" andContentType:nil forKey:key];
    }
    
    - (void)setData:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key
    {
        // Remove any existing value
        NSUInteger i;
        for (i=0; i<[[self fileData] count]; i++) {
            NSDictionary *val = [[self fileData] objectAtIndex:i];
            if ([[val objectForKey:@"key"] isEqualToString:key]) {
                [[self fileData] removeObjectAtIndex:i];
                i--;
            }
        }
        [self addData:data withFileName:fileName andContentType:contentType forKey:key];
    }
    
    - (void)buildPostBody
    {
        if ([self haveBuiltPostBody]) {
            return;
        }
        
    #if DEBUG_FORM_DATA_REQUEST
        [self setDebugBodyString:@""];    
    #endif
        
        if (![self postData] && ![self fileData]) {
            [super buildPostBody];
            return;
        }    
        if ([[self fileData] count] > 0) {
            [self setShouldStreamPostDataFromDisk:YES];
        }
        
        if ([self postFormat] == ASIURLEncodedPostFormat) {
            [self buildURLEncodedPostBody];
        } else {
            [self buildMultipartFormDataPostBody];
        }
    
        [super buildPostBody];
        
    #if DEBUG_FORM_DATA_REQUEST
        ASI_DEBUG_LOG(@"%@",[self debugBodyString]);
        [self setDebugBodyString:nil];
    #endif
    }
    
    
    - (void)buildMultipartFormDataPostBody
    {
    #if DEBUG_FORM_DATA_REQUEST
        [self addToDebugBody:@"
    ==== Building a multipart/form-data body ====
    "];
    #endif
        
        NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding([self stringEncoding]));
        
        // We don't bother to check if post data contains the boundary, since it's pretty unlikely that it does.
        CFUUIDRef uuid = CFUUIDCreate(nil);
        NSString *uuidString = [(NSString*)CFUUIDCreateString(nil, uuid) autorelease];
        CFRelease(uuid);
        NSString *stringBoundary = [NSString stringWithFormat:@"0xKhTmLbOuNdArY-%@",uuidString];
        
        [self addRequestHeader:@"Content-Type" value:[NSString stringWithFormat:@"multipart/form-data; charset=%@; boundary=%@", charset, stringBoundary]];
        
        [self appendPostString:[NSString stringWithFormat:@"--%@
    ",stringBoundary]];
        
        // Adds post data
        NSString *endItemBoundary = [NSString stringWithFormat:@"
    --%@
    ",stringBoundary];
        NSUInteger i=0;
        for (NSDictionary *val in [self postData]) {
            [self appendPostString:[NSString stringWithFormat:@"Content-Disposition: form-data; name="%@"
    
    ",[val objectForKey:@"key"]]];
            [self appendPostString:[val objectForKey:@"value"]];
            i++;
            if (i != [[self postData] count] || [[self fileData] count] > 0) { //Only add the boundary if this is not the last item in the post body
                [self appendPostString:endItemBoundary];
            }
        }
        
        // Adds files to upload
        i=0;
        for (NSDictionary *val in [self fileData]) {
    
            [self appendPostString:[NSString stringWithFormat:@"Content-Disposition: form-data; name="%@"; filename="%@"
    ", [val objectForKey:@"key"], [val objectForKey:@"fileName"]]];
            [self appendPostString:[NSString stringWithFormat:@"Content-Type: %@
    
    ", [val objectForKey:@"contentType"]]];
            
            id data = [val objectForKey:@"data"];
            if ([data isKindOfClass:[NSString class]]) {
                [self appendPostDataFromFile:data];
            } else {
                [self appendPostData:data];
            }
            i++;
            // Only add the boundary if this is not the last item in the post body
            if (i != [[self fileData] count]) { 
                [self appendPostString:endItemBoundary];
            }
        }
        
        [self appendPostString:[NSString stringWithFormat:@"
    --%@--
    ",stringBoundary]];
        
    #if DEBUG_FORM_DATA_REQUEST
        [self addToDebugBody:@"==== End of multipart/form-data body ====
    "];
    #endif
    }
    
    - (void)buildURLEncodedPostBody
    {
    
        // We can't post binary data using application/x-www-form-urlencoded
        if ([[self fileData] count] > 0) {
            [self setPostFormat:ASIMultipartFormDataPostFormat];
            [self buildMultipartFormDataPostBody];
            return;
        }
        
    #if DEBUG_FORM_DATA_REQUEST
        [self addToDebugBody:@"
    ==== Building an application/x-www-form-urlencoded body ====
    "]; 
    #endif
        
        
        NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding([self stringEncoding]));
    
        [self addRequestHeader:@"Content-Type" value:[NSString stringWithFormat:@"application/x-www-form-urlencoded; charset=%@",charset]];
    
        
        NSUInteger i=0;
        NSUInteger count = [[self postData] count]-1;
        for (NSDictionary *val in [self postData]) {
            NSString *data = [NSString stringWithFormat:@"%@=%@%@", [self encodeURL:[val objectForKey:@"key"]], [self encodeURL:[val objectForKey:@"value"]],(i<count ?  @"&" : @"")]; 
            [self appendPostString:data];
            i++;
        }
    #if DEBUG_FORM_DATA_REQUEST
        [self addToDebugBody:@"
    ==== End of application/x-www-form-urlencoded body ====
    "]; 
    #endif
    }
    
    - (void)appendPostString:(NSString *)string
    {
    #if DEBUG_FORM_DATA_REQUEST
        [self addToDebugBody:string];
    #endif
        [super appendPostData:[string dataUsingEncoding:[self stringEncoding]]];
    }
    
    #if DEBUG_FORM_DATA_REQUEST
    - (void)appendPostData:(NSData *)data
    {
        [self addToDebugBody:[NSString stringWithFormat:@"[%lu bytes of data]",(unsigned long)[data length]]];
        [super appendPostData:data];
    }
    
    - (void)appendPostDataFromFile:(NSString *)file
    {
        NSError *err = nil;
        unsigned long long fileSize = [[[[[[NSFileManager alloc] init] autorelease] attributesOfItemAtPath:file error:&err] objectForKey:NSFileSize] unsignedLongLongValue];
        if (err) {
            [self addToDebugBody:[NSString stringWithFormat:@"[Error: Failed to obtain the size of the file at '%@']",file]];
        } else {
            [self addToDebugBody:[NSString stringWithFormat:@"[%llu bytes of data from file '%@']",fileSize,file]];
        }
    
        [super appendPostDataFromFile:file];
    }
    
    - (void)addToDebugBody:(NSString *)string
    {
        if (string) {
            [self setDebugBodyString:[[self debugBodyString] stringByAppendingString:string]];
        }
    }
    #endif
    
    #pragma mark NSCopying
    
    - (id)copyWithZone:(NSZone *)zone
    {
        ASIFormDataRequest *newRequest = [super copyWithZone:zone];
        [newRequest setPostData:[[[self postData] mutableCopyWithZone:zone] autorelease]];
        [newRequest setFileData:[[[self fileData] mutableCopyWithZone:zone] autorelease]];
        [newRequest setPostFormat:[self postFormat]];
        [newRequest setStringEncoding:[self stringEncoding]];
        [newRequest setRequestMethod:[self requestMethod]];
        return newRequest;
    }
    
    @synthesize postData;
    @synthesize fileData;
    @synthesize postFormat;
    @synthesize stringEncoding;
    #if DEBUG_FORM_DATA_REQUEST
    @synthesize debugBodyString;
    #endif
    @end
  • 相关阅读:
    Basic INFO InstallShield的版本区分
    月光博客 从软件保护到软件授权
    Basic INFO InstallShield Professional for AdminStudio版本中如何打开InstallScript工程类型
    Basic INFO InstallScript脚本编程的限制
    从软件加密到软件授权保护
    月光博客 再谈软件保护中软加密和硬加密的安全强度
    INFO:Visual Studio 11 Beta版本中去除对Visual Studio Installer的支持,只保留InstallShield LE版本
    android 抓包分析
    android 巧用 dimerns 分辨率
    android 抓包 2
  • 原文地址:https://www.cnblogs.com/langtianya/p/4005193.html
Copyright © 2011-2022 走看看