From 51f2afdda6e408bc014357463f036bcea7f75997 Mon Sep 17 00:00:00 2001 From: Satakarni Amirneni Date: Wed, 14 Sep 2022 15:20:48 +0530 Subject: [PATCH 1/9] fix leaks --- lib/http/HttpClient_Apple.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/http/HttpClient_Apple.mm b/lib/http/HttpClient_Apple.mm index e1127c773..837847766 100644 --- a/lib/http/HttpClient_Apple.mm +++ b/lib/http/HttpClient_Apple.mm @@ -29,6 +29,8 @@ return std::string("RESP-") + std::to_string(seq.fetch_add(1)); } +static NSURLSession* m_session = nil; + class HttpRequestApple : public SimpleHttpRequest { public: @@ -50,9 +52,11 @@ void SendAsync(IHttpResponseCallback* callback) { m_callback = callback; NSString* url = [[NSString alloc] initWithUTF8String:m_url.c_str()]; - NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; m_urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; - m_session = [NSURLSession sessionWithConfiguration:sessionConfig]; + if(m_session == nil) { + NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + m_session = [NSURLSession sessionWithConfiguration:sessionConfig]; + } m_session.sessionDescription = url; for(const auto& header : m_headers) @@ -150,7 +154,6 @@ void Cancel() private: HttpClient_Apple* m_parent = nullptr; IHttpResponseCallback* m_callback = nullptr; - NSURLSession* m_session = nullptr; NSURLSessionDataTask* m_dataTask = nullptr; NSMutableURLRequest* m_urlRequest = nullptr; void (^m_completionMethod)(NSData* data, NSURLResponse* response, NSError* error); From 55e631322a8a4037d7237367ec76d01efc7e49d8 Mon Sep 17 00:00:00 2001 From: Satakarni Amirneni Date: Thu, 15 Sep 2022 12:30:34 +0530 Subject: [PATCH 2/9] initialising session in constructor --- lib/http/HttpClient_Apple.mm | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/http/HttpClient_Apple.mm b/lib/http/HttpClient_Apple.mm index 837847766..a17ca6afb 100644 --- a/lib/http/HttpClient_Apple.mm +++ b/lib/http/HttpClient_Apple.mm @@ -39,6 +39,10 @@ m_parent(parent) { m_parent->Add(static_cast(this)); + if(m_session == nil) { + NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + m_session = [NSURLSession sessionWithConfiguration:sessionConfig]; + } } ~HttpRequestApple() noexcept @@ -53,11 +57,6 @@ void SendAsync(IHttpResponseCallback* callback) m_callback = callback; NSString* url = [[NSString alloc] initWithUTF8String:m_url.c_str()]; m_urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; - if(m_session == nil) { - NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; - m_session = [NSURLSession sessionWithConfiguration:sessionConfig]; - } - m_session.sessionDescription = url; for(const auto& header : m_headers) { From 9d75370cb0f859b4ff55c36fa763b025bbd20a57 Mon Sep 17 00:00:00 2001 From: Satakarni Amirneni Date: Mon, 19 Sep 2022 09:51:58 +0530 Subject: [PATCH 3/9] using dispatch once --- lib/http/HttpClient_Apple.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/http/HttpClient_Apple.mm b/lib/http/HttpClient_Apple.mm index a17ca6afb..726ce7ee2 100644 --- a/lib/http/HttpClient_Apple.mm +++ b/lib/http/HttpClient_Apple.mm @@ -29,6 +29,7 @@ return std::string("RESP-") + std::to_string(seq.fetch_add(1)); } +static dispatch_once_t once; static NSURLSession* m_session = nil; class HttpRequestApple : public SimpleHttpRequest @@ -39,10 +40,10 @@ m_parent(parent) { m_parent->Add(static_cast(this)); - if(m_session == nil) { + dispatch_once(&once, ^{ NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; m_session = [NSURLSession sessionWithConfiguration:sessionConfig]; - } + }); } ~HttpRequestApple() noexcept From aeea76ba6533fa21ac49bcc9fdc6121ea4645fc8 Mon Sep 17 00:00:00 2001 From: Satakarni Amirneni Date: Tue, 11 Oct 2022 14:18:01 +0530 Subject: [PATCH 4/9] address comments --- lib/http/HttpClient_Apple.hpp | 2 - lib/http/HttpClient_Apple.mm | 144 +------------------------------ lib/http/HttpRequestApple.hpp | 34 ++++++++ lib/http/HttpRequestApple.mm | 154 ++++++++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+), 145 deletions(-) create mode 100644 lib/http/HttpRequestApple.hpp create mode 100644 lib/http/HttpRequestApple.mm diff --git a/lib/http/HttpClient_Apple.hpp b/lib/http/HttpClient_Apple.hpp index 7dde1642d..e9b22b1f0 100644 --- a/lib/http/HttpClient_Apple.hpp +++ b/lib/http/HttpClient_Apple.hpp @@ -34,5 +34,3 @@ namespace MAT_NS_BEGIN { } MAT_NS_END #endif // HTTPCLIENT_APPLE_HPP - - diff --git a/lib/http/HttpClient_Apple.mm b/lib/http/HttpClient_Apple.mm index 726ce7ee2..fd7334ff9 100644 --- a/lib/http/HttpClient_Apple.mm +++ b/lib/http/HttpClient_Apple.mm @@ -12,153 +12,12 @@ #import #include "HttpClient_Apple.hpp" +#include "HttpRequestApple.hpp" #include "utils/StringUtils.hpp" #include "utils/Utils.hpp" namespace MAT_NS_BEGIN { -static std::string NextReqId() -{ - static std::atomic seq; - return std::string("REQ-") + std::to_string(seq.fetch_add(1)); -} - -static std::string NextRespId() -{ - static std::atomic seq; - return std::string("RESP-") + std::to_string(seq.fetch_add(1)); -} - -static dispatch_once_t once; -static NSURLSession* m_session = nil; - -class HttpRequestApple : public SimpleHttpRequest -{ -public: - HttpRequestApple(HttpClient_Apple* parent) : - SimpleHttpRequest(NextReqId()), - m_parent(parent) - { - m_parent->Add(static_cast(this)); - dispatch_once(&once, ^{ - NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; - m_session = [NSURLSession sessionWithConfiguration:sessionConfig]; - }); - } - - ~HttpRequestApple() noexcept - { - m_parent->Erase(static_cast(this)); - } - - void SendAsync(IHttpResponseCallback* callback) - { - @autoreleasepool - { - m_callback = callback; - NSString* url = [[NSString alloc] initWithUTF8String:m_url.c_str()]; - m_urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; - - for(const auto& header : m_headers) - { - NSString* name = [[NSString alloc] initWithUTF8String:header.first.c_str()]; - NSString* value = [[NSString alloc] initWithUTF8String:header.second.c_str()]; - [m_urlRequest setValue:value forHTTPHeaderField:name]; - } - - m_completionMethod = - ^(NSData *data, NSURLResponse *response, NSError *error) - { - HandleResponse(data, response, error); - }; - - if(equalsIgnoreCase(m_method, "get")) - { - [m_urlRequest setHTTPMethod:@"GET"]; - m_dataTask = [m_session dataTaskWithRequest:m_urlRequest completionHandler:m_completionMethod]; - } - else - { - [m_urlRequest setHTTPMethod:@"POST"]; - NSData* postData = [NSData dataWithBytes:m_body.data() length:m_body.size()]; - m_dataTask = [m_session uploadTaskWithRequest:m_urlRequest fromData:postData completionHandler:m_completionMethod]; - } - - [m_dataTask resume]; - } - } - - void HandleResponse(NSData* data, NSURLResponse* response, NSError* error) - { - @autoreleasepool - { - NSHTTPURLResponse *httpResp = static_cast(response); - auto simpleResponse = new SimpleHttpResponse { NextRespId() }; - - simpleResponse->m_statusCode = httpResp.statusCode; - - NSDictionary *responseHeaders = [httpResp allHeaderFields]; - for (id key in responseHeaders) - { - simpleResponse->m_headers.add([key UTF8String], [responseHeaders[key] UTF8String]); - } - - if (error) - { - NSString* errorDomain = [error domain]; - long errorCode = [error code]; - - if ([errorDomain isEqualToString:@"NSURLErrorDomain"] && (errorCode == NSURLErrorCancelled)) - { - simpleResponse->m_result = HttpResult_Aborted; - } - else - { - LOG_TRACE("HTTP response error code: %li", errorCode); - simpleResponse->m_result = HttpResult_NetworkFailure; - } - } - else - { - simpleResponse->m_result = HttpResult_OK; - auto body = static_cast([data bytes]); - simpleResponse->m_body.reserve(data.length); - std::copy(body, body + data.length, std::back_inserter(simpleResponse->m_body)); - } - m_callback->OnHttpResponse(simpleResponse); - } - } - - void Cancel() - { - [m_dataTask cancel]; - [m_session getTasksWithCompletionHandler:^(NSArray* dataTasks, NSArray* uploadTasks, NSArray* downloadTasks) - { - for (NSURLSessionTask* _task in dataTasks) - { - [_task cancel]; - } - - for (NSURLSessionTask* _task in downloadTasks) - { - [_task cancel]; - } - - for (NSURLSessionTask* _task in uploadTasks) - { - [_task cancel]; - } - }]; - } - -private: - HttpClient_Apple* m_parent = nullptr; - IHttpResponseCallback* m_callback = nullptr; - NSURLSessionDataTask* m_dataTask = nullptr; - NSMutableURLRequest* m_urlRequest = nullptr; - void (^m_completionMethod)(NSData* data, NSURLResponse* response, NSError* error); -}; - HttpClient_Apple::HttpClient_Apple() { LOG_TRACE("Initializing HttpClient_Apple..."); @@ -236,4 +95,3 @@ void Cancel() } MAT_NS_END #endif - diff --git a/lib/http/HttpRequestApple.hpp b/lib/http/HttpRequestApple.hpp new file mode 100644 index 000000000..60252c587 --- /dev/null +++ b/lib/http/HttpRequestApple.hpp @@ -0,0 +1,34 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 +// +#ifndef HTTPREQUESTAPPLE_H +#define HTTPREQUESTAPPLE_H + +#import + +#include "IHttpClient.hpp" +#include "HttpClient_Apple.hpp" + +namespace MAT_NS_BEGIN { + + class HttpRequestApple : public SimpleHttpRequest { + public: + HttpRequestApple(HttpClient_Apple* parent); + ~HttpRequestApple() noexcept; + + void SendAsync(IHttpResponseCallback* callback); + void HandleResponse(NSData* data, NSURLResponse* response, NSError* error); + void Cancel(); + + private: + HttpClient_Apple* m_parent = nullptr; + IHttpResponseCallback* m_callback = nullptr; + NSURLSessionDataTask* m_dataTask = nullptr; + NSMutableURLRequest* m_urlRequest = nullptr; + void (^m_completionMethod)(NSData* data, NSURLResponse* response, NSError* error); + }; + +} MAT_NS_END + +#endif // HTTPREQUESTAPPLE_H diff --git a/lib/http/HttpRequestApple.mm b/lib/http/HttpRequestApple.mm new file mode 100644 index 000000000..85f9f22e9 --- /dev/null +++ b/lib/http/HttpRequestApple.mm @@ -0,0 +1,154 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 +// +#include "mat/config.h" + +// Assume that if we are compiling with MSVC, then we prefer to use Windows HTTP stack, +// e.g. WinInet.dll or Win 10 HTTP client instead +#if defined(MATSDK_PAL_CPP11) && !defined(_MSC_VER) && defined(HAVE_MAT_DEFAULT_HTTP_CLIENT) + +#import +#import + +#include "HttpClient_Apple.hpp" +#include "HttpRequestApple.hpp" +#include "utils/StringUtils.hpp" +#include "utils/Utils.hpp" + +namespace MAT_NS_BEGIN { + +static dispatch_once_t once; +static NSURLSession* m_session; + +static std::string NextReqId() +{ + static std::atomic seq; + return std::string("REQ-") + std::to_string(seq.fetch_add(1)); +} + +static std::string NextRespId() +{ + static std::atomic seq; + return std::string("RESP-") + std::to_string(seq.fetch_add(1)); +} + +HttpRequestApple::HttpRequestApple(HttpClient_Apple* parent) : + SimpleHttpRequest(NextReqId()), + m_parent(parent) +{ + m_parent->Add(static_cast(this)); + dispatch_once(&once, ^{ + NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + m_session = [NSURLSession sessionWithConfiguration:sessionConfig]; + }); +} + +HttpRequestApple::~HttpRequestApple() noexcept +{ + m_parent->Erase(static_cast(this)); +} + +void HttpRequestApple::SendAsync(IHttpResponseCallback* callback) +{ + @autoreleasepool + { + m_callback = callback; + NSString* url = [[NSString alloc] initWithUTF8String:m_url.c_str()]; + m_urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; + + for(const auto& header : m_headers) + { + NSString* name = [[NSString alloc] initWithUTF8String:header.first.c_str()]; + NSString* value = [[NSString alloc] initWithUTF8String:header.second.c_str()]; + [m_urlRequest setValue:value forHTTPHeaderField:name]; + } + + m_completionMethod = + ^(NSData *data, NSURLResponse *response, NSError *error) + { + HandleResponse(data, response, error); + }; + + if(equalsIgnoreCase(m_method, "get")) + { + [m_urlRequest setHTTPMethod:@"GET"]; + m_dataTask = [m_session dataTaskWithRequest:m_urlRequest completionHandler:m_completionMethod]; + } + else + { + [m_urlRequest setHTTPMethod:@"POST"]; + NSData* postData = [NSData dataWithBytes:m_body.data() length:m_body.size()]; + m_dataTask = [m_session uploadTaskWithRequest:m_urlRequest fromData:postData completionHandler:m_completionMethod]; + } + + [m_dataTask resume]; + } +} + +void HttpRequestApple::HandleResponse(NSData* data, NSURLResponse* response, NSError* error) +{ + @autoreleasepool + { + NSHTTPURLResponse *httpResp = static_cast(response); + auto simpleResponse = new SimpleHttpResponse { NextRespId() }; + + simpleResponse->m_statusCode = httpResp.statusCode; + + NSDictionary *responseHeaders = [httpResp allHeaderFields]; + for (id key in responseHeaders) + { + simpleResponse->m_headers.add([key UTF8String], [responseHeaders[key] UTF8String]); + } + + if (error) + { + NSString* errorDomain = [error domain]; + long errorCode = [error code]; + + if ([errorDomain isEqualToString:@"NSURLErrorDomain"] && (errorCode == NSURLErrorCancelled)) + { + simpleResponse->m_result = HttpResult_Aborted; + } + else + { + LOG_TRACE("HTTP response error code: %li", errorCode); + simpleResponse->m_result = HttpResult_NetworkFailure; + } + } + else + { + simpleResponse->m_result = HttpResult_OK; + auto body = static_cast([data bytes]); + simpleResponse->m_body.reserve(data.length); + std::copy(body, body + data.length, std::back_inserter(simpleResponse->m_body)); + } + m_callback->OnHttpResponse(simpleResponse); + } +} + +void HttpRequestApple::Cancel() +{ + [m_dataTask cancel]; + [m_session getTasksWithCompletionHandler:^(NSArray* dataTasks, NSArray* uploadTasks, NSArray* downloadTasks) + { + for (NSURLSessionTask* _task in dataTasks) + { + [_task cancel]; + } + + for (NSURLSessionTask* _task in downloadTasks) + { + [_task cancel]; + } + + for (NSURLSessionTask* _task in uploadTasks) + { + [_task cancel]; + } + }]; +} + +} MAT_NS_END + +#endif From 893dbab82f32eb597e8b752d96931f40db527996 Mon Sep 17 00:00:00 2001 From: Satakarni Amirneni Date: Tue, 11 Oct 2022 16:31:32 +0530 Subject: [PATCH 5/9] fix pipeline failures --- lib/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 1055d8ec1..69c49cdb9 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -128,6 +128,7 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11") if(BUILD_APPLE_HTTP OR BUILD_IOS) list(APPEND SRCS http/HttpClient_Apple.mm + http/HttpRequestApple.mm ) else() list(APPEND SRCS From f964684f6311f3dff2880bd9534b77ac4a4403b6 Mon Sep 17 00:00:00 2001 From: Satakarni Amirneni Date: Tue, 11 Oct 2022 16:39:03 +0530 Subject: [PATCH 6/9] remove unneccesary headers --- lib/http/HttpClient_Apple.mm | 5 ----- lib/http/HttpRequestApple.mm | 1 - 2 files changed, 6 deletions(-) diff --git a/lib/http/HttpClient_Apple.mm b/lib/http/HttpClient_Apple.mm index fd7334ff9..f035bc966 100644 --- a/lib/http/HttpClient_Apple.mm +++ b/lib/http/HttpClient_Apple.mm @@ -8,13 +8,8 @@ // e.g. WinInet.dll or Win 10 HTTP client instead #if defined(MATSDK_PAL_CPP11) && !defined(_MSC_VER) && defined(HAVE_MAT_DEFAULT_HTTP_CLIENT) -#import -#import - #include "HttpClient_Apple.hpp" #include "HttpRequestApple.hpp" -#include "utils/StringUtils.hpp" -#include "utils/Utils.hpp" namespace MAT_NS_BEGIN { diff --git a/lib/http/HttpRequestApple.mm b/lib/http/HttpRequestApple.mm index 85f9f22e9..40c71ecee 100644 --- a/lib/http/HttpRequestApple.mm +++ b/lib/http/HttpRequestApple.mm @@ -14,7 +14,6 @@ #include "HttpClient_Apple.hpp" #include "HttpRequestApple.hpp" #include "utils/StringUtils.hpp" -#include "utils/Utils.hpp" namespace MAT_NS_BEGIN { From fca02e07219ea03d4e56af697c8f85ebfa477086 Mon Sep 17 00:00:00 2001 From: Satakarni Amirneni Date: Wed, 19 Oct 2022 12:12:34 +0530 Subject: [PATCH 7/9] rename variables --- lib/http/HttpRequestApple.mm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/http/HttpRequestApple.mm b/lib/http/HttpRequestApple.mm index 40c71ecee..94a9951ea 100644 --- a/lib/http/HttpRequestApple.mm +++ b/lib/http/HttpRequestApple.mm @@ -18,7 +18,7 @@ namespace MAT_NS_BEGIN { static dispatch_once_t once; -static NSURLSession* m_session; +static NSURLSession* session; static std::string NextReqId() { @@ -39,7 +39,7 @@ m_parent->Add(static_cast(this)); dispatch_once(&once, ^{ NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; - m_session = [NSURLSession sessionWithConfiguration:sessionConfig]; + session = [NSURLSession sessionWithConfiguration:sessionConfig]; }); } @@ -72,13 +72,13 @@ if(equalsIgnoreCase(m_method, "get")) { [m_urlRequest setHTTPMethod:@"GET"]; - m_dataTask = [m_session dataTaskWithRequest:m_urlRequest completionHandler:m_completionMethod]; + m_dataTask = [session dataTaskWithRequest:m_urlRequest completionHandler:m_completionMethod]; } else { [m_urlRequest setHTTPMethod:@"POST"]; NSData* postData = [NSData dataWithBytes:m_body.data() length:m_body.size()]; - m_dataTask = [m_session uploadTaskWithRequest:m_urlRequest fromData:postData completionHandler:m_completionMethod]; + m_dataTask = [session uploadTaskWithRequest:m_urlRequest fromData:postData completionHandler:m_completionMethod]; } [m_dataTask resume]; @@ -129,7 +129,7 @@ void HttpRequestApple::Cancel() { [m_dataTask cancel]; - [m_session getTasksWithCompletionHandler:^(NSArray* dataTasks, NSArray* uploadTasks, NSArray* downloadTasks) + [session getTasksWithCompletionHandler:^(NSArray* dataTasks, NSArray* uploadTasks, NSArray* downloadTasks) { for (NSURLSessionTask* _task in dataTasks) { From eb860e3adf884886382a986f5a0be4cf59e93344 Mon Sep 17 00:00:00 2001 From: Satakarni Amirneni Date: Fri, 21 Oct 2022 11:51:29 +0530 Subject: [PATCH 8/9] revert changes --- lib/CMakeLists.txt | 1 - lib/http/HttpClient_Apple.mm | 150 ++++++++++++++++++++++++++++++++- lib/http/HttpRequestApple.hpp | 34 -------- lib/http/HttpRequestApple.mm | 153 ---------------------------------- 4 files changed, 149 insertions(+), 189 deletions(-) delete mode 100644 lib/http/HttpRequestApple.hpp delete mode 100644 lib/http/HttpRequestApple.mm diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 69c49cdb9..1055d8ec1 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -128,7 +128,6 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11") if(BUILD_APPLE_HTTP OR BUILD_IOS) list(APPEND SRCS http/HttpClient_Apple.mm - http/HttpRequestApple.mm ) else() list(APPEND SRCS diff --git a/lib/http/HttpClient_Apple.mm b/lib/http/HttpClient_Apple.mm index f035bc966..a7865749b 100644 --- a/lib/http/HttpClient_Apple.mm +++ b/lib/http/HttpClient_Apple.mm @@ -8,11 +8,159 @@ // e.g. WinInet.dll or Win 10 HTTP client instead #if defined(MATSDK_PAL_CPP11) && !defined(_MSC_VER) && defined(HAVE_MAT_DEFAULT_HTTP_CLIENT) +#import +#import + #include "HttpClient_Apple.hpp" -#include "HttpRequestApple.hpp" +#include "utils/StringUtils.hpp" +#include "utils/Utils.hpp" namespace MAT_NS_BEGIN { +static std::string NextReqId() +{ + static std::atomic seq; + return std::string("REQ-") + std::to_string(seq.fetch_add(1)); +} + +static std::string NextRespId() +{ + static std::atomic seq; + return std::string("RESP-") + std::to_string(seq.fetch_add(1)); +} + +static dispatch_once_t once; +static NSURLSession* session; + +class HttpRequestApple : public SimpleHttpRequest +{ +public: + HttpRequestApple(HttpClient_Apple* parent) : + SimpleHttpRequest(NextReqId()), + m_parent(parent) + { + m_parent->Add(static_cast(this)); + dispatch_once(&once, ^{ + NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + session = [NSURLSession sessionWithConfiguration:sessionConfig]; + }); + } + + ~HttpRequestApple() noexcept + { + m_parent->Erase(static_cast(this)); + } + + void SendAsync(IHttpResponseCallback* callback) + { + @autoreleasepool + { + m_callback = callback; + NSString* url = [[NSString alloc] initWithUTF8String:m_url.c_str()]; + NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + m_urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; + + for(const auto& header : m_headers) + { + NSString* name = [[NSString alloc] initWithUTF8String:header.first.c_str()]; + NSString* value = [[NSString alloc] initWithUTF8String:header.second.c_str()]; + [m_urlRequest setValue:value forHTTPHeaderField:name]; + } + + m_completionMethod = + ^(NSData *data, NSURLResponse *response, NSError *error) + { + HandleResponse(data, response, error); + }; + + if(equalsIgnoreCase(m_method, "get")) + { + [m_urlRequest setHTTPMethod:@"GET"]; + m_dataTask = [session dataTaskWithRequest:m_urlRequest completionHandler:m_completionMethod]; + } + else + { + [m_urlRequest setHTTPMethod:@"POST"]; + NSData* postData = [NSData dataWithBytes:m_body.data() length:m_body.size()]; + m_dataTask = [session uploadTaskWithRequest:m_urlRequest fromData:postData completionHandler:m_completionMethod]; + } + + [m_dataTask resume]; + } + } + + void HandleResponse(NSData* data, NSURLResponse* response, NSError* error) + { + @autoreleasepool + { + NSHTTPURLResponse *httpResp = static_cast(response); + auto simpleResponse = new SimpleHttpResponse { NextRespId() }; + + simpleResponse->m_statusCode = httpResp.statusCode; + + NSDictionary *responseHeaders = [httpResp allHeaderFields]; + for (id key in responseHeaders) + { + simpleResponse->m_headers.add([key UTF8String], [responseHeaders[key] UTF8String]); + } + + if (error) + { + NSString* errorDomain = [error domain]; + long errorCode = [error code]; + + if ([errorDomain isEqualToString:@"NSURLErrorDomain"] && (errorCode == NSURLErrorCancelled)) + { + simpleResponse->m_result = HttpResult_Aborted; + } + else + { + LOG_TRACE("HTTP response error code: %li", errorCode); + simpleResponse->m_result = HttpResult_NetworkFailure; + } + } + else + { + simpleResponse->m_result = HttpResult_OK; + auto body = static_cast([data bytes]); + simpleResponse->m_body.reserve(data.length); + std::copy(body, body + data.length, std::back_inserter(simpleResponse->m_body)); + } + m_callback->OnHttpResponse(simpleResponse); + } + } + + void Cancel() + { + [m_dataTask cancel]; + [session getTasksWithCompletionHandler:^(NSArray* dataTasks, NSArray* uploadTasks, NSArray* downloadTasks) + { + for (NSURLSessionTask* _task in dataTasks) + { + [_task cancel]; + } + + for (NSURLSessionTask* _task in downloadTasks) + { + [_task cancel]; + } + + for (NSURLSessionTask* _task in uploadTasks) + { + [_task cancel]; + } + }]; + } + +private: + HttpClient_Apple* m_parent = nullptr; + IHttpResponseCallback* m_callback = nullptr; + NSURLSessionDataTask* m_dataTask = nullptr; + NSMutableURLRequest* m_urlRequest = nullptr; + void (^m_completionMethod)(NSData* data, NSURLResponse* response, NSError* error); +}; + + HttpClient_Apple::HttpClient_Apple() { LOG_TRACE("Initializing HttpClient_Apple..."); diff --git a/lib/http/HttpRequestApple.hpp b/lib/http/HttpRequestApple.hpp deleted file mode 100644 index 60252c587..000000000 --- a/lib/http/HttpRequestApple.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -#ifndef HTTPREQUESTAPPLE_H -#define HTTPREQUESTAPPLE_H - -#import - -#include "IHttpClient.hpp" -#include "HttpClient_Apple.hpp" - -namespace MAT_NS_BEGIN { - - class HttpRequestApple : public SimpleHttpRequest { - public: - HttpRequestApple(HttpClient_Apple* parent); - ~HttpRequestApple() noexcept; - - void SendAsync(IHttpResponseCallback* callback); - void HandleResponse(NSData* data, NSURLResponse* response, NSError* error); - void Cancel(); - - private: - HttpClient_Apple* m_parent = nullptr; - IHttpResponseCallback* m_callback = nullptr; - NSURLSessionDataTask* m_dataTask = nullptr; - NSMutableURLRequest* m_urlRequest = nullptr; - void (^m_completionMethod)(NSData* data, NSURLResponse* response, NSError* error); - }; - -} MAT_NS_END - -#endif // HTTPREQUESTAPPLE_H diff --git a/lib/http/HttpRequestApple.mm b/lib/http/HttpRequestApple.mm deleted file mode 100644 index 94a9951ea..000000000 --- a/lib/http/HttpRequestApple.mm +++ /dev/null @@ -1,153 +0,0 @@ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -#include "mat/config.h" - -// Assume that if we are compiling with MSVC, then we prefer to use Windows HTTP stack, -// e.g. WinInet.dll or Win 10 HTTP client instead -#if defined(MATSDK_PAL_CPP11) && !defined(_MSC_VER) && defined(HAVE_MAT_DEFAULT_HTTP_CLIENT) - -#import -#import - -#include "HttpClient_Apple.hpp" -#include "HttpRequestApple.hpp" -#include "utils/StringUtils.hpp" - -namespace MAT_NS_BEGIN { - -static dispatch_once_t once; -static NSURLSession* session; - -static std::string NextReqId() -{ - static std::atomic seq; - return std::string("REQ-") + std::to_string(seq.fetch_add(1)); -} - -static std::string NextRespId() -{ - static std::atomic seq; - return std::string("RESP-") + std::to_string(seq.fetch_add(1)); -} - -HttpRequestApple::HttpRequestApple(HttpClient_Apple* parent) : - SimpleHttpRequest(NextReqId()), - m_parent(parent) -{ - m_parent->Add(static_cast(this)); - dispatch_once(&once, ^{ - NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; - session = [NSURLSession sessionWithConfiguration:sessionConfig]; - }); -} - -HttpRequestApple::~HttpRequestApple() noexcept -{ - m_parent->Erase(static_cast(this)); -} - -void HttpRequestApple::SendAsync(IHttpResponseCallback* callback) -{ - @autoreleasepool - { - m_callback = callback; - NSString* url = [[NSString alloc] initWithUTF8String:m_url.c_str()]; - m_urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; - - for(const auto& header : m_headers) - { - NSString* name = [[NSString alloc] initWithUTF8String:header.first.c_str()]; - NSString* value = [[NSString alloc] initWithUTF8String:header.second.c_str()]; - [m_urlRequest setValue:value forHTTPHeaderField:name]; - } - - m_completionMethod = - ^(NSData *data, NSURLResponse *response, NSError *error) - { - HandleResponse(data, response, error); - }; - - if(equalsIgnoreCase(m_method, "get")) - { - [m_urlRequest setHTTPMethod:@"GET"]; - m_dataTask = [session dataTaskWithRequest:m_urlRequest completionHandler:m_completionMethod]; - } - else - { - [m_urlRequest setHTTPMethod:@"POST"]; - NSData* postData = [NSData dataWithBytes:m_body.data() length:m_body.size()]; - m_dataTask = [session uploadTaskWithRequest:m_urlRequest fromData:postData completionHandler:m_completionMethod]; - } - - [m_dataTask resume]; - } -} - -void HttpRequestApple::HandleResponse(NSData* data, NSURLResponse* response, NSError* error) -{ - @autoreleasepool - { - NSHTTPURLResponse *httpResp = static_cast(response); - auto simpleResponse = new SimpleHttpResponse { NextRespId() }; - - simpleResponse->m_statusCode = httpResp.statusCode; - - NSDictionary *responseHeaders = [httpResp allHeaderFields]; - for (id key in responseHeaders) - { - simpleResponse->m_headers.add([key UTF8String], [responseHeaders[key] UTF8String]); - } - - if (error) - { - NSString* errorDomain = [error domain]; - long errorCode = [error code]; - - if ([errorDomain isEqualToString:@"NSURLErrorDomain"] && (errorCode == NSURLErrorCancelled)) - { - simpleResponse->m_result = HttpResult_Aborted; - } - else - { - LOG_TRACE("HTTP response error code: %li", errorCode); - simpleResponse->m_result = HttpResult_NetworkFailure; - } - } - else - { - simpleResponse->m_result = HttpResult_OK; - auto body = static_cast([data bytes]); - simpleResponse->m_body.reserve(data.length); - std::copy(body, body + data.length, std::back_inserter(simpleResponse->m_body)); - } - m_callback->OnHttpResponse(simpleResponse); - } -} - -void HttpRequestApple::Cancel() -{ - [m_dataTask cancel]; - [session getTasksWithCompletionHandler:^(NSArray* dataTasks, NSArray* uploadTasks, NSArray* downloadTasks) - { - for (NSURLSessionTask* _task in dataTasks) - { - [_task cancel]; - } - - for (NSURLSessionTask* _task in downloadTasks) - { - [_task cancel]; - } - - for (NSURLSessionTask* _task in uploadTasks) - { - [_task cancel]; - } - }]; -} - -} MAT_NS_END - -#endif From 73744726385bd3349f91796cc9a8e0946b5c89d1 Mon Sep 17 00:00:00 2001 From: Satakarni Amirneni Date: Fri, 21 Oct 2022 11:53:04 +0530 Subject: [PATCH 9/9] nit --- lib/http/HttpClient_Apple.mm | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/http/HttpClient_Apple.mm b/lib/http/HttpClient_Apple.mm index a7865749b..05817087a 100644 --- a/lib/http/HttpClient_Apple.mm +++ b/lib/http/HttpClient_Apple.mm @@ -57,7 +57,6 @@ void SendAsync(IHttpResponseCallback* callback) { m_callback = callback; NSString* url = [[NSString alloc] initWithUTF8String:m_url.c_str()]; - NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; m_urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; for(const auto& header : m_headers) @@ -160,7 +159,6 @@ void Cancel() void (^m_completionMethod)(NSData* data, NSURLResponse* response, NSError* error); }; - HttpClient_Apple::HttpClient_Apple() { LOG_TRACE("Initializing HttpClient_Apple...");