mirror of
https://github.com/swisspol/GCDWebServer.git
synced 2026-04-05 00:04:17 +08:00
Added GCDWebServerChunkedResponse
This commit is contained in:
@@ -55,6 +55,15 @@
|
||||
}
|
||||
@end
|
||||
|
||||
@interface GCDWebServerChunkedResponse () {
|
||||
@private
|
||||
GCDWebServerChunkBlock _block;
|
||||
NSData* _chunk;
|
||||
NSUInteger _offset;
|
||||
BOOL _terminated;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation GCDWebServerResponse
|
||||
|
||||
@synthesize contentType=_type, contentLength=_length, statusCode=_status, cacheControlMaxAge=_maxAge, additionalHeaders=_headers;
|
||||
@@ -378,3 +387,74 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GCDWebServerChunkedResponse
|
||||
|
||||
+ (GCDWebServerChunkedResponse*)responseWithContentType:(NSString*)type chunkBlock:(GCDWebServerChunkBlock)block {
|
||||
return ARC_AUTORELEASE([[[self class] alloc] initWithContentType:type chunkBlock:block]);
|
||||
}
|
||||
|
||||
- (id)initWithContentType:(NSString*)type chunkBlock:(GCDWebServerChunkBlock)block {
|
||||
if ((self = [super init])) {
|
||||
_block = [block copy];
|
||||
|
||||
self.contentType = type;
|
||||
[self setValue:@"chunked" forAdditionalHeader:@"Transfer-Encoding"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)open {
|
||||
DCHECK(_chunk == nil);
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSInteger)read:(void*)buffer maxLength:(NSUInteger)length {
|
||||
if (_offset >= _chunk.length) {
|
||||
ARC_RELEASE(_chunk);
|
||||
_chunk = nil;
|
||||
}
|
||||
if (_chunk == nil) {
|
||||
if (_terminated) {
|
||||
return 0;
|
||||
}
|
||||
NSData* data = _block();
|
||||
if (data.length > 0) {
|
||||
const char* hexString = [[NSString stringWithFormat:@"%lx", (unsigned long)data.length] UTF8String];
|
||||
size_t hexLength = strlen(hexString);
|
||||
_chunk = [[NSMutableData alloc] initWithLength:(hexLength + 2 + data.length + 2)];
|
||||
char* ptr = (char*)_chunk.bytes;
|
||||
bcopy(hexString, ptr, hexLength);
|
||||
ptr += hexLength;
|
||||
*ptr++ = '\r';
|
||||
*ptr++ = '\n';
|
||||
bcopy(data.bytes, ptr, data.length);
|
||||
ptr += data.length;
|
||||
*ptr++ = '\r';
|
||||
*ptr = '\n';
|
||||
} else {
|
||||
_chunk = [[NSData alloc] initWithBytes:"0\r\n\r\n" length:5];
|
||||
_terminated = YES;
|
||||
}
|
||||
_offset = 0;
|
||||
}
|
||||
NSInteger size = MIN(_chunk.length - _offset, length);
|
||||
bcopy((char*)_chunk.bytes + _offset, buffer, size);
|
||||
_offset += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
- (BOOL)close {
|
||||
ARC_RELEASE(_chunk);
|
||||
_chunk = nil;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
DCHECK(_chunk == nil);
|
||||
ARC_RELEASE(_chunk);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user