@@ -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,11 +179,11 @@ 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] @@ -296,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; } @@ -330,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; @@ -352,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]; @@ -368,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]; @@ -395,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 @@ -437,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]; @@ -460,15 +452,14 @@ value = [old stringByAppendingFormat: @",%@", value]; [_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 = @@ -498,12 +489,11 @@ 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 @@ -533,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]; @@ -549,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 @@ -692,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]; } @@ -907,14 +897,14 @@ @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;