/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "http_exec_ios_iml.h"
#import "http_ios_request.h"
namespace OHOS::NetStack::Http {
SuccessCallback HttpExecIosIml::successResponseCallback_ = nullptr;
FailedCallback HttpExecIosIml::failedResponseCallback_ = nullptr;
ProgressCallback HttpExecIosIml::progressCallback_ = nullptr;
WritingBodyCallback HttpExecIosIml::writingBodyCallback_ = nullptr;
WritingHeaderCallback HttpExecIosIml::writingHeaderCallback_ = nullptr;
HttpExecIosIml::~HttpExecIosIml()
{
http_ios_request* request = (__bridge http_ios_request*)request_;
if (!request) {
return;
}
[request deInitialize];
}
std::string HttpExecIosIml::GetCacheFileName()
{
NSString * stringPath = [http_ios_request getBaseCachePath];
std::string path = [stringPath UTF8String];
return path;
}
bool HttpExecIosIml::SendRequest(HttpRequestOptions& requestOptions,void* userData)
{
http_ios_param* requestParam = [[http_ios_param alloc] init];
const char* url = requestOptions.GetUrl().c_str();
const char* method = requestOptions.GetMethod().c_str();
requestParam.urlPath = [NSString stringWithCString:url encoding:NSUTF8StringEncoding];
requestParam.method = [NSString stringWithCString:method encoding:NSUTF8StringEncoding];
std::string proxyHost;
int32_t proxprot;
std::string exclusionList;
NapiUtils::SecureData username;
NapiUtils::SecureData password;
requestOptions.GetSpecifiedHttpProxy(proxyHost, proxprot, exclusionList, username, password);
requestParam.proxyhost = [NSString stringWithCString:proxyHost.c_str() encoding:NSUTF8StringEncoding];
requestParam.proxyport = (NSInteger)proxprot;
requestParam.exclusionList = [NSString stringWithCString:exclusionList.c_str() encoding:NSUTF8StringEncoding];
requestParam.returnDataType = (NSInteger)requestOptions.GetHttpDataType();
const char* body = requestOptions.GetBody().c_str();
requestParam.bodyParam = [NSString stringWithCString:body encoding:NSUTF8StringEncoding];
requestParam.bodyOrQueryConfigured = requestOptions.GetBodyOrQueryConfigured();
requestParam.context = userData;
NSMutableDictionary* headerDic = [NSMutableDictionary dictionary];
for (std::map<std::string,
std::string>::const_iterator it = requestOptions.GetHeader().begin();
it != requestOptions.GetHeader().end(); it++) {
NSString* key = [NSString stringWithUTF8String:it->first.c_str()];
NSString* value = [NSString stringWithUTF8String:it->second.c_str()];
headerDic[key] = value;
}
requestParam.headerJson = headerDic;
requestParam.priority = requestOptions.GetPriority();
requestParam.readTimeout = (NSTimeInterval)requestOptions.GetReadTimeout()/1000;
requestParam.connectTimeout = (NSTimeInterval)requestOptions.GetConnectTimeout()/1000;
requestParam.httpVersion = requestOptions.GetHttpVersion();
std::string cert;
std::string certType;
std::string key;
Secure::SecureChar keyPasswd;
requestOptions.GetClientCert(cert, certType, key, keyPasswd);
requestParam.ca = [NSString stringWithCString:cert.c_str() encoding:NSUTF8StringEncoding];;
requestParam.caType = [NSString stringWithCString:certType.c_str() encoding:NSUTF8StringEncoding];;
requestParam.key = [NSString stringWithCString:key.c_str() encoding:NSUTF8StringEncoding];;
requestParam.password = [NSString stringWithCString:keyPasswd.Data() encoding:NSUTF8StringEncoding];;
requestParam.usingHttpProxyType = static_cast<NSInteger>(requestOptions.GetUsingHttpProxyType());
http_ios_request* request = [[http_ios_request alloc] init];
request_ = (__bridge void*)request;
RequestCallBack();
[request sendRequestWith:requestParam];
return true;
}
void HttpExecIosIml::RequestCallBack()
{
http_ios_request* request = (__bridge http_ios_request*)request_;
[request setMemoryHeaderBlock:^(NSDictionary* _Nonnull headers, void* _Nonnull userData) {
NSData* data = [NSJSONSerialization dataWithJSONObject:headers options:NSJSONWritingPrettyPrinted error:nil];
if (!data) {
return;
}
const void* buf = [data bytes];
size_t size = [data length];
HttpExecIosIml::writingHeaderCallback_(buf, size, userData);
}];
[request setMemoryBodyBlock:^(NSData* _Nonnull data, void* _Nonnull userData) {
const void* buf = [data bytes];
size_t size = [data length];
HttpExecIosIml::writingBodyCallback_(buf, size, userData);
}];
[request setUploadProgress:^(void* _Nonnull userData, long total, long now) {
HttpExecIosIml::progressCallback_(userData, 0, 0, total, now);
}];
[request setDownloadProgress:^(void* _Nonnull userData, long total, long now) {
HttpExecIosIml::progressCallback_(userData, total, now, 0, 0);
}];
[request setResponseBlock:^(NSURLSessionTask* _Nonnull task,
NSHTTPURLResponse* _Nullable response,
NSData* _Nullable data,
void* _Nonnull userData) {
NSInteger code = response.statusCode;
uint32_t statueCode = (uint32_t)code;
NSDictionary* headerDic = response.allHeaderFields;
std::string header;
for (NSString* key in headerDic.allKeys) {
NSString* value = [headerDic valueForKey:key];
header += [[NSString stringWithFormat:@"%@: %@", key, value] UTF8String];
header += "\r\n";
}
NSHTTPCookieStorage* cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
std::string cookiesStr;
for (NSHTTPCookie* cookie in [cookieJar cookies]) {
cookiesStr += [[NSString stringWithFormat:@"%@: %@", cookie.name, cookie.value] UTF8String];
cookiesStr += "\r\n";
}
HttpResponse httpRespone;
std::string dataChat((const char*)[data bytes], [data length]);
httpRespone.SetResult(dataChat);
httpRespone.SetResponseCode(statueCode);
httpRespone.SetRawHeader(header);
httpRespone.SetCookies(cookiesStr);
HttpExecIosIml::successResponseCallback_(httpRespone, userData);
headerDic = nil;
}];
[request setFailBlock:^(NSInteger errorCode, NSString* _Nonnull errorMessage, void* _Nonnull userData) {
uint32_t code = (uint32_t)errorCode;
std::string errormsg = [errorMessage UTF8String];
HttpExecIosIml::failedResponseCallback_(code, errormsg, userData);
}];
}
void HttpExecIosIml::SetSuccessCallback(SuccessCallback successResponseCallback)
{
if (successResponseCallback_ == nullptr) {
successResponseCallback_ = successResponseCallback;
}
}
void HttpExecIosIml::SetFailedCallback(FailedCallback failedResponseCallback)
{
if (failedResponseCallback_ == nullptr) {
failedResponseCallback_ = failedResponseCallback;
}
}
void HttpExecIosIml::SetProgressCallback(ProgressCallback progressCallback)
{
if (progressCallback_ == nullptr) {
progressCallback_ = progressCallback;
}
}
void HttpExecIosIml::SetWritingBodyCallback(WritingBodyCallback writingBodyCallback)
{
if (writingBodyCallback_ == nullptr) {
writingBodyCallback_ = writingBodyCallback;
}
}
void HttpExecIosIml::SetWritingHeaderCallback(WritingHeaderCallback writingHeaderCallback)
{
if (writingHeaderCallback_ == nullptr) {
writingHeaderCallback_ = writingHeaderCallback;
}
}
} // namespace OHOS::NetStack::Http