diff --git a/interfaces/kits/ani/webview/BUILD.gn b/interfaces/kits/ani/webview/BUILD.gn index 6bf09842cc6efabc3cb85bf1890f089df068b831..769db3f3394c7756c6d84635ad924d83a18bf666 100644 --- a/interfaces/kits/ani/webview/BUILD.gn +++ b/interfaces/kits/ani/webview/BUILD.gn @@ -48,6 +48,7 @@ ohos_shared_library("webview_ani") { "./src/common/ani_business_error.cpp", "./src/common/ani_parse_utils.cpp", "./src/common/ani_parse_utils.h", + "./src/common/ani_web_net_error_list.h", "./src/webstorage/ani_web_storage.cpp", "./src/webadsblockmanager/ani_web_adsblock_manager.h", "./src/webadsblockmanager/ani_web_adsblock_manager.cpp", @@ -65,6 +66,8 @@ ohos_shared_library("webview_ani") { "./src/webviewcontroller/ani_web_scheme_handler.h", "./src/webviewcontroller/ani_web_scheme_handler_response.cpp", "./src/webviewcontroller/ani_web_scheme_handler_response.h", + "./src/webviewcontroller/ani_web_http_body_stream.cpp", + "./src/webviewcontroller/ani_web_http_body_stream.h", "./src/webviewcontroller/ani_web_download_delegate.cpp", "./src/webviewcontroller/ani_web_download_item.cpp", "./src/webviewcontroller/ani_web_download_manager.cpp", @@ -154,6 +157,7 @@ generate_static_abc("web_webview") { base_url = "./ets" files = [ "./ets/@ohos.web.webview.ets", + "./ets/@ohos.web.netErrorList.ets", ] is_boot_abc = "True" device_dst_file = "/system/framework/web_webview.abc" diff --git a/interfaces/kits/ani/webview/ets/@ohos.web.netErrorList.ets b/interfaces/kits/ani/webview/ets/@ohos.web.netErrorList.ets new file mode 100644 index 0000000000000000000000000000000000000000..b543f366827849040effaf6284e622ff00a4490e --- /dev/null +++ b/interfaces/kits/ani/webview/ets/@ohos.web.netErrorList.ets @@ -0,0 +1,257 @@ +/* + * 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. + */ + +export enum WebNetErrorList { + NET_OK = 0, + ERR_IO_PENDING = -1, + ERR_FAILED = -2, + ERR_ABORTED = -3, + ERR_INVALID_ARGUMENT = -4, + ERR_INVALID_HANDLE = -5, + ERR_FILE_NOT_FOUND = -6, + ERR_TIMED_OUT = -7, + ERR_FILE_TOO_LARGE = -8, + ERR_UNEXPECTED = -9, + ERR_ACCESS_DENIED = -10, + ERR_NOT_IMPLEMENTED = -11, + ERR_INSUFFICIENT_RESOURCES = -12, + ERR_OUT_OF_MEMORY = -13, + ERR_UPLOAD_FILE_CHANGED = -14, + ERR_SOCKET_NOT_CONNECTED = -15, + ERR_FILE_EXISTS = -16, + ERR_FILE_PATH_TOO_LONG = -17, + ERR_FILE_NO_SPACE = -18, + ERR_FILE_VIRUS_INFECTED = -19, + ERR_BLOCKED_BY_CLIENT = -20, + ERR_NETWORK_CHANGED = -21, + ERR_BLOCKED_BY_ADMINISTRATOR = -22, + ERR_SOCKET_CONNECTED = -23, + ERR_UPLOAD_STREAM_REWIND_NOT_SUPPORTED = -25, + ERR_CONTEXT_SHUT_DOWN = -26, + ERR_BLOCKED_BY_RESPONSE = -27, + ERR_CLEARTEXT_NOT_PERMITTED = -29, + ERR_BLOCKED_BY_CSP = -30, + ERR_H2_OR_QUIC_REQUIRED = -31, + ERR_BLOCKED_BY_ORB = -32, + ERR_CONNECTION_CLOSED = -100, + ERR_CONNECTION_RESET = -101, + ERR_CONNECTION_REFUSED = -102, + ERR_CONNECTION_ABORTED = -103, + ERR_CONNECTION_FAILED = -104, + ERR_NAME_NOT_RESOLVED = -105, + ERR_INTERNET_DISCONNECTED = -106, + ERR_SSL_PROTOCOL_ERROR = -107, + ERR_ADDRESS_INVALID = -108, + ERR_ADDRESS_UNREACHABLE = -109, + ERR_SSL_CLIENT_AUTH_CERT_NEEDED = -110, + ERR_TUNNEL_CONNECTION_FAILED = -111, + ERR_NO_SSL_VERSIONS_ENABLED = -112, + ERR_SSL_VERSION_OR_CIPHER_MISMATCH = -113, + ERR_SSL_RENEGOTIATION_REQUESTED = -114, + ERR_PROXY_AUTH_UNSUPPORTED = -115, + ERR_BAD_SSL_CLIENT_AUTH_CERT = -117, + ERR_CONNECTION_TIMED_OUT = -118, + ERR_HOST_RESOLVER_QUEUE_TOO_LARGE = -119, + ERR_SOCKS_CONNECTION_FAILED = -120, + ERR_SOCKS_CONNECTION_HOST_UNREACHABLE = -121, + ERR_ALPN_NEGOTIATION_FAILED = -122, + ERR_SSL_NO_RENEGOTIATION = -123, + ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES = -124, + ERR_SSL_DECOMPRESSION_FAILURE_ALERT = -125, + ERR_SSL_BAD_RECORD_MAC_ALERT = -126, + ERR_PROXY_AUTH_REQUESTED = -127, + ERR_PROXY_CONNECTION_FAILED = -130, + ERR_MANDATORY_PROXY_CONFIGURATION_FAILED = -131, + ERR_PRECONNECT_MAX_SOCKET_LIMIT = -133, + ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED = -134, + ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY = -135, + ERR_PROXY_CERTIFICATE_INVALID = -136, + ERR_NAME_RESOLUTION_FAILED = -137, + ERR_NETWORK_ACCESS_DENIED = -138, + ERR_TEMPORARILY_THROTTLED = -139, + ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT = -140, + ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED = -141, + ERR_MSG_TOO_BIG = -142, + ERR_WS_PROTOCOL_ERROR = -145, + ERR_ADDRESS_IN_USE = -147, + ERR_SSL_HANDSHAKE_NOT_COMPLETED = -148, + ERR_SSL_BAD_PEER_PUBLIC_KEY = -149, + ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN = -150, + ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED = -151, + ERR_SSL_DECRYPT_ERROR_ALERT = -153, + ERR_WS_THROTTLE_QUEUE_TOO_LARGE = -154, + ERR_SSL_SERVER_CERT_CHANGED = -156, + ERR_SSL_UNRECOGNIZED_NAME_ALERT = -159, + ERR_SOCKET_SET_RECEIVE_BUFFER_SIZE_ERROR = -160, + ERR_SOCKET_SET_SEND_BUFFER_SIZE_ERROR = -161, + ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE = -162, + ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE = -163, + ERR_SSL_CLIENT_AUTH_CERT_BAD_FORMAT = -164, + ERR_ICANN_NAME_COLLISION = -166, + ERR_SSL_SERVER_CERT_BAD_FORMAT = -167, + ERR_CT_STH_PARSING_FAILED = -168, + ERR_CT_STH_INCOMPLETE = -169, + ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH = -170, + ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED = -171, + ERR_SSL_OBSOLETE_CIPHER = -172, + ERR_WS_UPGRADE = -173, + ERR_READ_IF_READY_NOT_IMPLEMENTED = -174, + ERR_NO_BUFFER_SPACE = -176, + ERR_SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS = -177, + ERR_EARLY_DATA_REJECTED = -178, + ERR_WRONG_VERSION_ON_EARLY_DATA = -179, + ERR_TLS13_DOWNGRADE_DETECTED = -180, + ERR_SSL_KEY_USAGE_INCOMPATIBLE = -181, + ERR_INVALID_ECH_CONFIG_LIST = -182, + ERR_ECH_NOT_NEGOTIATED = -183, + ERR_ECH_FALLBACK_CERTIFICATE_INVALID = -184, + ERR_CERT_COMMON_NAME_INVALID = -200, + ERR_CERT_DATE_INVALID = -201, + ERR_CERT_AUTHORITY_INVALID = -202, + ERR_CERT_CONTAINS_ERRORS = -203, + ERR_CERT_NO_REVOCATION_MECHANISM = -204, + ERR_CERT_UNABLE_TO_CHECK_REVOCATION = -205, + ERR_CERT_REVOKED = -206, + ERR_CERT_INVALID = -207, + ERR_CERT_WEAK_SIGNATURE_ALGORITHM = -208, + ERR_CERT_NON_UNIQUE_NAME = -210, + ERR_CERT_WEAK_KEY = -211, + ERR_CERT_NAME_CONSTRAINT_VIOLATION = -212, + ERR_CERT_VALIDITY_TOO_LONG = -213, + ERR_CERTIFICATE_TRANSPARENCY_REQUIRED = -214, + ERR_CERT_SYMANTEC_LEGACY = -215, + ERR_CERT_KNOWN_INTERCEPTION_BLOCKED = -217, + ERR_SSL_OBSOLETE_VERSION_OR_CIPHER = -218, + ERR_CERT_END = -219, + ERR_INVALID_URL = -300, + ERR_DISALLOWED_URL_SCHEME = -301, + ERR_UNKNOWN_URL_SCHEME = -302, + ERR_INVALID_REDIRECT = -303, + ERR_TOO_MANY_REDIRECTS = -310, + ERR_UNSAFE_REDIRECT = -311, + ERR_UNSAFE_PORT = -312, + ERR_INVALID_RESPONSE = -320, + ERR_INVALID_CHUNKED_ENCODING = -321, + ERR_METHOD_UNSUPPORTED = -322, + ERR_UNEXPECTED_PROXY_AUTH = -323, + ERR_EMPTY_RESPONSE = -324, + ERR_RESPONSE_HEADERS_TOO_BIG = -325, + ERR_PAC_SCRIPT_FAILED = -327, + ERR_REQUEST_RANGE_NOT_SATISFIABLE = -328, + ERR_MALFORMED_IDENTITY = -329, + ERR_CONTENT_DECODING_FAILED = -330, + ERR_NETWORK_IO_SUSPENDED = -331, + ERR_SYN_REPLY_NOT_RECEIVED = -332, + ERR_ENCODING_CONVERSION_FAILED = -333, + ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT = -334, + ERR_NO_SUPPORTED_PROXIES = -336, + ERR_HTTP2_PROTOCOL_ERROR = -337, + ERR_INVALID_AUTH_CREDENTIALS = -338, + ERR_UNSUPPORTED_AUTH_SCHEME = -339, + ERR_ENCODING_DETECTION_FAILED = -340, + ERR_MISSING_AUTH_CREDENTIALS = -341, + ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS = -342, + ERR_MISCONFIGURED_AUTH_ENVIRONMENT = -343, + ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS = -344, + ERR_RESPONSE_BODY_TOO_BIG_TO_DRAIN = -345, + ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH = -346, + ERR_INCOMPLETE_HTTP2_HEADERS = -347, + ERR_PAC_NOT_IN_DHCP = -348, + ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION = -349, + ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION = -350, + ERR_HTTP2_SERVER_REFUSED_STREAM = -351, + ERR_HTTP2_PING_FAILED = -352, + ERR_CONTENT_LENGTH_MISMATCH = -354, + ERR_INCOMPLETE_CHUNKED_ENCODING = -355, + ERR_QUIC_PROTOCOL_ERROR = -356, + ERR_RESPONSE_HEADERS_TRUNCATED = -357, + ERR_QUIC_HANDSHAKE_FAILED = -358, + ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY = -360, + ERR_HTTP2_FLOW_CONTROL_ERROR = -361, + ERR_HTTP2_FRAME_SIZE_ERROR = -362, + ERR_HTTP2_COMPRESSION_ERROR = -363, + ERR_PROXY_AUTH_REQUESTED_WITH_NO_CONNECTION = -364, + ERR_HTTP_1_1_REQUIRED = -365, + ERR_PROXY_HTTP_1_1_REQUIRED = -366, + ERR_PAC_SCRIPT_TERMINATED = -367, + ERR_INVALID_HTTP_RESPONSE = -370, + ERR_CONTENT_DECODING_INIT_FAILED = -371, + ERR_HTTP2_RST_STREAM_NO_ERROR_RECEIVED = -372, + ERR_HTTP2_PUSHED_STREAM_NOT_AVAILABLE = -373, + ERR_HTTP2_CLAIMED_PUSHED_STREAM_RESET_BY_SERVER = -374, + ERR_TOO_MANY_RETRIES = -375, + ERR_HTTP2_STREAM_CLOSED = -376, + ERR_HTTP2_CLIENT_REFUSED_STREAM = -377, + ERR_HTTP2_PUSHED_RESPONSE_DOES_NOT_MATCH = -378, + ERR_HTTP_RESPONSE_CODE_FAILURE = -379, + ERR_QUIC_UNKNOWN_CERT_ROOT = -380, + ERR_QUIC_GOAWAY_REQUEST_CAN_BE_RETRIED = -381, + ERR_TOO_MANY_ACCEPT_CH_RESTARTS = -382, + ERR_INCONSISTENT_IP_ADDRESS_SPACE = -383, + ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY = -384, + ERR_CACHE_MISS = -400, + ERR_CACHE_READ_FAILURE = -401, + ERR_CACHE_WRITE_FAILURE = -402, + ERR_CACHE_OPERATION_UNSUPPORTED = -403, + ERR_CACHE_OPEN_FAILURE = -404, + ERR_CACHE_CREATE_FAILURE = -405, + ERR_CACHE_RACE = -406, + ERR_CACHE_CHECKSUM_READ_FAILURE = -407, + ERR_CACHE_CHECKSUM_MISMATCH = -408, + ERR_CACHE_LOCK_TIMEOUT = -409, + ERR_CACHE_AUTH_FAILURE_AFTER_READ = -410, + ERR_CACHE_ENTRY_NOT_SUITABLE = -411, + ERR_CACHE_DOOM_FAILURE = -412, + ERR_CACHE_OPEN_OR_CREATE_FAILURE = -413, + ERR_INSECURE_RESPONSE = -501, + ERR_NO_PRIVATE_KEY_FOR_CERT = -502, + ERR_ADD_USER_CERT_FAILED = -503, + ERR_INVALID_SIGNED_EXCHANGE = -504, + ERR_INVALID_WEB_BUNDLE = -505, + ERR_TRUST_TOKEN_OPERATION_FAILED = -506, + ERR_TRUST_TOKEN_OPERATION_SUCCESS_WITHOUT_SENDING_REQUEST = -507, + ERR_FTP_FAILED = -601, + ERR_FTP_SERVICE_UNAVAILABLE = -602, + ERR_FTP_TRANSFER_ABORTED = -603, + ERR_FTP_FILE_BUSY = -604, + ERR_FTP_SYNTAX_ERROR = -605, + ERR_FTP_COMMAND_UNSUPPORTED = -606, + ERR_FTP_BAD_COMMAND_SEQUENCE = -607, + ERR_PKCS12_IMPORT_BAD_PASSWORD = -701, + ERR_PKCS12_IMPORT_FAILED = -702, + ERR_IMPORT_CA_CERT_NOT_CA = -703, + ERR_IMPORT_CERT_ALREADY_EXISTS = -704, + ERR_IMPORT_CA_CERT_FAILED = -705, + ERR_IMPORT_SERVER_CERT_FAILED = -706, + ERR_PKCS12_IMPORT_INVALID_MAC = -707, + ERR_PKCS12_IMPORT_INVALID_FILE = -708, + ERR_PKCS12_IMPORT_UNSUPPORTED = -709, + ERR_KEY_GENERATION_FAILED = -710, + ERR_PRIVATE_KEY_EXPORT_FAILED = -712, + ERR_SELF_SIGNED_CERT_GENERATION_FAILED = -713, + ERR_CERT_DATABASE_CHANGED = -714, + ERR_CERT_VERIFIER_CHANGED = -716, + ERR_DNS_MALFORMED_RESPONSE = -800, + ERR_DNS_SERVER_REQUIRES_TCP = -801, + ERR_DNS_SERVER_FAILED = -802, + ERR_DNS_TIMED_OUT = -803, + ERR_DNS_CACHE_MISS = -804, + ERR_DNS_SEARCH_EMPTY = -805, + ERR_DNS_SORT_ERROR = -806, + ERR_DNS_SECURE_RESOLVER_HOSTNAME_RESOLUTION_FAILED = -808, + ERR_DNS_NAME_HTTPS_ONLY = -809, + ERR_DNS_REQUEST_CANCELED = -810, + ERR_DNS_NO_MATCHING_SUPPORTED_ALPN = -811, +} \ No newline at end of file diff --git a/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets b/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets index e3c97e017725250437285fde86f7cbfe1f9ba948..3b496ea9278a4538c3eb446d2511e2c3f2662530 100644 --- a/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets +++ b/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets @@ -18,6 +18,7 @@ import type image from '@ohos.multimedia.image'; import { AsyncCallback, BusinessError, Callback } from '@ohos.base'; import print from '@ohos.print' import {SizeOptions} from '@ohos.arkui.component'; +import { WebNetErrorList } from '@ohos.web.netErrorList'; import type cert from '@ohos.security.cert'; declare type Length = string | number | Resource; @@ -301,6 +302,30 @@ export default namespace webview { height?: Length; } + export interface WebCustomScheme { + schemeName: string; + isSupportCORS: boolean; + isSupportFetch: boolean; + isStandard?: boolean; + isLocal?: boolean; + isDisplayIsolated?: boolean; + isSecure?: boolean; + isCspBypassing?: boolean; + isCodeCacheSupported?: boolean; + } + + export class WebCustomSchemeClass implements WebCustomScheme { + schemeName: string; + isSupportCORS: boolean; + isSupportFetch: boolean; + isStandard?: boolean; + isLocal?: boolean; + isDisplayIsolated?: boolean; + isSecure?: boolean; + isCspBypassing?: boolean; + isCodeCacheSupported?: boolean; + } + export interface RectEvent { x: double; y: double; @@ -681,6 +706,7 @@ export default namespace webview { native loadData(data: string, mimeType: string, encoding: string, baseUrl?: string, historyUrl?: string): void; native clearHistory(): void; native setWebSchemeHandler(scheme: string, handler: WebSchemeHandler): void; + native static customizeSchemes(schemes: Array): void; native static setServiceWorkerWebSchemeHandler(scheme: string, handler: WebSchemeHandler): void; native clearWebSchemeHandler(): void; native terminateRenderProcess(): boolean; @@ -879,6 +905,8 @@ export default namespace webview { native getStatus(): number; native setHeaderByName(name: string, value: string, overwrite: boolean): void; native getHeaderByName(name: string): string; + native setNetErrorCode(code: WebNetErrorList): void; + native getNetErrorCode(): WebNetErrorList; } export class WebSchemeHandler { @@ -930,6 +958,7 @@ export default namespace webview { native getHeader(): Array; native getRequestResourceType(): WebResourceType; native getRequestUrl(): string; + native getHttpBodyStream(): WebHttpBodyStream | null; native isMainFrame(): boolean; native getRequestMethod(): string; } @@ -956,8 +985,37 @@ export default namespace webview { native didReceiveResponse(response: WebSchemeHandlerResponse): void; native didFinish(): void; + native didFail(code: WebNetErrorList): void; + native didReceiveResponseBody(data: ArrayBuffer): void; } + export class WebHttpBodyStream { + private nativePtr: long = 0; + private cleaner?: Cleaner; + + registerCleaner(ptr: long): void { + this.cleaner = new Cleaner(ptr, "WebHttpBodyStream"); + destroyRegister.register(this, this.cleaner!, unregisterToken); + } + unregisterCleaner(): void { + destroyRegister.unregister(unregisterToken); + } + + bindNativePtr(ptr: long): void { + if (this.nativePtr == 0) { + this.nativePtr = ptr; + this.registerCleaner(this.nativePtr); + } + } + + native constructor(); + native isChunked(): boolean; + native isInMemory(): boolean; + native isEof(): boolean; + native getSize():number; + native getPosition():number; + } + export class WebDownloadItem { static { loadLibrary("webview_ani.z"); diff --git a/interfaces/kits/ani/webview/native/common/ani_web_net_error_list.h b/interfaces/kits/ani/webview/native/common/ani_web_net_error_list.h new file mode 100644 index 0000000000000000000000000000000000000000..d50a8977412cfec878807079bdbf63479cc3cfb2 --- /dev/null +++ b/interfaces/kits/ani/webview/native/common/ani_web_net_error_list.h @@ -0,0 +1,529 @@ +/* + * 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 OHOS_NWEB_WEB_NET_ERROR_LIST_H +#define OHOS_NWEB_WEB_NET_ERROR_LIST_H + +namespace OHOS { +namespace NWeb { +constexpr int32_t NET_OK = 0; +constexpr int32_t ERR_IO_PENDING = -1; +constexpr int32_t ERR_FAILED = -2; +constexpr int32_t ERR_ABORTED = -3; +constexpr int32_t ERR_INVALID_ARGUMENT = -4; +constexpr int32_t ERR_INVALID_HANDLE = -5; +constexpr int32_t ERR_FILE_NOT_FOUND = -6; +constexpr int32_t ERR_TIMED_OUT = -7; +constexpr int32_t ERR_FILE_TOO_LARGE = -8; +constexpr int32_t ERR_UNEXPECTED = -9; +constexpr int32_t ERR_ACCESS_DENIED = -10; +constexpr int32_t ERR_NOT_IMPLEMENTED = -11; +constexpr int32_t ERR_INSUFFICIENT_RESOURCES = -12; +constexpr int32_t ERR_OUT_OF_MEMORY = -13; +constexpr int32_t ERR_UPLOAD_FILE_CHANGED = -14; +constexpr int32_t ERR_SOCKET_NOT_CONNECTED = -15; +constexpr int32_t ERR_FILE_EXISTS = -16; +constexpr int32_t ERR_FILE_PATH_TOO_LONG = -17; +constexpr int32_t ERR_FILE_NO_SPACE = -18; +constexpr int32_t ERR_FILE_VIRUS_INFECTED = -19; +constexpr int32_t ERR_BLOCKED_BY_CLIENT = -20; +constexpr int32_t ERR_NETWORK_CHANGED = -21; +constexpr int32_t ERR_BLOCKED_BY_ADMINISTRATOR = -22; +constexpr int32_t ERR_SOCKET_CONNECTED = -23; +constexpr int32_t ERR_UPLOAD_STREAM_REWIND_NOT_SUPPORTED = -25; +constexpr int32_t ERR_CONTEXT_SHUT_DOWN = -26; +constexpr int32_t ERR_BLOCKED_BY_RESPONSE = -27; +constexpr int32_t ERR_CLEARTEXT_NOT_PERMITTED = -29; +constexpr int32_t ERR_BLOCKED_BY_CSP = -30; +constexpr int32_t ERR_H2_OR_QUIC_REQUIRED = -31; +constexpr int32_t ERR_BLOCKED_BY_ORB = -32; +constexpr int32_t ERR_CONNECTION_CLOSED = -100; +constexpr int32_t ERR_CONNECTION_RESET = -101; +constexpr int32_t ERR_CONNECTION_REFUSED = -102; +constexpr int32_t ERR_CONNECTION_ABORTED = -103; +constexpr int32_t ERR_CONNECTION_FAILED = -104; +constexpr int32_t ERR_NAME_NOT_RESOLVED = -105; +constexpr int32_t ERR_INTERNET_DISCONNECTED = -106; +constexpr int32_t ERR_SSL_PROTOCOL_ERROR = -107; +constexpr int32_t ERR_ADDRESS_INVALID = -108; +constexpr int32_t ERR_ADDRESS_UNREACHABLE = -109; +constexpr int32_t ERR_SSL_CLIENT_AUTH_CERT_NEEDED = -110; +constexpr int32_t ERR_TUNNEL_CONNECTION_FAILED = -111; +constexpr int32_t ERR_NO_SSL_VERSIONS_ENABLED = -112; +constexpr int32_t ERR_SSL_VERSION_OR_CIPHER_MISMATCH = -113; +constexpr int32_t ERR_SSL_RENEGOTIATION_REQUESTED = -114; +constexpr int32_t ERR_PROXY_AUTH_UNSUPPORTED = -115; +constexpr int32_t ERR_BAD_SSL_CLIENT_AUTH_CERT = -117; +constexpr int32_t ERR_CONNECTION_TIMED_OUT = -118; +constexpr int32_t ERR_HOST_RESOLVER_QUEUE_TOO_LARGE = -119; +constexpr int32_t ERR_SOCKS_CONNECTION_FAILED = -120; +constexpr int32_t ERR_SOCKS_CONNECTION_HOST_UNREACHABLE = -121; +constexpr int32_t ERR_ALPN_NEGOTIATION_FAILED = -122; +constexpr int32_t ERR_SSL_NO_RENEGOTIATION = -123; +constexpr int32_t ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES = -124; +constexpr int32_t ERR_SSL_DECOMPRESSION_FAILURE_ALERT = -125; +constexpr int32_t ERR_SSL_BAD_RECORD_MAC_ALERT = -126; +constexpr int32_t ERR_PROXY_AUTH_REQUESTED = -127; +constexpr int32_t ERR_PROXY_CONNECTION_FAILED = -130; +constexpr int32_t ERR_MANDATORY_PROXY_CONFIGURATION_FAILED = -131; +constexpr int32_t ERR_PRECONNECT_MAX_SOCKET_LIMIT = -133; +constexpr int32_t ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED = -134; +constexpr int32_t ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY = -135; +constexpr int32_t ERR_PROXY_CERTIFICATE_INVALID = -136; +constexpr int32_t ERR_NAME_RESOLUTION_FAILED = -137; +constexpr int32_t ERR_NETWORK_ACCESS_DENIED = -138; +constexpr int32_t ERR_TEMPORARILY_THROTTLED = -139; +constexpr int32_t ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT = -140; +constexpr int32_t ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED = -141; +constexpr int32_t ERR_MSG_TOO_BIG = -142; +constexpr int32_t ERR_WS_PROTOCOL_ERROR = -145; +constexpr int32_t ERR_ADDRESS_IN_USE = -147; +constexpr int32_t ERR_SSL_HANDSHAKE_NOT_COMPLETED = -148; +constexpr int32_t ERR_SSL_BAD_PEER_PUBLIC_KEY = -149; +constexpr int32_t ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN = -150; +constexpr int32_t ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED = -151; +constexpr int32_t ERR_SSL_DECRYPT_ERROR_ALERT = -153; +constexpr int32_t ERR_WS_THROTTLE_QUEUE_TOO_LARGE = -154; +constexpr int32_t ERR_SSL_SERVER_CERT_CHANGED = -156; +constexpr int32_t ERR_SSL_UNRECOGNIZED_NAME_ALERT = -159; +constexpr int32_t ERR_SOCKET_SET_RECEIVE_BUFFER_SIZE_ERROR = -160; +constexpr int32_t ERR_SOCKET_SET_SEND_BUFFER_SIZE_ERROR = -161; +constexpr int32_t ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE = -162; +constexpr int32_t ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE = -163; +constexpr int32_t ERR_SSL_CLIENT_AUTH_CERT_BAD_FORMAT = -164; +constexpr int32_t ERR_ICANN_NAME_COLLISION = -166; +constexpr int32_t ERR_SSL_SERVER_CERT_BAD_FORMAT = -167; +constexpr int32_t ERR_CT_STH_PARSING_FAILED = -168; +constexpr int32_t ERR_CT_STH_INCOMPLETE = -169; +constexpr int32_t ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH = -170; +constexpr int32_t ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED = -171; +constexpr int32_t ERR_SSL_OBSOLETE_CIPHER = -172; +constexpr int32_t ERR_WS_UPGRADE = -173; +constexpr int32_t ERR_READ_IF_READY_NOT_IMPLEMENTED = -174; +constexpr int32_t ERR_NO_BUFFER_SPACE = -176; +constexpr int32_t ERR_SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS = -177; +constexpr int32_t ERR_EARLY_DATA_REJECTED = -178; +constexpr int32_t ERR_WRONG_VERSION_ON_EARLY_DATA = -179; +constexpr int32_t ERR_TLS13_DOWNGRADE_DETECTED = -180; +constexpr int32_t ERR_SSL_KEY_USAGE_INCOMPATIBLE = -181; +constexpr int32_t ERR_INVALID_ECH_CONFIG_LIST = -182; +constexpr int32_t ERR_ECH_NOT_NEGOTIATED = -183; +constexpr int32_t ERR_ECH_FALLBACK_CERTIFICATE_INVALID = -184; +constexpr int32_t ERR_CERT_COMMON_NAME_INVALID = -200; +constexpr int32_t ERR_CERT_DATE_INVALID = -201; +constexpr int32_t ERR_CERT_AUTHORITY_INVALID = -202; +constexpr int32_t ERR_CERT_CONTAINS_ERRORS = -203; +constexpr int32_t ERR_CERT_NO_REVOCATION_MECHANISM = -204; +constexpr int32_t ERR_CERT_UNABLE_TO_CHECK_REVOCATION = -205; +constexpr int32_t ERR_CERT_REVOKED = -206; +constexpr int32_t ERR_CERT_INVALID = -207; +constexpr int32_t ERR_CERT_WEAK_SIGNATURE_ALGORITHM = -208; +constexpr int32_t ERR_CERT_NON_UNIQUE_NAME = -210; +constexpr int32_t ERR_CERT_WEAK_KEY = -211; +constexpr int32_t ERR_CERT_NAME_CONSTRAINT_VIOLATION = -212; +constexpr int32_t ERR_CERT_VALIDITY_TOO_LONG = -213; +constexpr int32_t ERR_CERTIFICATE_TRANSPARENCY_REQUIRED = -214; +constexpr int32_t ERR_CERT_SYMANTEC_LEGACY = -215; +constexpr int32_t ERR_CERT_KNOWN_INTERCEPTION_BLOCKED = -217; +constexpr int32_t ERR_SSL_OBSOLETE_VERSION_OR_CIPHER = -218; +constexpr int32_t ERR_CERT_END = -219; +constexpr int32_t ERR_INVALID_URL = -300; +constexpr int32_t ERR_DISALLOWED_URL_SCHEME = -301; +constexpr int32_t ERR_UNKNOWN_URL_SCHEME = -302; +constexpr int32_t ERR_INVALID_REDIRECT = -303; +constexpr int32_t ERR_TOO_MANY_REDIRECTS = -310; +constexpr int32_t ERR_UNSAFE_REDIRECT = -311; +constexpr int32_t ERR_UNSAFE_PORT = -312; +constexpr int32_t ERR_INVALID_RESPONSE = -320; +constexpr int32_t ERR_INVALID_CHUNKED_ENCODING = -321; +constexpr int32_t ERR_METHOD_UNSUPPORTED = -322; +constexpr int32_t ERR_UNEXPECTED_PROXY_AUTH = -323; +constexpr int32_t ERR_EMPTY_RESPONSE = -324; +constexpr int32_t ERR_RESPONSE_HEADERS_TOO_BIG = -325; +constexpr int32_t ERR_PAC_SCRIPT_FAILED = -327; +constexpr int32_t ERR_REQUEST_RANGE_NOT_SATISFIABLE = -328; +constexpr int32_t ERR_MALFORMED_IDENTITY = -329; +constexpr int32_t ERR_CONTENT_DECODING_FAILED = -330; +constexpr int32_t ERR_NETWORK_IO_SUSPENDED = -331; +constexpr int32_t ERR_SYN_REPLY_NOT_RECEIVED = -332; +constexpr int32_t ERR_ENCODING_CONVERSION_FAILED = -333; +constexpr int32_t ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT = -334; +constexpr int32_t ERR_NO_SUPPORTED_PROXIES = -336; +constexpr int32_t ERR_HTTP2_PROTOCOL_ERROR = -337; +constexpr int32_t ERR_INVALID_AUTH_CREDENTIALS = -338; +constexpr int32_t ERR_UNSUPPORTED_AUTH_SCHEME = -339; +constexpr int32_t ERR_ENCODING_DETECTION_FAILED = -340; +constexpr int32_t ERR_MISSING_AUTH_CREDENTIALS = -341; +constexpr int32_t ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS = -342; +constexpr int32_t ERR_MISCONFIGURED_AUTH_ENVIRONMENT = -343; +constexpr int32_t ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS = -344; +constexpr int32_t ERR_RESPONSE_BODY_TOO_BIG_TO_DRAIN = -345; +constexpr int32_t ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH = -346; +constexpr int32_t ERR_INCOMPLETE_HTTP2_HEADERS = -347; +constexpr int32_t ERR_PAC_NOT_IN_DHCP = -348; +constexpr int32_t ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION = -349; +constexpr int32_t ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION = -350; +constexpr int32_t ERR_HTTP2_SERVER_REFUSED_STREAM = -351; +constexpr int32_t ERR_HTTP2_PING_FAILED = -352; +constexpr int32_t ERR_CONTENT_LENGTH_MISMATCH = -354; +constexpr int32_t ERR_INCOMPLETE_CHUNKED_ENCODING = -355; +constexpr int32_t ERR_QUIC_PROTOCOL_ERROR = -356; +constexpr int32_t ERR_RESPONSE_HEADERS_TRUNCATED = -357; +constexpr int32_t ERR_QUIC_HANDSHAKE_FAILED = -358; +constexpr int32_t ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY = -360; +constexpr int32_t ERR_HTTP2_FLOW_CONTROL_ERROR = -361; +constexpr int32_t ERR_HTTP2_FRAME_SIZE_ERROR = -362; +constexpr int32_t ERR_HTTP2_COMPRESSION_ERROR = -363; +constexpr int32_t ERR_PROXY_AUTH_REQUESTED_WITH_NO_CONNECTION = -364; +constexpr int32_t ERR_HTTP_1_1_REQUIRED = -365; +constexpr int32_t ERR_PROXY_HTTP_1_1_REQUIRED = -366; +constexpr int32_t ERR_PAC_SCRIPT_TERMINATED = -367; +constexpr int32_t ERR_INVALID_HTTP_RESPONSE = -370; +constexpr int32_t ERR_CONTENT_DECODING_INIT_FAILED = -371; +constexpr int32_t ERR_HTTP2_RST_STREAM_NO_ERROR_RECEIVED = -372; +constexpr int32_t ERR_HTTP2_PUSHED_STREAM_NOT_AVAILABLE = -373; +constexpr int32_t ERR_HTTP2_CLAIMED_PUSHED_STREAM_RESET_BY_SERVER = -374; +constexpr int32_t ERR_TOO_MANY_RETRIES = -375; +constexpr int32_t ERR_HTTP2_STREAM_CLOSED = -376; +constexpr int32_t ERR_HTTP2_CLIENT_REFUSED_STREAM = -377; +constexpr int32_t ERR_HTTP2_PUSHED_RESPONSE_DOES_NOT_MATCH = -378; +constexpr int32_t ERR_HTTP_RESPONSE_CODE_FAILURE = -379; +constexpr int32_t ERR_QUIC_UNKNOWN_CERT_ROOT = -380; +constexpr int32_t ERR_QUIC_GOAWAY_REQUEST_CAN_BE_RETRIED = -381; +constexpr int32_t ERR_TOO_MANY_ACCEPT_CH_RESTARTS = -382; +constexpr int32_t ERR_INCONSISTENT_IP_ADDRESS_SPACE = -383; +constexpr int32_t ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY = -384; +constexpr int32_t ERR_CACHE_MISS = -400; +constexpr int32_t ERR_CACHE_READ_FAILURE = -401; +constexpr int32_t ERR_CACHE_WRITE_FAILURE = -402; +constexpr int32_t ERR_CACHE_OPERATION_UNSUPPORTED = -403; +constexpr int32_t ERR_CACHE_OPEN_FAILURE = -404; +constexpr int32_t ERR_CACHE_CREATE_FAILURE = -405; +constexpr int32_t ERR_CACHE_RACE = -406; +constexpr int32_t ERR_CACHE_CHECKSUM_READ_FAILURE = -407; +constexpr int32_t ERR_CACHE_CHECKSUM_MISMATCH = -408; +constexpr int32_t ERR_CACHE_LOCK_TIMEOUT = -409; +constexpr int32_t ERR_CACHE_AUTH_FAILURE_AFTER_READ = -410; +constexpr int32_t ERR_CACHE_ENTRY_NOT_SUITABLE = -411; +constexpr int32_t ERR_CACHE_DOOM_FAILURE = -412; +constexpr int32_t ERR_CACHE_OPEN_OR_CREATE_FAILURE = -413; +constexpr int32_t ERR_INSECURE_RESPONSE = -501; +constexpr int32_t ERR_NO_PRIVATE_KEY_FOR_CERT = -502; +constexpr int32_t ERR_ADD_USER_CERT_FAILED = -503; +constexpr int32_t ERR_INVALID_SIGNED_EXCHANGE = -504; +constexpr int32_t ERR_INVALID_WEB_BUNDLE = -505; +constexpr int32_t ERR_TRUST_TOKEN_OPERATION_FAILED = -506; +constexpr int32_t ERR_TRUST_TOKEN_OPERATION_SUCCESS_WITHOUT_SENDING_REQUEST = -507; +constexpr int32_t ERR_FTP_FAILED = -601; +constexpr int32_t ERR_FTP_SERVICE_UNAVAILABLE = -602; +constexpr int32_t ERR_FTP_TRANSFER_ABORTED = -603; +constexpr int32_t ERR_FTP_FILE_BUSY = -604; +constexpr int32_t ERR_FTP_SYNTAX_ERROR = -605; +constexpr int32_t ERR_FTP_COMMAND_UNSUPPORTED = -606; +constexpr int32_t ERR_FTP_BAD_COMMAND_SEQUENCE = -607; +constexpr int32_t ERR_PKCS12_IMPORT_BAD_PASSWORD = -701; +constexpr int32_t ERR_PKCS12_IMPORT_FAILED = -702; +constexpr int32_t ERR_IMPORT_CA_CERT_NOT_CA = -703; +constexpr int32_t ERR_IMPORT_CERT_ALREADY_EXISTS = -704; +constexpr int32_t ERR_IMPORT_CA_CERT_FAILED = -705; +constexpr int32_t ERR_IMPORT_SERVER_CERT_FAILED = -706; +constexpr int32_t ERR_PKCS12_IMPORT_INVALID_MAC = -707; +constexpr int32_t ERR_PKCS12_IMPORT_INVALID_FILE = -708; +constexpr int32_t ERR_PKCS12_IMPORT_UNSUPPORTED = -709; +constexpr int32_t ERR_KEY_GENERATION_FAILED = -710; +constexpr int32_t ERR_PRIVATE_KEY_EXPORT_FAILED = -712; +constexpr int32_t ERR_SELF_SIGNED_CERT_GENERATION_FAILED = -713; +constexpr int32_t ERR_CERT_DATABASE_CHANGED = -714; +constexpr int32_t ERR_CERT_VERIFIER_CHANGED = -716; +constexpr int32_t ERR_DNS_MALFORMED_RESPONSE = -800; +constexpr int32_t ERR_DNS_SERVER_REQUIRES_TCP = -801; +constexpr int32_t ERR_DNS_SERVER_FAILED = -802; +constexpr int32_t ERR_DNS_TIMED_OUT = -803; +constexpr int32_t ERR_DNS_CACHE_MISS = -804; +constexpr int32_t ERR_DNS_SEARCH_EMPTY = -805; +constexpr int32_t ERR_DNS_SORT_ERROR = -806; +constexpr int32_t ERR_DNS_SECURE_RESOLVER_HOSTNAME_RESOLUTION_FAILED = -808; +constexpr int32_t ERR_DNS_NAME_HTTPS_ONLY = -809; +constexpr int32_t ERR_DNS_REQUEST_CANCELED = -810; +constexpr int32_t ERR_DNS_NO_MATCHING_SUPPORTED_ALPN = -811; + +const std::unordered_map& GetErrorMap() +{ + static const auto errorMap = [] { + const std::vector codes = { + NET_OK, + ERR_IO_PENDING, + ERR_FAILED, + ERR_ABORTED, + ERR_INVALID_ARGUMENT, + ERR_INVALID_HANDLE, + ERR_FILE_NOT_FOUND, + ERR_TIMED_OUT, + ERR_FILE_TOO_LARGE, + ERR_UNEXPECTED, + ERR_ACCESS_DENIED, + ERR_NOT_IMPLEMENTED, + ERR_INSUFFICIENT_RESOURCES, + ERR_OUT_OF_MEMORY, + ERR_UPLOAD_FILE_CHANGED, + ERR_SOCKET_NOT_CONNECTED, + ERR_FILE_EXISTS, + ERR_FILE_PATH_TOO_LONG, + ERR_FILE_NO_SPACE, + ERR_FILE_VIRUS_INFECTED, + ERR_BLOCKED_BY_CLIENT, + ERR_NETWORK_CHANGED, + ERR_BLOCKED_BY_ADMINISTRATOR, + ERR_SOCKET_CONNECTED, + ERR_UPLOAD_STREAM_REWIND_NOT_SUPPORTED, + ERR_CONTEXT_SHUT_DOWN, + ERR_BLOCKED_BY_RESPONSE, + ERR_CLEARTEXT_NOT_PERMITTED, + ERR_BLOCKED_BY_CSP, + ERR_H2_OR_QUIC_REQUIRED, + ERR_BLOCKED_BY_ORB, + ERR_CONNECTION_CLOSED, + ERR_CONNECTION_RESET, + ERR_CONNECTION_REFUSED, + ERR_CONNECTION_ABORTED, + ERR_CONNECTION_FAILED, + ERR_NAME_NOT_RESOLVED, + ERR_INTERNET_DISCONNECTED, + ERR_SSL_PROTOCOL_ERROR, + ERR_ADDRESS_INVALID, + ERR_ADDRESS_UNREACHABLE, + ERR_SSL_CLIENT_AUTH_CERT_NEEDED, + ERR_TUNNEL_CONNECTION_FAILED, + ERR_NO_SSL_VERSIONS_ENABLED, + ERR_SSL_VERSION_OR_CIPHER_MISMATCH, + ERR_SSL_RENEGOTIATION_REQUESTED, + ERR_PROXY_AUTH_UNSUPPORTED, + ERR_BAD_SSL_CLIENT_AUTH_CERT, + ERR_CONNECTION_TIMED_OUT, + ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, + ERR_SOCKS_CONNECTION_FAILED, + ERR_SOCKS_CONNECTION_HOST_UNREACHABLE, + ERR_ALPN_NEGOTIATION_FAILED, + ERR_SSL_NO_RENEGOTIATION, + ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES, + ERR_SSL_DECOMPRESSION_FAILURE_ALERT, + ERR_SSL_BAD_RECORD_MAC_ALERT, + ERR_PROXY_AUTH_REQUESTED, + ERR_PROXY_CONNECTION_FAILED, + ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, + ERR_PRECONNECT_MAX_SOCKET_LIMIT, + ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED, + ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY, + ERR_PROXY_CERTIFICATE_INVALID, + ERR_NAME_RESOLUTION_FAILED, + ERR_NETWORK_ACCESS_DENIED, + ERR_TEMPORARILY_THROTTLED, + ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT, + ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED, + ERR_MSG_TOO_BIG, + ERR_WS_PROTOCOL_ERROR, + ERR_ADDRESS_IN_USE, + ERR_SSL_HANDSHAKE_NOT_COMPLETED, + ERR_SSL_BAD_PEER_PUBLIC_KEY, + ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN, + ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, + ERR_SSL_DECRYPT_ERROR_ALERT, + ERR_WS_THROTTLE_QUEUE_TOO_LARGE, + ERR_SSL_SERVER_CERT_CHANGED, + ERR_SSL_UNRECOGNIZED_NAME_ALERT, + ERR_SOCKET_SET_RECEIVE_BUFFER_SIZE_ERROR, + ERR_SOCKET_SET_SEND_BUFFER_SIZE_ERROR, + ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE, + ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE, + ERR_SSL_CLIENT_AUTH_CERT_BAD_FORMAT, + ERR_ICANN_NAME_COLLISION, + ERR_SSL_SERVER_CERT_BAD_FORMAT, + ERR_CT_STH_PARSING_FAILED, + ERR_CT_STH_INCOMPLETE, + ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH, + ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED, + ERR_SSL_OBSOLETE_CIPHER, + ERR_WS_UPGRADE, + ERR_READ_IF_READY_NOT_IMPLEMENTED, + ERR_NO_BUFFER_SPACE, + ERR_SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS, + ERR_EARLY_DATA_REJECTED, + ERR_WRONG_VERSION_ON_EARLY_DATA, + ERR_TLS13_DOWNGRADE_DETECTED, + ERR_SSL_KEY_USAGE_INCOMPATIBLE, + ERR_INVALID_ECH_CONFIG_LIST, + ERR_ECH_NOT_NEGOTIATED, + ERR_ECH_FALLBACK_CERTIFICATE_INVALID, + ERR_CERT_COMMON_NAME_INVALID, + ERR_CERT_DATE_INVALID, + ERR_CERT_AUTHORITY_INVALID, + ERR_CERT_CONTAINS_ERRORS, + ERR_CERT_NO_REVOCATION_MECHANISM, + ERR_CERT_UNABLE_TO_CHECK_REVOCATION, + ERR_CERT_REVOKED, + ERR_CERT_INVALID, + ERR_CERT_WEAK_SIGNATURE_ALGORITHM, + ERR_CERT_NON_UNIQUE_NAME, + ERR_CERT_WEAK_KEY, + ERR_CERT_NAME_CONSTRAINT_VIOLATION, + ERR_CERT_VALIDITY_TOO_LONG, + ERR_CERTIFICATE_TRANSPARENCY_REQUIRED, + ERR_CERT_SYMANTEC_LEGACY, + ERR_CERT_KNOWN_INTERCEPTION_BLOCKED, + ERR_SSL_OBSOLETE_VERSION_OR_CIPHER, + ERR_CERT_END, + ERR_INVALID_URL, + ERR_DISALLOWED_URL_SCHEME, + ERR_UNKNOWN_URL_SCHEME, + ERR_INVALID_REDIRECT, + ERR_TOO_MANY_REDIRECTS, + ERR_UNSAFE_REDIRECT, + ERR_UNSAFE_PORT, + ERR_INVALID_RESPONSE, + ERR_INVALID_CHUNKED_ENCODING, + ERR_METHOD_UNSUPPORTED, + ERR_UNEXPECTED_PROXY_AUTH, + ERR_EMPTY_RESPONSE, + ERR_RESPONSE_HEADERS_TOO_BIG, + ERR_PAC_SCRIPT_FAILED, + ERR_REQUEST_RANGE_NOT_SATISFIABLE, + ERR_MALFORMED_IDENTITY, + ERR_CONTENT_DECODING_FAILED, + ERR_NETWORK_IO_SUSPENDED, + ERR_SYN_REPLY_NOT_RECEIVED, + ERR_ENCODING_CONVERSION_FAILED, + ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT, + ERR_NO_SUPPORTED_PROXIES, + ERR_HTTP2_PROTOCOL_ERROR, + ERR_INVALID_AUTH_CREDENTIALS, + ERR_UNSUPPORTED_AUTH_SCHEME, + ERR_ENCODING_DETECTION_FAILED, + ERR_MISSING_AUTH_CREDENTIALS, + ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS, + ERR_MISCONFIGURED_AUTH_ENVIRONMENT, + ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS, + ERR_RESPONSE_BODY_TOO_BIG_TO_DRAIN, + ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, + ERR_INCOMPLETE_HTTP2_HEADERS, + ERR_PAC_NOT_IN_DHCP, + ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, + ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, + ERR_HTTP2_SERVER_REFUSED_STREAM, + ERR_HTTP2_PING_FAILED, + ERR_CONTENT_LENGTH_MISMATCH, + ERR_INCOMPLETE_CHUNKED_ENCODING, + ERR_QUIC_PROTOCOL_ERROR, + ERR_RESPONSE_HEADERS_TRUNCATED, + ERR_QUIC_HANDSHAKE_FAILED, + ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY, + ERR_HTTP2_FLOW_CONTROL_ERROR, + ERR_HTTP2_FRAME_SIZE_ERROR, + ERR_HTTP2_COMPRESSION_ERROR, + ERR_PROXY_AUTH_REQUESTED_WITH_NO_CONNECTION, + ERR_HTTP_1_1_REQUIRED, + ERR_PROXY_HTTP_1_1_REQUIRED, + ERR_PAC_SCRIPT_TERMINATED, + ERR_INVALID_HTTP_RESPONSE, + ERR_CONTENT_DECODING_INIT_FAILED, + ERR_HTTP2_RST_STREAM_NO_ERROR_RECEIVED, + ERR_HTTP2_PUSHED_STREAM_NOT_AVAILABLE, + ERR_HTTP2_CLAIMED_PUSHED_STREAM_RESET_BY_SERVER, + ERR_TOO_MANY_RETRIES, + ERR_HTTP2_STREAM_CLOSED, + ERR_HTTP2_CLIENT_REFUSED_STREAM, + ERR_HTTP2_PUSHED_RESPONSE_DOES_NOT_MATCH, + ERR_HTTP_RESPONSE_CODE_FAILURE, + ERR_QUIC_UNKNOWN_CERT_ROOT, + ERR_QUIC_GOAWAY_REQUEST_CAN_BE_RETRIED, + ERR_TOO_MANY_ACCEPT_CH_RESTARTS, + ERR_INCONSISTENT_IP_ADDRESS_SPACE, + ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY, + ERR_CACHE_MISS, + ERR_CACHE_READ_FAILURE, + ERR_CACHE_WRITE_FAILURE, + ERR_CACHE_OPERATION_UNSUPPORTED, + ERR_CACHE_OPEN_FAILURE, + ERR_CACHE_CREATE_FAILURE, + ERR_CACHE_RACE, + ERR_CACHE_CHECKSUM_READ_FAILURE, + ERR_CACHE_CHECKSUM_MISMATCH, + ERR_CACHE_LOCK_TIMEOUT, + ERR_CACHE_AUTH_FAILURE_AFTER_READ, + ERR_CACHE_ENTRY_NOT_SUITABLE, + ERR_CACHE_DOOM_FAILURE, + ERR_CACHE_OPEN_OR_CREATE_FAILURE, + ERR_INSECURE_RESPONSE, + ERR_NO_PRIVATE_KEY_FOR_CERT, + ERR_ADD_USER_CERT_FAILED, + ERR_INVALID_SIGNED_EXCHANGE, + ERR_INVALID_WEB_BUNDLE, + ERR_TRUST_TOKEN_OPERATION_FAILED, + ERR_TRUST_TOKEN_OPERATION_SUCCESS_WITHOUT_SENDING_REQUEST, + ERR_FTP_FAILED, + ERR_FTP_SERVICE_UNAVAILABLE, + ERR_FTP_TRANSFER_ABORTED, + ERR_FTP_FILE_BUSY, + ERR_FTP_SYNTAX_ERROR, + ERR_FTP_COMMAND_UNSUPPORTED, + ERR_FTP_BAD_COMMAND_SEQUENCE, + ERR_PKCS12_IMPORT_BAD_PASSWORD, + ERR_PKCS12_IMPORT_FAILED, + ERR_IMPORT_CA_CERT_NOT_CA, + ERR_IMPORT_CERT_ALREADY_EXISTS, + ERR_IMPORT_CA_CERT_FAILED, + ERR_IMPORT_SERVER_CERT_FAILED, + ERR_PKCS12_IMPORT_INVALID_MAC, + ERR_PKCS12_IMPORT_INVALID_FILE, + ERR_PKCS12_IMPORT_UNSUPPORTED, + ERR_KEY_GENERATION_FAILED, + ERR_PRIVATE_KEY_EXPORT_FAILED, + ERR_SELF_SIGNED_CERT_GENERATION_FAILED, + ERR_CERT_DATABASE_CHANGED, + ERR_CERT_VERIFIER_CHANGED, + ERR_DNS_MALFORMED_RESPONSE, + ERR_DNS_SERVER_REQUIRES_TCP, + ERR_DNS_SERVER_FAILED, + ERR_DNS_TIMED_OUT, + ERR_DNS_CACHE_MISS, + ERR_DNS_SEARCH_EMPTY, + ERR_DNS_SORT_ERROR, + ERR_DNS_SECURE_RESOLVER_HOSTNAME_RESOLUTION_FAILED, + ERR_DNS_NAME_HTTPS_ONLY, + ERR_DNS_REQUEST_CANCELED, + ERR_DNS_NO_MATCHING_SUPPORTED_ALPN, + }; + + std::unordered_map map; + map.reserve(codes.size()); + for (size_t i = 0; i < codes.size(); ++i) { + map[codes[i]] = static_cast(i); + } + return map; + }(); + return errorMap; +} + +int32_t GetErrorIndex(int32_t errorCode) +{ + const auto& map = GetErrorMap(); + try { + return map.at(errorCode); + } catch (const std::out_of_range&) { + return -1; + } +} +} // namespace NWeb +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.cpp b/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.cpp index 8d80d2643cf91fbfdffa410df7d832b05774be92..6e50abc593b5b1aae92300531ead5b5d8f43f755 100644 --- a/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.cpp +++ b/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.cpp @@ -198,7 +198,6 @@ WebSchemeHandler::WebSchemeHandler(ani_env* env) : vm_(nullptr) return; } env_ = env; - WVLOG_E("create WebSchemeHandler"); ArkWeb_SchemeHandler* handler; OH_ArkWeb_CreateSchemeHandler(&handler); if (!handler) { @@ -258,7 +257,6 @@ void WebSchemeHandler::RequestStart( if (resourceHandler == nullptr) { WVLOG_E("RequestStart, new resourceHandler failed"); delete schemeHandlerRequest; - resourceHandler->DecStrongRef(resourceHandler); env->DestroyLocalScope(); return; } @@ -449,4 +447,218 @@ void WebResourceHandler::DestoryArkWebResourceHandler() } } +WebHttpBodyStream::WebHttpBodyStream(ani_env* env) +{ + WVLOG_D("WebHttpBodyStream::WebHttpBodyStream"); + env_ = env; +} + +WebHttpBodyStream::WebHttpBodyStream(ani_env* env, ArkWeb_HttpBodyStream* stream) +{ + WVLOG_D("WebHttpBodyStream::WebHttpBodyStream"); + env_ = env; + stream_ = stream; + if (OH_ArkWebHttpBodyStream_SetUserData(stream_, this) != 0) { + WVLOG_E("OH_ArkWebHttpBodyStream_SetUserData failed"); + return; + } + if (OH_ArkWebHttpBodyStream_SetReadCallback(stream_, &WebHttpBodyStream::HttpBodyStreamReadCallback) != 0) { + WVLOG_E("OH_ArkWebHttpBodyStream_SetReadCallback failed"); + return; + } +} + +WebHttpBodyStream::~WebHttpBodyStream() +{ + WVLOG_D("WebHttpBodyStream::~WebHttpBodyStream"); + if (stream_) { + OH_ArkWebResourceRequest_DestroyHttpBodyStream(stream_); + stream_ = nullptr; + } +} + +void WebHttpBodyStream::HttpBodyStreamReadCallback( + const ArkWeb_HttpBodyStream* httpBodyStream, uint8_t* buffer, int bytesRead) +{ + WVLOG_D("WebHttpBodyStream::HttpBodyStreamReadCallback"); + WebHttpBodyStream* stream = + reinterpret_cast(OH_ArkWebHttpBodyStream_GetUserData(httpBodyStream)); + if (!stream) { + WVLOG_E("OH_ArkWebHttpBodyStream_GetUserData is nullptr"); + return; + } + stream->ExecuteRead(buffer, bytesRead); +} + +void WebHttpBodyStream::HttpBodyStreamInitCallback(const ArkWeb_HttpBodyStream* httpBodyStream, ArkWeb_NetError result) +{ + WVLOG_D("WebHttpBodyStream::HttpBodyStreamInitCallback"); + WebHttpBodyStream* stream = + reinterpret_cast(OH_ArkWebHttpBodyStream_GetUserData(httpBodyStream)); + if (!stream) { + WVLOG_E("OH_ArkWebHttpBodyStream_GetUserData is nullptr"); + return; + } + stream->ExecuteInit(result); +} + +void WebHttpBodyStream::Init(ani_ref jsCallback, ani_resolver initResolver) +{ + WVLOG_D("WebHttpBodyStream::Init"); + if (!jsCallback && !initResolver) { + WVLOG_E("WebHttpBodyStream::InitCallback callback is nullptr"); + return; + } + if (jsCallback) { + initJsCallback_ = std::move(jsCallback); + } + if (initResolver) { + initResolver_ = std::move(initResolver); + } + int ret = OH_ArkWebHttpBodyStream_Init(stream_, &WebHttpBodyStream::HttpBodyStreamInitCallback); + if (ret != 0) { + WVLOG_E("OH_ArkWebHttpBodyStream_Init failed"); + return; + } +} + +void WebHttpBodyStream::Read(int bufLen, ani_ref jsCallback, ani_resolver readResolver) +{ + WVLOG_D("WebHttpBodyStream::Read"); + if (!jsCallback && !readResolver) { + WVLOG_E("WebHttpBodyStream::Read callback is nullptr"); + return; + } + if (bufLen <= 0) { + return; + } + if (jsCallback) { + readJsCallback_ = std::move(jsCallback); + } + if (readResolver) { + readResolver_ = std::move(readResolver); + } + uint8_t* buffer = new (std::nothrow) uint8_t[bufLen]; + if (buffer == nullptr) { + return; + } + OH_ArkWebHttpBodyStream_Read(stream_, buffer, bufLen); +} + +void WebHttpBodyStream::ExecuteInit(ArkWeb_NetError result) +{ + WVLOG_D("WebHttpBodyStream::ExecuteInit"); + if (!env_) { + WVLOG_E("WebHttpBodyStream::ExecuteInit env_ is nullptr"); + return; + } + + auto* asyncCtx = new InitAsyncCtx { + .env = env_, + .deferred = initResolver_, + .errCode = result, + }; + if (asyncCtx == nullptr) { + WVLOG_D("WebHttpBodyStream::ExecuteInit"); + return; + } + WVLOG_D("WebHttpBodyStream::ExecuteInit task started"); + + if (!asyncCtx->env) { + WVLOG_E("WebHttpBodyStream::ExecuteInit asyncCtx or env is nullptr"); + delete asyncCtx; + return; + } + + ani_ref resultRef; + asyncCtx->env->GetUndefined(&resultRef); + + if (asyncCtx->errCode != 0) { + resultRef = NWebError::AniBusinessError::CreateError(asyncCtx->env, NWebError::HTTP_BODY_STREAN_INIT_FAILED); + } else { + asyncCtx->env->GetUndefined(&resultRef); + } + std::vector vec; + vec.push_back(resultRef); + if (asyncCtx->deferred) { + if (asyncCtx->errCode == 0) { + if (asyncCtx->env->PromiseResolver_Resolve(asyncCtx->deferred, resultRef) != ANI_OK) { + WVLOG_E("WebHttpBodyStream::ExecuteInit PromiseResolver_Resolve failed"); + } + } else { + if (asyncCtx->env->PromiseResolver_Reject(asyncCtx->deferred, static_cast(resultRef)) != + ANI_OK) { + WVLOG_E("WebHttpBodyStream::ExecuteInit PromiseResolver_Reject failed"); + } + } + } else { + WVLOG_E("WebHttpBodyStream::ExecuteInit no deferred provided"); + } + WVLOG_D("WebHttpBodyStream::ExecuteInit"); + delete asyncCtx; +} + +void WebHttpBodyStream::ExecuteRead(uint8_t* buffer, int bytesRead) +{ + WVLOG_D("WebHttpBodyStream::ExecuteRead"); + if (!env_) { + return; + } + auto* asyncCtx = new ReadAsyncCtx { + .env = env_, + .deferred = initResolver_, + .buffer = buffer, + }; + if (asyncCtx == nullptr) { + WVLOG_E("WebHttpBodyStream::ExecuteRead asyncCtx is nullptr"); + return; + } + WVLOG_D("WebHttpBodyStream::ExecuteRead task started"); + if (!asyncCtx->env) { + WVLOG_E("WebHttpBodyStream::ExecuteRead asyncCtx or env is nullptr"); + delete asyncCtx; + return; + } + ani_ref resultRef; + asyncCtx->env->GetUndefined(&resultRef); + if (asyncCtx->buffer) { + delete asyncCtx->buffer; + } + if (asyncCtx->deferred) { + if (asyncCtx->env->PromiseResolver_Reject(asyncCtx->deferred, static_cast(resultRef)) != ANI_OK) { + WVLOG_E("WebHttpBodyStream::ExecuteInit PromiseResolver_Reject failed"); + } + } + delete asyncCtx; +} + +uint64_t WebHttpBodyStream::GetPostion() const +{ + return OH_ArkWebHttpBodyStream_GetPosition(stream_); +} + +uint64_t WebHttpBodyStream::GetSize() const +{ + WVLOG_D("WebHttpBodyStream::GetSize"); + return OH_ArkWebHttpBodyStream_GetSize(stream_); +} + +bool WebHttpBodyStream::IsChunked() const +{ + WVLOG_D("WebHttpBodyStream::IsChunked"); + return OH_ArkWebHttpBodyStream_IsChunked(stream_); +} + +bool WebHttpBodyStream::IsEof() +{ + WVLOG_D("WebHttpBodyStream::IsEof"); + return OH_ArkWebHttpBodyStream_IsEof(stream_); +} + +bool WebHttpBodyStream::IsInMemory() +{ + WVLOG_D("WebHttpBodyStream::IsInMemory"); + return OH_ArkWebHttpBodyStream_IsInMemory(stream_); +} + } // namespace OHOS::NWeb \ No newline at end of file diff --git a/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.h b/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.h index 92d2ea416b1f80f5ebf8cf0053830bb47d46fa7b..bd724674bf10b158924be56645ca4c09d35eb119 100644 --- a/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.h +++ b/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.h @@ -125,6 +125,44 @@ private: ani_ref request_stop_callback_ = nullptr; }; +class WebHttpBodyStream { +public: + explicit WebHttpBodyStream(ani_env* env); + static void HttpBodyStreamReadCallback(const ArkWeb_HttpBodyStream* httpBodyStream, uint8_t* buffer, int bytesRead); + static void HttpBodyStreamInitCallback(const ArkWeb_HttpBodyStream* httpBodyStream, ArkWeb_NetError result); + WebHttpBodyStream(ani_env* env, ArkWeb_HttpBodyStream* stream); + ~WebHttpBodyStream(); + void Init(ani_ref jsCallback, ani_resolver initResolver); + void Read(int bufLen, ani_ref jsCallback, ani_resolver readResolver); + uint64_t GetPostion() const; + uint64_t GetSize() const; + bool IsChunked() const; + bool IsEof(); + bool IsInMemory(); + + void ExecuteInit(ArkWeb_NetError result); + void ExecuteRead(uint8_t* buffer, int bytesRead); + +private: + struct InitAsyncCtx { + ani_env* env = nullptr; + ani_resolver deferred; + int32_t errCode = -1; + }; + + struct ReadAsyncCtx { + ani_env* env = nullptr; + ani_resolver deferred; + uint8_t* buffer = nullptr; + }; + ani_ref initJsCallback_ = nullptr; + ani_resolver initResolver_ = nullptr; + ani_ref readJsCallback_ = nullptr; + ani_resolver readResolver_ = nullptr; + ani_env* env_; + ArkWeb_HttpBodyStream* stream_ = nullptr; +}; + } // namespace NWeb } // namespace OHOS #endif // OHOS_NWEB_ANI_SCHEME_HANDLER_REQUEST_H \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/sts_web_webview.cpp b/interfaces/kits/ani/webview/src/sts_web_webview.cpp index 4fafeeb821a8969029a6d34863b366f45d1728d4..48444ae31410e3acf9c5678801deb3e9cdc05baa 100644 --- a/interfaces/kits/ani/webview/src/sts_web_webview.cpp +++ b/interfaces/kits/ani/webview/src/sts_web_webview.cpp @@ -53,6 +53,7 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) StsBackForwardListInit(env); StsWebMessagePortInit(env); StsWebSchemeHandlerResponseInit(env); + StsWebHttpBodyStreamInit(env); StsWebDownloadDelegateInit(env); StsWebDownLoadItemInit(env); StsWebDownloadManagerInit(env); diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_http_body_stream.cpp b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_http_body_stream.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a9f100495ca12ec2829479d4e4e24528b89a9e11 --- /dev/null +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_http_body_stream.cpp @@ -0,0 +1,174 @@ +/* + * 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. + */ + +#include +#include + +#include "web_scheme_handler_request.h" +#include "webview_controller.h" + +#include "ani_business_error.h" +#include "ani_parse_utils.h" +#include "nweb_log.h" +#include "web_errors.h" +#include "arkweb_scheme_handler.h" + +namespace OHOS { +namespace NWeb { +using namespace NWebError; +using NWebError::NO_ERROR; +namespace { +const char* WEB_HTTP_BODY_STREAM_CLASS_NAME = "L@ohos/web/webview/webview/WebHttpBodyStream;"; +} + +static void Constructor(ani_env* env, ani_object object) +{ + WVLOG_I("WebHttpBodyStream native Constructor"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } +} + +static ani_boolean JsIsChunked(ani_env* env, ani_object object) +{ + WVLOG_D("WebHttpBodyStream JsIsChunked."); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return ANI_FALSE; + } + auto* stream = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!stream) { + WVLOG_E("stream is null"); + return ANI_FALSE; + } + return stream->IsChunked() ? ANI_TRUE : ANI_FALSE; +} + +static ani_boolean JsIsInMemory(ani_env* env, ani_object object) +{ + WVLOG_D("WebHttpBodyStream JsIsInMemory."); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return ANI_FALSE; + } + auto* stream = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!stream) { + WVLOG_E("stream is null"); + return ANI_FALSE; + } + return stream->IsInMemory() ? ANI_TRUE : ANI_FALSE; +} + +static ani_boolean JsIsEof(ani_env* env, ani_object object) +{ + WVLOG_D("WebHttpBodyStream JsIsEof."); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return ANI_FALSE; + } + auto* stream = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!stream) { + WVLOG_E("stream is null"); + return ANI_FALSE; + } + return stream->IsEof() ? ANI_TRUE : ANI_FALSE; +} + +static ani_double GetPosition(ani_env* env, ani_object object) +{ + WVLOG_D("WebHttpBodyStream GetSize."); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return -1; + } + + ani_double position; + + auto* stream = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!stream) { + WVLOG_E("stream is nullptr"); + return -1; + } + std::shared_ptr httpBodyStream; + if (stream != nullptr) { + httpBodyStream = std::shared_ptr(stream, [](OHOS::NWeb::WebHttpBodyStream*) {}); + } + if (httpBodyStream == nullptr) { + WVLOG_E("httpBodyStream is nullptr"); + return -1; + } + position = static_cast(httpBodyStream->GetSize()); + return position; +} + +static ani_double GetSize(ani_env* env, ani_object object) +{ + WVLOG_D("WebHttpBodyStream GetSize."); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return -1; + } + + ani_double size; + + auto* stream = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!stream) { + WVLOG_E("stream is nullptr"); + return -1; + } + std::shared_ptr httpBodyStream; + if (stream != nullptr) { + httpBodyStream = std::shared_ptr(stream, [](OHOS::NWeb::WebHttpBodyStream*) {}); + } + if (httpBodyStream == nullptr) { + WVLOG_E("httpBodyStream is nullptr"); + return -1; + } + size = static_cast(httpBodyStream->GetSize()); + return size; +} + +ani_status StsWebHttpBodyStreamInit(ani_env* env) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return ANI_ERROR; + } + ani_class WebHttpBodyStreamCls = nullptr; + ani_status status = env->FindClass(WEB_HTTP_BODY_STREAM_CLASS_NAME, &WebHttpBodyStreamCls); + if (status != ANI_OK || !WebHttpBodyStreamCls) { + WVLOG_E("find %{public}s class failed, status: %{public}d", WEB_HTTP_BODY_STREAM_CLASS_NAME, status); + return ANI_ERROR; + } + std::array allMethods = { + ani_native_function { "", nullptr, reinterpret_cast(Constructor) }, + ani_native_function { "isChunked", nullptr, reinterpret_cast(JsIsChunked) }, + ani_native_function { "isInMemory", nullptr, reinterpret_cast(JsIsInMemory) }, + ani_native_function { "isEof", nullptr, reinterpret_cast(JsIsEof) }, + ani_native_function { "getPosition", nullptr, reinterpret_cast(GetPosition) }, + ani_native_function { "getSize", nullptr, reinterpret_cast(GetSize) }, + }; + + status = env->Class_BindNativeMethods(WebHttpBodyStreamCls, allMethods.data(), allMethods.size()); + if (status != ANI_OK) { + WVLOG_E("Class_BindNativeMethods failed status: %{public}d", status); + return ANI_ERROR; + } + return ANI_OK; +} + +} // namespace NWeb +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_http_body_stream.h b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_http_body_stream.h new file mode 100644 index 0000000000000000000000000000000000000000..2dd9ff8dd9e833b77d9f65203bd9c481c837114a --- /dev/null +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_http_body_stream.h @@ -0,0 +1,25 @@ +/* + * 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 OHOS_NWEB_ANI_WEB_HTTP_BODY_STREAM_H +#define OHOS_NWEB_ANI_WEB_HTTP_BODY_STREAM_H + +#include + +namespace OHOS { +namespace NWeb { +ani_status StsWebHttpBodyStreamInit(ani_env* env); +} // namespace NWeb +} // namespace OHOS +#endif // OHOS_NWEB_ANI_WEB_HTTP_BODY_STREAM_H \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_request.cpp b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_request.cpp index 4ee0dba598275778b853d3fcb7a821440cfb6299..e2db2c720ebb8fef0561b0c6c162a1f6a103e163 100644 --- a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_request.cpp +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_request.cpp @@ -36,6 +36,7 @@ using NWebError::NO_ERROR; namespace { const char* ANI_CLASS_WEB_REQUESTTYPE = "L@ohos/web/webview/webview/WebSchemeHandlerRequest;"; const char* ANI_CLASS_WEB_RESOURCETYPE = "L@ohos/web/webview/webview/WebResourceType;"; +const char* ANI_HTTP_BODY_STREAM = "L@ohos/web/webview/webview/WebHttpBodyStream;"; } // namespace static ani_boolean JSHasGesture(ani_env* env, ani_object object) @@ -269,6 +270,52 @@ static ani_ref GetHeader(ani_env* env, ani_object object) return array; } +static ani_object GetHttpBodyStream(ani_env* env, ani_object object) +{ + WVLOG_D("getHttpBodyStream start"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return nullptr; + } + auto* request = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!request) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return nullptr; + } + + ArkWeb_HttpBodyStream* arkWebPostStream = request->GetHttpBodyStream(); + if (!arkWebPostStream) { + WVLOG_E("getHttpBodyStream: arkWebPostStream is nullptr"); + return nullptr; + } + ani_object httpBodyStreamObject; + WebHttpBodyStream* stream = new (std::nothrow) WebHttpBodyStream(env, arkWebPostStream); + if (stream == nullptr) { + WVLOG_E("stream is nullptr"); + return nullptr; + } + + ani_class cls; + ani_method ctor; + if (env->FindClass(ANI_HTTP_BODY_STREAM, &cls) != ANI_OK) { + return nullptr; + } + if (env->Class_FindMethod(cls, "", nullptr, &ctor) != ANI_OK) { + return nullptr; + } + if (env->Object_New(cls, ctor, &httpBodyStreamObject) != ANI_OK) { + WVLOG_E("Object_New failed"); + return nullptr; + } + if (!AniParseUtils::Wrap(env, httpBodyStreamObject, ANI_HTTP_BODY_STREAM, reinterpret_cast(stream))) { + WVLOG_E("webview controller wrap failed"); + delete stream; + stream = nullptr; + } + WVLOG_D("getHttpBodyStream: arkWebPostStream success"); + return httpBodyStreamObject; +} + static void Constructor(ani_env* env, ani_object object) { WVLOG_D("WebSchemeHandlerRequest native Constructor"); @@ -300,6 +347,7 @@ ani_status StsWebSchemeHandlerRequestInit(ani_env* env) ani_native_function { "getRequestResourceType", nullptr, reinterpret_cast(GetRequestResourceType) }, ani_native_function { "getRequestUrl", nullptr, reinterpret_cast(GetRequestUrl) }, ani_native_function { "isMainFrame", nullptr, reinterpret_cast(IsMainFrame) }, + ani_native_function { "getHttpBodyStream", nullptr, reinterpret_cast(GetHttpBodyStream) }, ani_native_function { "getRequestMethod", nullptr, reinterpret_cast(GetRequestMethod) }, }; diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_resource.cpp b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_resource.cpp index eab52eb9238873b4547e3deb5d1f636dc40210f5..f5093d292dca43ec463901191568b1378c1f6072 100644 --- a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_resource.cpp +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_resource.cpp @@ -48,7 +48,7 @@ static void JSDidReceiveResponse(ani_env* env, ani_object object, ani_object res auto* receiveResponse = reinterpret_cast(AniParseUtils::Unwrap(env, response)); if (!receiveResponse) { - WVLOG_E("stream is nullptr"); + WVLOG_E("receiveResponse is nullptr"); return; } @@ -88,6 +88,66 @@ static void JsDidFinish(ani_env* env, ani_object object) return; } +static void JsDidReceiveResponseBody(ani_env* env, ani_object object, ani_object arrayBufferObj) +{ + WVLOG_I("Enter aniwebResourceHandler JsDidReceiveResponseBody"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + + auto* resourceHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!resourceHandler) { + WVLOG_E("resourceHandler is nullPtr"); + return; + } + + uint8_t* arrayBuffer = nullptr; + size_t byteLength = 0; + if (env->ArrayBuffer_GetInfo(reinterpret_cast(arrayBufferObj), + reinterpret_cast(&arrayBuffer), &byteLength) != ANI_OK) { + WVLOG_E("ArrayBuffer_GetInfo failed"); + return; + } + int32_t ret = resourceHandler->DidReceiveResponseBody(arrayBuffer, static_cast(byteLength)); + if (ret != 0) { + WVLOG_E("JSDidReceiveResponseBody ret=%{public}d", ret); + AniBusinessError::ThrowErrorByErrCode(env, RESOURCE_HANDLER_INVALID); + return; + } + return; +} + +static void JsDidFailWithError(ani_env* env, ani_object object, ani_enum_item errorCode) +{ + WVLOG_I("Enter aniwebResourceHandler JsDidFailWithError"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + + auto* rosourceHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!rosourceHandler) { + WVLOG_E("rosourceHandler is nullptr"); + return; + } + ani_int iCode; + if (env->EnumItem_GetValue_Int(errorCode, &iCode) != ANI_OK) { + AniBusinessError::ThrowErrorByErrCode(env, PARAM_CHECK_ERROR); + WVLOG_E("EnumItem_GetValue_Int failed"); + return; + } + + int32_t codeInt = static_cast(iCode); + int32_t ret = rosourceHandler->DidFailWithError(static_cast(codeInt)); + WVLOG_I("JSDidFailWithError ret=%{public}d", ret); + if (ret != 0) { + AniBusinessError::ThrowErrorByErrCode(env, RESOURCE_HANDLER_INVALID); + WVLOG_E("JSDidFailWithError ret=%{public}d", ret); + } + return; +} + static void Constructor(ani_env* env, ani_object object) { WVLOG_D("WebResourceHandler WebResourceHandler native Constructor"); @@ -114,6 +174,8 @@ ani_status StsWebSchemeHandlerResourceInit(ani_env* env) ani_native_function { "", nullptr, reinterpret_cast(Constructor) }, ani_native_function { "didFinish", nullptr, reinterpret_cast(JsDidFinish) }, ani_native_function { "didReceiveResponse", nullptr, reinterpret_cast(JSDidReceiveResponse) }, + ani_native_function { "didFail", nullptr, reinterpret_cast(JsDidFailWithError) }, + ani_native_function { "didReceiveResponseBody", nullptr, reinterpret_cast(JsDidReceiveResponseBody) }, }; status = env->Class_BindNativeMethods(WebResourceCls, allMethods.data(), allMethods.size()); diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_response.cpp b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_response.cpp index a536aba4bc4d7b0518bbdc29bc86b90b3a8458c0..442b38f715d0ad2a5fa08aa4fee7ebaf8f038759 100644 --- a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_response.cpp +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_response.cpp @@ -14,10 +14,12 @@ */ #include +#include #include #include "webview_controller.h" #include "web_scheme_handler_response.h" +#include "ani_web_net_error_list.h" #include "ani_business_error.h" #include "ani_parse_utils.h" @@ -341,6 +343,61 @@ static ani_string JsGetHeaderByName(ani_env* env, ani_object object, ani_object return headerValue; } +static ani_enum_item JsGetNetErrorCode(ani_env* env, ani_object object) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return nullptr; + } + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + WVLOG_E("Unwrap WebSchemeHandler failed"); + return nullptr; + } + ani_int result = 0; + ani_enum enumType; + ani_status status = env->FindEnum("L@ohos/web/netErrorList/WebNetErrorList;", &enumType); + if (status != ANI_OK) { + WVLOG_E("JsGetNetErrorCode FindEnum error"); + return nullptr; + } + + result = schemeHandler->GetErrorCode(); + ani_int index = static_cast(GetErrorIndex(result)); + ani_enum_item code; + status = env->Enum_GetEnumItemByIndex(enumType, index, &code); + if (status != ANI_OK) { + WVLOG_E("Enum_GetEnumItemByIndex status: %{public}d", status); + return nullptr; + } + return code; +} + +static void JsSetNetErrorCode(ani_env* env, ani_object object, ani_enum_item code) +{ + WVLOG_I("JsSetNetErrorCode begin"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + WVLOG_E("Unwrap WebSchemeHandler failed"); + return; + } + ani_int iCode; + if (env->EnumItem_GetValue_Int(code, &iCode) != ANI_OK) { + AniBusinessError::ThrowErrorByErrCode(env, PARAM_CHECK_ERROR); + return; + } + int32_t codeInt = static_cast(iCode); + schemeHandler->SetErrorCode(codeInt); + return; +} + static void Constructor(ani_env *env, ani_object object) { WVLOG_D("WebSchemeHandlerResponse native Constructor"); @@ -388,6 +445,8 @@ ani_status StsWebSchemeHandlerResponseInit(ani_env *env) ani_native_function { "getStatus", nullptr, reinterpret_cast(JsGetStatus) }, ani_native_function { "setHeaderByName", nullptr, reinterpret_cast(JsSetHeaderByName) }, ani_native_function { "getHeaderByName", nullptr, reinterpret_cast(JsGetHeaderByName) }, + ani_native_function { "getNetErrorCode", nullptr, reinterpret_cast(JsGetNetErrorCode) }, + ani_native_function { "setNetErrorCode", nullptr, reinterpret_cast(JsSetNetErrorCode) }, }; status = env->Class_BindNativeMethods(webSchemeHandlerResponseCls, allMethods.data(), allMethods.size()); diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp b/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp index 065888cd6e133e4b139c6f27500cbe096568ad3e..0bd0b4a44b377ebf86c7f8145c845fce5d3d07d3 100644 --- a/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp @@ -100,6 +100,7 @@ constexpr double SCALE_MIN = 0.1; constexpr double SCALE_MAX = 2.0; constexpr double HALF = 2.0; constexpr double TEN_MILLIMETER_TO_INCH = 0.39; +const char* ANI_WEB_CUSTOM_SCHEME_CLASS = "L@ohos/web/webview/webview/WebCustomSchemeClass;"; using WebPrintWriteResultCallback = std::function; struct PDFMarginConfig { double top = TEN_MILLIMETER_TO_INCH; @@ -116,6 +117,19 @@ struct SnapshotOptions { PixelUnit sizeType = PixelUnit::NONE; }; +struct Scheme { + std::string name; + bool isSupportCORS; + bool isSupportFetch; + bool isStandard; + bool isLocal; + bool isDisplayIsolated; + bool isSecure; + bool isCspBypassing; + bool isCodeCacheSupported; + int32_t option = 0; +}; + bool ParsePrepareUrl(ani_env* env, ani_ref urlObj, std::string& url) { if (AniParseUtils::ParseString(env, urlObj, url)) { @@ -467,6 +481,8 @@ static void Clean(ani_env *env, ani_object object) delete reinterpret_cast(ptr); } else if (clsName == "WebResourceHandler") { reinterpret_cast(ptr)->DecStrongRef(reinterpret_cast(ptr)); + } else if (clsName == "WebHttpBodyStream") { + delete reinterpret_cast(ptr); } else if (clsName == "JsMessageExt") { delete reinterpret_cast(ptr); } else { @@ -2147,6 +2163,156 @@ static void SetServiceWorkerWebSchemeHandler( return; } +bool CheckSchemeName(const std::string& schemeName) +{ + if (schemeName.empty() || schemeName.size() > MAX_CUSTOM_SCHEME_NAME_LENGTH) { + WVLOG_E("Invalid scheme name length"); + return false; + } + + for (auto it = schemeName.begin(); it != schemeName.end(); it++) { + char chr = *it; + if (!((chr >= 'a' && chr <= 'z') || (chr >= '0' && chr <= '9') || (chr == '.') || (chr == '+') || + (chr == '-'))) { + WVLOG_E("invalid character %{public}c", chr); + return false; + } + } + return true; +} + +void SetCustomizeSchemeOption(Scheme& scheme) +{ + std::map> schemeProperties = { + { 0, [](const Scheme& scheme) { return scheme.isStandard; } }, + { 1, [](const Scheme& scheme) { return scheme.isLocal; } }, + { 2, [](const Scheme& scheme) { return scheme.isDisplayIsolated; } }, + { 3, [](const Scheme& scheme) { return scheme.isSecure; } }, + { 4, [](const Scheme& scheme) { return scheme.isSupportCORS; } }, + { 5, [](const Scheme& scheme) { return scheme.isCspBypassing; } }, + { 6, [](const Scheme& scheme) { return scheme.isSupportFetch; } }, + { 7, [](const Scheme& scheme) { return scheme.isCodeCacheSupported; } } + }; + for (const auto& property : schemeProperties) { + if (property.second(scheme)) { + scheme.option += 1 << property.first; + } + } +} + +bool SetCustomizeScheme(ani_env* env, ani_ref ref, Scheme& scheme) +{ + std::map> schemeBooleanProperties = { + { "isSupportCORS", [](Scheme& scheme, bool value) { scheme.isSupportCORS = value; } }, + { "isSupportFetch", [](Scheme& scheme, bool value) { scheme.isSupportFetch = value; } }, + { "isStandard", [](Scheme& scheme, bool value) { scheme.isStandard = value; } }, + { "isLocal", [](Scheme& scheme, bool value) { scheme.isLocal = value; } }, + { "isDisplayIsolated", [](Scheme& scheme, bool value) { scheme.isDisplayIsolated = value; } }, + { "isSecure", [](Scheme& scheme, bool value) { scheme.isSecure = value; } }, + { "isCspBypassing", [](Scheme& scheme, bool value) { scheme.isCspBypassing = value; } }, + { "isCodeCacheSupported", [](Scheme& scheme, bool value) { scheme.isCodeCacheSupported = value; } } + }; + + ani_ref schemePropertyRef = nullptr; + for (const auto& property : schemeBooleanProperties) { + ani_status status = ANI_OK; + WVLOG_D("property.first.c_str() : %{public}s", property.first.c_str()); + + status = + env->Object_GetPropertyByName_Ref(static_cast(ref), property.first.c_str(), &schemePropertyRef); + if (status != ANI_OK) { + WVLOG_E("Object_GetPropertyByName_Ref status != ANI_OK : %{public}s", property.first.c_str()); + } + bool schemeProperty = false; + if (!AniParseUtils::ParseBoolean(env, schemePropertyRef, schemeProperty)) { + WVLOG_D("ParseBoolean schemeProperty %{public}d ", schemeProperty); + if (property.first == "isSupportCORS" || property.first == "isSupportFetch") { + return false; + } + } + if (!schemeProperty) { + if (property.first == "isSupportCORS" || property.first == "isSupportFetch") { + WVLOG_D("property.first.c_str() : %{public}s", property.first.c_str()); + return false; + } + } + + property.second(scheme, schemeProperty); + } + ani_ref schemeNameObj = nullptr; + if (env->Object_GetPropertyByName_Ref(static_cast(ref), "schemeName", &schemeNameObj) != ANI_OK) { + return false; + } + if (!AniParseUtils::ParseString(env, schemeNameObj, scheme.name)) { + return false; + } + if (!CheckSchemeName(scheme.name)) { + return false; + } + SetCustomizeSchemeOption(scheme); + return true; +} + +int32_t CustomizeSchemesArrayDataHandler(ani_env* env, ani_ref array) +{ + uint32_t arrayLength = 0; + env->Array_GetLength(static_cast(array), &arrayLength); + if (arrayLength > MAX_CUSTOM_SCHEME_SIZE) { + WVLOG_E("PARAM_CHECK_ERROR"); + return PARAM_CHECK_ERROR; + } + std::vector schemeVector; + ani_object obj = {}; + if (AniParseUtils::CreateObjectVoid(env, ANI_WEB_CUSTOM_SCHEME_CLASS, obj) == false) { + WVLOG_E("Obj CreateObjectVoid failed"); + return false; + } + ani_ref objRef = static_cast(obj); + for (uint32_t i = 0; i < arrayLength; ++i) { + ani_status status = env->Array_Get_Ref(static_cast(array), i, &objRef); + if (status != ANI_OK) { + WVLOG_E("Array_Get_Ref failed %{public}d", status); + } + + Scheme scheme; + bool result = SetCustomizeScheme(env, objRef, scheme); + if (!result) { + return PARAM_CHECK_ERROR; + } + schemeVector.push_back(scheme); + } + int32_t registerResult; + for (auto it = schemeVector.begin(); it != schemeVector.end(); ++it) { + registerResult = OH_ArkWeb_RegisterCustomSchemes(it->name.c_str(), it->option); + if (registerResult != NO_ERROR) { + return registerResult; + } + } + return NO_ERROR; +} + +static void CustomizeSchemes(ani_env* env, ani_object object, ani_object schemes) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + if (WebviewController::existNweb_) { + WVLOG_E("There exist web component which has been already created."); + } + int32_t registerResult = CustomizeSchemesArrayDataHandler(env, schemes); + if (registerResult == NO_ERROR) { + return; + } + if (registerResult == PARAM_CHECK_ERROR) { + AniBusinessError::ThrowError(env, PARAM_CHECK_ERROR, + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "schemeName", "string")); + return; + } + AniBusinessError::ThrowErrorByErrCode(env, REGISTER_CUSTOM_SCHEME_FAILED); + return; +} + static void ClearWebSchemeHandler(ani_env *env, ani_object object) { if (!env) { @@ -5316,6 +5482,7 @@ ani_status StsWebviewControllerInit(ani_env *env) ani_native_function { "runJavaScriptCallbackExt", nullptr, reinterpret_cast(RunJavaScriptCallbackExt) }, ani_native_function { "runJavaScriptPromiseExt", nullptr, reinterpret_cast(RunJavaScriptPromiseExt) }, ani_native_function { "setWebSchemeHandler", nullptr, reinterpret_cast(SetWebSchemeHandler) }, + ani_native_function { "customizeSchemes", nullptr, reinterpret_cast(CustomizeSchemes) }, ani_native_function { "setServiceWorkerWebSchemeHandler", nullptr, reinterpret_cast(SetServiceWorkerWebSchemeHandler) }, ani_native_function { "hasImageCallback", nullptr, reinterpret_cast(HasImageCallback) }, diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.h b/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.h index 467d231872546ba08399888c2af95bbc997bf40c..07d6bfadb58864319a8a3acc88cb0e629d04c65a 100644 --- a/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.h +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.h @@ -35,6 +35,7 @@ ani_status StsCleanerInit(ani_env *env); ani_status StsBackForwardListInit(ani_env *env); ani_status StsWebMessagePortInit(ani_env *env); ani_status StsWebSchemeHandlerResponseInit(ani_env *env); +ani_status StsWebHttpBodyStreamInit(ani_env *env); ani_status StsWebDownloadDelegateInit(ani_env *env); ani_status StsWebDownLoadItemInit(ani_env *env); ani_status StsWebDownloadManagerInit(ani_env *env);