* Copyright (c) 2024 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 WEB_SCHEME_HANDLER_REQUEST_H
#define WEB_SCHEME_HANDLER_REQUEST_H
#include <cstdint>
#include <map>
#include "ffi_remote_data.h"
#include "web_errors.h"
#include "webview_javascript_result_callback.h"
#include "nweb.h"
#include "nweb_helper.h"
#include "arkweb_scheme_handler.h"
#include "nweb_log.h"
namespace OHOS::Webview {
enum class WebResourceType : int {
MAIN_FRAME = 0,
SUB_FRAME = 1,
STYLE_SHEET = 2,
SCRIPT = 3,
IMAGE = 4,
FONT_RESOURCE = 5,
SUB_RESOURCE = 6,
OBJECT = 7,
MEDIA = 8,
WORKED = 9,
SHARED_WORKED = 10,
PREFETCH = 11,
FAVICON = 12,
XHR = 13,
PING = 14,
SERVICE_WORKED = 15,
CSP_REPORT = 16,
PLUNGIN_RESOURCE = 17,
NAVIGATION_PRELOAD_MAIN_FRAME = 19,
NAVIGATION_PRELOAD_SUB_FRAME = 20
};
class WebHttpBodyStreamImpl : public OHOS::FFI::FFIData {
DECL_TYPE(WebHttpBodyStreamImpl, OHOS::FFI::FFIData)
public:
explicit WebHttpBodyStreamImpl() = default;
WebHttpBodyStreamImpl(ArkWeb_HttpBodyStream* stream)
{
stream_ = stream;
};
~WebHttpBodyStreamImpl()
{
if (stream_) {
OH_ArkWebResourceRequest_DestroyHttpBodyStream(stream_);
stream_ = nullptr;
}
};
static void HttpBodyStreamInitCallback(const ArkWeb_HttpBodyStream* httpBodyStream, ArkWeb_NetError result);
int32_t initialize();
int32_t Read(int32_t bufLen);
uint64_t GetPostion();
uint64_t GetSize();
bool IsChunked();
bool IsEof();
bool IsInMemory();
private:
ArkWeb_HttpBodyStream* stream_ = nullptr;
};
using WebHeaderList = std::vector<std::pair<std::string, std::string>>;
class WebSchemeHandlerRequestImpl : public OHOS::FFI::FFIData {
DECL_TYPE(WebSchemeHandlerRequestImpl, OHOS::FFI::FFIData)
public:
explicit WebSchemeHandlerRequestImpl() = default;
WebSchemeHandlerRequestImpl(const ArkWeb_ResourceRequest* request)
{
OH_ArkWebResourceRequest_GetUrl(request, &url_);
OH_ArkWebResourceRequest_GetMethod(request, &method_);
OH_ArkWebResourceRequest_GetReferrer(request, &referrer_);
isRedirect_ = OH_ArkWebResourceRequest_IsRedirect(request);
isMainFrame_ = OH_ArkWebResourceRequest_IsMainFrame(request);
hasGesture_ = OH_ArkWebResourceRequest_HasGesture(request);
OH_ArkWebResourceRequest_GetFrameUrl(request, &frameUrl_);
OH_ArkWebResourceRequest_GetHttpBodyStream(request, &stream_);
requestResourceType_ = OH_ArkWebResourceRequest_GetResourceType(request);
ArkWeb_RequestHeaderList* arkWebHeaderlist = nullptr;
OH_ArkWebResourceRequest_GetRequestHeaders(request, &arkWebHeaderlist);
if (!arkWebHeaderlist) {
WVLOG_E("OH_ArkWebRequestHeaderList_Create failed");
return;
}
int32_t size = OH_ArkWebRequestHeaderList_GetSize(arkWebHeaderlist);
if (size <= 0) {
WVLOG_E("OH_ArkWebRequestHeaderList_GetSize:%{public}d", size);
return;
}
for (int32_t index = 0; index < size; index++) {
char* key;
char* value;
OH_ArkWebRequestHeaderList_GetHeader(arkWebHeaderlist, index, &key, &value);
if (!key || !value) {
continue;
}
std::string strKey(key);
std::string strValue(value);
headerList_.emplace_back(std::make_pair(strKey, strValue));
OH_ArkWeb_ReleaseString(key);
OH_ArkWeb_ReleaseString(value);
}
OH_ArkWebRequestHeaderList_Destroy(arkWebHeaderlist);
};
std::string GetRequestUrl();
std::string GetMethod();
std::string GetReferrer();
std::string GetFrameUrl();
int32_t GetRequestResourceType();
ArkWeb_HttpBodyStream* GetHttpBodyStream();
const WebHeaderList& GetHeader();
bool HasGesture();
bool IsMainFrame();
bool IsRedirect();
private:
char* url_ = nullptr;
char* method_ = nullptr;
char* referrer_ = nullptr;
char* frameUrl_ = nullptr;
int32_t requestResourceType_ = -1;
bool isRedirect_ = false;
bool isMainFrame_ = false;
bool hasGesture_ = false;
WebHeaderList headerList_;
ArkWeb_HttpBodyStream* stream_ = nullptr;
};
class WebSchemeHandlerImpl : public OHOS::FFI::FFIData {
DECL_TYPE(WebSchemeHandlerImpl, OHOS::FFI::FFIData)
public:
explicit WebSchemeHandlerImpl();
~WebSchemeHandlerImpl();
static const ArkWeb_SchemeHandler* GetArkWebSchemeHandler(
WebSchemeHandlerImpl* handler);
static WebSchemeHandlerImpl* GetWebSchemeHandler(
const ArkWeb_SchemeHandler* handler);
void RequestStart(ArkWeb_ResourceRequest* request,
const ArkWeb_ResourceHandler* ArkWeb_ResourceHandler,
bool* intercept);
void RequestStop(const ArkWeb_ResourceRequest* resourceRequest);
void PutRequestStart(std::function<bool(int64_t, int64_t)> callback);
void PutRequestStop(std::function<void(int64_t)> callback);
static std::unordered_map<WebSchemeHandlerImpl*, const ArkWeb_SchemeHandler*>
webSchemeHandlerMap_;
static std::unordered_map<const ArkWeb_SchemeHandler*, WebSchemeHandlerImpl*>
arkWebSchemeHandlerMap_;
private:
typedef struct RequestStopParam {
std::function<void(int64_t)> callbackRef_;
WebSchemeHandlerRequestImpl* request_;
const ArkWeb_ResourceRequest* arkWebRequest_;
} RequestStopParam;
static void RequestStopAfterWorkCb(RequestStopParam* param);
ArkWeb_OnRequestStart onRequestStart_ = nullptr;
ArkWeb_OnRequestStop onRequestStop_ = nullptr;
std::function<bool(int64_t, int64_t)> request_start_callback_ = nullptr;
std::function<void(int64_t)> request_stop_callback_ = nullptr;
};
class WebResourceHandlerImpl : public OHOS::FFI::FFIData {
DECL_TYPE(WebResourceHandlerImpl, OHOS::FFI::FFIData)
public:
explicit WebResourceHandlerImpl() = default;
WebResourceHandlerImpl(const ArkWeb_ResourceHandler* handler)
{
handler_ = const_cast<ArkWeb_ResourceHandler*>(handler);
};
~WebResourceHandlerImpl() = default;
int32_t DidReceiveResponse(const ArkWeb_Response* response);
int32_t DidReceiveResponseBody(const uint8_t* buffer, int64_t buflen);
int32_t DidFinish();
int32_t DidFailWithError(ArkWeb_NetError errorCode);
void DestroyArkWebResourceHandler();
void SetFinishFlag()
{
isFinished_ = true;
}
private:
bool isFinished_ = false;
ArkWeb_ResourceHandler* handler_ = nullptr;
};
}
#endif