@@ -24,10 +24,11 @@ #import "OFDate.h" #import "OFDictionary.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" #import "OFNumber.h" +#import "OFSocket+Private.h" #import "OFTCPSocket.h" #import "OFTLSSocket.h" #import "OFThread.h" #import "OFTimer.h" #import "OFURL.h" @@ -41,14 +42,10 @@ #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" #import "OFWriteFailedException.h" -#import "socket_helpers.h" - -#define BUFFER_SIZE 1024 - /* * FIXME: Key normalization replaces headers like "DNT" with "Dnt". * FIXME: Errors are not reported to the user. */ @@ -75,16 +72,16 @@ @public OFStreamSocket *_socket; OFHTTPServer *_server; OFTimer *_timer; enum { - AWAITING_PROLOG, - PARSING_HEADERS, - SEND_RESPONSE + stateAwaitingProlog, + stateParsingHeaders, + stateSendResponse } _state; uint8_t _HTTPMinorVersion; - of_http_request_method_t _method; + OFHTTPRequestMethod _method; OFString *_host, *_path; uint16_t _port; OFMutableDictionary *_headers; size_t _contentLength; OFStream *_requestBody; @@ -120,38 +117,33 @@ #endif static OF_INLINE OFString * normalizedKey(OFString *key) { - char *cString = of_strdup(key.UTF8String); + char *cString = OFStrDup(key.UTF8String); unsigned char *tmp = (unsigned char *)cString; bool firstLetter = true; - if (cString == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: strlen(key.UTF8String)]; - while (*tmp != '\0') { - if (!of_ascii_isalpha(*tmp)) { + if (!OFASCIIIsAlpha(*tmp)) { firstLetter = true; tmp++; continue; } *tmp = (firstLetter - ? of_ascii_toupper(*tmp) - : of_ascii_tolower(*tmp)); + ? OFASCIIToUpper(*tmp) : OFASCIIToLower(*tmp)); firstLetter = false; tmp++; } @try { return [OFString stringWithUTF8StringNoCopy: cString freeWhenDone: true]; } @catch (id e) { - free(cString); + OFFreeMemory(cString); @throw e; } } @implementation OFHTTPServerResponse @@ -187,28 +179,25 @@ OFEnumerator *keyEnumerator, *valueEnumerator; OFString *key, *value; [_socket writeFormat: @"HTTP/%@ %hd %@\r\n", self.protocolVersionString, _statusCode, - of_http_status_code_to_string(_statusCode)]; + OFHTTPStatusCodeString(_statusCode)]; headers = [[_headers mutableCopy] autorelease]; if ([headers objectForKey: @"Date"] == nil) { OFString *date = [[OFDate date] dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; - - [headers setObject: date - forKey: @"Date"]; + [headers setObject: date forKey: @"Date"]; } if ([headers objectForKey: @"Server"] == nil) { OFString *name = _server.name; if (name != nil) - [headers setObject: name - forKey: @"Server"]; + [headers setObject: name forKey: @"Server"]; } keyEnumerator = [headers keyEnumerator]; valueEnumerator = [headers objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && @@ -222,12 +211,11 @@ isEqual: @"chunked"]; objc_autoreleasePoolPop(pool); } -- (size_t)lowlevelWriteBuffer: (const void *)buffer - length: (size_t)length +- (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { /* TODO: Use non-blocking writes */ void *pool; @@ -236,19 +224,17 @@ if (!_headersSent) [self of_sendHeaders]; if (!_chunked) - return [_socket writeBuffer: buffer - length: length]; + return [_socket writeBuffer: buffer length: length]; pool = objc_autoreleasePoolPush(); [_socket writeString: [OFString stringWithFormat: @"%zX\r\n", length]]; objc_autoreleasePoolPop(pool); - [_socket writeBuffer: buffer - length: length]; + [_socket writeBuffer: buffer length: length]; [_socket writeString: @"\r\n"]; return length; } @@ -302,11 +288,11 @@ scheduledTimerWithTimeInterval: 10 target: _socket selector: @selector( cancelAsyncRequests) repeats: false] retain]; - _state = AWAITING_PROLOG; + _state = stateAwaitingProlog; } @catch (id e) { [self release]; @throw e; } @@ -336,22 +322,22 @@ if (line == nil || exception != nil) return false; @try { switch (_state) { - case AWAITING_PROLOG: + case stateAwaitingProlog: return [self parseProlog: line]; - case PARSING_HEADERS: + case stateParsingHeaders: return [self parseHeaders: line]; default: return false; } } @catch (OFWriteFailedException *e) { return false; } - OF_ENSURE(0); + OFEnsure(0); } - (bool)parseProlog: (OFString *)line { OFString *method; @@ -358,12 +344,12 @@ OFMutableString *path; size_t pos; @try { OFString *version = [line - substringWithRange: of_range(line.length - 9, 9)]; - of_unichar_t tmp; + substringWithRange: OFRangeMake(line.length - 9, 9)]; + OFUnichar tmp; if (![version hasPrefix: @" HTTP/1."]) return [self sendErrorAndClose: 505]; tmp = [version characterAtIndex: 8]; @@ -374,22 +360,22 @@ } @catch (OFOutOfRangeException *e) { return [self sendErrorAndClose: 400]; } pos = [line rangeOfString: @" "].location; - if (pos == OF_NOT_FOUND) + if (pos == OFNotFound) return [self sendErrorAndClose: 400]; method = [line substringToIndex: pos]; @try { - _method = of_http_request_method_from_string(method); + _method = OFHTTPRequestMethodParseName(method); } @catch (OFInvalidArgumentException *e) { return [self sendErrorAndClose: 405]; } @try { - of_range_t range = of_range(pos + 1, line.length - pos - 10); + OFRange range = OFRangeMake(pos + 1, line.length - pos - 10); path = [[[line substringWithRange: range] mutableCopy] autorelease]; } @catch (OFOutOfRangeException *e) { return [self sendErrorAndClose: 400]; @@ -401,11 +387,11 @@ if (![path hasPrefix: @"/"]) return [self sendErrorAndClose: 400]; _headers = [[OFMutableDictionary alloc] init]; _path = [path copy]; - _state = PARSING_HEADERS; + _state = stateParsingHeaders; return true; } - (bool)parseHeaders: (OFString *)line @@ -443,18 +429,18 @@ [_timer invalidate]; [_timer release]; _timer = nil; } - _state = SEND_RESPONSE; + _state = stateSendResponse; [self createResponse]; return false; } pos = [line rangeOfString: @":"].location; - if (pos == OF_NOT_FOUND) + if (pos == OFNotFound) return [self sendErrorAndClose: 400]; key = [line substringToIndex: pos]; value = [line substringFromIndex: pos + 1]; @@ -463,19 +449,17 @@ old = [_headers objectForKey: key]; if (old != nil) value = [old stringByAppendingFormat: @",%@", value]; - [_headers setObject: value - forKey: key]; + [_headers setObject: value forKey: key]; if ([key isEqual: @"Host"]) { - pos = [value - rangeOfString: @":" - options: OF_STRING_SEARCH_BACKWARDS].location; + pos = [value rangeOfString: @":" + options: OFStringSearchBackwards].location; - if (pos != OF_NOT_FOUND) { + if (pos != OFNotFound) { [_host release]; _host = [[value substringToIndex: pos] retain]; @try { unsigned long long portTmp = @@ -501,19 +485,16 @@ - (bool)sendErrorAndClose: (short)statusCode { OFString *date = [[OFDate date] dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; - [_socket writeFormat: @"HTTP/1.1 %hd %@\r\n" @"Date: %@\r\n" @"Server: %@\r\n" @"\r\n", - statusCode, - of_http_status_code_to_string(statusCode), + statusCode, OFHTTPStatusCodeString(statusCode), date, _server.name]; - return false; } - (void)createResponse { @@ -542,11 +523,11 @@ URL.scheme = @"http"; URL.host = _host; if (_port != 80) URL.port = [OFNumber numberWithUnsignedShort: _port]; - if ((pos = [_path rangeOfString: @"?"].location) != OF_NOT_FOUND) { + if ((pos = [_path rangeOfString: @"?"].location) != OFNotFound) { OFString *path, *query; path = [_path substringToIndex: pos]; query = [_path substringFromIndex: pos + 1]; @@ -558,11 +539,11 @@ [URL makeImmutable]; request = [OFHTTPRequest requestWithURL: URL]; request.method = _method; request.protocolVersion = - (of_http_request_protocol_version_t){ 1, _HTTPMinorVersion }; + (OFHTTPRequestProtocolVersion){ 1, _HTTPMinorVersion }; request.headers = _headers; request.remoteAddress = _socket.remoteAddress; response = [[[OFHTTPServerResponse alloc] initWithSocket: _socket @@ -614,12 +595,11 @@ - (bool)lowlevelIsAtEndOfStream { return _atEndOfStream; } -- (size_t)lowlevelReadIntoBuffer: (void *)buffer - length: (size_t)length +- (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) @@ -633,12 +613,11 @@ size_t ret; if (length > (unsigned long long)_toRead) length = (size_t)_toRead; - ret = [_socket readIntoBuffer: buffer - length: length]; + ret = [_socket readIntoBuffer: buffer length: length]; _toRead -= ret; if (_toRead == 0) _atEndOfStream = true; @@ -648,12 +627,11 @@ /* Chunked */ if (_toRead == -2) { char tmp[2]; - switch ([_socket readIntoBuffer: tmp - length: 2]) { + switch ([_socket readIntoBuffer: tmp length: 2]) { case 2: _toRead++; if (tmp[1] != '\n') @throw [OFInvalidFormatException exception]; case 1: @@ -667,12 +645,11 @@ return 0; } else if (_toRead == -1) { char tmp; - if ([_socket readIntoBuffer: &tmp - length: 1] == 1) { + if ([_socket readIntoBuffer: &tmp length: 1] == 1) { _toRead++; if (tmp != '\n') @throw [OFInvalidFormatException exception]; } @@ -682,15 +659,13 @@ return 0; } else if (_toRead > 0) { if (length > (unsigned long long)_toRead) length = (size_t)_toRead; - length = [_socket readIntoBuffer: buffer - length: length]; + length = [_socket readIntoBuffer: buffer length: length]; _toRead -= length; - if (_toRead == 0) _toRead = -2; return length; } else { @@ -707,19 +682,19 @@ if (line == nil) return 0; pos = [line rangeOfString: @";"].location; - if (pos != OF_NOT_FOUND) + if (pos != OFNotFound) line = [line substringToIndex: pos]; if (line.length < 1) { /* * We have read the empty string because the socket is * at end of stream. */ - if (_socket.atEndOfStream && pos == OF_NOT_FOUND) + if (_socket.atEndOfStream && pos == OFNotFound) @throw [OFTruncatedDataException exception]; else @throw [OFInvalidFormatException exception]; } @@ -922,24 +897,23 @@ @throw [OFAlreadyConnectedException exception]; if (_usesTLS) { OFTCPSocket *TLSSocket; - if (of_tls_socket_class == Nil) + if (OFTLSSocketClass == Nil) @throw [OFUnsupportedProtocolException exception]; - TLSSocket = [[of_tls_socket_class alloc] init]; + TLSSocket = [[OFTLSSocketClass alloc] init]; _listeningSocket = TLSSocket; TLSSocket.certificateFile = _certificateFile; TLSSocket.privateKeyFile = _privateKeyFile; TLSSocket.privateKeyPassphrase = _privateKeyPassphrase; } else _listeningSocket = [[OFTCPSocket alloc] init]; - _port = [_listeningSocket bindToHost: _host - port: _port]; + _port = [_listeningSocket bindToHost: _host port: _port]; [_listeningSocket listen]; #ifdef OF_HAVE_THREADS if (_numberOfThreads > 1) { OFMutableArray *threads = @@ -997,11 +971,11 @@ if (exception != nil) { if (![_delegate respondsToSelector: @selector(server:didReceiveExceptionOnListeningSocket:)]) return false; - return [_delegate server: self + return [_delegate server: self didReceiveExceptionOnListeningSocket: exception]; } #ifdef OF_HAVE_THREADS if (_numberOfThreads > 1) {