上传支持https

Signed-off-by: anyueling <anyueling@huawei.com>
This commit is contained in:
anyueling 2023-03-06 14:44:21 +08:00
parent 91221d4c8b
commit 1fed9b0a3b
7 changed files with 87 additions and 53 deletions

View File

@ -47,7 +47,6 @@ public:
static std::shared_ptr<Upload::UploadConfig> ParseUploadConfig(napi_env env, napi_value jsConfig,
const std::string &version);
static bool ToUploadConfig(napi_env env, napi_value jsConfig, Upload::UploadConfig &config);
static napi_value Convert2JSUploadConfig(napi_env env, const Upload::UploadConfig &config);
static bool Convert2File(napi_env env, napi_value jsFile, Upload::File &file);
static napi_value Convert2JSFile(napi_env env, const Upload::File &file);
@ -78,10 +77,10 @@ public:
static bool ToUploadOption(napi_env env, napi_value jsConfig, Upload::UploadConfig &config);
static bool SetData(napi_env env, napi_value jsConfig, Upload::UploadConfig &config);
static bool SetFiles(napi_env env, napi_value jsConfig, Upload::UploadConfig &config);
static bool SetHeader(napi_env env, napi_value jsConfig, Upload::UploadConfig &config);
static bool Convert2FileL5(napi_env env, napi_value jsFile, Upload::File &file);
static bool SetMandatoryParam(napi_env env, napi_value jsValue, const std::string &str, std::string &out);
static bool SetOptionalParam(napi_env env, napi_value jsValue, const std::string &str, std::string &out);
static bool ParseHeader(napi_env env, napi_value configValue, std::map<std::string, std::string> &header);
};
}
#endif // REQUEST_JS_UTIL_H

View File

