mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	externals: update httplib and libressl ...
* In older `httplib`, SSL connections were not handled correctly and will have issues with proxy servers. Also, keep alive directives were not available back then, which is probably necessary to implement HTTP_C service correctly. * Another reason being `httplib` now requires OpenSSL 1.1+ API while LibreSSL 2.x provided OpenSSL 1.0 compatible API. * The bundled LibreSSL has been updated to 3.2.2 so it now provides OpenSSL 1.1 compatible API now. * Also the path hint has been added so that it will find the correct path to the CA certs on *nix systems. * An option is provided so that *nix system distributions/providers can use their own SSL implementations when compiling Yuzu/Citra to (hopefully) complies with their maintenance guidelines. * LURLParse is also removed since `httplib` can handle `scheme:host:port` string itself now.
This commit is contained in:
		
							parent
							
								
									45a4a56264
								
							
						
					
					
						commit
						af24f75c18
					
				
					 12 changed files with 4436 additions and 2124 deletions
				
			
		|  | @ -476,12 +476,8 @@ target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core) | |||
| target_link_libraries(core PUBLIC Boost::boost PRIVATE cryptopp fmt open_source_archives Boost::serialization) | ||||
| 
 | ||||
| if (ENABLE_WEB_SERVICE) | ||||
|     get_directory_property(OPENSSL_LIBS | ||||
|         DIRECTORY ${PROJECT_SOURCE_DIR}/externals/libressl | ||||
|         DEFINITION OPENSSL_LIBS) | ||||
| 
 | ||||
