@@ -26,10 +26,11 @@ #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" #import "OFKernelEventObserver.h" #import "OFNumber.h" #import "OFRunLoop.h" +#import "OFSocket+Private.h" #import "OFString.h" #import "OFTCPSocket.h" #import "OFURL.h" #import "OFAlreadyConnectedException.h" @@ -45,13 +46,11 @@ #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" #import "OFUnsupportedVersionException.h" #import "OFWriteFailedException.h" -#import "socket_helpers.h" - -#define REDIRECTS_DEFAULT 10 +static const unsigned int defaultRedirects = 10; OF_DIRECT_MEMBERS @interface OFHTTPClientRequestHandler: OFObject { @public @@ -114,11 +113,11 @@ static OFString * constructRequestString(OFHTTPRequest *request) { void *pool = objc_autoreleasePoolPush(); - of_http_request_method_t method = request.method; + OFHTTPRequestMethod method = request.method; OFURL *URL = request.URL; OFString *path; OFString *user = URL.user, *password = URL.password; OFMutableString *requestString; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; @@ -130,11 +129,11 @@ path = URL.URLEncodedPath; else path = @"/"; requestString = [OFMutableString stringWithFormat: - @"%s %@", of_http_request_method_to_string(method), path]; + @"%s %@", OFHTTPRequestMethodName(method), path]; if (URL.query != nil) { [requestString appendString: @"?"]; [requestString appendString: URL.URLEncodedQuery]; } @@ -152,15 +151,13 @@ if (port != nil) { OFString *host = [OFString stringWithFormat: @"%@:%@", URL.URLEncodedHost, port]; - [headers setObject: host - forKey: @"Host"]; + [headers setObject: host forKey: @"Host"]; } else - [headers setObject: [URL URLEncodedHost] - forKey: @"Host"]; + [headers setObject: URL.URLEncodedHost forKey: @"Host"]; } if ((user.length > 0 || password.length > 0) && [headers objectForKey: @"Authorization"] == nil) { OFMutableData *authorizationData = [OFMutableData data]; @@ -173,12 +170,11 @@ count: password.UTF8StringLength]; authorization = [OFString stringWithFormat: @"Basic %@", authorizationData.stringByBase64Encoding]; - [headers setObject: authorization - forKey: @"Authorization"]; + [headers setObject: authorization forKey: @"Authorization"]; } if ([headers objectForKey: @"User-Agent"] == nil) [headers setObject: @"Something using ObjFW " @"" @@ -185,12 +181,11 @@ forKey: @"User-Agent"]; if (request.protocolVersion.major == 1 && request.protocolVersion.minor == 0 && [headers objectForKey: @"Connection"] == nil) - [headers setObject: @"keep-alive" - forKey: @"Connection"]; + [headers setObject: @"keep-alive" forKey: @"Connection"]; hasContentLength = ([headers objectForKey: @"Content-Length"] != nil); chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; @@ -221,37 +216,36 @@ { unsigned char *str = (unsigned char *)str_; bool firstLetter = true; while (*str != '\0') { - if (!of_ascii_isalpha(*str)) { + if (!OFASCIIIsAlpha(*str)) { firstLetter = true; str++; continue; } *str = (firstLetter - ? of_ascii_toupper(*str) - : of_ascii_tolower(*str)); + ? OFASCIIToUpper(*str) : OFASCIIToLower(*str)); firstLetter = false; str++; } } static bool -defaultShouldFollow(of_http_request_method_t method, short statusCode) +defaultShouldFollow(OFHTTPRequestMethod method, short statusCode) { bool follow; /* * 301, 302 and 307 should only redirect with user confirmation if the * request method is not GET or HEAD. Asking the delegate and getting * true returned is considered user confirmation. */ - if (method == OF_HTTP_REQUEST_METHOD_GET || - method == OF_HTTP_REQUEST_METHOD_HEAD) + if (method == OFHTTPRequestMethodGet || + method == OFHTTPRequestMethodHead) follow = true; /* 303 should always be redirected and converted to a GET request. */ else if (statusCode == 303) follow = true; else @@ -323,11 +317,11 @@ else keepAlive = true; } else { if (connectionHeader != nil) keepAlive = ([connectionHeader caseInsensitiveCompare: - @"keep-alive"] == OF_ORDERED_SAME); + @"keep-alive"] == OFOrderedSame); else keepAlive = false; } if (keepAlive) { @@ -334,11 +328,11 @@ response.of_keepAlive = true; _client->_socket = [sock retain]; _client->_lastURL = [URL copy]; _client->_lastWasHEAD = - (_request.method == OF_HTTP_REQUEST_METHOD_HEAD); + (_request.method == OFHTTPRequestMethodHead); _client->_lastResponse = [response retain]; } if (_redirects > 0 && (_status == 301 || _status == 302 || _status == 303 || _status == 307) && @@ -350,20 +344,20 @@ newURL = [OFURL URLWithString: location relativeToURL: URL]; newURLScheme = newURL.scheme; if ([newURLScheme caseInsensitiveCompare: @"http"] != - OF_ORDERED_SAME && + OFOrderedSame && [newURLScheme caseInsensitiveCompare: @"https"] != - OF_ORDERED_SAME) + OFOrderedSame) follow = false; if (!_client->_allowsInsecureRedirects && [URL.scheme caseInsensitiveCompare: @"https"] == - OF_ORDERED_SAME && + OFOrderedSame && [newURLScheme caseInsensitiveCompare: @"http"] == - OF_ORDERED_SAME) + OFOrderedSame) follow = false; if (follow && [_client->_delegate respondsToSelector: @selector( client:shouldFollowRedirect:statusCode:request:response:)]) follow = [_client->_delegate client: _client @@ -403,11 +397,11 @@ if ([key hasPrefix: @"Content-"] || [key hasPrefix: @"Transfer-"]) [newHeaders removeObjectForKey: key]; - newRequest.method = OF_HTTP_REQUEST_METHOD_GET; + newRequest.method = OFHTTPRequestMethodGet; } newRequest.URL = newURL; newRequest.headers = newHeaders; @@ -462,27 +456,26 @@ if (![line hasPrefix: @"HTTP/"] || line.length < 9 || [line characterAtIndex: 8] != ' ') @throw [OFInvalidServerReplyException exception]; - _version = [[line substringWithRange: of_range(5, 3)] copy]; + _version = [[line substringWithRange: OFRangeMake(5, 3)] copy]; if (![_version isEqual: @"1.0"] && ![_version isEqual: @"1.1"]) @throw [OFUnsupportedVersionException exceptionWithVersion: _version]; - status = [line substringWithRange: of_range(9, 3)].longLongValue; + status = [line substringWithRange: OFRangeMake(9, 3)].longLongValue; if (status < 0 || status > 599) @throw [OFInvalidServerReplyException exception]; _status = (short)status; return true; } -- (bool)handleServerHeader: (OFString *)line - socket: (OFTCPSocket *)sock +- (bool)handleServerHeader: (OFString *)line socket: (OFTCPSocket *)sock { OFString *key, *value, *old; const char *lineC, *tmp; char *keyC; @@ -511,20 +504,20 @@ lineC = line.UTF8String; if ((tmp = strchr(lineC, ':')) == NULL) @throw [OFInvalidServerReplyException exception]; - keyC = of_alloc(tmp - lineC + 1, 1); + keyC = OFAllocMemory(tmp - lineC + 1, 1); memcpy(keyC, lineC, tmp - lineC); keyC[tmp - lineC] = '\0'; normalizeKey(keyC); @try { key = [OFString stringWithUTF8StringNoCopy: keyC freeWhenDone: true]; } @catch (id e) { - free(keyC); + OFFreeMemory(keyC); @throw e; } do { tmp++; @@ -534,12 +527,11 @@ old = [_serverHeaders objectForKey: key]; if (old != nil) value = [old stringByAppendingFormat: @",%@", value]; - [_serverHeaders setObject: value - forKey: key]; + [_serverHeaders setObject: value forKey: key]; return true; } - (bool)stream: (OFStream *)sock @@ -572,11 +564,11 @@ return ret; } - (OFString *)stream: (OFStream *)stream didWriteString: (OFString *)string - encoding: (of_string_encoding_t)encoding + encoding: (OFStringEncoding)encoding bytesWritten: (size_t)bytesWritten exception: (id)exception { OFDictionary OF_GENERIC(OFString *, OFString *) *headers; bool chunked; @@ -704,16 +696,16 @@ OFNumber *URLPort; [_client close]; if ([URL.scheme caseInsensitiveCompare: @"https"] == - OF_ORDERED_SAME) { - if (of_tls_socket_class == Nil) + OFOrderedSame) { + if (OFTLSSocketClass == Nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; - sock = [[[of_tls_socket_class alloc] init] autorelease]; + sock = [[[OFTLSSocketClass alloc] init] autorelease]; port = 443; } else { sock = [OFTCPSocket socket]; port = 80; } @@ -721,12 +713,11 @@ URLPort = URL.port; if (URLPort != nil) port = URLPort.unsignedShortValue; sock.delegate = self; - [sock asyncConnectToHost: URL.host - port: port]; + [sock asyncConnectToHost: URL.host port: port]; } @catch (id e) { [self raiseException: e]; } } @end @@ -803,12 +794,11 @@ if (_chunked) [_socket writeFormat: @"%zX\r\n", length]; else if (length > _toWrite) length = (size_t)_toWrite; - ret = [_socket writeBuffer: buffer - length: length]; + ret = [_socket writeBuffer: buffer length: length]; if (_chunked) [_socket writeString: @"\r\n"]; if (ret > length) @throw [OFOutOfRangeException exception]; @@ -908,22 +898,20 @@ @throw [OFInvalidServerReplyException exception]; } } } -- (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) return 0; if (!_hasContentLength && !_chunked) - return [_socket readIntoBuffer: buffer - length: length]; + return [_socket readIntoBuffer: buffer length: length]; if (_socket.atEndOfStream) @throw [OFTruncatedDataException exception]; /* Content-Length */ @@ -931,13 +919,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]; if (ret > length) @throw [OFOutOfRangeException exception]; _toRead -= ret; @@ -949,12 +935,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 [OFInvalidServerReplyException exception]; @@ -970,12 +955,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 [OFInvalidServerReplyException exception]; } @@ -986,15 +970,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 { @@ -1010,19 +992,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 [OFInvalidServerReplyException exception]; } @@ -1118,15 +1100,12 @@ } - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { - [_client asyncPerformRequest: request - redirects: redirects]; - + [_client asyncPerformRequest: request redirects: redirects]; [[OFRunLoop currentRunLoop] run]; - return _response; } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request @@ -1224,12 +1203,11 @@ [super dealloc]; } - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request { - return [self performRequest: request - redirects: REDIRECTS_DEFAULT]; + return [self performRequest: request redirects: defaultRedirects]; } - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { @@ -1247,23 +1225,22 @@ return [response autorelease]; } - (void)asyncPerformRequest: (OFHTTPRequest *)request { - [self asyncPerformRequest: request - redirects: REDIRECTS_DEFAULT]; + [self asyncPerformRequest: request redirects: defaultRedirects]; } - (void)asyncPerformRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { void *pool = objc_autoreleasePoolPush(); OFURL *URL = request.URL; OFString *scheme = URL.scheme; - if ([scheme caseInsensitiveCompare: @"http"] != OF_ORDERED_SAME && - [scheme caseInsensitiveCompare: @"https"] != OF_ORDERED_SAME) + if ([scheme caseInsensitiveCompare: @"http"] != OFOrderedSame && + [scheme caseInsensitiveCompare: @"https"] != OFOrderedSame) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; if (_inProgress) /* TODO: Find a better exception */ @throw [OFAlreadyConnectedException exception];