From cb6fbd3b8c8650f25dd91f264764bf5a6000f96b Mon Sep 17 00:00:00 2001 From: maosiping Date: Wed, 1 Jun 2022 13:32:38 +0800 Subject: [PATCH] fixed 8da230b from https://gitee.com/maosiping/communication_netstack/pulls/137 http cache api Signed-off-by: maosiping --- frameworks/js/napi/BUILD.gn | 1 - .../async_context/include/fetch_context.h | 2 +- .../async_context/include/request_context.h | 8 +- .../async_context/src/request_context.cpp | 14 ++- .../http/async_work/include/http_async_work.h | 8 ++ .../http/async_work/src/http_async_work.cpp | 20 +++++ .../cache/cache_proxy/include/cache_proxy.h | 8 ++ .../cache/cache_proxy/src/cache_proxy.cpp | 86 ++++++++++++++++--- .../cache/cache_strategy/src/http_time.cpp | 3 + .../cache/lru_cache/include/disk_handler.h | 7 +- .../include/lru_cache_disk_handler.h | 11 ++- .../http/cache/lru_cache/src/disk_handler.cpp | 74 +++++----------- .../lru_cache/src/lru_cache_disk_handler.cpp | 32 +++---- .../js/napi/http/constant/include/constant.h | 1 + .../js/napi/http/constant/src/constant.cpp | 1 + .../napi/http/http_exec/include/http_exec.h | 17 ++++ .../js/napi/http/http_exec/src/http_exec.cpp | 26 +++++- .../http/http_module/include/http_module.h | 15 ++++ .../napi/http/http_module/src/http_module.cpp | 46 ++++++++++ .../async_context/include/bind_context.h | 2 +- .../async_context/include/common_context.h | 2 +- .../async_context/include/connect_context.h | 2 +- .../async_context/include/tcp_extra_context.h | 2 +- .../async_context/include/tcp_send_context.h | 2 +- .../async_context/include/udp_extra_context.h | 2 +- .../async_context/include/udp_send_context.h | 2 +- .../async_context/include/close_context.h | 2 +- .../async_context/include/connect_context.h | 2 +- .../async_context/include/send_context.h | 2 +- test/napi/http/CMakeLists.txt | 1 - .../include/netstack_base_context.h | 2 + .../src/netstack_base_context.cpp | 17 ++++ .../include/netstack_module_template.h | 2 + .../src/netstack_module_template.cpp | 16 ++++ .../napi_utils/include/netstack_napi_utils.h | 2 + utils/napi_utils/src/netstack_napi_utils.cpp | 7 ++ 36 files changed, 343 insertions(+), 104 deletions(-) diff --git a/frameworks/js/napi/BUILD.gn b/frameworks/js/napi/BUILD.gn index 177afae0a..c1a8986e4 100644 --- a/frameworks/js/napi/BUILD.gn +++ b/frameworks/js/napi/BUILD.gn @@ -108,7 +108,6 @@ ohos_shared_library("http") { ] external_deps = common_external_deps - defines = [ "USE_CACHE=1" ] relative_install_dir = common_relative_install_dir part_name = common_part_name diff --git a/frameworks/js/napi/fetch/async_context/include/fetch_context.h b/frameworks/js/napi/fetch/async_context/include/fetch_context.h index a187aca7c..f087dc175 100644 --- a/frameworks/js/napi/fetch/async_context/include/fetch_context.h +++ b/frameworks/js/napi/fetch/async_context/include/fetch_context.h @@ -30,7 +30,7 @@ public: explicit FetchContext(napi_env env, EventManager *manager); - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; [[nodiscard]] napi_value GetSuccessCallback() const; diff --git a/frameworks/js/napi/http/async_context/include/request_context.h b/frameworks/js/napi/http/async_context/include/request_context.h index c8f0754a2..ac9ccec4a 100644 --- a/frameworks/js/napi/http/async_context/include/request_context.h +++ b/frameworks/js/napi/http/async_context/include/request_context.h @@ -28,15 +28,19 @@ public: RequestContext() = delete; - explicit RequestContext(napi_env env, EventManager *manager); + RequestContext(napi_env env, EventManager *manager); - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; HttpRequestOptions options; HttpResponse response; + [[nodiscard]] bool IsUsingCache() const; + private: + bool usingCache_; + bool CheckParamsType(napi_value *params, size_t paramsCount); void ParseNumberOptions(napi_value optionsValue); diff --git a/frameworks/js/napi/http/async_context/src/request_context.cpp b/frameworks/js/napi/http/async_context/src/request_context.cpp index 040518ec0..218f40c5e 100644 --- a/frameworks/js/napi/http/async_context/src/request_context.cpp +++ b/frameworks/js/napi/http/async_context/src/request_context.cpp @@ -30,7 +30,7 @@ static constexpr const int PARAM_URL_AND_OPTIONS_OR_CALLBACK = 2; static constexpr const int PARAM_URL_AND_OPTIONS_AND_CALLBACK = 3; namespace OHOS::NetStack { -RequestContext::RequestContext(napi_env env, EventManager *manager) : BaseContext(env, manager) {} +RequestContext::RequestContext(napi_env env, EventManager *manager) : BaseContext(env, manager), usingCache_(true) {} void RequestContext::ParseParams(napi_value *params, size_t paramsCount) { @@ -101,6 +101,13 @@ void RequestContext::ParseNumberOptions(napi_value optionsValue) options.SetConnectTimeout(HttpConstant::DEFAULT_CONNECT_TIMEOUT); } + if (NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_USING_CACHE)) { + napi_value value = NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_USING_CACHE); + if (NapiUtils::GetValueType(GetEnv(), value) == napi_boolean) { + usingCache_ = NapiUtils::GetBooleanFromValue(GetEnv(), value); + } + } + if (NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_USING_PROTOCOL)) { napi_value value = NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_USING_PROTOCOL); if (NapiUtils::GetValueType(GetEnv(), value) == napi_number) { @@ -243,4 +250,9 @@ void RequestContext::UrlAndOptions(napi_value urlValue, napi_value optionsValue) SetParseOK(ParseExtraData(optionsValue)); } + +bool RequestContext::IsUsingCache() const +{ + return usingCache_; +} } // namespace OHOS::NetStack \ No newline at end of file diff --git a/frameworks/js/napi/http/async_work/include/http_async_work.h b/frameworks/js/napi/http/async_work/include/http_async_work.h index 01b974de0..c1e59f323 100644 --- a/frameworks/js/napi/http/async_work/include/http_async_work.h +++ b/frameworks/js/napi/http/async_work/include/http_async_work.h @@ -29,6 +29,14 @@ public: static void ExecRequest(napi_env env, void *data); static void RequestCallback(napi_env env, napi_status status, void *data); + + static void ExecFlush(napi_env env, void *data); + + static void FlushCallback(napi_env env, napi_status status, void *data); + + static void ExecDelete(napi_env env, void *data); + + static void DeleteCallback(napi_env env, napi_status status, void *data); }; } // namespace OHOS::NetStack diff --git a/frameworks/js/napi/http/async_work/src/http_async_work.cpp b/frameworks/js/napi/http/async_work/src/http_async_work.cpp index 64b18a616..e89df42c9 100644 --- a/frameworks/js/napi/http/async_work/src/http_async_work.cpp +++ b/frameworks/js/napi/http/async_work/src/http_async_work.cpp @@ -29,4 +29,24 @@ void HttpAsyncWork::RequestCallback(napi_env env, napi_status status, void *data { BaseAsyncWork::AsyncWorkCallback(env, status, data); } + +void HttpAsyncWork::ExecFlush(napi_env env, void *data) +{ + BaseAsyncWork::ExecAsyncWork(env, data); +} + +void HttpAsyncWork::FlushCallback(napi_env env, napi_status status, void *data) +{ + BaseAsyncWork::AsyncWorkCallback(env, status, data); +} + +void HttpAsyncWork::ExecDelete(napi_env env, void *data) +{ + BaseAsyncWork::ExecAsyncWork(env, data); +} + +void HttpAsyncWork::DeleteCallback(napi_env env, napi_status status, void *data) +{ + BaseAsyncWork::AsyncWorkCallback(env, status, data); +} } // namespace OHOS::NetStack \ No newline at end of file diff --git a/frameworks/js/napi/http/cache/cache_proxy/include/cache_proxy.h b/frameworks/js/napi/http/cache/cache_proxy/include/cache_proxy.h index 02d5a48b3..630263db8 100644 --- a/frameworks/js/napi/http/cache/cache_proxy/include/cache_proxy.h +++ b/frameworks/js/napi/http/cache/cache_proxy/include/cache_proxy.h @@ -39,6 +39,14 @@ public: bool ReadResponseFromCache(HttpResponse &response); void WriteResponseToCache(const HttpResponse &response); + + static void RunCacheWithSize(size_t capacity); + + static void RunCache(); + + static void FlushCache(); + + static void StopCacheAndDelete(); }; } // namespace OHOS::NetStack #endif // COMMUNICATIONNETSTACK_CACHE_PROXY_H diff --git a/frameworks/js/napi/http/cache/cache_proxy/src/cache_proxy.cpp b/frameworks/js/napi/http/cache/cache_proxy/src/cache_proxy.cpp index a85275aae..6372ef57c 100644 --- a/frameworks/js/napi/http/cache/cache_proxy/src/cache_proxy.cpp +++ b/frameworks/js/napi/http/cache/cache_proxy/src/cache_proxy.cpp @@ -13,25 +13,33 @@ * limitations under the License. */ +#include +#include +#include +#include + #include "base64_utils.h" #include "calculate_md5.h" #include "constant.h" -#if USE_CACHE #include "http_exec.h" -#endif #include "lru_cache_disk_handler.h" #include "netstack_common_utils.h" -#if USE_CACHE #include "netstack_log.h" #include "request_context.h" -#endif #include "cache_proxy.h" -static constexpr const char *CACHE_FILE = "/data/storage/el2/base/cache.json"; +static constexpr const char *CACHE_FILE = "/data/storage/el2/base/cache/cache.json"; +static constexpr const int WRITE_INTERVAL = 60; namespace OHOS::NetStack { -static LRUCacheDiskHandler DISK_LRU_CACHE(CACHE_FILE, MAX_DISK_CACHE_SIZE); // NOLINT(cert-err58-cpp) +std::mutex DISK_CACHE_MUTEX; +std::mutex CACHE_NEED_RUN_MUTEX; +std::atomic_bool CACHE_NEED_RUN(false); +std::atomic_bool CACHE_IS_RUNNING(false); +std::condition_variable CACHE_THREAD_CONDITION; +std::condition_variable CACHE_NEED_RUN_CONDITION; +static LRUCacheDiskHandler DISK_LRU_CACHE(CACHE_FILE, 0); // NOLINT(cert-err58-cpp) CacheProxy::CacheProxy(HttpRequestOptions &requestOptions) : requestOptions_(requestOptions), strategy_(requestOptions) { @@ -50,7 +58,10 @@ std::string CacheProxy::MakeKey() bool CacheProxy::ReadResponseFromCache(HttpResponse &response) { -#if USE_CACHE + if (!CACHE_IS_RUNNING.load()) { + return false; + } + if (!strategy_.CouldUseCache()) { NETSTACK_LOGI("only GET/HEAD method or header has [Range] can use cache"); return false; @@ -92,14 +103,14 @@ bool CacheProxy::ReadResponseFromCache(HttpResponse &response) } NETSTACK_LOGI("cache should not be used"); return false; -#else - return false; -#endif } void CacheProxy::WriteResponseToCache(const HttpResponse &response) { -#if USE_CACHE + if (!CACHE_IS_RUNNING.load()) { + return; + } + if (!strategy_.IsCacheable(response)) { NETSTACK_LOGI("do not cache this response"); return; @@ -111,6 +122,57 @@ void CacheProxy::WriteResponseToCache(const HttpResponse &response) cacheResponse[HttpConstant::RESPONSE_TIME] = Base64::Encode(response.GetResponseTime()); DISK_LRU_CACHE.Put(MakeKey(), cacheResponse); -#endif +} + +void CacheProxy::RunCache() +{ + RunCacheWithSize(MAX_DISK_CACHE_SIZE); +} + +void CacheProxy::RunCacheWithSize(size_t capacity) +{ + if (CACHE_IS_RUNNING.load()) { + return; + } + DISK_LRU_CACHE.SetCapacity(capacity); + + CACHE_NEED_RUN.store(true); + // 从磁盘中读取缓存到内存里 + DISK_LRU_CACHE.ReadCacheFromJsonFile(); + // 起线程每一分钟将内存缓存持久化 + std::thread([]() { + CACHE_IS_RUNNING.store(true); + while (CACHE_NEED_RUN.load()) { + std::unique_lock lock(CACHE_NEED_RUN_MUTEX); + CACHE_NEED_RUN_CONDITION.wait_for(lock, std::chrono::seconds(WRITE_INTERVAL), + [] { return CACHE_NEED_RUN.load(); }); + + DISK_LRU_CACHE.WriteCacheToJsonFile(); + } + + CACHE_IS_RUNNING.store(false); + CACHE_THREAD_CONDITION.notify_all(); + }).detach(); +} + +void CacheProxy::FlushCache() +{ + if (!CACHE_IS_RUNNING.load()) { + return; + } + DISK_LRU_CACHE.WriteCacheToJsonFile(); +} + +void CacheProxy::StopCacheAndDelete() +{ + if (!CACHE_IS_RUNNING.load()) { + return; + } + CACHE_NEED_RUN.store(false); + CACHE_NEED_RUN_CONDITION.notify_all(); + + std::unique_lock lock(DISK_CACHE_MUTEX); + CACHE_THREAD_CONDITION.wait(lock, [] { return !CACHE_IS_RUNNING.load(); }); + DISK_LRU_CACHE.Delete(); } } // namespace OHOS::NetStack diff --git a/frameworks/js/napi/http/cache/cache_strategy/src/http_time.cpp b/frameworks/js/napi/http/cache/cache_strategy/src/http_time.cpp index 26ee6d053..117c5b69b 100644 --- a/frameworks/js/napi/http/cache/cache_strategy/src/http_time.cpp +++ b/frameworks/js/napi/http/cache/cache_strategy/src/http_time.cpp @@ -22,6 +22,8 @@ static constexpr const char *GMT_TIME = "%a, %d %b %Y %H:%M:%S GMT"; static constexpr const int MAX_TIME_LEN = 128; +static constexpr const int GMT_UTC_DIFF = 8; + namespace OHOS::NetStack { time_t HttpTime::StrTimeToTimestamp(const std::string &time_str) { @@ -48,6 +50,7 @@ std::string HttpTime::GetNowTimeGMT() if (gmtime_r(&timeSeconds, &timeInfo) == nullptr) { return {}; } + timeInfo.tm_hour += GMT_UTC_DIFF; char s[MAX_TIME_LEN] = {0}; if (strftime(s, sizeof(s), GMT_TIME, &timeInfo) == 0) { return {}; diff --git a/frameworks/js/napi/http/cache/lru_cache/include/disk_handler.h b/frameworks/js/napi/http/cache/lru_cache/include/disk_handler.h index 400813b44..094c511d8 100644 --- a/frameworks/js/napi/http/cache/lru_cache/include/disk_handler.h +++ b/frameworks/js/napi/http/cache/lru_cache/include/disk_handler.h @@ -16,6 +16,7 @@ #ifndef COMMUNICATIONNETSTACK_DISK_HANDLER_H #define COMMUNICATIONNETSTACK_DISK_HANDLER_H +#include #include #include "nocopyable.h" @@ -25,15 +26,19 @@ class DiskHandler final { public: DiskHandler() = delete; - DiskHandler(std::string fileName); + explicit DiskHandler(std::string fileName); void Write(const std::string &str); + void Delete(); + [[nodiscard]] std::string Read(); private: DISALLOW_COPY_AND_MOVE(DiskHandler); + std::mutex mutex_; + std::string fileName_; }; } // namespace OHOS::NetStack diff --git a/frameworks/js/napi/http/cache/lru_cache/include/lru_cache_disk_handler.h b/frameworks/js/napi/http/cache/lru_cache/include/lru_cache_disk_handler.h index f188cc645..fe0edcb68 100644 --- a/frameworks/js/napi/http/cache/lru_cache/include/lru_cache_disk_handler.h +++ b/frameworks/js/napi/http/cache/lru_cache/include/lru_cache_disk_handler.h @@ -16,11 +16,14 @@ #ifndef COMMUNICATIONNETSTACK_LRU_CACHE_DISK_HANDLER_H #define COMMUNICATIONNETSTACK_LRU_CACHE_DISK_HANDLER_H +#include + #include "disk_handler.h" #include "lru_cache.h" #include "nocopyable.h" -static constexpr const int MAX_DISK_CACHE_SIZE = 1024 * 1024 * 5; +static constexpr const int MAX_DISK_CACHE_SIZE = 1024 * 1024 * 10; +static constexpr const int MIN_DISK_CACHE_SIZE = 1024 * 1024; namespace OHOS::NetStack { class LRUCacheDiskHandler { @@ -33,6 +36,10 @@ public: void ReadCacheFromJsonFile(); + void Delete(); + + void SetCapacity(size_t capacity); + std::unordered_map Get(const std::string &key); void Put(const std::string &key, const std::unordered_map &value); @@ -40,7 +47,7 @@ public: private: LRUCache cache_; DiskHandler diskHandler_; - size_t capacity_; + std::atomic capacity_; Json::Value ReadJsonValueFromFile(); diff --git a/frameworks/js/napi/http/cache/lru_cache/src/disk_handler.cpp b/frameworks/js/napi/http/cache/lru_cache/src/disk_handler.cpp index 8bbc76d58..88a607eaa 100644 --- a/frameworks/js/napi/http/cache/lru_cache/src/disk_handler.cpp +++ b/frameworks/js/napi/http/cache/lru_cache/src/disk_handler.cpp @@ -13,73 +13,39 @@ * limitations under the License. */ -#include "disk_handler.h" +#include +#include + #include "netstack_log.h" -#include -#include -#include -#include -#include -#include +#include "disk_handler.h" namespace OHOS::NetStack { DiskHandler::DiskHandler(std::string fileName) : fileName_(std::move(fileName)) {} void DiskHandler::Write(const std::string &str) { - int fd = open(fileName_.c_str(), O_CREAT | O_WRONLY, S_IWUSR | S_IRUSR); - if (fd < 0) { - NETSTACK_LOGE("errmsg: Write open [%{public}d] %{public}s|\n", errno, strerror(errno)); - return; - } - - int ret = flock(fd, LOCK_NB | LOCK_EX); - if (ret < 0) { - NETSTACK_LOGE("errmsg: Write open [%{public}d] %{public}s|\n", errno, strerror(errno)); - close(fd); - return; - } - - if (write(fd, str.c_str(), str.size()) < 0) { - NETSTACK_LOGE("errmsg: Write open [%{public}d] %{public}s|\n", errno, strerror(errno)); - } - - flock(fd, LOCK_UN); - close(fd); + std::lock_guard guard(mutex_); + std::ofstream w(fileName_); + w << str; + w.close(); } std::string DiskHandler::Read() { - int fd = open(fileName_.c_str(), O_RDONLY); - if (fd < 0) { - NETSTACK_LOGE("errmsg: Read open [%{public}d] %{public}s|\n", errno, strerror(errno)); - return {}; - } - - int ret = flock(fd, LOCK_NB | LOCK_EX); - if (ret < 0) { - NETSTACK_LOGE("errmsg: Read flock [%{public}d] %{public}s|\n", errno, strerror(errno)); - close(fd); - return {}; - } - - struct stat buf = {0}; - if (fstat(fd, &buf) < 0 || buf.st_size <= 0) { - flock(fd, LOCK_UN); - close(fd); - return {}; - } + std::lock_guard guard(mutex_); + std::ifstream r(fileName_); + std::stringstream b; + b << r.rdbuf(); + r.close(); + return b.str(); +} - std::unique_ptr mem(new char[buf.st_size]); - if (read(fd, mem.get(), buf.st_size) < 0) { - NETSTACK_LOGE("errmsg: Read read [%{public}d] %{public}s|\n", errno, strerror(errno)); +void DiskHandler::Delete() +{ + std::lock_guard guard(mutex_); + if (remove(fileName_.c_str()) < 0) { + NETSTACK_LOGI("remove file error %{public}d", errno); } - - flock(fd, LOCK_UN); - close(fd); - std::string str; - str.append(mem.get(), buf.st_size); - return str; } } // namespace OHOS::NetStack diff --git a/frameworks/js/napi/http/cache/lru_cache/src/lru_cache_disk_handler.cpp b/frameworks/js/napi/http/cache/lru_cache/src/lru_cache_disk_handler.cpp index 4ea48793c..546b3e27d 100644 --- a/frameworks/js/napi/http/cache/lru_cache/src/lru_cache_disk_handler.cpp +++ b/frameworks/js/napi/http/cache/lru_cache/src/lru_cache_disk_handler.cpp @@ -13,33 +13,29 @@ * limitations under the License. */ -#if USE_CACHE #include -#endif #include "netstack_log.h" #include "lru_cache_disk_handler.h" -#if USE_CACHE -static constexpr const int WRITE_INTERVAL = 60 * 1000; -#endif - namespace OHOS::NetStack { LRUCacheDiskHandler::LRUCacheDiskHandler(std::string fileName, size_t capacity) - : diskHandler_(std::move(fileName)), capacity_(std::min(MAX_DISK_CACHE_SIZE, capacity)) + : diskHandler_(std::move(fileName)), + capacity_(std::max(std::min(MAX_DISK_CACHE_SIZE, capacity), MIN_DISK_CACHE_SIZE)) +{ +} + +void LRUCacheDiskHandler::SetCapacity(size_t capacity) { -#if USE_CACHE - // 从磁盘中读取缓存到内存里 - ReadCacheFromJsonFile(); - // 起线程每一分钟讲内存缓存持久化 - std::thread([this]() { - while (true) { - std::this_thread::sleep_for(std::chrono::milliseconds(WRITE_INTERVAL)); - WriteCacheToJsonFile(); - } - }).detach(); -#endif + capacity_ = std::max(std::min(MAX_DISK_CACHE_SIZE, capacity), MIN_DISK_CACHE_SIZE); + WriteCacheToJsonFile(); +} + +void LRUCacheDiskHandler::Delete() +{ + cache_.Clear(); + diskHandler_.Delete(); } Json::Value LRUCacheDiskHandler::ReadJsonValueFromFile() diff --git a/frameworks/js/napi/http/constant/include/constant.h b/frameworks/js/napi/http/constant/include/constant.h index 2d446a137..405b92d90 100644 --- a/frameworks/js/napi/http/constant/include/constant.h +++ b/frameworks/js/napi/http/constant/include/constant.h @@ -84,6 +84,7 @@ public: static const char *const PARAM_KEY_READ_TIMEOUT; static const char *const PARAM_KEY_CONNECT_TIMEOUT; static const char *const PARAM_KEY_USING_PROTOCOL; + static const char *const PARAM_KEY_USING_CACHE; static const char *const RESPONSE_KEY_RESULT; static const char *const RESPONSE_KEY_RESPONSE_CODE; diff --git a/frameworks/js/napi/http/constant/src/constant.cpp b/frameworks/js/napi/http/constant/src/constant.cpp index 4af07af90..4adef4be6 100644 --- a/frameworks/js/napi/http/constant/src/constant.cpp +++ b/frameworks/js/napi/http/constant/src/constant.cpp @@ -34,6 +34,7 @@ const char *const HttpConstant::PARAM_KEY_HEADER = "header"; const char *const HttpConstant::PARAM_KEY_READ_TIMEOUT = "readTimeout"; const char *const HttpConstant::PARAM_KEY_CONNECT_TIMEOUT = "connectTimeout"; const char *const HttpConstant::PARAM_KEY_USING_PROTOCOL = "usingProtocol"; +const char *const HttpConstant::PARAM_KEY_USING_CACHE = "usingCache"; const char *const HttpConstant::RESPONSE_KEY_RESULT = "result"; const char *const HttpConstant::RESPONSE_KEY_RESPONSE_CODE = "responseCode"; diff --git a/frameworks/js/napi/http/http_exec/include/http_exec.h b/frameworks/js/napi/http/http_exec/include/http_exec.h index 2af91c721..ef8a0fddc 100644 --- a/frameworks/js/napi/http/http_exec/include/http_exec.h +++ b/frameworks/js/napi/http/http_exec/include/http_exec.h @@ -25,6 +25,23 @@ #include "request_context.h" namespace OHOS::NetStack { +class HttpResponseCacheExec final { +public: + DISALLOW_COPY_AND_MOVE(HttpResponseCacheExec); + + HttpResponseCacheExec() = default; + + ~HttpResponseCacheExec() = default; + + static bool ExecFlush(BaseContext *context); + + static napi_value FlushCallback(BaseContext *context); + + static bool ExecDelete(BaseContext *context); + + static napi_value DeleteCallback(BaseContext *context); +}; + class HttpExec final { public: DISALLOW_COPY_AND_MOVE(HttpExec); diff --git a/frameworks/js/napi/http/http_exec/src/http_exec.cpp b/frameworks/js/napi/http/http_exec/src/http_exec.cpp index 24c02df78..6745a0eb0 100644 --- a/frameworks/js/napi/http/http_exec/src/http_exec.cpp +++ b/frameworks/js/napi/http/http_exec/src/http_exec.cpp @@ -70,7 +70,7 @@ bool HttpExec::ExecRequest(RequestContext *context) { context->options.SetRequestTime(HttpTime::GetNowTimeGMT()); CacheProxy proxy(context->options); - if (proxy.ReadResponseFromCache(context->response)) { + if (context->IsUsingCache() && proxy.ReadResponseFromCache(context->response)) { return true; } @@ -357,4 +357,28 @@ bool HttpExec::IsUnReserved(unsigned char in) } return false; } + +bool HttpResponseCacheExec::ExecFlush(BaseContext *context) +{ + (void)context; + CacheProxy::FlushCache(); + return true; +} + +napi_value HttpResponseCacheExec::FlushCallback(BaseContext *context) +{ + return NapiUtils::GetUndefined(context->GetEnv()); +} + +bool HttpResponseCacheExec::ExecDelete(BaseContext *context) +{ + (void)context; + CacheProxy::StopCacheAndDelete(); + return true; +} + +napi_value HttpResponseCacheExec::DeleteCallback(BaseContext *context) +{ + return NapiUtils::GetUndefined(context->GetEnv()); +} } // namespace OHOS::NetStack diff --git a/frameworks/js/napi/http/http_module/include/http_module.h b/frameworks/js/napi/http/http_module/include/http_module.h index 26e452768..3a67e5395 100644 --- a/frameworks/js/napi/http/http_module/include/http_module.h +++ b/frameworks/js/napi/http/http_module/include/http_module.h @@ -21,6 +21,15 @@ namespace OHOS::NetStack { class HttpModuleExports { public: + class HttpResponseCache { + public: + static constexpr const char *FUNCTION_FLUSH = "flush"; + static constexpr const char *FUNCTION_DELETE = "delete"; + + static napi_value Flush(napi_env env, napi_callback_info info); + static napi_value Delete(napi_env env, napi_callback_info info); + }; + class HttpRequest { public: static constexpr const char *FUNCTION_REQUEST = "request"; @@ -37,18 +46,24 @@ public: }; static constexpr const char *FUNCTION_CREATE_HTTP = "createHttp"; + static constexpr const char *FUNCTION_CREATE_HTTP_RESPONSE_CACHE = "createHttpResponseCache"; static constexpr const char *INTERFACE_REQUEST_METHOD = "RequestMethod"; static constexpr const char *INTERFACE_RESPONSE_CODE = "ResponseCode"; static constexpr const char *INTERFACE_HTTP_REQUEST = "HttpRequest"; static constexpr const char *INTERFACE_HTTP_PROTOCOL = "HttpProtocol"; + static constexpr const char *INTERFACE_HTTP_RESPONSE_CACHE = "HttpResponseCache"; static napi_value InitHttpModule(napi_env env, napi_value exports); private: static napi_value CreateHttp(napi_env env, napi_callback_info info); + static napi_value CreateHttpResponseCache(napi_env env, napi_callback_info info); + static void DefineHttpRequestClass(napi_env env, napi_value exports); + static void DefineHttpResponseCacheClass(napi_env env, napi_value exports); + static void InitHttpProperties(napi_env env, napi_value exports); static void InitRequestMethod(napi_env env, napi_value exports); diff --git a/frameworks/js/napi/http/http_module/src/http_module.cpp b/frameworks/js/napi/http/http_module/src/http_module.cpp index c963de43a..a32168ee1 100644 --- a/frameworks/js/napi/http/http_module/src/http_module.cpp +++ b/frameworks/js/napi/http/http_module/src/http_module.cpp @@ -15,6 +15,7 @@ #include "http_module.h" +#include "cache_proxy.h" #include "constant.h" #include "event_list.h" #include "http_async_work.h" @@ -33,12 +34,17 @@ static constexpr const char *REQUEST_ASYNC_WORK_NAME = "ExecRequest"; +static constexpr const char *FLUSH_ASYNC_WORK_NAME = "ExecFlush"; + +static constexpr const char *DELETE_ASYNC_WORK_NAME = "ExecDelete"; + static constexpr const char *HTTP_MODULE_NAME = "net.http"; namespace OHOS::NetStack { napi_value HttpModuleExports::InitHttpModule(napi_env env, napi_value exports) { DefineHttpRequestClass(env, exports); + DefineHttpResponseCacheClass(env, exports); InitHttpProperties(env, exports); return exports; @@ -52,6 +58,24 @@ napi_value HttpModuleExports::CreateHttp(napi_env env, napi_callback_info info) }); } +napi_value HttpModuleExports::CreateHttpResponseCache(napi_env env, napi_callback_info info) +{ + napi_value thisVal = nullptr; + size_t paramsCount = MAX_PARAM_NUM; + napi_value params[MAX_PARAM_NUM] = {nullptr}; + NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr)); + if (paramsCount != 1 || NapiUtils::GetValueType(env, params[0]) != napi_number) { + CacheProxy::RunCache(); + } else { + size_t size = NapiUtils::GetUint32FromValue(env, params[0]); + CacheProxy::RunCacheWithSize(size); + } + + return ModuleTemplate::NewInstanceNoManager(env, info, INTERFACE_HTTP_RESPONSE_CACHE, [](napi_env, void *, void *) { + NETSTACK_LOGI("http response cache handle is finalized"); + }); +} + void HttpModuleExports::DefineHttpRequestClass(napi_env env, napi_value exports) { std::initializer_list properties = { @@ -64,10 +88,20 @@ void HttpModuleExports::DefineHttpRequestClass(napi_env env, napi_value exports) ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_HTTP_REQUEST); } +void HttpModuleExports::DefineHttpResponseCacheClass(napi_env env, napi_value exports) +{ + std::initializer_list properties = { + DECLARE_NAPI_FUNCTION(HttpResponseCache::FUNCTION_FLUSH, HttpResponseCache::Flush), + DECLARE_NAPI_FUNCTION(HttpResponseCache::FUNCTION_DELETE, HttpResponseCache::Delete), + }; + ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_HTTP_RESPONSE_CACHE); +} + void HttpModuleExports::InitHttpProperties(napi_env env, napi_value exports) { std::initializer_list properties = { DECLARE_NAPI_FUNCTION(FUNCTION_CREATE_HTTP, CreateHttp), + DECLARE_NAPI_FUNCTION(FUNCTION_CREATE_HTTP_RESPONSE_CACHE, CreateHttpResponseCache), }; NapiUtils::DefineProperties(env, exports, properties); @@ -183,6 +217,18 @@ napi_value HttpModuleExports::HttpRequest::Off(napi_env env, napi_callback_info return ModuleTemplate::Off(env, info, {ON_HEADER_RECEIVE}); } +napi_value HttpModuleExports::HttpResponseCache::Flush(napi_env env, napi_callback_info info) +{ + return ModuleTemplate::Interface(env, info, FLUSH_ASYNC_WORK_NAME, nullptr, HttpAsyncWork::ExecFlush, + HttpAsyncWork::FlushCallback); +} + +napi_value HttpModuleExports::HttpResponseCache::Delete(napi_env env, napi_callback_info info) +{ + return ModuleTemplate::Interface(env, info, DELETE_ASYNC_WORK_NAME, nullptr, HttpAsyncWork::ExecDelete, + HttpAsyncWork::DeleteCallback); +} + static napi_module g_httpModule = { .nm_version = 1, .nm_flags = 0, diff --git a/frameworks/js/napi/socket/async_context/include/bind_context.h b/frameworks/js/napi/socket/async_context/include/bind_context.h index 7c43029be..c66e5862d 100644 --- a/frameworks/js/napi/socket/async_context/include/bind_context.h +++ b/frameworks/js/napi/socket/async_context/include/bind_context.h @@ -30,7 +30,7 @@ public: explicit BindContext(napi_env env, EventManager *manager); - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; [[nodiscard]] int GetSocketFd() const; diff --git a/frameworks/js/napi/socket/async_context/include/common_context.h b/frameworks/js/napi/socket/async_context/include/common_context.h index 8260aa8bf..42b40197c 100644 --- a/frameworks/js/napi/socket/async_context/include/common_context.h +++ b/frameworks/js/napi/socket/async_context/include/common_context.h @@ -31,7 +31,7 @@ public: explicit CommonContext(napi_env env, EventManager *manager); - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; [[nodiscard]] int GetSocketFd() const; diff --git a/frameworks/js/napi/socket/async_context/include/connect_context.h b/frameworks/js/napi/socket/async_context/include/connect_context.h index e2aa2ba77..f880d1f03 100644 --- a/frameworks/js/napi/socket/async_context/include/connect_context.h +++ b/frameworks/js/napi/socket/async_context/include/connect_context.h @@ -29,7 +29,7 @@ public: explicit ConnectContext(napi_env env, EventManager *manager); - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; [[nodiscard]] int GetSocketFd() const; diff --git a/frameworks/js/napi/socket/async_context/include/tcp_extra_context.h b/frameworks/js/napi/socket/async_context/include/tcp_extra_context.h index ea63ca1b4..61ba47730 100644 --- a/frameworks/js/napi/socket/async_context/include/tcp_extra_context.h +++ b/frameworks/js/napi/socket/async_context/include/tcp_extra_context.h @@ -29,7 +29,7 @@ public: explicit TcpSetExtraOptionsContext(napi_env env, EventManager *manager); - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; [[nodiscard]] int GetSocketFd() const; diff --git a/frameworks/js/napi/socket/async_context/include/tcp_send_context.h b/frameworks/js/napi/socket/async_context/include/tcp_send_context.h index ec6f6faef..ff8102399 100644 --- a/frameworks/js/napi/socket/async_context/include/tcp_send_context.h +++ b/frameworks/js/napi/socket/async_context/include/tcp_send_context.h @@ -29,7 +29,7 @@ public: explicit TcpSendContext(napi_env env, EventManager *manager); - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; [[nodiscard]] int GetSocketFd() const; diff --git a/frameworks/js/napi/socket/async_context/include/udp_extra_context.h b/frameworks/js/napi/socket/async_context/include/udp_extra_context.h index b0995644b..99e958a85 100644 --- a/frameworks/js/napi/socket/async_context/include/udp_extra_context.h +++ b/frameworks/js/napi/socket/async_context/include/udp_extra_context.h @@ -29,7 +29,7 @@ public: explicit UdpSetExtraOptionsContext(napi_env env, EventManager *manager); - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; [[nodiscard]] int GetSocketFd() const; diff --git a/frameworks/js/napi/socket/async_context/include/udp_send_context.h b/frameworks/js/napi/socket/async_context/include/udp_send_context.h index c8e3d1a15..661a0534f 100644 --- a/frameworks/js/napi/socket/async_context/include/udp_send_context.h +++ b/frameworks/js/napi/socket/async_context/include/udp_send_context.h @@ -29,7 +29,7 @@ public: explicit UdpSendContext(napi_env env, EventManager *manager); - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; [[nodiscard]] int GetSocketFd() const; diff --git a/frameworks/js/napi/websocket/async_context/include/close_context.h b/frameworks/js/napi/websocket/async_context/include/close_context.h index 8baf8b14d..3bb8253d8 100644 --- a/frameworks/js/napi/websocket/async_context/include/close_context.h +++ b/frameworks/js/napi/websocket/async_context/include/close_context.h @@ -30,7 +30,7 @@ public: explicit CloseContext(napi_env env, EventManager *manager); - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; uint32_t code; diff --git a/frameworks/js/napi/websocket/async_context/include/connect_context.h b/frameworks/js/napi/websocket/async_context/include/connect_context.h index 63733f6d8..ddb0b08ee 100644 --- a/frameworks/js/napi/websocket/async_context/include/connect_context.h +++ b/frameworks/js/napi/websocket/async_context/include/connect_context.h @@ -34,7 +34,7 @@ public: ~ConnectContext() override; - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; std::string url; diff --git a/frameworks/js/napi/websocket/async_context/include/send_context.h b/frameworks/js/napi/websocket/async_context/include/send_context.h index 4dcf4b082..f054d2828 100644 --- a/frameworks/js/napi/websocket/async_context/include/send_context.h +++ b/frameworks/js/napi/websocket/async_context/include/send_context.h @@ -31,7 +31,7 @@ public: explicit SendContext(napi_env env, EventManager *manager); - void ParseParams(napi_value *params, size_t paramsCount); + void ParseParams(napi_value *params, size_t paramsCount) override; void *data; diff --git a/test/napi/http/CMakeLists.txt b/test/napi/http/CMakeLists.txt index 39d016881..3b2cb3c19 100644 --- a/test/napi/http/CMakeLists.txt +++ b/test/napi/http/CMakeLists.txt @@ -75,5 +75,4 @@ add_compile_definitions(NETSTACK_PROXY_URL_PORT="xxxx:xxxx") add_compile_definitions(NETSTACK_PROXY_TYPE=CURLPROXY_HTTP) add_compile_definitions(NETSTACK_PROXY_PASS="xxxx:xxxx") add_compile_definitions(SERVER_IP="x.x.x.x") -add_compile_definitions(USE_CACHE=1) set(CMAKE_CXX_FLAGS -g) diff --git a/utils/base_context/include/netstack_base_context.h b/utils/base_context/include/netstack_base_context.h index 24f617fa2..5b28e95e3 100644 --- a/utils/base_context/include/netstack_base_context.h +++ b/utils/base_context/include/netstack_base_context.h @@ -76,6 +76,8 @@ public: [[nodiscard]] EventManager *GetManager() const; + virtual void ParseParams(napi_value *params, size_t paramsCount); + protected: EventManager *manager_; diff --git a/utils/base_context/src/netstack_base_context.cpp b/utils/base_context/src/netstack_base_context.cpp index 20162d603..cf8408092 100644 --- a/utils/base_context/src/netstack_base_context.cpp +++ b/utils/base_context/src/netstack_base_context.cpp @@ -156,4 +156,21 @@ EventManager *BaseContext::GetManager() const { return manager_; } + +void BaseContext::ParseParams(napi_value *params, size_t paramsCount) +{ + if (paramsCount != 0 && paramsCount != 1) { + return; + } + + if (paramsCount == 1 && NapiUtils::GetValueType(env_, params[0]) != napi_function) { + return; + } + + if (paramsCount == 1) { + SetParseOK(SetCallback(params[0]) == napi_ok); + return; + } + SetParseOK(true); +} } // namespace OHOS::NetStack \ No newline at end of file diff --git a/utils/module_template/include/netstack_module_template.h b/utils/module_template/include/netstack_module_template.h index 3a3626f01..ddf5db207 100644 --- a/utils/module_template/include/netstack_module_template.h +++ b/utils/module_template/include/netstack_module_template.h @@ -104,5 +104,7 @@ void DefineClass(napi_env env, const std::string &className); napi_value NewInstance(napi_env env, napi_callback_info info, const std::string &className, Finalizer finalizer); + +napi_value NewInstanceNoManager(napi_env env, napi_callback_info info, const std::string &name, Finalizer finalizer); } // namespace OHOS::NetStack::ModuleTemplate #endif /* COMMUNICATIONNETSTACK_NETSTACK_MODULE_TEMPLATE_H */ diff --git a/utils/module_template/src/netstack_module_template.cpp b/utils/module_template/src/netstack_module_template.cpp index 3c4b63250..19722c259 100644 --- a/utils/module_template/src/netstack_module_template.cpp +++ b/utils/module_template/src/netstack_module_template.cpp @@ -154,4 +154,20 @@ napi_value NewInstance(napi_env env, napi_callback_info info, const std::string return result; } + +napi_value NewInstanceNoManager(napi_env env, napi_callback_info info, const std::string &name, Finalizer finalizer) +{ + napi_value thisVal = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr)); + + napi_value jsConstructor = NapiUtils::GetNamedProperty(env, thisVal, name); + if (NapiUtils::GetValueType(env, jsConstructor) == napi_undefined) { + return nullptr; + } + + napi_value result = nullptr; + NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result)); + + return result; +} } // namespace OHOS::NetStack::ModuleTemplate \ No newline at end of file diff --git a/utils/napi_utils/include/netstack_napi_utils.h b/utils/napi_utils/include/netstack_napi_utils.h index 720eae306..74e174c49 100644 --- a/utils/napi_utils/include/netstack_napi_utils.h +++ b/utils/napi_utils/include/netstack_napi_utils.h @@ -94,6 +94,8 @@ void SetBooleanProperty(napi_env env, napi_value object, const std::string &name napi_value GetBoolean(napi_env env, bool value); +bool GetBooleanFromValue(napi_env env, napi_value value); + /* define properties */ void DefineProperties(napi_env env, napi_value object, diff --git a/utils/napi_utils/src/netstack_napi_utils.cpp b/utils/napi_utils/src/netstack_napi_utils.cpp index 77abd6540..b1708fa06 100644 --- a/utils/napi_utils/src/netstack_napi_utils.cpp +++ b/utils/napi_utils/src/netstack_napi_utils.cpp @@ -308,6 +308,13 @@ napi_value GetBoolean(napi_env env, bool value) return jsValue; } +bool GetBooleanFromValue(napi_env env, napi_value value) +{ + bool ret = false; + NAPI_CALL_BASE(env, napi_get_value_bool(env, value, &ret), false); + return ret; +} + /* define properties */ void DefineProperties(napi_env env, napi_value object, -- Gitee