Fixed parsing of 'multipart/form-data' with non-ASCII headers

This commit is contained in:
Pierre-Olivier Latour
2014-04-17 11:50:09 -03:00
parent 80348079a6
commit 3f304b3c14

View File

@ -228,27 +228,34 @@ static NSData* _dashNewlineData = nil;
_contentType = nil; _contentType = nil;
ARC_RELEASE(_tmpPath); ARC_RELEASE(_tmpPath);
_tmpPath = nil; _tmpPath = nil;
CFHTTPMessageRef message = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, true); NSString* headers = [[NSString alloc] initWithData:[_parserData subdataWithRange:NSMakeRange(0, range.location)] encoding:NSUTF8StringEncoding];
const char* temp = "GET / HTTP/1.0\r\n"; if (headers) {
CFHTTPMessageAppendBytes(message, (const UInt8*)temp, strlen(temp)); for (NSString* header in [headers componentsSeparatedByString:@"\r\n"]) {
CFHTTPMessageAppendBytes(message, _parserData.bytes, range.location + range.length); NSRange subRange = [header rangeOfString:@":"];
if (CFHTTPMessageIsHeaderComplete(message)) { if (subRange.location != NSNotFound) {
NSString* controlName = nil; NSString* name = [header substringToIndex:subRange.location];
NSString* fileName = nil; NSString* value = [[header substringFromIndex:(subRange.location + subRange.length)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSDictionary* headers = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(message)); if ([name caseInsensitiveCompare:@"Content-Type"] == NSOrderedSame) {
NSString* contentDisposition = GCDWebServerNormalizeHeaderValue([headers objectForKey:@"Content-Disposition"]); _contentType = ARC_RETAIN(GCDWebServerNormalizeHeaderValue(value));
} else if ([name caseInsensitiveCompare:@"Content-Disposition"] == NSOrderedSame) {
NSString* contentDisposition = GCDWebServerNormalizeHeaderValue(value);
if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"form-data"]) { if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"form-data"]) {
controlName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"name"); _controlName = ARC_RETAIN(GCDWebServerExtractHeaderValueParameter(contentDisposition, @"name"));
fileName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename"); _fileName = ARC_RETAIN(GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename"));
}
}
} else {
DNOT_REACHED();
}
} }
_controlName = [controlName copy];
_fileName = [fileName copy];
_contentType = ARC_RETAIN(GCDWebServerNormalizeHeaderValue([headers objectForKey:@"Content-Type"]));
if (_contentType == nil) { if (_contentType == nil) {
_contentType = @"text/plain"; _contentType = @"text/plain";
} }
ARC_RELEASE(headers);
} else {
LOG_ERROR(@"Failed decoding headers in part of 'multipart/form-data'");
DNOT_REACHED();
} }
CFRelease(message);
if (_controlName) { if (_controlName) {
if (_fileName) { if (_fileName) {
NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]; NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];