From bc2f70fc406e2de3edca0a1fd1f17623fd32977e Mon Sep 17 00:00:00 2001 From: yangweimin Date: Sat, 26 Jul 2025 09:18:38 +0800 Subject: [PATCH 1/3] handover dft report to CHR Signed-off-by: yangweimin --- frameworks/js/napi/http/BUILD.gn | 8 +- .../async_context/include/request_context.h | 6 +- .../async_context/src/request_context.cpp | 18 +- .../napi/http/http_exec/include/http_exec.h | 5 + .../js/napi/http/http_exec/src/http_exec.cpp | 77 ++++-- .../native/http/http_client/http_client.cpp | 59 ++++- .../http/http_client/http_client_task.cpp | 72 ++++++ interfaces/innerkits/http_client/BUILD.gn | 16 +- .../http_client/include/http_client.h | 12 + .../http_client/include/http_client_task.h | 35 +++ .../utils/http_handover_handler/BUILD.gn | 8 +- .../http_handover_handler_test.cpp | 244 ++++++++++-------- .../include/epoll_request_handler.h | 4 +- .../include/http_handover_handler.h | 37 ++- .../include/http_handover_info.h | 41 +++ utils/http_over_curl/include/request_info.h | 11 +- .../include/transfer_callbacks.h | 7 + .../http_over_curl/src/epoll_multi_driver.cpp | 10 +- .../src/epoll_request_handler.cpp | 5 +- .../src/http_handover_handler.cpp | 238 +++++++++-------- 20 files changed, 631 insertions(+), 282 deletions(-) create mode 100644 utils/http_over_curl/include/http_handover_info.h diff --git a/frameworks/js/napi/http/BUILD.gn b/frameworks/js/napi/http/BUILD.gn index d36fec729..b67277f6c 100644 --- a/frameworks/js/napi/http/BUILD.gn +++ b/frameworks/js/napi/http/BUILD.gn @@ -171,7 +171,13 @@ ohos_shared_library("http") { "$NETSTACK_DIR/utils/http_over_curl/src/epoll_request_handler.cpp", "$NETSTACK_DIR/utils/http_over_curl/src/http_handover_handler.cpp", ] - defines += [ "HTTP_HANDOVER_FEATURE" ] + defines += [ + "HTTP_HANDOVER_FEATURE", + "HTTP_STACK_NAME=\"http\"", + ] + include_dirs += [ + "$NETSTACK_DIR/interfaces/innerkits/http_client/include", + ] } else { defines = [ "HAS_NETMANAGER_BASE=0", 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 148d13c6c..2e0453259 100644 --- a/frameworks/js/napi/http/async_context/include/request_context.h +++ b/frameworks/js/napi/http/async_context/include/request_context.h @@ -57,7 +57,7 @@ struct RequestHandoverInfo { int32_t handoverNum = 0; int32_t handoverReason = 0; double flowControlTime = 0; - bool isRead = false; + int32_t readFlag = 0; }; #endif @@ -170,8 +170,8 @@ public: std::string GetPinnedPubkey() const; #ifdef HTTP_HANDOVER_FEATURE - void SetRequestHandoverInfo(int32_t handoverNum, int32_t handoverReason, double flowControlTime, bool isRead); - + void SetRequestHandoverInfo(int32_t handoverNum, int32_t handoverReason, double flowControlTime, int32_t readFlag); + std::string GetRequestHandoverInfo(); #endif private: 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 6662f6025..fc6e37871 100755 --- a/frameworks/js/napi/http/async_context/src/request_context.cpp +++ b/frameworks/js/napi/http/async_context/src/request_context.cpp @@ -38,7 +38,6 @@ #include "http_handover_handler.h" #endif - static constexpr const int PARAM_JUST_URL = 1; static constexpr const int PARAM_JUST_URL_OR_CALLBACK = 1; @@ -1048,14 +1047,14 @@ std::string RequestContext::GetPinnedPubkey() const #ifdef HTTP_HANDOVER_FEATURE void RequestContext::SetRequestHandoverInfo(int32_t handoverNum, int32_t handoverReason, double flowControlTime, - bool isRead) + int32_t readFlag) { requestHandoverInfo_.handoverNum = handoverNum; requestHandoverInfo_.handoverReason = handoverReason; requestHandoverInfo_.flowControlTime = flowControlTime; - requestHandoverInfo_.isRead = isRead; + requestHandoverInfo_.readFlag = readFlag; } - + std::string RequestContext::GetRequestHandoverInfo() { std::string requestHandoverInfo; @@ -1063,26 +1062,27 @@ std::string RequestContext::GetRequestHandoverInfo() requestHandoverInfo = "no handover"; return requestHandoverInfo; } - auto isRead = requestHandoverInfo_.isRead; + int32_t readFlag = requestHandoverInfo_.readFlag; requestHandoverInfo += "HandoverNum:"; requestHandoverInfo += std::to_string(requestHandoverInfo_.handoverNum); requestHandoverInfo += ", handoverReason:"; switch (requestHandoverInfo_.handoverReason) { - case HttpOverCurl::HttpHandoverHandler::RequestType::INCOMING: + case HandoverRequestType::INCOMING: requestHandoverInfo += "flowControl, flowControlTime:"; break; - case HttpOverCurl::HttpHandoverHandler::RequestType::NETWORKERROR: + case HandoverRequestType::NETWORKERROR: requestHandoverInfo += "netErr, retransTime:"; break; - case HttpOverCurl::HttpHandoverHandler::RequestType::UNDONE: + case HandoverRequestType::UNDONE: requestHandoverInfo += "undone, retransTime:"; break; default: + requestHandoverInfo += "unkown type"; break; } requestHandoverInfo += std::to_string(requestHandoverInfo_.flowControlTime); requestHandoverInfo += ", isRead:"; - requestHandoverInfo += isRead == 1 ? "true" : (isRead == 0 ? "false" : "error"); + requestHandoverInfo += readFlag == 1 ? "true" : (readFlag == 0 ? "false" : "error"); requestHandoverInfo += ", isStream:"; requestHandoverInfo += this->IsRequestInStream() ? "true" : "false"; return requestHandoverInfo; 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 62bf7eace..38f580246 100644 --- a/frameworks/js/napi/http/http_exec/include/http_exec.h +++ b/frameworks/js/napi/http/http_exec/include/http_exec.h @@ -32,6 +32,9 @@ #include "curl/curl.h" #include "napi/native_api.h" #include "request_context.h" +#ifdef HTTP_HANDOVER_FEATURE +#include "request_info.h" +#endif namespace OHOS::NetStack::Http { class HttpResponseCacheExec final { @@ -108,6 +111,8 @@ private: static bool SetCertPinnerOption(CURL *curl, RequestContext *context); + static void SetRequestInfoCallbacks(HttpOverCurl::TransferCallbacks &callbacks); + static size_t OnWritingMemoryBody(const void *data, size_t size, size_t memBytes, void *userData); static size_t OnWritingMemoryHeader(const void *data, size_t size, size_t memBytes, void *userData); 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 327b389ca..29b41136c 100755 --- a/frameworks/js/napi/http/http_exec/src/http_exec.cpp +++ b/frameworks/js/napi/http/http_exec/src/http_exec.cpp @@ -68,6 +68,9 @@ #include "secure_char.h" #include "trace_events.h" #include "hi_app_event_report.h" +#ifdef HTTP_HANDOVER_FEATURE +#include "http_handover_info.h" +#endif #define NETSTACK_CURL_EASY_SET_OPTION(handle, opt, data, asyncContext) \ do { \ @@ -168,6 +171,56 @@ static void AsyncWorkRequestInStreamCallback(napi_env env, napi_status status, v } } +void HttpExec::SetRequestInfoCallbacks(HttpOverCurl::TransferCallbacks &callbacks) +{ + static auto startedCallback = +[](CURL *easyHandle, void *opaqueData) { + char *url = nullptr; + curl_easy_getinfo(easyHandle, CURLINFO_EFFECTIVE_URL, &url); + auto context = static_cast(opaqueData); + context->GetTrace().Tracepoint(TraceEvents::QUEUE); + }; + + static auto responseCallback = +[](CURLMsg *curlMessage, void *opaqueData) { + auto context = static_cast(opaqueData); + context->GetTrace().Tracepoint(TraceEvents::NAPI_QUEUE); + HttpExec::HandleCurlData(curlMessage, context); + }; + callbacks.startedCallback = startedCallback; + callbacks.doneCallback = responseCallback; + +#ifdef HTTP_HANDOVER_FEATURE + static auto handoverInfoCallback = +[](void *opaqueData) { + HttpHandoverStackInfo httpHandoverStackInfo; + auto context = static_cast(opaqueData); + if (context == nullptr) { + NETSTACK_LOGE("handoverInfoCallback context is nullptr, error!"); + return httpHandoverStackInfo; + } + httpHandoverStackInfo.taskId = context->GetTaskId(); + httpHandoverStackInfo.readTimeout = context->options.GetReadTimeout(); + httpHandoverStackInfo.connectTimeout = context->options.GetConnectTimeout(); + httpHandoverStackInfo.method = context->options.GetMethod(); + httpHandoverStackInfo.requestUrl = context->options.GetUrl(); + httpHandoverStackInfo.isInStream = context->IsRequestInStream(); + httpHandoverStackInfo.isSuccess = (context->IsParseOK() && context->IsExecOK()); + return httpHandoverStackInfo; + }; + static auto setHandoverInfoCallback = +[](HttpHandoverInfo httpHandoverInfo, void *opaqueData) { + auto context = static_cast(opaqueData); + if (context == nullptr) { + NETSTACK_LOGE("setHandoverInfoCallback context is nullptr, error!"); + return; + } + context->SetRequestHandoverCallback(httpHandoverInfo.handoverNum, + httpHandoverInfo.handoverReason, + httpHandoverInfo.flowControlTime, + httpHandoverInfo.readFlag); + }; + callbacks.handoverInfoCallback = handoverInfoCallback; + callbacks.setHandoverInfoCallback = setHandoverInfoCallback; +#endif +} + void HttpExec::AsyncWorkRequestCallback(napi_env env, napi_status status, void *data) { if (status != napi_ok) { @@ -291,21 +344,9 @@ bool HttpExec::AddCurlHandle(CURL *handle, RequestContext *context) SetServerSSLCertOption(handle, context); static HttpOverCurl::EpollRequestHandler requestHandler; - - static auto startedCallback = +[](CURL *easyHandle, void *opaqueData) { - char *url = nullptr; - curl_easy_getinfo(easyHandle, CURLINFO_EFFECTIVE_URL, &url); - auto context = static_cast(opaqueData); - context->GetTrace().Tracepoint(TraceEvents::QUEUE); - }; - - static auto responseCallback = +[](CURLMsg *curlMessage, void *opaqueData) { - auto context = static_cast(opaqueData); - context->GetTrace().Tracepoint(TraceEvents::NAPI_QUEUE); - HttpExec::HandleCurlData(curlMessage, context); - }; - - requestHandler.Process(handle, startedCallback, responseCallback, context); + HttpOverCurl::TransferCallbacks callbacks; + SetRequestInfoCallbacks(callbacks); + requestHandler.Process(handle, callbacks, context); return true; #else std::thread([context, handle] { @@ -497,12 +538,18 @@ void HttpExec::CacheCurlPerformanceTiming(CURL *handle, RequestContext *context) ", size:%{public}" CURL_FORMAT_CURL_OFF_T ", dns:%{public}.3f, connect:%{public}.3f, tls:%{public}.3f, firstSend:%{public}.3f" ", firstRecv:%{public}.3f, total:%{public}.3f, redirect:%{public}.3f" +#ifdef HTTP_HANDOVER_FEATURE + ", %{public}s" +#endif ", errCode:%{public}d, RespCode:%{public}s, httpVer:%{public}s, method:%{public}s, osErr:%{public}ld" ", saddr:%{public}s, sport:%{public}ld, daddr:%{public}s, dport:%{public}ld", context->GetTaskId(), size, dnsTime, connectTime == 0 ? 0 : connectTime - dnsTime, tlsTime == 0 ? 0 : tlsTime - connectTime, firstSendTime == 0 ? 0 : firstSendTime - std::max({dnsTime, connectTime, tlsTime}), firstRecvTime == 0 ? 0 : firstRecvTime - firstSendTime, totalTime, redirectTime, +#ifdef HTTP_HANDOVER_FEATURE + context->GetRequestHandoverInfo().c_str(), +#endif errCode, std::to_string(responseCode).c_str(), std::to_string(httpVer).c_str(), context->options.GetMethod().c_str(), osErr, anomSaddr.c_str(), sport, anomDaddr.c_str(), dport); diff --git a/frameworks/native/http/http_client/http_client.cpp b/frameworks/native/http/http_client/http_client.cpp index ae5b18a6c..ba7aef87c 100644 --- a/frameworks/native/http/http_client/http_client.cpp +++ b/frameworks/native/http/http_client/http_client.cpp @@ -24,6 +24,9 @@ #include "trace_events.h" #include "http_client.h" #include "netstack_log.h" +#ifdef HTTP_HANDOVER_FEATURE +#include "http_handover_info.h" +#endif namespace OHOS { namespace NetStack { @@ -79,17 +82,12 @@ std::shared_ptr HttpSession::CreateTask(const HttpClientRequest return ptr; } -void HttpSession::StartTask(const std::shared_ptr &ptr) +void HttpSession::SetRequestInfoCallbacks( + HttpOverCurl::TransferCallbacks &callbacks, const std::shared_ptr &ptr) { - if (nullptr == ptr) { - NETSTACK_LOGE("HttpSession::StartTask shared_ptr = nullptr! Error!"); + if (nullptr === ptr) { return; } - - static HttpOverCurl::EpollRequestHandler requestHandler; - - ptr->SetStatus(TaskStatus::RUNNING); - auto startedCallback = [ptr](CURL *, void *) { ptr->GetTrace().Tracepoint(TraceEvents::QUEUE); }; @@ -98,7 +96,50 @@ void HttpSession::StartTask(const std::shared_ptr &ptr) ptr->ProcessResponse(curlMessage); ptr->SetStatus(TaskStatus::IDLE); }; - requestHandler.Process(ptr->GetCurlHandle(), startedCallback, responseCallback); + callbacks.startedCallback = startedCallback; + callbacks.doneCallback = responseCallback; + +#ifdef HTTP_HANDOVER_FEATURE + auto handoverInfoCallback = [ptr](void *) { + HttpHandoverStackInfo httpHandoverStackInfo; + httpHandoverStackInfo.taskId = ptr->GetTaskId(); + httpHandoverStackInfo.readTimeout = ptr->GetRequest().GetTimeout(); + httpHandoverStackInfo.connectTimeout = ptr->GetRequest().GetConnectTimeout(); + httpHandoverStackInfo.method = ptr->GetRequest().GetMethod(); + httpHandoverStackInfo.requestUrl = ptr->GetRequest().GetURL(); + httpHandoverStackInfo.isInStream = ptr->onDataReceive_ ? true : false; + httpHandoverStackInfo.isSuccess = ptr->IsSuccess(); + return httpHandoverStackInfo; + }; + static auto setHandoverInfoCallback = [ptr](HttpHandoverInfo httpHandoverInfo, void *) { + ptr->SetRequestHandoverCallback(httpHandoverInfo.handoverNum, + httpHandoverInfo.handoverReason, + httpHandoverInfo.flowControlTime, + httpHandoverInfo.readFlag); + }; + callbacks.handoverInfoCallback = handoverInfoCallback; + callbacks.setHandoverInfoCallback = setHandoverInfoCallback; +#endif +} + +void HttpSession::StartTask(const std::shared_ptr &ptr) +{ + if (nullptr == ptr) { + NETSTACK_LOGE("HttpSession::StartTask shared_ptr = nullptr! Error!"); + return; + } + + static HttpOverCurl::EpollRequestHandler requestHandler; + + ptr->SetStatus(TaskStatus::RUNNING); + + HttpOverCurl::TransferCallbacks callbacks; + SetRequestInfoCallbacks(callbacks, ptr); +#ifdef HTTP_HANDOVER_FEATURE + requestHandler.Process(ptr->GetCurlHandle(), callbacks, &ptr->GetRequest()); +#else + requestHandler.Process(ptr->GetCurlHandle(), callbacks); +#endif } } // namespace HttpClient diff --git a/frameworks/native/http/http_client/http_client_task.cpp b/frameworks/native/http/http_client/http_client_task.cpp index faf1a8683..c01e66181 100644 --- a/frameworks/native/http/http_client/http_client_task.cpp +++ b/frameworks/native/http/http_client/http_client_task.cpp @@ -35,6 +35,9 @@ #include "netsys_client.h" #endif #include "netstack_hisysevent.h" +#ifdef HTTP_HANDOVER_FEATURE +#include "http_handover_info.h" +#endif #define NETSTACK_CURL_EASY_SET_OPTION(handle, opt, data) \ do { \ @@ -797,6 +800,9 @@ void HttpClientTask::DumpHttpPerformance() curl_off_t size = GetSizeFromCurl(curlHandle_); char *ip = nullptr; curl_easy_getinfo(curlHandle_, CURLINFO_PRIMARY_IP, &ip); +#ifdef HTTP_HANDOVER_FEATURE + std::string handoverInfo = GetRequestHandoverInfo(); +#endif NETSTACK_LOGI( "taskid=%{public}d" ", size:%{public}" CURL_FORMAT_CURL_OFF_T @@ -807,6 +813,9 @@ void HttpClientTask::DumpHttpPerformance() ", firstRecv:%{public}.3f" ", total:%{public}.3f" ", redirect:%{public}.3f" +#ifdef HTTP_HANDOVER_FEATURE + ", %{public}s" +#endif ", errCode:%{public}d" ", RespCode:%{public}s" ", httpVer:%{public}s" @@ -816,6 +825,9 @@ void HttpClientTask::DumpHttpPerformance() tlsTime == 0 ? 0 : tlsTime - connectTime, firstSendTime == 0 ? 0 : firstSendTime - std::max({dnsTime, connectTime, tlsTime}), firstRecvTime == 0 ? 0 : firstRecvTime - firstSendTime, totalTime, redirectTime, +#ifdef HTTP_HANDOVER_FEATURE + handoverInfo.c_str(), +#endif error_.GetErrorCode(), std::to_string(responseCode).c_str(), std::to_string(httpVer).c_str(), request_.GetMethod().c_str(), osErr); @@ -850,6 +862,9 @@ void HttpClientTask::ProcessResponse(CURLMsg *msg) if (onCanceled_) { onCanceled_(request_, response_); } +#ifdef HTTP_HANDOVER_FEATURE + SetSuccess(false); +#endif return; } @@ -857,6 +872,9 @@ void HttpClientTask::ProcessResponse(CURLMsg *msg) if (onFailed_) { onFailed_(request_, response_, error_); } +#ifdef HTTP_HANDOVER_FEATURE + SetSuccess(false); +#endif return; } @@ -867,8 +885,14 @@ void HttpClientTask::ProcessResponse(CURLMsg *msg) if (onSucceeded_) { onSucceeded_(request_, response_); } +#ifdef HTTP_HANDOVER_FEATURE + SetSuccess(true); +#endif } else if (onFailed_) { onFailed_(request_, response_, error_); +#ifdef HTTP_HANDOVER_FEATURE + SetSuccess(false); +#endif } #if HAS_NETMANAGER_BASE HttpClientNetworkMessage httpClientNetworkMessage(std::to_string(GetTaskId()), request_, response_, curlHandle_); @@ -894,6 +918,54 @@ bool HttpClientTask::SetDnsCacheOption(CURL *handle) #endif return true; } + +#ifdef HTTP_HANDOVER_FEATURE +void HttpClientTask::SetSuccess(bool isSuccess) +{ + isSuccess_ = isSuccess; +} + +void HttpClientTask::SetRequestHandoverInfo( + int32_t handoverNum, int32_t handoverReason, double flowControlTime, int32_t readFlag) +{ + handoverNum_ = handoverNum; + handoverReason_ = handoverReason; + flowControlTime_ = flowControlTime; + readFlag_ = readFlag; +} + +std::string HttpClientTask::GetRequestHandoverInfo() +{ + std::string requestHandoverInfo; + if (handoverNum_ <= 0) { + requestHandoverInfo = "no handover"; + return requestHandoverInfo; + } + requestHandoverInfo += "HandoverNum:"; + requestHandoverInfo += std::to_string(handoverNum_); + requestHandoverInfo += ", handoverReason:"; + switch (handoverReason_) { + case HandoverRequestType::INCOMING: + requestHandoverInfo += "flowControl, flowControlTime:"; + break; + case HandoverRequestType::NETWORKERROR: + requestHandoverInfo += "netErr, retransTime:"; + break; + case HandoverRequestType::UNDONE: + requestHandoverInfo += "undone, retransTime:"; + break; + default: + requestHandoverInfo += "unkown type"; + break; + } + requestHandoverInfo += std::to_string(flowControlTime_); + requestHandoverInfo += ", isRead:"; + requestHandoverInfo += readFlag_ == 1 ? "true" : (readFlag_ == 0 ? "false" : "error"); + requestHandoverInfo += ", isStream:"; + requestHandoverInfo += onDataReceive_ ? "true" : "false"; + return requestHandoverInfo; +} +#endif } // namespace HttpClient } // namespace NetStack } // namespace OHOS diff --git a/interfaces/innerkits/http_client/BUILD.gn b/interfaces/innerkits/http_client/BUILD.gn index cc2d3ffc4..ddd67d95e 100644 --- a/interfaces/innerkits/http_client/BUILD.gn +++ b/interfaces/innerkits/http_client/BUILD.gn @@ -50,11 +50,21 @@ config("http_client_config") { "HTTP_MULTIPATH_CERT_ENABLE", "HAS_NETSTACK_CHR", ] + include_dirs += [ + "$NETSTACK_DIR/frameworks/js/napi/http/async_context/include", + "$NETSTACK_DIR/frameworks/js/napi/http/constant/include", + "$NETSTACK_DIR/frameworks/js/napi/http/options/include", + "$NETSTACK_DIR/frameworks/js/napi/http/http_exec/include", + ] } if (defined(global_parts_info) && defined(global_parts_info.communication_netmanager_base) && global_parts_info.communication_netmanager_base) { - defines += [ "HAS_NETMANAGER_BASE=1" ] + defines += [ + "HAS_NETMANAGER_BASE=1", + "HTTP_HANDOVER_FEATURE", + "HTTP_STACK_NAME=\"HTTP_CLIEND\"", + ] } } @@ -83,6 +93,9 @@ ohos_shared_library("http_client") { "$NETSTACK_NATIVE_ROOT/http/http_client/http_client_response.cpp", "$NETSTACK_NATIVE_ROOT/http/http_client/http_client_task.cpp", "$NETSTACK_NATIVE_ROOT/http/http_client/http_client_time.cpp", + "$NETSTACK_DIR/frameworks/js/napi/http/async_context/src/request_context.cpp", + "$NETSTACK_DIR/frameworks/js/napi/http/options/src/http_request_options.cpp", + "$NETSTACK_DIR/utils/http_over_curl/src/http_handover_handler.cpp", ] include_dirs = [ @@ -134,6 +147,7 @@ ohos_shared_library("http_client") { "netmanager_base:net_conn_manager_if", "netmanager_base:net_security_config_if", "time_service:time_client", + "napi:ace_napi", ] if (product_name != "ohos-sdk") { external_deps += [ "init:libbegetutil" ] diff --git a/interfaces/innerkits/http_client/include/http_client.h b/interfaces/innerkits/http_client/include/http_client.h index 3b156b5ca..32cb98583 100644 --- a/interfaces/innerkits/http_client/include/http_client.h +++ b/interfaces/innerkits/http_client/include/http_client.h @@ -31,6 +31,10 @@ #include "http_client_request.h" #include "http_client_task.h" +namespace OHOS::NetStack::HttpOverCurl { + struct TransferCallbacks; +} + namespace OHOS { namespace NetStack { namespace HttpClient { @@ -73,6 +77,14 @@ private: * @param ptr A shared pointer to the HttpClientTask object. */ void StartTask(const std::shared_ptr &ptr); + + /** + * Set RequestInfo callbacks. + * @param callbacks A structure object of callback functions for RequestInfo. + * @param ptr A shared pointer to the HttpClientTask object. + */ + void SetRequestInfoCallbacks( + HttpOverCurl::TransferCallbacks &callbacks, const std::shared_ptr &ptr); }; } // namespace HttpClient } // namespace NetStack diff --git a/interfaces/innerkits/http_client/include/http_client_task.h b/interfaces/innerkits/http_client/include/http_client_task.h index cc5725dc8..7310f07c1 100644 --- a/interfaces/innerkits/http_client/include/http_client_task.h +++ b/interfaces/innerkits/http_client/include/http_client_task.h @@ -357,6 +357,34 @@ private: */ bool SetIpResolve(CURL *handle); +#ifdef HTTP_HANDOVER_FEATURE + /** + * Get the flag which indicating whether the request is success. + * @return Return flag indicating the request whether is success. + */ + bool IsSuccess() + { + return isSuccess_; + } + + /** + * Set the request whether is success. + */ + void SetSuccess(bool isSuccess); + + /** + * Get network switch information. + * @return Return String format for obtaining network sswitching information. + */ + std::string GetRequestHandoverInfo(); + + /** + * Set the request information and print it to the log. + */ + void SetRequestHandoverInfo(int32_t handoverNum, int32_t handoverReason, double flowControlTime, + int32_t readFlag); +#endif + /** * Gets the start and end download position for the HTTP request. * @return Returns the string of range. If the position is invallid, the string is empty. @@ -377,6 +405,13 @@ private: HttpClientRequest request_; HttpClientResponse response_; HttpClientError error_; +#ifdef HTTP_HANDOVER_FEATURE + bool isSuccess_ = false; + int32_t handoverNum_ = -1; + int32_t handoverReason_ = -1; + double flowControlTime_ = 0.0; + int32_t readFlag_ = -1; +#endif TaskType type_; TaskStatus status_; diff --git a/test/unittest/utils/http_handover_handler/BUILD.gn b/test/unittest/utils/http_handover_handler/BUILD.gn index 0a461aa22..990e08422 100644 --- a/test/unittest/utils/http_handover_handler/BUILD.gn +++ b/test/unittest/utils/http_handover_handler/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# todo import("//build/ohos.gni") import("//build/test.gni") import("//foundation/communication/netstack/netstack_config.gni") @@ -33,7 +34,7 @@ ohos_unittest("http_handover_handler_test") { branch_protector_ret = "pac_ret" - module_out_path = "netstack/http_handover_handler_test" + module_out_path = "netstack/netstack/http_handover_handler_test" include_dirs = [ "$NETSTACK_DIR/frameworks/js/napi/http/async_context/include", @@ -51,7 +52,10 @@ ohos_unittest("http_handover_handler_test") { ] include_dirs += utils_include - defines = [ "HTTP_HANDOVER_FEATURE" ] + defines = [ + "HTTP_HANDOVER_FEATURE", + "HTTP_STACK_NAME=\"test\"", + ] deps = [ "$NETSTACK_DIR/frameworks/js/napi/http:http", diff --git a/test/unittest/utils/http_handover_handler/http_handover_handler_test.cpp b/test/unittest/utils/http_handover_handler/http_handover_handler_test.cpp index a854e7b19..ce7f18282 100644 --- a/test/unittest/utils/http_handover_handler/http_handover_handler_test.cpp +++ b/test/unittest/utils/http_handover_handler/http_handover_handler_test.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +// todo #include #include "curl/curl.h" #include "http_handover_handler.h" @@ -25,7 +25,6 @@ static constexpr const char *REQUEST_URL = "https://127.0.0.1"; static constexpr const long TIMEOUT_MS = 6000; static constexpr const long TIMEOUT_IMMEDIATE = 0; static constexpr const long TIMEOUT_STOP = -1; -static constexpr const int32_t INIT_NET_ID = -1; static constexpr const FileDescriptor FILE_DESCRIPTOR = 222; CURL *GetCurlHandle() @@ -35,6 +34,35 @@ CURL *GetCurlHandle() curl_easy_setopt(handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); return handle; } + +RequestInfo *GetRequestInfo() +{ + CURL *handle = GetCurlHandle(); + RequestInfo *requestInfo = new RequestInfo(); + requestInfo->easyHandle = handle; + static auto startedCallback = +[](CURL *easyHandle, void *opaqueData) {}; + static auto responseCallback = +[](CURLMsg *curlMessage, void *opaqueData) {}; + static auto handoverInfoCallback = +[](void *opaqueData) { + HttpHandoverStackInfo httpHandoverStackInfo; + return httpHandoverStackInfo; + }; + static auto setHandoverInfoCallback = +[](HttpHandoverInfo httpHandoverInfo, void *opaqueData) {}; + HttpOverCurl::TransferCallbacks callbacks = { + .startedCallback = startedCallback; + .doneCallback = responseCallback; + .handoverInfoCallback = handoverInfoCallback; + .setHandoverInfoCallback = setHandoverInfoCallback; + }; + requestInfo->callbacks = callbacks; + requestInfo->opaqueData = static_cast(malloc(sizeof(Http::RequestContext))); + return requestInfo; +} + +void DeleteRequestInfo(RequestInfo *requestInfo) +{ + free(requestInfo->opaqueData); + delete requestInfo; +} } class HttpHandoverHandlerTest : public testing::Test { @@ -48,34 +76,34 @@ public: virtual void TearDown() {} }; -HWTEST_F(HttpHandoverHandlerTest, TestSocketTime, TestSize.Level2) +HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestSocketTime, TestSize.Level2) { - auto mockHandler = std::make_shared(); + auto netHandoverHandler = std::make_shared(); curl_socket_t fd = 0; - EXPECT_EQ(CheckSocketTime(mockHandler.get(), fd), true); + EXPECT_TRUE(CheckSocketTime(netHandoverHandler.get(), fd)); + EXPECT_TRUE(CheckSocketTime(nullptr, fd)); } -HWTEST_F(HttpHandoverHandlerTest, TestOpenSocket, TestSize.Level2) +HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestOpenSocket, TestSize.Level2) { - auto mockHandler = std::make_shared(); + auto netHandoverHandler = std::make_shared(); curl_sockaddr addr = {AF_INET, SOCK_STREAM, 0}; curlsocktype purpose = CURLSOCKTYPE_IPCXN; - curl_socket_t sockfd = OpenSocket(mockHandler.get(), purpose, &addr); + curl_socket_t sockfd = OpenSocket(netHandoverHandler.get(), purpose, &addr); EXPECT_GE(sockfd, 0); } -HWTEST_F(HttpHandoverHandlerTest, TestCloseSocketCallback, TestSize.Level2) +HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestCloseSocketCallback, TestSize.Level2) { - auto mockHandler = std::make_shared(); + auto netHandoverHandler = std::make_shared(); curl_socket_t fd = 0; - int ret = CloseSocketCallback(mockHandler.get(), fd); + int ret = CloseSocketCallback(netHandoverHandler.get(), fd); EXPECT_EQ(ret, 0); } HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestEvent, TestSize.Level2) { - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); + std::shared_ptr netHandoverHandler = std::make_shared(); netHandoverHandler->Initialize(); netHandoverHandler->IsInitSuccess(); @@ -87,53 +115,45 @@ HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestEvent, TestSize.Level2) netHandoverHandler->SetHandoverTimeoutEvent(TIMEOUT_STOP); FileDescriptor descriptor = FILE_DESCRIPTOR; - EXPECT_TRUE(!netHandoverHandler->IsItHandoverEvent(descriptor)); - EXPECT_TRUE(!netHandoverHandler->IsItHandoverTimeoutEvent(descriptor)); + EXPECT_FALSE(netHandoverHandler->IsItHandoverEvent(descriptor)); + EXPECT_FALSE(netHandoverHandler->IsItHandoverTimeoutEvent(descriptor)); } -HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestTimeoutTimerEvent, TestSize.Level2) +HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestCallbackEvent, TestSize.Level2) { - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); - + std::shared_ptr netHandoverHandler = std::make_shared(); HandoverCallback(static_cast(netHandoverHandler.get())); HandoverTimerCallback(static_cast(netHandoverHandler.get()), TIMEOUT_MS); HandoverCallback(nullptr); HandoverTimerCallback(nullptr, TIMEOUT_MS); netHandoverHandler->HandoverTimeoutCallback(); -} -HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestHandoverEvent, TestSize.Level2) -{ - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); - CURL *handle = GetCurlHandle(); - RequestInfo *requestInfo = new RequestInfo(); - requestInfo->easyHandle = handle; + RequestInfo *requestInfo = GetRequestInfo(); netHandoverHandler->SetCallback(requestInfo); std::map ongoingRequests; CURLM *multi = curl_multi_init(); - netHandoverHandler->SetHandoverEvent(); netHandoverHandler->HandoverRequestCallback(ongoingRequests, multi); - delete requestInfo; + DeleteRequestInfo(requestInfo); + + CURL *handle = GetCurlHandle(); + EXPECT_EQ(netHandoverHandler->IsRequestRead(handlle), 0); } HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestHandoverQuery, TestSize.Level2) { - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); - int32_t status; - int32_t netId; - netHandoverHandler->HandoverQuery(status, netId); - EXPECT_EQ(status, HttpHandoverHandler::INIT); - EXPECT_EQ(netId, INIT_NET_ID); + std::shared_ptr netHandoverHandler = std::make_shared(); + netHandoverHandler->HandoverQuery(); + EXPECT_EQ(netHandoverHandler->GetStatus(), HttpHandoverHandler::INIT); + EXPECT_EQ(netHandoverHandler->GetNetId(), 0); + int32_t netId = 100; + netHandoverHandler->SetNetId(netId); + EXPECT_EQ(netHandoverHandler->GetNetId(), netId); } HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestCheckSocket, TestSize.Level2) { - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); + std::shared_ptr netHandoverHandler = std::make_shared(); curl_socket_t fd = 0; netHandoverHandler->SetSocketOpenTime(fd); @@ -143,117 +163,121 @@ HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestCheckSocket, TestSize.L HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestTryFlowControl, TestSize.Level2) { - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); - CURL *handle = GetCurlHandle(); - RequestInfo *requestInfo = new RequestInfo(); - requestInfo->easyHandle = handle; - requestInfo->opaqueData = static_cast(malloc(sizeof(Http::RequestContext))); + std::shared_ptr netHandoverHandler = std::make_shared(); + RequestInfo *requestInfo = GetRequestInfo(); + netHandoverHandler->SetStatus(HttpHandoverHandler::INIT); + EXPECT_FALSE(netHandoverHandler->TryFlowControl(requestInfo, HandoverRequestType::INCOMING)); + netHandoverHandler->SetStatus(HttpHandoverHandler::START); + EXPECT_TRUE(netHandoverHandler->TryFlowControl(requestInfo, HandoverRequestType::INCOMING)); + EXPECT_TRUE(netHandoverHandler->TryFlowControl(requestInfo, HandoverRequestType::NETWORKERROR)); + EXPECT_TRUE(netHandoverHandler->TryFlowControl(requestInfo, HandoverRequestType::UNDONE)); + netHandoverHandler->SetStatus(HttpHandoverHandler::FATAL); + EXPECT_FALSE(netHandoverHandler->TryFlowControl(requestInfo, HandoverRequestType::INCOMING)); + DeleteRequestInfo(requestInfo); +} - EXPECT_TRUE(!netHandoverHandler->TryFlowControl(requestInfo, HttpHandoverHandler::RequestType::OLD)); - free(requestInfo->opaqueData); - delete requestInfo; +HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTesthandoverRequestCallback, TestSize.Level2) +{ + std::shared_ptr netHandoverHandler = std::make_shared(); + RequestInfo *requestInfo = GetRequestInfo(); + std::map ongoingRequests; + ongoingRequests[requestInfo->easyHandle] = requestInfo; + CURLM *multi = curl_multi_init(); + + netHandoverHandler->SetHandoverEvent(); + netHandoverHandler->SetStatus(HttpHandoverHandler::START); + netHandoverHandler->HandoverRequestCallback(ongoingRequests, multi); + netHandoverHandler->SetHandoverEvent(); + netHandoverHandler->SetStatus(HttpHandoverHandler::END); + netHandoverHandler->HandoverRequestCallback(ongoingRequests, multi); + netHandoverHandler->SetHandoverEvent(); + netHandoverHandler->SetStatus(HttpHandoverHandler::TIMEOUT); + netHandoverHandler->HandoverRequestCallback(ongoingRequests, multi); + netHandoverHandler->SetHandoverEvent(); + netHandoverHandler->SetStatus(HttpHandoverHandler::FATAL); + netHandoverHandler->HandoverRequestCallback(ongoingRequests, multi); + EXPECT_eq(netHandoverHandler->getStatus(), HttpHandoverHandler::FATAL); + DeleteRequestInfo(requestInfo); } HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestRetransRequest, TestSize.Level2) { - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); + std::shared_ptr netHandoverHandler = std::make_shared(); std::map ongoingRequests; CURLM *multi = curl_multi_init(); - CURL *handle = GetCurlHandle(); - RequestInfo *requestInfo = new RequestInfo(); - requestInfo->easyHandle = handle; + RequestInfo *requestInfo = GetRequestInfo(); + EXPECT_TRUE(netHandoverHandler->RetransRequest(ongoingRequests, multi, requestInfo)); + DeleteRequestInfo(requestInfo); +} - EXPECT_TRUE(!netHandoverHandler->RetransRequest(ongoingRequests, multi, requestInfo)); - delete requestInfo; +HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestIsNetworkErrorTypeCorrect, TestSize.Level2) +{ + std::shared_ptr netHandoverHandler = std::make_shared(); + EXPECT_TRUE(netHandoverHandler->IsNetworkErrorTypeCorrect(CURLE_SEND_ERROR)); + EXPECT_TRUE(netHandoverHandler->IsNetworkErrorTypeCorrect(CURLE_RECV_ERROR)); + + EXPECT_TRUE(netHandoverHandler->IsNetworkErrorTypeCorrect(CURLE_COULDNT_RESOLVE_HOST)); + EXPECT_TRUE(netHandoverHandler->IsNetworkErrorTypeCorrect(CURLE_COULDNT_CONNECT)); + EXPECT_TRUE(netHandoverHandler->IsNetworkErrorTypeCorrect(CURLE_SSL_CONNECT_ERROR)); + EXPECT_TRUE(netHandoverHandler->IsNetworkErrorTypeCorrect(CURLE_QUIC_CONNECT_ERROR)); + + EXPECT_FALSE(netHandoverHandler->IsNetworkErrorTypeCorrect(CURLE_OK)); } HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestCheckRequestCanRetrans, TestSize.Level2) { - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); - CURL *handle = GetCurlHandle(); - RequestInfo *requestInfo = new RequestInfo(); - requestInfo->easyHandle = handle; - requestInfo->opaqueData = static_cast(malloc(sizeof(Http::RequestContext))); - - EXPECT_TRUE(netHandoverHandler->CheckRequestCanRetrans(requestInfo, HttpHandoverHandler::RequestType::INCOMING)); - EXPECT_TRUE(netHandoverHandler->CheckRequestCanRetrans(requestInfo, - HttpHandoverHandler::RequestType::NETWORKERROR)); - EXPECT_TRUE(netHandoverHandler->CheckRequestCanRetrans(requestInfo, HttpHandoverHandler::RequestType::OLD)); - EXPECT_TRUE(netHandoverHandler->CheckRequestCanRetrans(requestInfo, HttpHandoverHandler::RequestType::UNDONE)); - free(requestInfo->opaqueData); - delete requestInfo; + std::shared_ptr netHandoverHandler = std::make_shared(); + RequestInfo *requestInfo = GetRequestInfo(); + + EXPECT_TRUE(netHandoverHandler->CheckRequestCanRetrans( + requestInfo, HandoverRequestType::INCOMING, CURLE_SEND_ERROR)); + EXPECT_TRUE(netHandoverHandler->CheckRequestCanRetrans( + requestInfo, HandoverRequestType::NETWORKERROR, CURLE_RECV_ERROR)); + EXPECT_TRUE(netHandoverHandler->CheckRequestCanRetrans( + requestInfo, HandoverRequestType::OLD, CURLE_COULDNT_RESOLVE_HOST)); + EXPECT_TRUE(netHandoverHandler->CheckRequestCanRetrans( + requestInfo, HandoverRequestType::UNDONE, CURLE_COULDNT_CONNECT)); + DeleteRequestInfo(requestInfo); } HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestUndoneRequestHandle, TestSize.Level2) { - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); - CURL *handle = GetCurlHandle(); - RequestInfo *requestInfo = new RequestInfo(); - requestInfo->easyHandle = handle; - requestInfo->opaqueData = static_cast(malloc(sizeof(Http::RequestContext))); + std::shared_ptr netHandoverHandler = std::make_shared(); + RequestInfo *requestInfo = GetRequestInfo(); std::map ongoingRequests; ongoingRequests[requestInfo->easyHandle] = requestInfo; CURLM *multi = curl_multi_init(); - netHandoverHandler->UndoneRequestHandle(ongoingRequests, multi); - free(requestInfo->opaqueData); - delete requestInfo; + DeleteRequestInfo(requestInfo); } HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestProcessRequestErr, TestSize.Level2) { - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); + std::shared_ptr netHandoverHandler = std::make_shared(); std::map ongoingRequests; CURLM *multi = curl_multi_init(); - CURL *handle = GetCurlHandle(); - RequestInfo *requestInfo = new RequestInfo(); - requestInfo->easyHandle = handle; - requestInfo->opaqueData = static_cast(malloc(sizeof(Http::RequestContext))); + RequestInfo *requestInfo = GetRequestInfo(); CURLMsg message; message.msg = CURLMSG_DONE; message.data.result = CURLE_SEND_ERROR; - EXPECT_EQ(netHandoverHandler->ProcessRequestErr(ongoingRequests, multi, requestInfo, &message), 0); - free(requestInfo->opaqueData); - delete requestInfo; + DeleteRequestInfo(requestInfo); } -HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestCheckRequestNetError, TestSize.Level2) +HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestProcessRequestNetErrorType, TestSize.Level2) { - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); + std::shared_ptr netHandoverHandler = std::make_shared(); std::map ongoingRequests; CURLM *multi = curl_multi_init(); - CURL *handle = GetCurlHandle(); - RequestInfo *requestInfo = new RequestInfo(); - requestInfo->easyHandle = handle; - requestInfo->opaqueData = static_cast(malloc(sizeof(Http::RequestContext))); + RequestInfo *requestInfo = GetRequestInfo(); ongoingRequests[requestInfo->easyHandle] = requestInfo; CURLMsg message; - message.msg = CURLMSG_DONE; - message.data.result = CURLE_SEND_ERROR; netHandoverHandler->SetHandoverEvent(); netHandoverHandler->HandoverRequestCallback(ongoingRequests, multi); - netHandoverHandler->CheckRequestNetError(ongoingRequests, multi, requestInfo, &message); - free(requestInfo->opaqueData); - delete requestInfo; -} - -HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestIsNetworkErrorTypeCorrect, TestSize.Level2) -{ - std::shared_ptr netHandoverHandler; - netHandoverHandler = std::make_shared(); - - EXPECT_TRUE(IsNetworkErrorTypeCorrect(CURLE_SEND_ERROR)); - EXPECT_TRUE(IsNetworkErrorTypeCorrect(CURLE_RECV_ERROR)); - EXPECT_TRUE(IsNetworkErrorTypeCorrect(CURLE_COULDNT_CONNECT)); - EXPECT_TRUE(IsNetworkErrorTypeCorrect(CURLE_COULDNT_RESOLVE_HOST)); - EXPECT_TRUE(!IsNetworkErrorTypeCorrect(CURLE_AUTH_ERROR)); + message.msg = CURLMSG_DONE; + message.data.result = CURLE_SEND_ERROR; + EXPECT_FALLSE(netHandoverHandler->ProcessRequestNetError(ongoingRequests, multi, requestInfo, &message)); + DeleteRequestInfo(requestInfo); } } \ No newline at end of file diff --git a/utils/http_over_curl/include/epoll_request_handler.h b/utils/http_over_curl/include/epoll_request_handler.h index 94d40f342..68d105403 100644 --- a/utils/http_over_curl/include/epoll_request_handler.h +++ b/utils/http_over_curl/include/epoll_request_handler.h @@ -25,6 +25,7 @@ #include "thread_safe_storage.h" #include "transfer_callbacks.h" +#include "request_info.h" namespace OHOS::NetStack::HttpOverCurl { @@ -35,8 +36,7 @@ public: explicit EpollRequestHandler(int sleepTimeoutMs = 5000); ~EpollRequestHandler(); - void Process(CURL *easyHandle, const TransferStartedCallback &startedCallback, - const TransferDoneCallback &responseCallback, void *opaqueData = nullptr); + void Process(CURL *easyHandle, TransferCallbacks callbacks, void *opaqueData = nullptr); private: void WorkingThread(); diff --git a/utils/http_over_curl/include/http_handover_handler.h b/utils/http_over_curl/include/http_handover_handler.h index e4489eceb..a63d59325 100644 --- a/utils/http_over_curl/include/http_handover_handler.h +++ b/utils/http_over_curl/include/http_handover_handler.h @@ -32,21 +32,19 @@ #include "request_context.h" namespace OHOS::NetStack::HttpOverCurl { - struct RequestInfo; typedef void *(*HTTP_HAND_OVER_INIT)(void *user, void (*HMS_NetworkBoost_HandoverEventCallback)(void *), - void (*HMS_NetworkBoost_HandoverTimerCallback)(void *, long)); + void (*HMS_NetworkBoost_HandoverTimerCallback)(void *, long), const char* stackName); typedef int32_t (*HTTP_HAND_OVER_UNINIT)(void *handle); typedef void (*HTTP_HAND_OVER_QUERY)(void *handle, int32_t *status, int32_t *netId); -typedef void (*HTTP_HAND_OVER_ADD)(void *handle, void *userp, int32_t type, int32_t isRead); +typedef void (*HTTP_HAND_OVER_ADD)(void *handle, void *userp, int32_t type, int32_t readFlag); typedef void (*HTTP_HAND_OVER_DEL)(void *handle, void *userp, bool isSuccess); typedef int32_t (*HTTP_HAND_OVER_QUERY_REQUEST)(void *handle, void *userp, int32_t *handOverReason, - double *flowControlTime, int32_t *isRead); + double *flowControlTime, int32_t *readFlag); typedef void (*HTTP_HAND_OVER_REPORT_TIMEOUT)(void *handle); -extern void HandoverCallback(void *user); -extern void HandoverTimerCallback(void *user, long timeoutMs); -extern bool IsNetworkErrorTypeCorrect(CURLcode result); +void HandoverCallback(void *user); +void HandoverTimerCallback(void *user, long timeoutMs); bool CheckSocketTime(void *user, curl_socket_t fd); curl_socket_t OpenSocket(void *user, curlsocktype purpose, struct curl_sockaddr *addr); int CloseSocketCallback(void *user, curl_socket_t fd); @@ -54,12 +52,6 @@ int CloseSocketCallback(void *user, curl_socket_t fd); class HttpHandoverHandler { public: enum { INIT, START, CONTINUE, END, FATAL, TIMEOUT }; - enum RequestType { - OLD, // old request before network change - INCOMING, // new request during network change - NETWORKERROR, // old request of network error - UNDONE // undone old request after network change - }; explicit HttpHandoverHandler(); ~HttpHandoverHandler(); @@ -77,20 +69,25 @@ public: bool Initialize(); void SetCallback(RequestInfo *request); void SetHandoverInfo(RequestInfo *requestInfo); - void HandoverQuery(int32_t &status, int32_t &netId); + void HandoverQuery(); bool CheckSocketOpentimeLessThanEndTime(curl_socket_t fd); void SetSocketOpenTime(curl_socket_t fd); void EraseFd(curl_socket_t fd); bool RetransRequest(std::map &ongoingRequests, CURLM *multi, RequestInfo *request); - bool CheckRequestCanRetrans(RequestInfo *request, int32_t requestType); + bool CheckRequestCanRetrans(RequestInfo *request, int32_t requestType, CURLcode result); void UndoneRequestHandle(std::map &ongoingRequests, CURLM *multi); int32_t IsRequestRead(CURL *easyHandle); int32_t IsRequestRead(CURL *easyHandle, time_t &recvtime, time_t &sendtime); - bool CheckRequestNetError(std::map &ongoingRequests, CURLM *multi, + bool IsNetWorkErrorTypeCorret(CURLcode result); + bool ProcessRequestNetError(std::map &ongoingRequests, CURLM *multi, RequestInfo *requestInfo, CURLMsg *msg); - void AddRequest(void *userp, int32_t type, int32_t isRead); - void DelRequest(void *userp); - int32_t QueryRequest(void *userp, int32_t &handOverReason, double &flowControlTime, int32_t &isRead); + void AddRequest(RequestInfo *requestInfo, int32_t type); + void DelRequest(RequestInfo *requestInfo); + int32_t QueryRequest(void *userp, int32_t &handOverReason, double &flowControlTime, int32_t &readFlag); + int32_t GetStatus(); + void SetStatus(int32_t status); + int32_t GetNetId(); + void SetNetId(int32_t netId); private: void *netHandoverHandler_ = nullptr; void *httpHandoverManager_ = nullptr; @@ -111,6 +108,8 @@ private: int endTime_ = 0; int timeoutTime_ = 0; int retrans_ = 0; + int32_t status_ = HttpHandoverHandler::INIT; + int32_t netId_ = 0; }; } // namespace OHOS::NetStack::HttpOverCurl diff --git a/utils/http_over_curl/include/http_handover_info.h b/utils/http_over_curl/include/http_handover_info.h new file mode 100644 index 000000000..d43f597b5 --- /dev/null +++ b/utils/http_over_curl/include/http_handover_info.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 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. + */ + +#ifndef COMMUNICATIONNETSTACK_HTTP_HANDOVER_INFO_H +#define COMMUNICATIONNETSTACK_HTTP_HANDOVER_INFO_H +struct HttpHandoverStackInfo { + unsigned int taskId = 0; + uint32_t readTimeout = 0; + uint32_t connectTimeout = 0; + std::string method = "init"; + std::string requestUrl = "init"; + bool isInStream = false; + bool isSuccess = false; +}; + +struct HttpHandoverInfo { + int32_t handoverNum = 0; + int32_t handoverReason = 0; + double flowControlTime = 0.0; + int32_t readFlag = 0; +}; + +enum HandoverRequestType { + OLD, // old request before network change + INCOMING, // new request during network change + NETWORKERROR, // old request of network error + UNDONE // undone old request after network change +} +#endif // COMMUNICATIONNETSTACK_HTTP_HANDOVER_INFO_H \ No newline at end of file diff --git a/utils/http_over_curl/include/request_info.h b/utils/http_over_curl/include/request_info.h index 8025146cc..1ee9eb164 100644 --- a/utils/http_over_curl/include/request_info.h +++ b/utils/http_over_curl/include/request_info.h @@ -21,11 +21,18 @@ #include "transfer_callbacks.h" namespace OHOS::NetStack::HttpOverCurl { +struct TransferCallbacks { + TransferStartedCallback startedCallback; + TransferDoneCallback doneCallback; +#ifdef HTTP_HANDOVER_FEATURE + TransferHandoverInfoCallback handoverInfoCallback; + SetHandoverInfoCallback setHandoverInfoCallback; +#endif +}; struct RequestInfo { CURL *easyHandle; - TransferStartedCallback startedCallback; - TransferDoneCallback doneCallback; + TransferCallbacks callbacks; void *opaqueData; }; diff --git a/utils/http_over_curl/include/transfer_callbacks.h b/utils/http_over_curl/include/transfer_callbacks.h index f484b1c62..9fdc3154d 100644 --- a/utils/http_over_curl/include/transfer_callbacks.h +++ b/utils/http_over_curl/include/transfer_callbacks.h @@ -19,11 +19,18 @@ #include #include "curl/curl.h" +#ifdef HTTP_HANDOVER_FEATURE +#include "http_handover_info.h" +#endif namespace OHOS::NetStack::HttpOverCurl { using TransferDoneCallback = std::function; using TransferStartedCallback = std::function; +#ifdef HTTP_HANDOVER_FEATURE +using TransferHandoverInfoCallback = std::function; +using SetHandoverInfoCallback = std::function; +#endif } // namespace OHOS::NetStack::HttpOverCurl diff --git a/utils/http_over_curl/src/epoll_multi_driver.cpp b/utils/http_over_curl/src/epoll_multi_driver.cpp index 1500fd04b..9582797a1 100644 --- a/utils/http_over_curl/src/epoll_multi_driver.cpp +++ b/utils/http_over_curl/src/epoll_multi_driver.cpp @@ -117,7 +117,7 @@ void EpollMultiDriver::IncomingRequestCallback() for (auto &request : requestsToAdd) { #ifdef HTTP_HANDOVER_FEATURE if (netHandoverHandler_ && - netHandoverHandler_->TryFlowControl(request, HttpHandoverHandler::RequestType::INCOMING)) { + netHandoverHandler_->TryFlowControl(request, HandoverRequestType::INCOMING)) { continue; } #endif @@ -128,8 +128,8 @@ void EpollMultiDriver::IncomingRequestCallback() continue; } - if (request->startedCallback) { - request->startedCallback(request->easyHandle, request->opaqueData); + if (request->callbacks.startedCallback) { + request->callbacks.startedCallback(request->easyHandle, request->opaqueData); } } } @@ -187,8 +187,8 @@ __attribute__((no_sanitize("cfi"))) void EpollMultiDriver::CheckMultiInfo() break; } #endif - if (requestInfo != nullptr && requestInfo->doneCallback) { - requestInfo->doneCallback(message, requestInfo->opaqueData); + if (requestInfo != nullptr && requestInfo->callbacks.doneCallback) { + requestInfo->callbacks.doneCallback(message, requestInfo->opaqueData); } delete requestInfo; break; diff --git a/utils/http_over_curl/src/epoll_request_handler.cpp b/utils/http_over_curl/src/epoll_request_handler.cpp index 71108813c..6f6f3d543 100644 --- a/utils/http_over_curl/src/epoll_request_handler.cpp +++ b/utils/http_over_curl/src/epoll_request_handler.cpp @@ -38,10 +38,9 @@ EpollRequestHandler::~EpollRequestHandler() } } -void EpollRequestHandler::Process(CURL *easyHandle, const TransferStartedCallback &startedCallback, - const TransferDoneCallback &responseCallback, void *opaqueData) +void EpollRequestHandler::Process(CURL *easyHandle, const TransferCallbacks callbacks, void *opaqueData) { - auto requestInfo = new RequestInfo{easyHandle, startedCallback, responseCallback, opaqueData}; + auto requestInfo = new RequestInfo{easyHandle, callbacks, opaqueData}; incomingQueue_->Push(requestInfo); auto start = [this]() { diff --git a/utils/http_over_curl/src/http_handover_handler.cpp b/utils/http_over_curl/src/http_handover_handler.cpp index 5a4e68f30..455f1d08f 100644 --- a/utils/http_over_curl/src/http_handover_handler.cpp +++ b/utils/http_over_curl/src/http_handover_handler.cpp @@ -13,8 +13,8 @@ * limitations under the License. */ -#include "http_handover_handler.h" #include +#include "http_handover_handler.h" #include "netstack_log.h" #include "request_info.h" #include "request_context.h" @@ -25,7 +25,7 @@ constexpr const char *const METHOD_GET = "GET"; constexpr const char *const METHOD_HEAD = "HEAD"; constexpr const char *const METHOD_OPTIONS = "OPTIONS"; constexpr const char *const METHOD_TRACE = "TRACE"; -constexpr const long TIMEOUT_IMMEDIATE_NS = 1; +constexpr const long TIMEOUT_IMMEDIATE_NS = 1000; HttpHandoverHandler::HttpHandoverHandler() : handOverEvent_(std::make_unique(true)), @@ -34,10 +34,10 @@ HttpHandoverHandler::HttpHandoverHandler() initsuccess_ = Initialize(); } -extern void HandoverCallback(void *user) +void HandoverCallback(void *user) { if (user == nullptr) { - NETSTACK_LOGD("handover callback user is nullptr"); + NETSTACK_LOGE("handover callback user is nullptr"); return; } @@ -45,11 +45,11 @@ extern void HandoverCallback(void *user) handoverhandler->SetHandoverEvent(); } -extern void HandoverTimerCallback(void *user, long timeoutMs) +void HandoverTimerCallback(void *user, long timeoutMs) { NETSTACK_LOGD("HandoverTimerCallback enter, set timeout %{public}ld ms.", timeoutMs); if (user == nullptr) { - NETSTACK_LOGD("timer callback user is nullptr"); + NETSTACK_LOGE("timer callback user is nullptr"); return; } @@ -57,15 +57,6 @@ extern void HandoverTimerCallback(void *user, long timeoutMs) handoverHandler->SetHandoverTimeoutEvent(timeoutMs); } -extern bool IsNetworkErrorTypeCorrect(CURLcode result) -{ - if (result == CURLE_SEND_ERROR || result == CURLE_RECV_ERROR || result == CURLE_COULDNT_CONNECT - || result == CURLE_COULDNT_RESOLVE_HOST) { - return true; - } - return false; -} - bool CheckSocketTime(void *user, curl_socket_t fd) { auto handover = static_cast(user); @@ -79,7 +70,7 @@ curl_socket_t OpenSocket(void *user, curlsocktype purpose, struct curl_sockaddr { curl_socket_t sockfd = socket(addr->family, addr->socktype, addr->protocol); if (sockfd < 0) { - NETSTACK_LOGD("Failed to open socket: %{public}d, errno: %{public}d", sockfd, errno); + NETSTACK_LOGE("Failed to open socket: %{public}d, errno: %{public}d", sockfd, errno); return -1; } auto handover = static_cast(user); @@ -97,12 +88,37 @@ int CloseSocketCallback(void *user, curl_socket_t fd) } int ret = close(fd); if (ret < 0) { - NETSTACK_LOGD("Failed to close socket: %{public}d, errno: %{public}d", fd, errno); + NETSTACK_LOGE("Failed to close socket: %{public}d, errno: %{public}d", fd, errno); return ret; } return 0; } +static bool IsIoError(CURLcode result) +{ + if (result == CURLE_SEND_ERROR || result == CURLE_RECV_ERROR) { + return true; + } + return false; +} + +static bool IsConnectError(CURLcode result) +{ + if (result == CURLE_COULDNT_RESOLVE_HOST || result == CURLE_COULDNT_CONNECT || + result == CURLE_SSL_CONNECT_ERROR || result == CURLE_QUIC_CONNECT_ERROR) { + return true; + } + return false; +} + +bool HttpHandoverHandler::IsNetworkErrorTypeCorrect(CURLcode result) +{ + if (IsIoError(result) || IsConnectError(result)) { + return true; + } + return false; +} + bool HttpHandoverHandler::IsInitSuccess() { return initsuccess_; @@ -113,7 +129,7 @@ bool HttpHandoverHandler::Initialize() const std::string HTTP_HANDOVER_WRAPPER_PATH = "/system/lib64/libhttp_handover.z.so"; netHandoverHandler_ = dlopen(HTTP_HANDOVER_WRAPPER_PATH.c_str(), RTLD_NOW); if (netHandoverHandler_ == nullptr) { - NETSTACK_LOGD("libhttp_handover.z.so was not loaded, error: %{public}s", dlerror()); + NETSTACK_LOGE("libhttp_handover.z.so was not loaded, error: %{public}s", dlerror()); return false; } httpHandoverInit_ = (HTTP_HAND_OVER_INIT)dlsym(netHandoverHandler_, "HMS_NetworkBoost_HttpHandoverManagerInit"); @@ -133,13 +149,17 @@ bool HttpHandoverHandler::Initialize() httpHandoverQuery_ == nullptr || httpHandoverAddRequest_ == nullptr || httpHandoverDelRequest_ == nullptr || httpHandoverQueryRequest_ == nullptr || httpHandoverReportTimeout_ == nullptr); if (hasFuncNull) { - NETSTACK_LOGD("http handover wrapper symbol failed, error: %{public}s", dlerror()); + NETSTACK_LOGE("http handover wrapper symbol failed, error: %{public}s", dlerror()); + dlclose(netHandoverHandler_); + netHandoverHandler_ = nullptr; return false; } NETSTACK_LOGD("NetHandover enabled"); - httpHandoverManager_ = httpHandoverInit_(this, HandoverCallback, HandoverTimerCallback); + httpHandoverManager_ = httpHandoverInit_(this, HandoverCallback, HandoverTimerCallback, HTTP_STACK_NAME); if (httpHandoverManager_ == nullptr) { - NETSTACK_LOGD("http handover manager init fail"); + NETSTACK_LOGE("http handover manager init fail"); + dlclose(netHandoverHandler_); + netHandoverHandler_ = nullptr; return false; } return true; @@ -197,13 +217,13 @@ void HttpHandoverHandler::SetHandoverTimeoutEvent(long timeoutMs) } } -void HttpHandoverHandler::HandoverQuery(int32_t &status, int32_t &netId) +void HttpHandoverHandler::HandoverQuery() { if (httpHandoverQuery_ == nullptr || httpHandoverManager_ == nullptr) { - NETSTACK_LOGD("nullptr param error"); + NETSTACK_LOGE("nullptr param error"); return; } - httpHandoverQuery_(httpHandoverManager_, &status, &netId); + httpHandoverQuery_(httpHandoverManager_, &status_, &netId_); } bool HttpHandoverHandler::CheckSocketOpentimeLessThanEndTime(curl_socket_t fd) @@ -245,29 +265,28 @@ void HttpHandoverHandler::SetCallback(RequestInfo *request) bool HttpHandoverHandler::TryFlowControl(RequestInfo *requestInfo, int32_t requestType) { - int32_t status = -1; - int32_t netId = -1; - HandoverQuery(status, netId); - if (status == HttpHandoverHandler::FATAL) { - NETSTACK_LOGD("Handover status fatal, feature disable."); + HandoverQuery(); + if (GetStatus() == HttpHandoverHandler::FATAL) { + NETSTACK_LOGE("Handover status fatal, feature disable."); return false; } SetCallback(requestInfo); - if (status == HttpHandoverHandler::START) { + if (GetStatus() == HttpHandoverHandler::START) { handoverQueue_.insert(requestInfo); - auto context = static_cast(requestInfo->opaqueData); std::string reason; - if (requestType == RequestType::INCOMING) { + if (requestType == HandoverRequestType::INCOMING) { reason = "incoming request"; - } else if (requestType == RequestType::NETWORKERROR) { + } else if (requestType == HandoverRequestType::NETWORKERROR) { reason = "network error"; } - NETSTACK_LOGD("taskid=%{public}d, FlowControl reason:%{public}s", context->GetTaskId(), reason.c_str()); - AddRequest(requestInfo->opaqueData, requestType, IsRequestRead(requestInfo->easyHandle)); + HttpHandoverStackInfo httpHandoverStackInfo = + requestInfo->callbacks.handoverInfoCallback(requestInfo->opaqueData); + NETSTACK_LOGD("taskid=%{public}d, FlowControl reason:%{public}s", httpHandoverStackInfo.taskId, reason.c_str()); + AddRequest(requestInfo, requestType); return true; } - AddRequest(requestInfo->opaqueData, RequestType::OLD, IsRequestRead(requestInfo->easyHandle)); + AddRequest(requestInfo, HandoverRequestType::OLD); return false; } @@ -283,39 +302,41 @@ bool HttpHandoverHandler::RetransRequest(std::map &ongoin return true; } -bool HttpHandoverHandler::CheckRequestCanRetrans(RequestInfo *request, int32_t requestType) +bool HttpHandoverHandler::CheckRequestCanRetrans(RequestInfo *request, int32_t requestType, CURLcode result) { + if (request == nullptr) { + return false; + } time_t recvtime = 0; time_t sendtime = 0; - int32_t isRead = IsRequestRead(request->easyHandle, recvtime, sendtime); - if (isRead == -1) { + int32_t readFlag = IsRequestRead(request->easyHandle, recvtime, sendtime); + if (readFlag == -1) { return false; } - auto context = static_cast(request->opaqueData); - auto method = context->options.GetMethod(); - int isInstream = context->IsRequestInStream(); - uint32_t readTimeout = context->options.GetReadTimeout(); - uint32_t connecttimeout = context->options.GetConnectTimeout(); - bool isSafe = (method == METHOD_GET || method == METHOD_HEAD || method == METHOD_OPTIONS || method == METHOD_TRACE); + HttpHandoverStackInfo httpHandoverStackInfo = + requestInfo->callbacks.handoverInfoCallback(requestInfo->opaqueData); + bool isSafe = (httpHandoverStackInfo.method == METHOD_GET || httpHandoverStackInfo.method == METHOD_HEAD || + httpHandoverStackInfo.method == METHOD_OPTIONS || httpHandoverStackInfo.method == METHOD_TRACE); bool ret = false; - if (sendtime == 0 || (isSafe && (!isInstream || isRead == 0))) { + if (IsConnectError(result) || sendtime == 0 || (isSafe && (!httpHandoverStackInfo.isInStream || readFlag == 0))) { ret = true; } - if (requestType == RequestType::INCOMING || requestType == RequestType::NETWORKERROR) { + if (requestType == HandoverRequestType::INCOMING || requestType == HandoverRequestType::NETWORKERROR) { return ret; } std::string type; - if (requestType == RequestType::OLD) { + if (requestType == HandoverRequestType::OLD) { type = "old request"; } else { type = "undone request"; } NETSTACK_LOGI( "taskid=%{public}d,requestType:%{public}s,canRetrans:%{public}d," - "method:%{public}s,isInstream:%{public}d,recvtime:%{public}d,sendtime:%{public}d,readTimeout:%{public}u," - "connecttimeout:%{public}u,url:%{public}s ", context->GetTaskId(), type.c_str(), (int)ret, method.c_str(), - isInstream, (int)recvtime, (int)sendtime, readTimeout, connecttimeout, context->options.GetUrl().c_str()); - + "method:%{public}s,isInStream:%{public}d,recvtime:%{public}d,sendtime:%{public}d,readTimeout:%{public}u," + "connecttimeout:%{public}u,url:%{public}s ", + httpHandoverStackInfo.taskId, type.c_str(), (int)ret, httpHandoverStackInfo.method.c_str(), + httpHandoverStackInfo.isInStream, (int)recvtime, (int)sendtime, httpHandoverStackInfo.readTimeout, + httpHandoverStackInfo.connectTimeout, httpHandoverStackInfo.requestUrl.c_str()); return ret; } @@ -324,44 +345,42 @@ void HttpHandoverHandler::UndoneRequestHandle(std::map &o for (auto it = ongoingRequests.begin(); it != ongoingRequests.end();) { auto handle = it->first; auto requestInfo = it->second; - if (CheckRequestCanRetrans(requestInfo, RequestType::UNDONE)) { + if (CheckRequestCanRetrans(requestInfo, HandoverRequestType::UNDONE, CURLE_OK)) { curl_multi_remove_handle(multi, handle); if (RetransRequest(ongoingRequests, multi, requestInfo)) { ++retrans_; - AddRequest(requestInfo->opaqueData, RequestType::UNDONE, IsRequestRead(requestInfo->easyHandle)); + AddRequest(requestInfo, HandoverRequestType::UNDONE); ++it; continue; } - if (requestInfo != nullptr && requestInfo->doneCallback) { + if (requestInfo != nullptr && requestInfo->callbacks.doneCallback) { CURLMsg message; message.msg = CURLMSG_DONE; message.data.result = CURLE_SEND_ERROR; - requestInfo->doneCallback(&message, requestInfo->opaqueData); + requestInfo->callbacks.doneCallback(&message, requestInfo->opaqueData); } it = ongoingRequests.erase(it); + } else { + ++it; } - ++it; } } void HttpHandoverHandler::HandoverRequestCallback(std::map &ongoingRequests, CURLM *multi) { handOverEvent_->Reset(); - int32_t status = -1; - int32_t netId = -1; - HandoverQuery(status, netId); - - NETSTACK_LOGD("Enter HandoverRequestCallback status %{public}d", status); - if (status == HttpHandoverHandler::START) { + HandoverQuery(); + NETSTACK_LOGD("Enter HandoverRequestCallback status %{public}d", GetStatus()); + if (GetStatus() == HttpHandoverHandler::START) { NETSTACK_LOGD("start ongoingRequests:%{public}d", (int)ongoingRequests.size()); for (auto &request : ongoingRequests) { if (requestEndtime_.count(request.second) == 0) { requestEndtime_[request.second] = endTime_; } - (void)CheckRequestCanRetrans(request.second, RequestType::OLD); + (void)CheckRequestCanRetrans(request.second, HandoverRequestType::OLD, CURLE_OK); } - } else if (status == HttpHandoverHandler::END || status == HttpHandoverHandler::TIMEOUT) { - (status == HttpHandoverHandler::END) ? ++endTime_ : ++timeoutTime_; + } else if (GetStatus() == HttpHandoverHandler::END || GetStatus() == HttpHandoverHandler::TIMEOUT) { + (GetStatus() == HttpHandoverHandler::END) ? ++endTime_ : ++timeoutTime_; NETSTACK_LOGD("endTime:%{public}d, timeoutTime: %{public}d, ongoingRequests:%{public}d, retrans count before " "end:%{public}d", endTime_, timeoutTime_, (int)ongoingRequests.size(), retrans_); UndoneRequestHandle(ongoingRequests, multi); @@ -373,8 +392,8 @@ void HttpHandoverHandler::HandoverRequestCallback(std::mapResetEvent(); handOverTimerEvent_->Stop(); - int32_t status = -1; - int32_t netId = -1; - HandoverQuery(status, netId); - if (status == HttpHandoverHandler::END) { + HandoverQuery(); + if (GetStatus() == HttpHandoverHandler::END) { return; } if (httpHandoverManager_ == nullptr) { - NETSTACK_LOGD("httpHandoverManager_ nullptr error"); + NETSTACK_LOGE("httpHandoverManager_ nullptr error"); return; } httpHandoverReportTimeout_(httpHandoverManager_); @@ -421,7 +438,7 @@ int32_t HttpHandoverHandler::IsRequestRead(CURL *easyHandle, time_t &recvtime, t bool HttpHandoverHandler::ProcessRequestErr(std::map &ongoingRequests, CURLM *multi, RequestInfo *requestInfo, CURLMsg *msg) { - if (CheckRequestNetError(ongoingRequests, multi, requestInfo, msg)) { + if (ProcessRequestNetError(ongoingRequests, multi, requestInfo, msg)) { return true; } SetHandoverInfo(requestInfo); @@ -431,20 +448,22 @@ bool HttpHandoverHandler::ProcessRequestErr(std::map &ong void HttpHandoverHandler::SetHandoverInfo(RequestInfo *requestInfo) { if (requestInfo != nullptr) { - int32_t handOverReason = 0; + int32_t handoverReason = 0; double flowControlTime = 0; - int32_t isRead = false; - int32_t handOverNum = QueryRequest(requestInfo->opaqueData, handOverReason, flowControlTime, isRead); - auto context = static_cast(requestInfo->opaqueData); - if (context) { - context->SetRequestHandoverInfo(handOverNum, handOverReason, flowControlTime, isRead); - } - DelRequest(requestInfo->opaqueData); + int32_t readFlag = 0; + int32_t handOverNum = + QueryRequest(requestInfo->opaqueData, handoverReason, flowControlTime, readFlag); + HttpHandoverInfo httpHandoverInfo; + httpHandoverInfo.handoverNum = handOverNum; + httpHandoverInfo.handoverReason = handoverReason; + httpHandoverInfo.flowControlTime = flowControlTime; + httpHandoverInfo.readFlag = readFlag; + requestInfo->callbacks.setHandoverInfoCallback(httpHandoverInfo, requestInfo->opaqueData); + DelRequest(requestInfo); } - return; } -bool HttpHandoverHandler::CheckRequestNetError(std::map &ongoingRequests, CURLM *multi, +bool HttpHandoverHandler::ProcessRequestNetError(std::map &ongoingRequests, CURLM *multi, RequestInfo *requestInfo, CURLMsg *msg) { if (!requestInfo || requestEndtime_.count(requestInfo) == 0) { @@ -455,51 +474,68 @@ bool HttpHandoverHandler::CheckRequestNetError(std::map & if (!msg || !IsNetworkErrorTypeCorrect(msg->data.result)) { return false; } - if (!CheckRequestCanRetrans(requestInfo, RequestType::NETWORKERROR)) { + if (!CheckRequestCanRetrans(requestInfo, HandoverRequestType::NETWORKERROR, msg->data.result)) { return false; } - if (TryFlowControl(requestInfo, RequestType::NETWORKERROR)) { + if (TryFlowControl(requestInfo, HandoverRequestType::NETWORKERROR)) { ++retrans_; return true; } if (endTime == endTime_ - 1) { NETSTACK_LOGD("networkerror after end status"); - AddRequest(requestInfo->opaqueData, RequestType::NETWORKERROR, IsRequestRead(requestInfo->easyHandle)); + AddRequest(requestInfo, HandoverRequestType::NETWORKERROR); return RetransRequest(ongoingRequests, multi, requestInfo); } return false; } -void HttpHandoverHandler::AddRequest(void *userp, int32_t type, int32_t isRead) +void HttpHandoverHandler::AddRequest(RequestInfo *requestInfo, int32_t type) { if (httpHandoverManager_ == nullptr) { - NETSTACK_LOGD("httpHandoverManager_ nullptr error"); + NETSTACK_LOGE("httpHandoverManager_ nullptr error"); return; } - httpHandoverAddRequest_(httpHandoverManager_, userp, type, isRead); + httpHandoverAddRequest_(httpHandoverManager_, requestInfo->opaqueData, type, + IsRequestRead(requestInfo->easyHandle)); } -void HttpHandoverHandler::DelRequest(void *userp) +void HttpHandoverHandler::DelRequest(RequestInfo *requestInfo) { if (httpHandoverManager_ == nullptr) { - NETSTACK_LOGD("httpHandoverManager_ nullptr error"); - return; - } - auto context = static_cast(userp); - if (context->IsParseOK() && context->IsExecOK()) { - httpHandoverDelRequest_(httpHandoverManager_, userp, true); + NETSTACK_LOGE("httpHandoverManager_ nullptr error"); return; } - httpHandoverDelRequest_(httpHandoverManager_, userp, false); + HttpHandoverStackInfo httpHandoverStackInfo = requestInfo->callbacks.handoverInfoCallback(requestInfo->opaqueData); + httpHandoverDelRequest_(httpHandoverManager_, requestInfo->opaqueData, httpHandoverStackInfo.isSuccess); } int32_t HttpHandoverHandler::QueryRequest(void *userp, int32_t &handOverReason, double &flowControlTime, - int32_t &isRead) + int32_t &readFlag) { if (httpHandoverManager_ == nullptr) { - NETSTACK_LOGD("httpHandoverManager_ nullptr error"); + NETSTACK_LOGE("httpHandoverManager_ nullptr error"); return -1; } - return httpHandoverQueryRequest_(httpHandoverManager_, userp, &handOverReason, &flowControlTime, &isRead); + return httpHandoverQueryRequest_(httpHandoverManager_, userp, &handOverReason, &flowControlTime, &readFlag); +} + +int32_t HttpHandoverHandler::GetStatus() +{ + return status_; +} + +void HttpHandoverHandler::SetStatus(int32_t status) +{ + status_ = status; +} + +int32_t HttpHandoverHandler::GetNetId() +{ + return netId_; +} + +void HttpHandoverHandler::SetNetId(int32_t netId) +{ + netId_ = netId; } } \ No newline at end of file -- Gitee From c99eea3f4c38e9c7935ac84286dec5b7320992ef Mon Sep 17 00:00:00 2001 From: YangWeimin Date: Thu, 14 Aug 2025 11:41:26 +0000 Subject: [PATCH 2/3] update test/unittest/utils/http_handover_handler/BUILD.gn. Signed-off-by: YangWeimin --- .../utils/http_handover_handler/BUILD.gn | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/test/unittest/utils/http_handover_handler/BUILD.gn b/test/unittest/utils/http_handover_handler/BUILD.gn index 990e08422..84ce9e50b 100644 --- a/test/unittest/utils/http_handover_handler/BUILD.gn +++ b/test/unittest/utils/http_handover_handler/BUILD.gn @@ -11,7 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -# todo import("//build/ohos.gni") import("//build/test.gni") import("//foundation/communication/netstack/netstack_config.gni") @@ -52,10 +51,7 @@ ohos_unittest("http_handover_handler_test") { ] include_dirs += utils_include - defines = [ - "HTTP_HANDOVER_FEATURE", - "HTTP_STACK_NAME=\"test\"", - ] + defines = [] deps = [ "$NETSTACK_DIR/frameworks/js/napi/http:http", @@ -74,6 +70,35 @@ ohos_unittest("http_handover_handler_test") { "hiappevent:hiappevent_innerapi", ] + if (is_mingw || is_mac) { + sources += + [ "$NETSTACK_DIR/utils/common_utils/src/netstack_common_utils.cpp" ] + deps += [ + "//vendor/open_source/boringssl:crypto_boringssl", + "//vendor/open_source/boringssl:ssl_boringssl", + ] + } else { + if (defined(global_parts_info) && + defined(global_parts_info.communication_netmanager_base) && + global_parts_info.communication_netmanager_base) { + external_deps += [ + "netmanager_base:net_conn_manager_if", + "netmanager_base:net_security_config_if", + "netmanager_base:netsys_client", + "hitrace:hitrace_meter", + "samgr:samgr_proxy", + "safwk:system_ability_fwk", + ] + defines += [ + "HAS_NETMANAGER_BASE=1", + "HTTP_HANDOVER_FEATURE", + "HTTP_STACK_NAME=\"test\"", + ] + } else { + defines += [ "HAS_NETMANAGER_BASE=0" ] + } + } + sources = [ "$NETSTACK_DIR/frameworks/js/napi/http/async_context/src/request_context.cpp", "$NETSTACK_DIR/frameworks/js/napi/http/constant/src/constant.cpp", @@ -81,7 +106,7 @@ ohos_unittest("http_handover_handler_test") { "$NETSTACK_DIR/frameworks/js/napi/http/http_exec/src/http_tls_config.cpp", "$NETSTACK_DIR/frameworks/js/napi/http/options/src/http_request_options.cpp", "$NETSTACK_DIR/utils/profiler_utils/src/netstack_network_profiler.cpp", - "$NETSTACK_UTILS_ROOT/http_over_curl/src/http_handover_handler.cpp", + "$SUBSYSTEM_DIR/netstack/frameworks/js/napi/websocket/websocket_module/src/http_handover_handler.cpp", "http_handover_handler_test.cpp", ] -- Gitee From d3c2ea89995e3870cffda9af3569fc4ddeec1ac0 Mon Sep 17 00:00:00 2001 From: YangWeimin Date: Thu, 14 Aug 2025 11:42:30 +0000 Subject: [PATCH 3/3] update test/unittest/utils/http_handover_handler/http_handover_handler_test.cpp. Signed-off-by: YangWeimin --- .../http_handover_handler_test.cpp | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/test/unittest/utils/http_handover_handler/http_handover_handler_test.cpp b/test/unittest/utils/http_handover_handler/http_handover_handler_test.cpp index ce7f18282..2d816ab71 100644 --- a/test/unittest/utils/http_handover_handler/http_handover_handler_test.cpp +++ b/test/unittest/utils/http_handover_handler/http_handover_handler_test.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// todo + #include #include "curl/curl.h" #include "http_handover_handler.h" @@ -40,18 +40,18 @@ RequestInfo *GetRequestInfo() CURL *handle = GetCurlHandle(); RequestInfo *requestInfo = new RequestInfo(); requestInfo->easyHandle = handle; - static auto startedCallback = +[](CURL *easyHandle, void *opaqueData) {}; - static auto responseCallback = +[](CURLMsg *curlMessage, void *opaqueData) {}; - static auto handoverInfoCallback = +[](void *opaqueData) { + static auto startCallback = +[](CURL *easyHandle, void *opaqueData){}; + static auto responseCallback = +[](CURLMsg *curlMessage, void *opaqueData){}; + static auto handoverInfoCallback = +[](void *opaqueData){ HttpHandoverStackInfo httpHandoverStackInfo; return httpHandoverStackInfo; }; - static auto setHandoverInfoCallback = +[](HttpHandoverInfo httpHandoverInfo, void *opaqueData) {}; + static auto setHandoverInfoCallback = +[](HttpHandoverInfo httpHandoverInfo, void *opaqueData){}; HttpOverCurl::TransferCallbacks callbacks = { - .startedCallback = startedCallback; - .doneCallback = responseCallback; - .handoverInfoCallback = handoverInfoCallback; - .setHandoverInfoCallback = setHandoverInfoCallback; + .startedCallback = startCallback, + .doneCallback = responseCallback, + .handoverInfoCallback = handoverInfoCallback, + .setHandoverInfoCallback = setHandoverInfoCallback, }; requestInfo->callbacks = callbacks; requestInfo->opaqueData = static_cast(malloc(sizeof(Http::RequestContext))); @@ -78,7 +78,7 @@ public: HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestSocketTime, TestSize.Level2) { - auto netHandoverHandler = std::make_shared(); + std::shared_ptr netHandoverHandler = std::make_shared(); curl_socket_t fd = 0; EXPECT_TRUE(CheckSocketTime(netHandoverHandler.get(), fd)); EXPECT_TRUE(CheckSocketTime(nullptr, fd)); @@ -86,7 +86,7 @@ HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestSocketTime, TestSize.Le HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestOpenSocket, TestSize.Level2) { - auto netHandoverHandler = std::make_shared(); + std::shared_ptr netHandoverHandler = std::make_shared(); curl_sockaddr addr = {AF_INET, SOCK_STREAM, 0}; curlsocktype purpose = CURLSOCKTYPE_IPCXN; curl_socket_t sockfd = OpenSocket(netHandoverHandler.get(), purpose, &addr); @@ -115,8 +115,8 @@ HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestEvent, TestSize.Level2) netHandoverHandler->SetHandoverTimeoutEvent(TIMEOUT_STOP); FileDescriptor descriptor = FILE_DESCRIPTOR; - EXPECT_FALSE(netHandoverHandler->IsItHandoverEvent(descriptor)); - EXPECT_FALSE(netHandoverHandler->IsItHandoverTimeoutEvent(descriptor)); + EXPECT_TRUE(!netHandoverHandler->IsItHandoverEvent(descriptor)); + EXPECT_TRUE(!netHandoverHandler->IsItHandoverTimeoutEvent(descriptor)); } HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestCallbackEvent, TestSize.Level2) @@ -137,7 +137,7 @@ HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestCallbackEvent, TestSize DeleteRequestInfo(requestInfo); CURL *handle = GetCurlHandle(); - EXPECT_EQ(netHandoverHandler->IsRequestRead(handlle), 0); + EXPECT_EQ(netHandoverHandler->IsRequestRead(handle), 0); } HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestHandoverQuery, TestSize.Level2) @@ -154,7 +154,6 @@ HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestHandoverQuery, TestSize HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestCheckSocket, TestSize.Level2) { std::shared_ptr netHandoverHandler = std::make_shared(); - curl_socket_t fd = 0; netHandoverHandler->SetSocketOpenTime(fd); netHandoverHandler->EraseFd(fd); @@ -176,7 +175,7 @@ HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestTryFlowControl, TestSiz DeleteRequestInfo(requestInfo); } -HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTesthandoverRequestCallback, TestSize.Level2) +HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestHandoverRequestCallback, TestSize.Level2) { std::shared_ptr netHandoverHandler = std::make_shared(); RequestInfo *requestInfo = GetRequestInfo(); @@ -196,7 +195,7 @@ HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTesthandoverRequestCallback netHandoverHandler->SetHandoverEvent(); netHandoverHandler->SetStatus(HttpHandoverHandler::FATAL); netHandoverHandler->HandoverRequestCallback(ongoingRequests, multi); - EXPECT_eq(netHandoverHandler->getStatus(), HttpHandoverHandler::FATAL); + EXPECT_EQ(netHandoverHandler->GetStatus(), HttpHandoverHandler::FATAL); DeleteRequestInfo(requestInfo); } @@ -264,20 +263,19 @@ HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestProcessRequestErr, Test DeleteRequestInfo(requestInfo); } -HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestProcessRequestNetErrorType, TestSize.Level2) +HWTEST_F(HttpHandoverHandlerTest, HttpHandoverHandlerTestProcessRequestNetErrorErrorType, TestSize.Level2) { std::shared_ptr netHandoverHandler = std::make_shared(); std::map ongoingRequests; CURLM *multi = curl_multi_init(); RequestInfo *requestInfo = GetRequestInfo(); - ongoingRequests[requestInfo->easyHandle] = requestInfo; CURLMsg message; netHandoverHandler->SetHandoverEvent(); netHandoverHandler->HandoverRequestCallback(ongoingRequests, multi); message.msg = CURLMSG_DONE; message.data.result = CURLE_SEND_ERROR; - EXPECT_FALLSE(netHandoverHandler->ProcessRequestNetError(ongoingRequests, multi, requestInfo, &message)); + EXPECT_FALSE(netHandoverHandler->ProcessRequestNetError(ongoingRequests, multi, requestInfo, &message)); DeleteRequestInfo(requestInfo); } } \ No newline at end of file -- Gitee