@ -16,6 +16,7 @@
#include <securec.h>
#include <regex>
#include <string>
#include "napi_utils.h"
#include "js_util.h"
using namespace OHOS::Request::Upload;
@ -286,21 +287,6 @@ bool JSUtil::SetFiles(napi_env env, napi_value jsConfig, UploadConfig &config)
return true;
}
bool JSUtil::SetHeader(napi_env env, napi_value jsConfig, UploadConfig &config)
{
if (!HasNamedProperty(env, jsConfig, "header")) {
return true;
}
napi_value header = nullptr;
napi_get_named_property(env, jsConfig, "header", &header);
if (header == nullptr) {
UPLOAD_HILOGE(UPLOAD_MODULE_JS_NAPI, "GetNamedProperty SetHeader failed");
return false;
}
config.header = Convert2Header(env, header);
return true;
}
bool JSUtil::ToUploadOption(napi_env env, napi_value jsConfig, UploadConfig &config)
{
if (!SetMandatoryParam(env, jsConfig, "url", config.url)) {
@ -312,7 +298,7 @@ bool JSUtil::ToUploadOption(napi_env env, napi_value jsConfig, UploadConfig &con
if (!SetFiles(env, jsConfig, config)) {
return false;
}
if (!SetHeader(env, jsConfig, config)) {
if (!ParseHeader(env, jsConfig, config.header)) {
return false;
}
if (!SetOptionalParam(env, jsConfig, "method", config.method)) {
@ -321,6 +307,32 @@ bool JSUtil::ToUploadOption(napi_env env, napi_value jsConfig, UploadConfig &con
return true;
}
bool JSUtil::ParseHeader(napi_env env, napi_value configValue, std::map<std::string, std::string> &header)
{
if (!Download::NapiUtils::HasNamedProperty(env, configValue, "header")) {
UPLOAD_HILOGE(UPLOAD_MODULE_JS_NAPI, "No header present, Reassign value");
header[Download::tlsVersion] = Download::TLS_VERSION;
header[Download::cipherList] = Download::TLS_CIPHER;
return true;
}
napi_value jsHeader = Download::NapiUtils::GetNamedProperty(env, configValue, "header");
if (Download::NapiUtils::GetValueType(env, jsHeader) != napi_object) {
return false;
}
auto names = Download::NapiUtils::GetPropertyNames(env, jsHeader);
auto iter = find(names.begin(), names.end(), Download::cipherList);
if (iter == names.end()) {
header[Download::cipherList] = Download::TLS_CIPHER;
}
for (iter = names.begin(); iter != names.end(); ++iter) {
auto value = Download::NapiUtils::GetStringPropertyUtf8(env, jsHeader, *iter);
if (!value.empty()) {
header[Download::NapiUtils::ToLower(*iter)] = value;
}
}
return true;
}
bool JSUtil::ToUploadConfig(napi_env env, napi_value jsConfig, UploadConfig &config)
{
napi_value url = GetNamedProperty(env, jsConfig, "url");
@ -329,11 +341,9 @@ bool JSUtil::ToUploadConfig(napi_env env, napi_value jsConfig, UploadConfig &con
}
config.url = Convert2String(env, url);
napi_value header = GetNamedProperty(env, jsConfig, "header");
if (header == nullptr) {
if (!ParseHeader(env, jsConfig, config.header)) {
return false;
}
config.header = Convert2Header(env, header);
napi_value method = GetNamedProperty(env, jsConfig, "method");
if (method == nullptr) {
@ -356,18 +366,6 @@ bool JSUtil::ToUploadConfig(napi_env env, napi_value jsConfig, UploadConfig &con
return true;
}
napi_value JSUtil::Convert2JSUploadConfig(napi_env env, const UploadConfig &config)
{
napi_value jsConfig = nullptr;
napi_create_object(env, &jsConfig);
napi_set_named_property(env, jsConfig, "url", Convert2JSString(env, config.url));
napi_set_named_property(env, jsConfig, "header", Convert2JSStringVector(env, config.header));
napi_set_named_property(env, jsConfig, "method", Convert2JSString(env, config.method));
napi_set_named_property(env, jsConfig, "files", Convert2JSFileVector(env, config.files));
napi_set_named_property(env, jsConfig, "data", Convert2JSRequestDataVector(env, config.data));
return jsConfig;
}
bool JSUtil::Convert2File(napi_env env, napi_value jsFile, Upload::File &file)
{
napi_value filename = GetNamedProperty(env, jsFile, "filename");

View File

@ -63,6 +63,7 @@ private:
void SetNetworkOpt(CURL *curl);
void SetCallbackOpt(CURL *curl);
void SetBehaviorOpt(CURL *curl);
std::string ReadCertification();
void CurlGlobalInit();
void CurlGlobalCleanup();
void StartTimer();

View File

@ -18,6 +18,7 @@
#include <string>
#include <vector>
#include <map>
#include "curl/curl.h"
namespace OHOS::Request::Upload {
@ -41,7 +42,7 @@ struct UploadResponse {
struct UploadConfig {
std::string url;
std::vector<std::string> header;
std::map<std::string, std::string> header;
std::string method;
std::vector<File> files;
std::vector<RequestData> data;

View File

@ -22,6 +22,9 @@
#include <string>
#include <unistd.h>
#include <vector>
#include <fstream>
#include <ios>
#include "constant.h"
#include "common_timer_errors.h"
#include "hisysevent.h"
@ -103,8 +106,13 @@ bool CUrlAdp::MultiAddHandle(CURLM *curlMulti, std::vector<CURL *> &curlArray)
void CUrlAdp::SetHeadData(CURL *curl)
{
std::vector<std::string> vec;
std::for_each(config_->header.begin(), config_->header.end(),
[&vec](const std::pair<std::string, std::string> &header) {
vec.emplace_back(header.first + ":" + header.second);
});
bool hasContentType = false;
for (auto &headerData : config_->header) {
for (auto &headerData : vec) {
if (headerData.find("Content-Type:") != std::string::npos) {
hasContentType = true;
}
@ -146,8 +154,40 @@ void CUrlAdp::SetConnectionOpt(CURL *curl)
void CUrlAdp::SetSslOpt(CURL *curl)
{
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
if (config_->url.find("https") != 0) {
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
return;
}
std::string certInfo = ReadCertification();
if (certInfo.empty()) {
UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "Read certinfo failed");
return;
}
struct curl_blob blob {.data = const_cast<char *>(certInfo.c_str()),
.len = certInfo.size(),
.flags = CURL_BLOB_COPY};
std::string version = "CURL_SSLVERSION_TLSv1_2";
if (config_->header.find(Download::tlsVersion) != config_->header.end()) {
version = config_->header[Download::tlsVersion];
}
curl_easy_setopt(curl, CURLOPT_SSLVERSION, version.c_str());
CURLcode code = curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &blob);
if (code != CURLE_OK) {
UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "set ssl ca option failed");
}
}
std::string CUrlAdp::ReadCertification()
{
std::ifstream inFile(Download::HTTP_DEFAULT_CA_PATH, std::ios::in | std::ios::binary);
if (!inFile.is_open()) {
UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "open cacert.pem failed, errno:%{public}d", errno);
return "";
}
std::stringstream buf;
buf << inFile.rdbuf();
return std::string(buf.str());
}
void CUrlAdp::SetCurlOpt(CURL *curl)
@ -169,21 +209,17 @@ void CUrlAdp::SetMimePost(CURL *curl)
{
curl_mimepart *part;
curl_mime *mime = curl_mime_init(curl);
if (config_->data.size()) {
for (auto &vdata : config_->data) {
part = curl_mime_addpart(mime);
curl_mime_name(part, vdata.name.c_str());
curl_mime_data(part, vdata.value.c_str(), vdata.value.size());
}
}
part = curl_mime_addpart(mime);
if (mfileData_.name.size()) {
curl_mime_name(part, mfileData_.name.c_str());
if (!config_->data.empty()) {
UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "config_->data.size = %{public}u", config_->data.size());
auto vdata = config_->data;
curl_mime_name(part, vdata[0].name.c_str());
curl_mime_data(part, vdata[0].value.c_str(), vdata[0].value.size());
config_->data.erase(config_->data.begin());
} else {
curl_mime_name(part, "file");
}
curl_mime_type(part, mfileData_.type.c_str());
UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "===> MultiAddHandle mfileData_.type=%{public}s", mfileData_.type.c_str());
curl_mime_filename(part, mfileData_.filename.c_str());
curl_mime_data_cb(part, mfileData_.totalsize, ReadCallback, NULL, NULL, &mfileData_);
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);

View File

@ -66,6 +66,7 @@ ohos_unittest("upload_UT_test") {
]
deps = [
"${request_path}/common:request_common_static",
"${request_path}/frameworks/native/upload:upload_lib",
"//third_party/curl:curl_shared",
]

View File

@ -72,9 +72,8 @@ HWTEST_F(UploadTest, PostUploadNetworkOff001, TestSize.Level0)
std::shared_ptr<UploadConfig> uploadConfig = std::make_shared<UploadConfig>();
uploadConfig->url = "http://192.168.1.180/uploadservice/";
uploadConfig->method = "POST";
std::vector<std::string> header;
std::string str = "Content-Type:multipart/form-data";
header.push_back(str);
std::map<std::string, std::string> header;
header["Content-Type"] = "multipart/form-data";
uploadConfig->header = header;
auto curl = std::make_shared<CUrlAdp>(fileDatas, uploadConfig);
@ -128,9 +127,8 @@ HWTEST_F(UploadTest, PutUploadNetworkOff001, TestSize.Level0)
uploadConfig->url = "http://192.168.1.180/uploadservice/";
uploadConfig->method = "PUT";
uploadConfig->protocolVersion = "API5";
std::vector<std::string> header;
std::string str = "multipart/form-data";
header.push_back(str);
std::map<std::string, std::string> header;
header[""] = "multipart/form-data";
uploadConfig->header = header;
auto curl = std::make_shared<CUrlAdp>(fileDatas, uploadConfig);