@@ -1,7 +1,7 @@ /* - * Copyright (c) 2008-2021 Jonathan Schleifer + * Copyright (c) 2008-2022 Jonathan Schleifer * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in @@ -31,12 +31,16 @@ #endif #import "OFSandbox.h" #import "OFStdIOStream.h" #import "OFSystemInfo.h" #import "OFTCPSocket.h" -#import "OFTLSSocket.h" +#import "OFTLSStream.h" #import "OFURL.h" + +#ifdef HAVE_TLS_SUPPORT +# import "ObjFWTLS.h" +#endif #import "OFConnectionFailedException.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" @@ -75,10 +79,18 @@ ProgressBar *_progressBar; } - (void)downloadNextURL; @end + +#ifdef HAVE_TLS_SUPPORT +void +_reference_to_ObjFWTLS(void) +{ + _ObjFWTLS_reference = 1; +} +#endif OF_APPLICATION_DELEGATE(OFHTTP) static void help(OFStream *stream, bool full, int status) @@ -276,21 +288,10 @@ objc_autoreleasePoolPop(pool); return [fileName autorelease]; } @implementation OFHTTP -#ifdef OF_HAVE_PLUGINS -+ (void)initialize -{ - if (self != [OFHTTP class]) - return; - - /* Opportunistically try loading ObjOpenSSL and ignore any errors. */ - OFDLOpen(@LIB_PREFIX @"objopenssl" @LIB_SUFFIX, OFDLOpenFlagLazy); -} -#endif - - (instancetype)init { self = [super init]; @try { @@ -530,15 +531,15 @@ #ifdef OF_HAVE_SANDBOX if (outputPath != nil) [sandbox unveilPath: outputPath permissions: (_continue ? @"rwc" : @"wc")]; else - [sandbox unveilPath: [[OFFileManger defaultManager] + [sandbox unveilPath: [[OFFileManager defaultManager] currentDirectoryPath] permissions: (_continue ? @"rwc" : @"wc")]; - /* In case we use ObjOpenSSL for https later */ + /* In case we use OpenSSL for HTTPS later */ [sandbox unveilPath: @"/etc/ssl" permissions: @"r"]; sandbox.allowsUnveil = false; [OFApplication of_activateSandbox: sandbox]; #endif @@ -576,22 +577,25 @@ } if (_insecure) _HTTPClient.allowsInsecureRedirects = true; +#ifdef OF_WINDOWS + _useUnicode = [OFSystemInfo isWindowsNT]; +#else _useUnicode = ([OFLocale encoding] == OFStringEncodingUTF8); +#endif [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } -- (void)client: (OFHTTPClient *)client - didCreateSocket: (OFTCPSocket *)sock - request: (OFHTTPRequest *)request +- (void)client: (OFHTTPClient *)client + didCreateTLSStream: (OFTLSStream *)stream + request: (OFHTTPRequest *)request { - if (_insecure && [sock respondsToSelector: - @selector(setVerifiesCertificates:)]) - ((id )sock).verifiesCertificates = false; + /* Use setter instead of property access to work around GCC bug. */ + [stream setVerifiesCertificates: !_insecure]; } - (void)client: (OFHTTPClient *)client wantsRequestBody: (OFStream *)body request: (OFHTTPRequest *)request @@ -843,15 +847,16 @@ } else if ([exception isKindOfClass: [OFUnsupportedProtocolException class]]) { if (!_quiet) [OFStdOut writeString: @"\n"]; - [OFStdErr writeLine: OF_LOCALIZED(@"no_ssl_library", - @"%[prog]: No TLS library loaded!\n" - @" In order to download via https, you need to " - @"preload an TLS library for ObjFW\n" - @" such as ObjOpenSSL!", + [OFStdErr writeLine: OF_LOCALIZED(@"no_tls_support", + @"%[prog]: No TLS support in ObjFW!\n" + @" In order to download via HTTPS, you need to " + @"either build ObjFW with TLS\n" + @" support or preload a library adding TLS " + @"support to ObjFW!", @"prog", [OFApplication programName])]; } else if ([exception isKindOfClass: [OFReadOrWriteFailedException class]]) { OFString *error = OF_LOCALIZED( @"download_failed_read_or_write_failed_any",