|     target_compile_definitions(core PRIVATE -DENABLE_WEB_SERVICE -DCPPHTTPLIB_OPENSSL_SUPPORT) | ||||
|     target_link_libraries(core PRIVATE web_service ${OPENSSL_LIBS} httplib lurlparser) | ||||
|     target_link_libraries(core PRIVATE web_service ${OPENSSL_LIBS} httplib) | ||||
|     if (ANDROID) | ||||
|         target_link_libraries(core PRIVATE ifaddrs) | ||||
|     endif() | ||||
|  |  | |||
|  | @ -3,9 +3,6 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <atomic> | ||||
| #ifdef ENABLE_WEB_SERVICE | ||||
| #include <LUrlParser.h> | ||||
| #endif | ||||
| #include <cryptopp/aes.h> | ||||
| #include <cryptopp/modes.h> | ||||
| #include "common/archives.h" | ||||
|  | @ -61,27 +58,9 @@ void Context::MakeRequest() { | |||
|     ASSERT(state == RequestState::NotStarted); | ||||
| 
 | ||||
| #ifdef ENABLE_WEB_SERVICE | ||||
|     LUrlParser::clParseURL parsedUrl = LUrlParser::clParseURL::ParseURL(url); | ||||
|     int port; | ||||
|     std::unique_ptr<httplib::Client> client; | ||||
|     if (parsedUrl.m_Scheme == "http") { | ||||
|         if (!parsedUrl.GetPort(&port)) { | ||||
|             port = 80; | ||||
|         } | ||||
|         // TODO(B3N30): Support for setting timeout
 | ||||
|         // Figure out what the default timeout on 3DS is
 | ||||
|         client = std::make_unique<httplib::Client>(parsedUrl.m_Host.c_str(), port); | ||||
|     } else { | ||||
|         if (!parsedUrl.GetPort(&port)) { | ||||
|             port = 443; | ||||
|         } | ||||
|         // TODO(B3N30): Support for setting timeout
 | ||||
|         // Figure out what the default timeout on 3DS is
 | ||||
| 
 | ||||
|         auto ssl_client = std::make_unique<httplib::SSLClient>(parsedUrl.m_Host, port); | ||||
|         SSL_CTX* ctx = ssl_client->ssl_context(); | ||||
|         client = std::move(ssl_client); | ||||
| 
 | ||||
|     std::unique_ptr<httplib::Client> client = std::make_unique<httplib::Client>(url.c_str()); | ||||
|     SSL_CTX* ctx = client->ssl_context(); | ||||
|     if (ctx) { | ||||
|         if (auto client_cert = ssl_config.client_cert_ctx.lock()) { | ||||
|             SSL_CTX_use_certificate_ASN1(ctx, static_cast<int>(client_cert->certificate.size()), | ||||
|                                          client_cert->certificate.data()); | ||||
|  | @ -105,6 +84,7 @@ void Context::MakeRequest() { | |||
|     }; | ||||
| 
 | ||||
|     httplib::Request request; | ||||
|     httplib::Error error; | ||||
|     request.method = request_method_strings.at(method); | ||||
|     request.path = url; | ||||
|     // TODO(B3N30): Add post data body
 | ||||
|  | @ -119,8 +99,8 @@ void Context::MakeRequest() { | |||
|         request.headers.emplace(header.name, header.value); | ||||
|     } | ||||
| 
 | ||||
|     if (!client->send(request, response)) { | ||||
|         LOG_ERROR(Service_HTTP, "Request failed"); | ||||
|     if (!client->send(request, response, error)) { | ||||
|         LOG_ERROR(Service_HTTP, "Request failed: {}", error); | ||||
|         state = RequestState::TimedOut; | ||||
|     } else { | ||||
|         LOG_DEBUG(Service_HTTP, "Request successful"); | ||||
|  |  | |||
|  | @ -13,11 +13,10 @@ add_library(web_service STATIC | |||
| 
 | ||||
| create_target_directory_groups(web_service) | ||||
| 
 | ||||
| get_directory_property(OPENSSL_LIBS | ||||
|         DIRECTORY ${PROJECT_SOURCE_DIR}/externals/libressl | ||||
|         DEFINITION OPENSSL_LIBS) | ||||
| target_compile_definitions(web_service PRIVATE -DCPPHTTPLIB_OPENSSL_SUPPORT) | ||||
| target_link_libraries(web_service PRIVATE common network json-headers ${OPENSSL_LIBS} httplib lurlparser cpp-jwt) | ||||
| target_link_libraries(web_service PRIVATE common network json-headers ${OPENSSL_LIBS} httplib cpp-jwt) | ||||
| if (ANDROID) | ||||
|     target_link_libraries(web_service PRIVATE ifaddrs) | ||||
| elseif(WIN32) | ||||
|     target_link_libraries(web_service PRIVATE crypt32) | ||||
| endif() | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ | |||
| #include <cstdlib> | ||||
| #include <mutex> | ||||
| #include <string> | ||||
| #include <LUrlParser.h> | ||||
| #include <fmt/format.h> | ||||
| #if defined(__ANDROID__) | ||||
| #include <ifaddrs.h> | ||||
|  | @ -21,9 +20,6 @@ namespace WebService { | |||
| 
 | ||||
| constexpr std::array<const char, 1> API_VERSION{'1'}; | ||||
| 
 | ||||
| constexpr int HTTP_PORT = 80; | ||||
| constexpr int HTTPS_PORT = 443; | ||||
| 
 | ||||
| constexpr std::size_t TIMEOUT_SECONDS = 30; | ||||
| 
 | ||||
| struct Client::Impl { | ||||
|  | @ -33,6 +29,10 @@ struct Client::Impl { | |||
|         if (this->username == jwt_cache.username && this->token == jwt_cache.token) { | ||||
|             jwt = jwt_cache.jwt; | ||||
|         } | ||||
|         // normalize host expression
 | ||||
|         if (this->host.back() == '/') { | ||||
|             static_cast<void>(this->host.pop_back()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// A generic function handles POST, GET and DELETE request together
 | ||||
|  | @ -70,29 +70,16 @@ struct Client::Impl { | |||
|                                      const std::string& jwt = "", const std::string& username = "", | ||||
|                                      const std::string& token = "") { | ||||
|         if (cli == nullptr) { | ||||
|             auto parsedUrl = LUrlParser::clParseURL::ParseURL(host); | ||||
|             int port; | ||||
|             if (parsedUrl.m_Scheme == "http") { | ||||
|                 if (!parsedUrl.GetPort(&port)) { | ||||
|                     port = HTTP_PORT; | ||||
|                 } | ||||
|                 cli = std::make_unique<httplib::Client>(parsedUrl.m_Host.c_str(), port); | ||||
|                 cli->set_timeout_sec(TIMEOUT_SECONDS); | ||||
|             } else if (parsedUrl.m_Scheme == "https") { | ||||
|                 if (!parsedUrl.GetPort(&port)) { | ||||
|                     port = HTTPS_PORT; | ||||
|                 } | ||||
|                 cli = std::make_unique<httplib::SSLClient>(parsedUrl.m_Host.c_str(), port); | ||||
|                 cli->set_timeout_sec(TIMEOUT_SECONDS); | ||||
|             } else { | ||||
|                 LOG_ERROR(WebService, "Bad URL scheme {}", parsedUrl.m_Scheme); | ||||
|                 return Common::WebResult{Common::WebResult::Code::InvalidURL, "Bad URL scheme"}; | ||||
|             } | ||||
|             cli = std::make_unique<httplib::Client>(host.c_str()); | ||||
|             cli->set_connection_timeout(TIMEOUT_SECONDS); | ||||
|             cli->set_read_timeout(TIMEOUT_SECONDS); | ||||
|             cli->set_write_timeout(TIMEOUT_SECONDS); | ||||
|         } | ||||
|         if (cli == nullptr) { | ||||
|         if (!cli->is_valid()) { | ||||
|             LOG_ERROR(WebService, "Invalid URL {}", host + path); | ||||
|             return Common::WebResult{Common::WebResult::Code::InvalidURL, "Invalid URL"}; | ||||
|         } | ||||
|         LOG_ERROR(WebService, "{}", host); | ||||
| 
 | ||||
|         httplib::Headers params; | ||||
|         if (!jwt.empty()) { | ||||
|  | @ -118,13 +105,15 @@ struct Client::Impl { | |||
|         request.headers = params; | ||||
|         request.body = data; | ||||
| 
 | ||||
|         httplib::Response response; | ||||
|         httplib::Result result = cli->send(request); | ||||
| 
 | ||||
|         if (!cli->send(request, response)) { | ||||
|         if (!result) { | ||||
|             LOG_ERROR(WebService, "{} to {} returned null", method, host + path); | ||||
|             return Common::WebResult{Common::WebResult::Code::LibError, "Null response"}; | ||||
|         } | ||||
| 
 | ||||
|         httplib::Response response = result.value(); | ||||
| 
 | ||||
|         if (response.status >= 400) { | ||||
|             LOG_ERROR(WebService, "{} to {} returned error status code: {}", method, host + path, | ||||
|                       response.status); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue