From 32c010cd2e6e849885bca772d49aa631ef1c28bd Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Wed, 22 Apr 2026 12:30:18 -0500 Subject: [PATCH] Update to 2.52.3 Resolves: RHEL-157522 Resolves: RHEL-157538 Resolves: RHEL-157595 Resolves: RHEL-157609 Resolves: RHEL-157623 Resolves: RHEL-157638 Resolves: RHEL-157652 Resolves: RHEL-157666 Resolves: RHEL-157682 Resolves: RHEL-157696 Resolves: RHEL-157710 Resolves: RHEL-162720 Resolves: RHEL-162734 Resolves: RHEL-162749 Resolves: RHEL-162763 Resolves: RHEL-162777 Resolves: RHEL-162791 Resolves: RHEL-162805 --- aarch64-build.patch | 329 +++ cairo-1.15.patch | 14 +- compiler-flags.patch | 14 +- evolution-sandbox-warning.patch | 8 +- evolution-shared-secondary-process.patch | 10 +- g-ir-scanner-nonfatal.patch | 28 + glib-2.56.patch | 113 +- gstreamer-1.16.patch | 169 +- harfbuzz-1.7.5.patch | 30 +- icu60.patch | 178 +- libsoup2.patch | 3178 ++++++++++++++++++++++ sources | 4 +- webkit2gtk3.spec | 23 +- 13 files changed, 3853 insertions(+), 245 deletions(-) create mode 100644 aarch64-build.patch create mode 100644 g-ir-scanner-nonfatal.patch create mode 100644 libsoup2.patch diff --git a/aarch64-build.patch b/aarch64-build.patch new file mode 100644 index 0000000..d246a68 --- /dev/null +++ b/aarch64-build.patch @@ -0,0 +1,329 @@ +From a98fdf70489a743d3ee98f91758e043ffee9f9ca Mon Sep 17 00:00:00 2001 +From: Shu-yu Guo +Date: Fri, 17 Apr 2026 16:10:11 -0500 +Subject: [PATCH] Cherry-pick 7cda001308f2. + https://bugs.webkit.org/show_bug.cgi?id=306638 + +[JSC] Fix !ENABLE(JIT) build +https://bugs.webkit.org/show_bug.cgi?id=306638 +rdar://169822205 + +Reviewed by NOBODY (OOPS!). + +* Source/JavaScriptCore/jit/ExecutableAllocator.h: +(JSC::performJITMemcpy): +* Source/JavaScriptCore/llint/InPlaceInterpreter.asm: +* Source/JavaScriptCore/llint/LLIntData.cpp: +(JSC::LLInt::initialize): +* Source/JavaScriptCore/wasm/WasmCallee.cpp: +* Source/WTF/wtf/PlatformEnable.h: +--- + .../JavaScriptCore/jit/ExecutableAllocator.h | 8 ++ + .../llint/InPlaceInterpreter.asm | 8 +- + Source/JavaScriptCore/llint/LLIntData.cpp | 81 +++++++++++++++---- + Source/JavaScriptCore/wasm/WasmCallee.cpp | 18 ++++- + Source/WTF/wtf/PlatformEnable.h | 2 +- + 5 files changed, 93 insertions(+), 24 deletions(-) + +diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.h b/Source/JavaScriptCore/jit/ExecutableAllocator.h +index 3e8efce28cfe..cb81579c8703 100644 +--- a/Source/JavaScriptCore/jit/ExecutableAllocator.h ++++ b/Source/JavaScriptCore/jit/ExecutableAllocator.h +@@ -390,6 +390,14 @@ WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN + WTF_ALLOW_UNSAFE_BUFFER_USAGE_END + } + ++template ++inline void* performJITMemcpy(void *dst, const void *src, size_t n) ++{ ++WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN ++ return memcpy(dst, src, n); ++WTF_ALLOW_UNSAFE_BUFFER_USAGE_END ++} ++ + inline bool isJITPC(void*) { return false; } + #endif // ENABLE(JIT) + +diff --git a/Source/JavaScriptCore/llint/InPlaceInterpreter.asm b/Source/JavaScriptCore/llint/InPlaceInterpreter.asm +index 64db9cdb21df..dac1faa5260a 100644 +--- a/Source/JavaScriptCore/llint/InPlaceInterpreter.asm ++++ b/Source/JavaScriptCore/llint/InPlaceInterpreter.asm +@@ -420,7 +420,7 @@ end + + # OSR + macro ipintPrologueOSR(increment) +-if JIT ++if WEBASSEMBLY_BBQJIT + loadp UnboxedWasmCalleeStackSlot[cfr], ws0 + baddis increment, Wasm::IPIntCallee::m_tierUpCounter + Wasm::IPIntTierUpCounter::m_counter[ws0], .continue + +@@ -457,11 +457,11 @@ end + if ARMv7 + break # FIXME: ipint support. + end # ARMv7 +-end # JIT ++end # WEBASSEMBLY_BBQJIT + end + + macro ipintLoopOSR(increment) +-if JIT and not ARMv7 ++if WEBASSEMBLY_BBQJIT and not ARMv7 + validateOpcodeConfig(ws0) + loadp UnboxedWasmCalleeStackSlot[cfr], ws0 + baddis increment, Wasm::IPIntCallee::m_tierUpCounter + Wasm::IPIntTierUpCounter::m_counter[ws0], .continue +@@ -492,7 +492,7 @@ end + end + + macro ipintEpilogueOSR(increment) +-if JIT and not ARMv7 ++if WEBASSEMBLY_BBQJIT and not ARMv7 + loadp UnboxedWasmCalleeStackSlot[cfr], ws0 + baddis increment, Wasm::IPIntCallee::m_tierUpCounter + Wasm::IPIntTierUpCounter::m_counter[ws0], .continue + +diff --git a/Source/JavaScriptCore/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp +index 5d7c88f72571..2509dc4132f3 100644 +--- a/Source/JavaScriptCore/llint/LLIntData.cpp ++++ b/Source/JavaScriptCore/llint/LLIntData.cpp +@@ -199,8 +199,28 @@ void initialize() + #if CPU(ARM64E) + + #if ENABLE(JIT_CAGE) +- if (Options::useJITCage()) ++ if (Options::useJITCage()) { + g_jscConfig.llint.gateMap[static_cast(Gate::jitCagePtr)] = jitCagePtrThunk().code().taggedPtr(); ++#if ENABLE(WEBASSEMBLY) ++ // JSPI JITCage gates ++ g_jscConfig.llint.gateMap[static_cast(Gate::jspiResignReturnPCs)] = jspiResignReturnPCsThunk().code().taggedPtr(); ++ g_jscConfig.llint.gateMap[static_cast(Gate::jspiExecuteSliceEntry)] = jspiExecuteSliceEntryThunk().code().taggedPtr(); ++ // jspiExitImplantedSlice is stored untagged because it's used as a return address ++ // (not as a jump target) and will be signed by JITCage with the stack pointer diversifier. ++ g_jscConfig.llint.gateMap[static_cast(Gate::jspiExitImplantedSlice)] = jspiExitImplantedSliceThunk().code().untaggedPtr(); ++#endif // ENABLE(WEBASSEMBLY) ++ } ++#endif ++ ++#if ENABLE(JIT) ++#define INITIALIZE_JS_GATE_JIT_PATH(name, tag) \ ++ if (Options::useJIT()) { \ ++ codeRef8.construct(createJSGateThunk(retagCodePtr(LLInt::getCodeFunctionPtr(name##_return_location)), tag, #name)); \ ++ codeRef16.construct(createJSGateThunk(retagCodePtr(LLInt::getWide16CodeFunctionPtr(name##_return_location)), tag, #name "_wide16")); \ ++ codeRef32.construct(createJSGateThunk(retagCodePtr(LLInt::getWide32CodeFunctionPtr(name##_return_location)), tag, #name "_wide32")); \ ++ } else ++#else ++#define INITIALIZE_JS_GATE_JIT_PATH(name, tag) + #endif + + #define INITIALIZE_JS_GATE(name, tag) \ +@@ -208,11 +228,7 @@ void initialize() + static LazyNeverDestroyed> codeRef8; \ + static LazyNeverDestroyed> codeRef16; \ + static LazyNeverDestroyed> codeRef32; \ +- if (Options::useJIT()) { \ +- codeRef8.construct(createJSGateThunk(retagCodePtr(LLInt::getCodeFunctionPtr(name##_return_location)), tag, #name)); \ +- codeRef16.construct(createJSGateThunk(retagCodePtr(LLInt::getWide16CodeFunctionPtr(name##_return_location)), tag, #name "_wide16")); \ +- codeRef32.construct(createJSGateThunk(retagCodePtr(LLInt::getWide32CodeFunctionPtr(name##_return_location)), tag, #name "_wide32")); \ +- } else { \ ++ INITIALIZE_JS_GATE_JIT_PATH(name, tag) { \ + codeRef8.construct(LLInt::getCodeRef(js_trampoline_##name)); \ + codeRef16.construct(LLInt::getWide16CodeRef(js_trampoline_##name)); \ + codeRef32.construct(LLInt::getWide32CodeRef(js_trampoline_##name)); \ +@@ -226,16 +242,23 @@ void initialize() + + #if ENABLE(WEBASSEMBLY) + ++#if ENABLE(JIT) ++#define INITIALIZE_WASM_GATE_JIT_PATH(name, tag) \ ++ if (Options::useJIT()) { \ ++ codeRef8.construct(createWasmGateThunk(retagCodePtr(LLInt::getCodeFunctionPtr(name##_return_location)), tag, #name)); \ ++ codeRef16.construct(createWasmGateThunk(retagCodePtr(LLInt::getWide16CodeFunctionPtr(name##_return_location)), tag, #name "_wide16")); \ ++ codeRef32.construct(createWasmGateThunk(retagCodePtr(LLInt::getWide32CodeFunctionPtr(name##_return_location)), tag, #name "_wide32")); \ ++ } else ++#else ++#define INITIALIZE_WASM_GATE_JIT_PATH(name, tag) ++#endif ++ + #define INITIALIZE_WASM_GATE(name, tag) \ + do { \ + static LazyNeverDestroyed> codeRef8; \ + static LazyNeverDestroyed> codeRef16; \ + static LazyNeverDestroyed> codeRef32; \ +- if (Options::useJIT()) { \ +- codeRef8.construct(createWasmGateThunk(retagCodePtr(LLInt::getCodeFunctionPtr(name##_return_location)), tag, #name)); \ +- codeRef16.construct(createWasmGateThunk(retagCodePtr(LLInt::getWide16CodeFunctionPtr(name##_return_location)), tag, #name "_wide16")); \ +- codeRef32.construct(createWasmGateThunk(retagCodePtr(LLInt::getWide32CodeFunctionPtr(name##_return_location)), tag, #name "_wide32")); \ +- } else { \ ++ INITIALIZE_WASM_GATE_JIT_PATH(name, tag) { \ + codeRef8.construct(LLInt::getCodeRef(wasm_trampoline_##name)); \ + codeRef16.construct(LLInt::getWide16CodeRef(wasm_trampoline_##name)); \ + codeRef32.construct(LLInt::getWide32CodeRef(wasm_trampoline_##name)); \ +@@ -253,10 +276,12 @@ void initialize() + // This is key to entering the interpreter. + { + static LazyNeverDestroyed> codeRef; ++#if ENABLE(JIT) + if (Options::useJIT()) { + auto gateCodeRef = createJSGateThunk(retagCodePtr(&vmEntryToJavaScriptGateAfter), JSEntryPtrTag, "vmEntryToJavaScript"); + codeRef.construct(gateCodeRef.retagged()); + } else ++#endif + codeRef.construct(MacroAssemblerCodeRef::createSelfManagedCodeRef(CodePtr::fromTaggedPtr(retagCodePtr(&vmEntryToJavaScriptTrampoline)))); + g_jscConfig.llint.gateMap[static_cast(Gate::vmEntryToJavaScript)] = codeRef.get().code().taggedPtr(); + } +@@ -268,79 +293,103 @@ void initialize() + + { + static LazyNeverDestroyed> codeRef; ++#if ENABLE(JIT) + if (Options::useJIT()) + codeRef.construct(createTailCallGate(JSEntryPtrTag, true)); + else ++#endif + codeRef.construct(MacroAssemblerCodeRef::createSelfManagedCodeRef(CodePtr::fromTaggedPtr(retagCodePtr(&tailCallJSEntryTrampoline)))); + g_jscConfig.llint.gateMap[static_cast(Gate::tailCallJSEntryPtrTag)]= codeRef.get().code().taggedPtr(); + } + { + static LazyNeverDestroyed> codeRef; ++#if ENABLE(JIT) + if (Options::useJIT()) + codeRef.construct(createTailCallGate(JSEntryPtrTag, true)); + else ++#endif + codeRef.construct(MacroAssemblerCodeRef::createSelfManagedCodeRef(CodePtr::fromTaggedPtr(retagCodePtr(&tailCallJSEntrySlowPathTrampoline)))); + g_jscConfig.llint.gateMap[static_cast(Gate::tailCallJSEntrySlowPathPtrTag)] = codeRef.get().code().taggedPtr(); + } + { + static LazyNeverDestroyed> codeRef; ++#if ENABLE(JIT) + if (Options::useJIT()) + codeRef.construct(createTailCallGate(JSEntryPtrTag, false)); + else ++#endif + codeRef.construct(MacroAssemblerCodeRef::createSelfManagedCodeRef(CodePtr::fromTaggedPtr(retagCodePtr(&tailCallWithoutUntagJSEntryTrampoline)))); + g_jscConfig.llint.gateMap[static_cast(Gate::tailCallWithoutUntagJSEntryPtrTag)]= codeRef.get().code().taggedPtr(); + } + { + static LazyNeverDestroyed> codeRef; ++#if ENABLE(JIT) + if (Options::useJIT()) + codeRef.construct(createWasmTailCallGate(WasmEntryPtrTag)); + else ++#endif + codeRef.construct(MacroAssemblerCodeRef::createSelfManagedCodeRef(CodePtr::fromTaggedPtr(retagCodePtr(&wasmTailCallTrampoline)))); + g_jscConfig.llint.gateMap[static_cast(Gate::wasmTailCallWasmEntryPtrTag)]= codeRef.get().code().taggedPtr(); + } + { + static LazyNeverDestroyed> codeRef; ++#if ENABLE(JIT) + if (Options::useJIT()) + codeRef.construct(createWasmTailCallGate(WasmEntryPtrTag)); + else ++#endif + codeRef.construct(MacroAssemblerCodeRef::createSelfManagedCodeRef(CodePtr::fromTaggedPtr(retagCodePtr(&wasmTailCallTrampoline)))); + g_jscConfig.llint.gateMap[static_cast(Gate::wasmIPIntTailCallWasmEntryPtrTag)]= codeRef.get().code().taggedPtr(); + } + { + static LazyNeverDestroyed> codeRef; ++#if ENABLE(JIT) + if (Options::useJIT()) + codeRef.construct(exceptionHandlerGateThunk()); + else ++#endif + codeRef.construct(MacroAssemblerCodeRef::createSelfManagedCodeRef(CodePtr::fromTaggedPtr(retagCodePtr(&exceptionHandlerTrampoline)))); + g_jscConfig.llint.gateMap[static_cast(Gate::exceptionHandler)] = codeRef.get().code().taggedPtr(); + } + { + static LazyNeverDestroyed> codeRef; ++#if ENABLE(JIT) + if (Options::useJIT()) + codeRef.construct(returnFromLLIntGateThunk()); + else ++#endif + codeRef.construct(MacroAssemblerCodeRef::createSelfManagedCodeRef(CodePtr::fromTaggedPtr(retagCodePtr(&returnFromLLIntTrampoline)))); + g_jscConfig.llint.gateMap[static_cast(Gate::returnFromLLInt)] = codeRef.get().code().taggedPtr(); + } + ++#if ENABLE(JIT) + if (Options::useJIT()) { + g_jscConfig.llint.gateMap[static_cast(Gate::loopOSREntry)] = loopOSREntryGateThunk().code().taggedPtr(); + g_jscConfig.llint.gateMap[static_cast(Gate::entryOSREntry)] = entryOSREntryGateThunk().code().taggedPtr(); + g_jscConfig.llint.gateMap[static_cast(Gate::wasmOSREntry)] = wasmOSREntryGateThunk().code().taggedPtr(); +- } else { ++ } else ++#endif ++ { + g_jscConfig.llint.gateMap[static_cast(Gate::loopOSREntry)] = LLInt::getCodeRef(loop_osr_entry_gate).code().taggedPtr(); + g_jscConfig.llint.gateMap[static_cast(Gate::entryOSREntry)] = nullptr; + g_jscConfig.llint.gateMap[static_cast(Gate::wasmOSREntry)] = nullptr; + } + ++#if ENABLE(JIT) ++#define INITIALIZE_TAG_AND_UNTAG_THUNKS_JIT_PATH(name) \ ++ if (Options::useJIT()) { \ ++ tagCodeRef.construct(tagGateThunk(retagCodePtr(name##TagGateAfter))); \ ++ untagCodeRef.construct(untagGateThunk(retagCodePtr(name##UntagGateAfter))); \ ++ } else ++#else ++#define INITIALIZE_TAG_AND_UNTAG_THUNKS_JIT_PATH(name) ++#endif ++ + #define INITIALIZE_TAG_AND_UNTAG_THUNKS(name) \ + do { \ + static LazyNeverDestroyed> tagCodeRef; \ + static LazyNeverDestroyed> untagCodeRef; \ +- if (Options::useJIT()) { \ +- tagCodeRef.construct(tagGateThunk(retagCodePtr(name##TagGateAfter))); \ +- untagCodeRef.construct(untagGateThunk(retagCodePtr(name##UntagGateAfter))); \ +- } else { \ ++ INITIALIZE_TAG_AND_UNTAG_THUNKS_JIT_PATH(name) { \ + tagCodeRef.construct(LLInt::getCodeRef(js_trampoline_##name##_tag)); \ + untagCodeRef.construct(LLInt::getCodeRef(js_trampoline_##name##_untag)); \ + } \ +diff --git a/Source/JavaScriptCore/wasm/WasmCallee.cpp b/Source/JavaScriptCore/wasm/WasmCallee.cpp +index 94a845ab47e4..b689f00143ab 100644 +--- a/Source/JavaScriptCore/wasm/WasmCallee.cpp ++++ b/Source/JavaScriptCore/wasm/WasmCallee.cpp +@@ -55,13 +55,25 @@ WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(Callee); + WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(JITCallee); + WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(JSToWasmCallee); + WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(WasmToJSCallee); ++WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(IPIntCallee); ++WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(WasmBuiltinCallee); ++ ++#if ENABLE(JIT) + WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(JSToWasmICCallee); ++#endif ++ ++#if ENABLE(WEBASSEMBLY_BBQJIT) || ENABLE(WEBASSEMBLY_OMGJIT) + WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(OptimizingJITCallee); ++#endif ++ ++#if ENABLE(WEBASSEMBLY_BBQJIT) ++WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(BBQCallee); ++#endif ++ ++#if ENABLE(WEBASSEMBLY_OMGJIT) + WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(OMGCallee); + WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(OMGOSREntryCallee); +-WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(BBQCallee); +-WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(IPIntCallee); +-WTF_MAKE_COMPACT_TZONE_ALLOCATED_IMPL(WasmBuiltinCallee); ++#endif + + Callee::Callee(Wasm::CompilationMode compilationMode) + : NativeCallee(NativeCallee::Category::Wasm, ImplementationVisibility::Private) +diff --git a/Source/WTF/wtf/PlatformEnable.h b/Source/WTF/wtf/PlatformEnable.h +index 9c20eb45de48..1561e5ecc85a 100644 +--- a/Source/WTF/wtf/PlatformEnable.h ++++ b/Source/WTF/wtf/PlatformEnable.h +@@ -1006,7 +1006,7 @@ + #define ENABLE_JIT_OPERATION_DISASSEMBLY 1 + #endif + +-#if CPU(ARM64E) ++#if CPU(ARM64E) && ENABLE(JIT) + #define ENABLE_JIT_SIGN_ASSEMBLER_BUFFER 1 + #endif + +-- +2.53.0 + diff --git a/cairo-1.15.patch b/cairo-1.15.patch index e1e51c7..4515551 100644 --- a/cairo-1.15.patch +++ b/cairo-1.15.patch @@ -1,4 +1,4 @@ -From 35146c99cad7f842666d9123113936ec89388261 Mon Sep 17 00:00:00 2001 +From a36c4b810651f0c4a66142514da0acc338995431 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Tue, 23 Sep 2025 15:47:39 -0500 Subject: [PATCH] Build against cairo 1.15 @@ -8,19 +8,19 @@ Subject: [PATCH] Build against cairo 1.15 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake -index 5222f5ea81ab..77ec61c954c0 100644 +index a70213b2edf5..eea6eb87ad4b 100644 --- a/Source/cmake/OptionsGTK.cmake +++ b/Source/cmake/OptionsGTK.cmake @@ -9,7 +9,7 @@ set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string") # Update Source/WTF/wtf/Platform.h to match required GLib versions. - find_package(GLIB 2.70.0 REQUIRED COMPONENTS gio gio-unix gobject gthread gmodule) + find_package(GLib 2.56.0 REQUIRED COMPONENTS GioUnix Thread Module) -find_package(Cairo 1.16.0 REQUIRED) +find_package(Cairo 1.14.0 REQUIRED) find_package(LibGcrypt 1.7.0 REQUIRED) - find_package(Libtasn1 REQUIRED) - find_package(HarfBuzz 2.7.4 REQUIRED COMPONENTS ICU) -@@ -132,7 +132,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE ${ENABLE_DEVELOPER_MODE} + find_package(Soup3 3.0.0 REQUIRED) + find_package(Tasn1 REQUIRED) +@@ -134,7 +134,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE ${ENABLE_DEVELOPER_MODE} WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PERIODIC_MEMORY_MONITOR PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHAREABLE_RESOURCE PRIVATE ON) @@ -30,5 +30,5 @@ index 5222f5ea81ab..77ec61c954c0 100644 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_CODECS PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_RTC PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES}) -- -2.51.0 +2.53.0 diff --git a/compiler-flags.patch b/compiler-flags.patch index ad5c638..c39989f 100644 --- a/compiler-flags.patch +++ b/compiler-flags.patch @@ -1,4 +1,4 @@ -From f3dd0fe388842a7cb35266b4b0b79cfb4ef930c4 Mon Sep 17 00:00:00 2001 +From ee1a6eb354e881e211b7004e465828a669be5156 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Tue, 23 Sep 2025 15:46:28 -0500 Subject: [PATCH] Suppress some build warnings @@ -21,10 +21,10 @@ index 7ea8f0469ad7..13a9e390643a 100644 -Wno-unused-parameter ) diff --git a/Source/cmake/WebKitCompilerFlags.cmake b/Source/cmake/WebKitCompilerFlags.cmake -index 77a292fb8b15..f6648c39c4e0 100644 +index 7eb24e774b40..fe7eedd20507 100644 --- a/Source/cmake/WebKitCompilerFlags.cmake +++ b/Source/cmake/WebKitCompilerFlags.cmake -@@ -129,11 +129,6 @@ if (DEVELOPER_MODE AND DEVELOPER_MODE_FATAL_WARNINGS) +@@ -130,11 +130,6 @@ if (DEVELOPER_MODE AND DEVELOPER_MODE_FATAL_WARNINGS) else () set(FATAL_WARNINGS_FLAG -Werror) endif () @@ -36,9 +36,9 @@ index 77a292fb8b15..f6648c39c4e0 100644 endif () if (DEVELOPER_MODE OR ARM) -@@ -186,8 +181,7 @@ if (COMPILER_IS_GCC_OR_CLANG) - -Wno-misleading-indentation - -Wno-psabi) +@@ -188,8 +183,7 @@ if (COMPILER_IS_GCC_OR_CLANG) + -Wno-psabi + -Wno-nullability-completeness) - # GCC < 12.0 gives false warnings for mismatched-new-delete - if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0.0")) @@ -47,5 +47,5 @@ index 77a292fb8b15..f6648c39c4e0 100644 WEBKIT_PREPEND_GLOBAL_COMPILER_FLAGS(-Wno-uninitialized) endif () -- -2.51.0 +2.53.0 diff --git a/evolution-sandbox-warning.patch b/evolution-sandbox-warning.patch index c9531a0..41dd859 100644 --- a/evolution-sandbox-warning.patch +++ b/evolution-sandbox-warning.patch @@ -1,4 +1,4 @@ -From 01c16493deb6dab8e04adfcdd244aaad3067d434 Mon Sep 17 00:00:00 2001 +From 2de7d9e8776e5c49b889c8eaeec49f53e62f55b8 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Tue, 7 Oct 2025 11:19:06 -0500 Subject: [PATCH] Suppress warning about WEBKIT_FORCE_SANDBOX for Evolution @@ -8,10 +8,10 @@ Subject: [PATCH] Suppress warning about WEBKIT_FORCE_SANDBOX for Evolution 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp b/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp -index 044ddc0c3e95..a953dda3dcb8 100644 +index 329dbe6a0281..80b9609a47be 100644 --- a/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp +++ b/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp -@@ -155,7 +155,8 @@ void WebProcessPool::platformInitialize(NeedsGlobalStaticInitialization) +@@ -154,7 +154,8 @@ void WebProcessPool::platformInitialize(NeedsGlobalStaticInitialization) else { static bool once = false; if (!once) { @@ -22,5 +22,5 @@ index 044ddc0c3e95..a953dda3dcb8 100644 } } -- -2.51.0 +2.53.0 diff --git a/evolution-shared-secondary-process.patch b/evolution-shared-secondary-process.patch index 5c7ebe9..71eeb71 100644 --- a/evolution-shared-secondary-process.patch +++ b/evolution-shared-secondary-process.patch @@ -1,4 +1,4 @@ -From 5fd4924b8d61545a7798be25ac9cb45c007a1795 Mon Sep 17 00:00:00 2001 +From e13100155debec49c5ded3740901ac2a3c669370 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Tue, 7 Oct 2025 11:18:05 -0500 Subject: [PATCH] Use a single web process for Evolution @@ -8,19 +8,19 @@ Subject: [PATCH] Use a single web process for Evolution 1 file changed, 3 insertions(+) diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp -index dca689a7ace5..b63d037a00f4 100644 +index 5cbc8739a2fe..5778f7a2da72 100644 --- a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp +++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp @@ -457,6 +457,9 @@ static void webkitWebContextConstructed(GObject* object) } - configuration.setTimeZoneOverride(String::fromUTF8(priv->timeZoneOverride.span())); + configuration->setTimeZoneOverride(String::fromUTF8(priv->timeZoneOverride.span())); + if (!g_strcmp0(g_get_prgname(), "evolution")) -+ configuration.setUsesSingleWebProcess(true); ++ configuration->setUsesSingleWebProcess(true); + #if !ENABLE(2022_GLIB_API) if (!priv->websiteDataManager) priv->websiteDataManager = adoptGRef(webkit_website_data_manager_new("local-storage-directory", priv->localStorageDirectory.data(), nullptr)); -- -2.51.0 +2.53.0 diff --git a/g-ir-scanner-nonfatal.patch b/g-ir-scanner-nonfatal.patch new file mode 100644 index 0000000..e836434 --- /dev/null +++ b/g-ir-scanner-nonfatal.patch @@ -0,0 +1,28 @@ +From f3a8648a0c5902b0e44c26bba1a882ff296a6c8d Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Mon, 6 Apr 2026 18:05:37 -0500 +Subject: [PATCH] Make g-ir-scanner warnings nonfatal + +Otherwise, the build fails whenever it sees an unrecognized annotation, +which is not great whenever WebKit starts using new annotations that do +not exist in old RHELs. +--- + Source/cmake/FindGI.cmake | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Source/cmake/FindGI.cmake b/Source/cmake/FindGI.cmake +index 8cf372f3b172..cb724a418020 100644 +--- a/Source/cmake/FindGI.cmake ++++ b/Source/cmake/FindGI.cmake +@@ -342,7 +342,7 @@ function(GI_INTROSPECT namespace nsversion header) + VERBATIM + COMMAND_EXPAND_LISTS + COMMAND ${CMAKE_COMMAND} -E env "CC=${CMAKE_C_COMPILER}" "CFLAGS=${CMAKE_C_FLAGS}" +- "${GI_SCANNER_EXE}" --quiet --warn-all --warn-error --no-libtool ++ "${GI_SCANNER_EXE}" --quiet --warn-all --no-libtool + "--output=${gir_path}" + "--library=$" + "--library-path=$" +-- +2.53.0 + diff --git a/glib-2.56.patch b/glib-2.56.patch index dc6b5c9..76625d6 100644 --- a/glib-2.56.patch +++ b/glib-2.56.patch @@ -1,49 +1,42 @@ -From b668f6fc8731b55105a49e72faf266a90d8e65ac Mon Sep 17 00:00:00 2001 +From faa96c8ff6fa906beaa5daf8e36bc1f865a9cf66 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Fri, 4 Apr 2025 13:58:05 -0500 Subject: [PATCH] Build against GLib 2.56 --- - Source/WTF/wtf/Platform.h | 2 -- - Source/WTF/wtf/URL.h | 4 ++-- - Source/WTF/wtf/glib/GRefPtr.h | 2 ++ - Source/WTF/wtf/glib/SocketConnection.cpp | 13 ++++++++++++- - Source/WTF/wtf/glib/URLGLib.cpp | 2 ++ - Source/WebCore/platform/LowPowerModeNotifier.h | 2 ++ - .../platform/glib/LowPowerModeNotifierGLib.cpp | 8 ++++++++ - .../platform/network/soup/CertificateInfoSoup.cpp | 8 ++++++++ - Source/WebKit/NetworkProcess/glib/DNSCache.cpp | 12 ++++++++++++ - Source/WebKit/NetworkProcess/glib/DNSCache.h | 2 ++ - .../NetworkProcess/glib/WebKitCachedResolver.cpp | 6 ++++++ - .../glib/WebKitOverridingResolver.cpp | 4 ++++ - Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp | 6 ++++++ - Source/cmake/OptionsGTK.cmake | 14 ++++++++++++-- - Tools/MiniBrowser/gtk/BrowserSettingsDialog.c | 3 ++- - Tools/MiniBrowser/gtk/main.c | 3 ++- - 16 files changed, 82 insertions(+), 9 deletions(-) + Source/WTF/wtf/Platform.h | 2 +- + Source/WTF/wtf/URL.h | 4 ++-- + Source/WTF/wtf/glib/GRefPtr.h | 2 ++ + Source/WTF/wtf/glib/SocketConnection.cpp | 13 ++++++++++++- + Source/WTF/wtf/glib/URLGLib.cpp | 2 ++ + Source/WebCore/platform/LowPowerModeNotifier.h | 2 ++ + .../platform/glib/LowPowerModeNotifierGLib.cpp | 8 ++++++++ + .../platform/network/soup/CertificateInfoSoup.cpp | 8 ++++++++ + Source/WebKit/NetworkProcess/glib/DNSCache.cpp | 12 ++++++++++++ + Source/WebKit/NetworkProcess/glib/DNSCache.h | 2 ++ + .../NetworkProcess/glib/WebKitCachedResolver.cpp | 6 ++++++ + .../glib/WebKitOverridingResolver.cpp | 4 ++++ + Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp | 6 ++++++ + Source/cmake/OptionsGTK.cmake | 7 ++++++- + Tools/MiniBrowser/gtk/BrowserSettingsDialog.c | 3 ++- + Tools/MiniBrowser/gtk/main.c | 3 ++- + 16 files changed, 77 insertions(+), 7 deletions(-) diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h -index cbb81ce6c8dc..46cbad83fe4e 100644 +index 0c3ba74482f6..57a1b5126290 100644 --- a/Source/WTF/wtf/Platform.h +++ b/Source/WTF/wtf/Platform.h -@@ -84,7 +84,6 @@ +@@ -92,7 +92,7 @@ - #if PLATFORM(GTK) - #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_56 --#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_70 - #if USE(GTK4) - #define GDK_VERSION_MIN_REQUIRED GDK_VERSION_4_0 - #else -@@ -94,7 +93,6 @@ - - #if PLATFORM(WPE) + #if USE(GLIB) #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_56 -#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_70 ++#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_56 #endif - #if USE(SOUP) + #if PLATFORM(GTK) diff --git a/Source/WTF/wtf/URL.h b/Source/WTF/wtf/URL.h -index daa9f726eb0c..a24c68e1934b 100644 +index 677314b5c781..f739e6df4892 100644 --- a/Source/WTF/wtf/URL.h +++ b/Source/WTF/wtf/URL.h @@ -27,7 +27,7 @@ @@ -65,10 +58,10 @@ index daa9f726eb0c..a24c68e1934b 100644 WTF_EXPORT_PRIVATE GRefPtr createGUri() const; #endif diff --git a/Source/WTF/wtf/glib/GRefPtr.h b/Source/WTF/wtf/glib/GRefPtr.h -index e4cf3bd45104..9729d6709376 100644 +index 46d25f00cc69..d3a764808a6f 100644 --- a/Source/WTF/wtf/glib/GRefPtr.h +++ b/Source/WTF/wtf/glib/GRefPtr.h -@@ -328,7 +328,9 @@ WTF_DEFINE_GREF_TRAITS_INLINE(GMainLoop, g_main_loop_ref, g_main_loop_unref) +@@ -329,7 +329,9 @@ WTF_DEFINE_GREF_TRAITS_INLINE(GMainLoop, g_main_loop_ref, g_main_loop_unref) WTF_DEFINE_GREF_TRAITS_INLINE(GMappedFile, g_mapped_file_ref, g_mapped_file_unref) WTF_DEFINE_GREF_TRAITS_INLINE(GPtrArray, g_ptr_array_ref, g_ptr_array_unref) WTF_DEFINE_GREF_TRAITS_INLINE(GSource, g_source_ref, g_source_unref) @@ -79,10 +72,10 @@ index e4cf3bd45104..9729d6709376 100644 WTF_DEFINE_GREF_TRAITS_INLINE(GVariant, g_variant_ref_sink, g_variant_unref, g_variant_is_floating) diff --git a/Source/WTF/wtf/glib/SocketConnection.cpp b/Source/WTF/wtf/glib/SocketConnection.cpp -index d28e6dbd67f6..c98362e85f09 100644 +index b74955924938..4ea234a93c30 100644 --- a/Source/WTF/wtf/glib/SocketConnection.cpp +++ b/Source/WTF/wtf/glib/SocketConnection.cpp -@@ -165,7 +165,18 @@ bool SocketConnection::readMessage() +@@ -166,7 +166,18 @@ bool SocketConnection::readMessage() GRefPtr parameters; if (!it->value.first.isNull()) { GUniquePtr variantType(g_variant_type_new(it->value.first.data())); @@ -138,7 +131,7 @@ index c8f2051d77f6..e2ea0dae3292 100644 #endif }; diff --git a/Source/WebCore/platform/glib/LowPowerModeNotifierGLib.cpp b/Source/WebCore/platform/glib/LowPowerModeNotifierGLib.cpp -index e083cc66934e..7c0f55d089e6 100644 +index c9bf6a774f49..546a974075c6 100644 --- a/Source/WebCore/platform/glib/LowPowerModeNotifierGLib.cpp +++ b/Source/WebCore/platform/glib/LowPowerModeNotifierGLib.cpp @@ -28,10 +28,13 @@ namespace WebCore { @@ -146,7 +139,7 @@ index e083cc66934e..7c0f55d089e6 100644 LowPowerModeNotifier::LowPowerModeNotifier(LowPowerModeChangeCallback&& callback) +#if GLIB_CHECK_VERSION(2, 69, 1) - : m_callback(WTFMove(callback)) + : m_callback(WTF::move(callback)) , m_powerProfileMonitor(adoptGRef(g_power_profile_monitor_dup_default())) , m_lowPowerModeEnabled(g_power_profile_monitor_get_power_saver_enabled(m_powerProfileMonitor.get())) +#endif @@ -173,7 +166,7 @@ index e083cc66934e..7c0f55d089e6 100644 bool LowPowerModeNotifier::isLowPowerModeEnabled() const diff --git a/Source/WebCore/platform/network/soup/CertificateInfoSoup.cpp b/Source/WebCore/platform/network/soup/CertificateInfoSoup.cpp -index f32ecca7a300..e81a5433709d 100644 +index fb5773d56767..bc10fda05f78 100644 --- a/Source/WebCore/platform/network/soup/CertificateInfoSoup.cpp +++ b/Source/WebCore/platform/network/soup/CertificateInfoSoup.cpp @@ -73,9 +73,11 @@ CertificateInfo CertificateInfo::isolatedCopy() const @@ -218,7 +211,7 @@ index f32ecca7a300..e81a5433709d 100644 } // namespace WebCore diff --git a/Source/WebKit/NetworkProcess/glib/DNSCache.cpp b/Source/WebKit/NetworkProcess/glib/DNSCache.cpp -index a560e73f58a3..78007d891af1 100644 +index 5ecfdc770d9b..38911a681028 100644 --- a/Source/WebKit/NetworkProcess/glib/DNSCache.cpp +++ b/Source/WebKit/NetworkProcess/glib/DNSCache.cpp @@ -50,9 +50,17 @@ DNSCache::DNSCacheMap& DNSCache::mapForType(Type type) @@ -261,10 +254,10 @@ index a560e73f58a3..78007d891af1 100644 } // namespace WebKit diff --git a/Source/WebKit/NetworkProcess/glib/DNSCache.h b/Source/WebKit/NetworkProcess/glib/DNSCache.h -index 6aa530f44321..49aded549588 100644 +index 30332200b7ec..f0b6ac73389b 100644 --- a/Source/WebKit/NetworkProcess/glib/DNSCache.h +++ b/Source/WebKit/NetworkProcess/glib/DNSCache.h -@@ -65,8 +65,10 @@ private: +@@ -64,8 +64,10 @@ private: Lock m_lock; DNSCacheMap m_dnsMap WTF_GUARDED_BY_LOCK(m_lock); @@ -276,7 +269,7 @@ index 6aa530f44321..49aded549588 100644 }; diff --git a/Source/WebKit/NetworkProcess/glib/WebKitCachedResolver.cpp b/Source/WebKit/NetworkProcess/glib/WebKitCachedResolver.cpp -index 2752ff9cfc2c..7804e8b7a588 100644 +index 27399475ab7a..10f189484a2f 100644 --- a/Source/WebKit/NetworkProcess/glib/WebKitCachedResolver.cpp +++ b/Source/WebKit/NetworkProcess/glib/WebKitCachedResolver.cpp @@ -67,7 +67,9 @@ static Vector> addressListGListToVector(GList* addressList @@ -318,7 +311,7 @@ index 2752ff9cfc2c..7804e8b7a588 100644 resolverClass->lookup_by_address_async = webkitCachedResolverLookupByAddressAsync; resolverClass->lookup_by_address_finish = webkitCachedResolverLookupByAddressFinish; diff --git a/Source/WebKit/NetworkProcess/glib/WebKitOverridingResolver.cpp b/Source/WebKit/NetworkProcess/glib/WebKitOverridingResolver.cpp -index 150d74ed0296..f461e3c695fe 100644 +index c09d90cbd1dc..76a9ae84fb7e 100644 --- a/Source/WebKit/NetworkProcess/glib/WebKitOverridingResolver.cpp +++ b/Source/WebKit/NetworkProcess/glib/WebKitOverridingResolver.cpp @@ -90,6 +90,7 @@ static GList* webkitOverridingResolverLookupByNameFinish(GResolver* resolver, GA @@ -350,7 +343,7 @@ index 150d74ed0296..f461e3c695fe 100644 resolverClass->lookup_by_address_async = webkitOverridingResolverLookupByAddressAsync; resolverClass->lookup_by_address_finish = webkitOverridingResolverLookupByAddressFinish; diff --git a/Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp b/Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp -index a9ee8507c28a..eae6ab798c8f 100644 +index 6112a107f99a..b569c48de5ba 100644 --- a/Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp +++ b/Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp @@ -121,11 +121,13 @@ void ArgumentCoder>::encode(Encoder& encoder, const GRe @@ -395,33 +388,19 @@ index a9ee8507c28a..eae6ab798c8f 100644 issuer = certificate.get(); i++; diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake -index 4522ffdd9f36..0f25e3eae2e1 100644 +index a5ebd3e3d879..ce1791f7a470 100644 --- a/Source/cmake/OptionsGTK.cmake +++ b/Source/cmake/OptionsGTK.cmake -@@ -7,8 +7,6 @@ SET_PROJECT_VERSION(2 50 3) - +@@ -8,7 +8,7 @@ SET_PROJECT_VERSION(2 52 3) set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string") --# Update Source/WTF/wtf/Platform.h to match required GLib versions. --find_package(GLIB 2.70.0 REQUIRED COMPONENTS gio gio-unix gobject gthread gmodule) - find_package(Cairo 1.14.0 REQUIRED) + # Update Source/WTF/wtf/Platform.h to match required GLib versions. +-find_package(GLib 2.70.0 REQUIRED COMPONENTS GioUnix Thread Module) ++find_package(GLib 2.56.0 REQUIRED COMPONENTS GioUnix Thread Module) + find_package(Cairo 1.16.0 REQUIRED) find_package(LibGcrypt 1.7.0 REQUIRED) - find_package(Libtasn1 REQUIRED) -@@ -207,6 +205,13 @@ else () - SET_AND_EXPOSE_TO_BUILD(ENABLE_2022_GLIB_API OFF) - endif () - -+if (ENABLE_2022_GLIB_API) -+ set(GLIB_MINIMUM_VERSION 2.70.0) -+else () -+ set(GLIB_MINIMUM_VERSION 2.56.4) -+endif () -+find_package(GLIB ${GLIB_MINIMUM_VERSION} REQUIRED COMPONENTS gio gio-unix gobject gthread gmodule) -+ - EXPOSE_STRING_VARIABLE_TO_BUILD(WEBKITGTK_API_INFIX) - EXPOSE_STRING_VARIABLE_TO_BUILD(WEBKITGTK_API_VERSION) - -@@ -277,6 +282,11 @@ if (ENABLED_COMPILER_SANITIZERS) + find_package(Soup3 3.0.0 REQUIRED) +@@ -258,6 +258,11 @@ if (ENABLED_COMPILER_SANITIZERS) set(ENABLE_DOCUMENTATION OFF) endif () @@ -473,5 +452,5 @@ index d3fbb968ee46..4f49ad82f9fd 100644 } -- -2.52.0 +2.53.0 diff --git a/gstreamer-1.16.patch b/gstreamer-1.16.patch index 1b4d311..3341c6d 100644 --- a/gstreamer-1.16.patch +++ b/gstreamer-1.16.patch @@ -1,25 +1,26 @@ -From f083d6f8d80c919d185c1b3f77a2bdd705816a2e Mon Sep 17 00:00:00 2001 +From 757b61bda6fa34c3bd2de45eeccc976b10c5b035 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Fri, 4 Apr 2025 14:00:12 -0500 Subject: [PATCH] Build against GStreamer 1.16 --- .../AudioSourceProviderGStreamer.cpp | 3 +- - .../gstreamer/GLVideoSinkGStreamer.cpp | 35 ++++----- + .../gstreamer/GLVideoSinkGStreamer.cpp | 36 ++++---- .../gstreamer/GStreamerAudioMixer.cpp | 2 +- - .../graphics/gstreamer/GStreamerCommon.cpp | 78 +++++++++++++------ + .../graphics/gstreamer/GStreamerCommon.cpp | 82 +++++++++++++------ .../graphics/gstreamer/GStreamerCommon.h | 15 ++++ - .../gstreamer/MediaPlayerPrivateGStreamer.cpp | 23 +----- - .../gstreamer/GStreamerCodecUtilities.cpp | 39 ++++++---- + .../gstreamer/MediaPlayerPrivateGStreamer.cpp | 30 +------ + .../CoordinatedPlatformLayerBufferVideo.cpp | 14 +--- + .../gstreamer/GStreamerCodecUtilities.cpp | 39 +++++---- .../VideoEncoderPrivateGStreamer.cpp | 16 ---- Source/cmake/GStreamerChecks.cmake | 4 +- - 9 files changed, 114 insertions(+), 101 deletions(-) + 10 files changed, 121 insertions(+), 120 deletions(-) diff --git a/Source/WebCore/platform/audio/gstreamer/AudioSourceProviderGStreamer.cpp b/Source/WebCore/platform/audio/gstreamer/AudioSourceProviderGStreamer.cpp -index acee31b1cc4e..e54adb748f98 100644 +index 33037a80b0ca..20c3cdc80b31 100644 --- a/Source/WebCore/platform/audio/gstreamer/AudioSourceProviderGStreamer.cpp +++ b/Source/WebCore/platform/audio/gstreamer/AudioSourceProviderGStreamer.cpp -@@ -125,7 +125,8 @@ AudioSourceProviderGStreamer::AudioSourceProviderGStreamer(MediaStreamTrackPriva +@@ -141,7 +141,8 @@ AudioSourceProviderGStreamer::AudioSourceProviderGStreamer(MediaStreamTrackPriva g_signal_connect_swapped(decodebin, "pad-added", G_CALLBACK(+[](AudioSourceProviderGStreamer* provider, GstPad* pad) { auto padCaps = adoptGRef(gst_pad_query_caps(pad, nullptr)); bool isAudio = doCapsHaveType(padCaps.get(), "audio"_s); @@ -30,28 +31,32 @@ index acee31b1cc4e..e54adb748f98 100644 auto sinkPad = adoptGRef(gst_element_get_static_pad(provider->m_audioSinkBin.get(), "sink")); gst_pad_link(pad, sinkPad.get()); diff --git a/Source/WebCore/platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp -index 056f6ca71eb7..87d081cf1e6b 100644 +index f247b617d9c3..eadb3b0e97ba 100644 --- a/Source/WebCore/platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp -@@ -67,16 +67,7 @@ static bool s_isDMABufDisabled; +@@ -70,20 +70,10 @@ WEBKIT_DEFINE_TYPE_WITH_CODE(WebKitGLVideoSink, webkit_gl_video_sink, GST_TYPE_B + GST_DEBUG_CATEGORY_INIT(webkit_gl_video_sink_debug, "webkitglvideosink", 0, "GL video sink element")) + + #if USE(GBM) +-static bool s_isDMABufDisabled; ++static bool s_isDMABufDisabled = true; static void initializeDMABufAvailability() { - static std::once_flag onceFlag; - std::call_once(onceFlag, [] { -- if (!webkitGstCheckVersion(1, 20, 0)) +- if (!gst_check_version(1, 20, 0)) - return; - -- auto value = unsafeSpan(g_getenv("WEBKIT_GST_DMABUF_SINK_DISABLED")); -- s_isDMABufDisabled = value.data() && (equalLettersIgnoringASCIICase(value, "true"_s) || equalLettersIgnoringASCIICase(value, "1"_s)); +- auto value = CStringView::unsafeFromUTF8(g_getenv("WEBKIT_GST_DMABUF_SINK_DISABLED")); +- s_isDMABufDisabled = !value.isEmpty() && (equalLettersIgnoringASCIICase(value.span(), "true"_s) || equalLettersIgnoringASCIICase(value.span(), "1"_s)); - if (!s_isDMABufDisabled && !DRMDeviceManager::singleton().mainGBMDevice(DRMDeviceManager::NodeType::Render)) - s_isDMABufDisabled = true; - }); -+ s_isDMABufDisabled = true; } #endif -@@ -119,7 +110,19 @@ static void webKitGLVideoSinkConstructed(GObject* object) +@@ -129,7 +119,19 @@ static void webKitGLVideoSinkConstructed(GObject* object) if (!s_isDMABufDisabled) gst_caps_append(caps.get(), buildDMABufCaps().leakRef()); #endif @@ -72,7 +77,7 @@ index 056f6ca71eb7..87d081cf1e6b 100644 gst_caps_set_features(glCaps.get(), 0, gst_caps_features_new(GST_CAPS_FEATURE_MEMORY_GL_MEMORY, nullptr)); gst_caps_append(caps.get(), glCaps.leakRef()); -@@ -178,17 +181,11 @@ static GstStateChangeReturn webKitGLVideoSinkChangeState(GstElement* element, Gs +@@ -171,17 +173,11 @@ static GstStateChangeReturn webKitGLVideoSinkChangeState(GstElement* element, Gs return GST_ELEMENT_CLASS(webkit_gl_video_sink_parent_class)->change_state(element, transition); } @@ -93,7 +98,7 @@ index 056f6ca71eb7..87d081cf1e6b 100644 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, paramSpec); RELEASE_ASSERT_NOT_REACHED(); diff --git a/Source/WebCore/platform/graphics/gstreamer/GStreamerAudioMixer.cpp b/Source/WebCore/platform/graphics/gstreamer/GStreamerAudioMixer.cpp -index c982bcf51e01..01190fe89f9e 100644 +index afbe4777dbc7..d414525f0cb6 100644 --- a/Source/WebCore/platform/graphics/gstreamer/GStreamerAudioMixer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/GStreamerAudioMixer.cpp @@ -32,7 +32,7 @@ GST_DEBUG_CATEGORY_STATIC(webkit_media_gst_audio_mixer_debug); @@ -106,10 +111,10 @@ index c982bcf51e01..01190fe89f9e 100644 GStreamerAudioMixer& GStreamerAudioMixer::singleton() diff --git a/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp b/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp -index 419190b917b5..c7b0dacfc117 100644 +index a78ef36c5eec..de77a6ef4760 100644 --- a/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp -@@ -136,6 +136,25 @@ WARN_UNUSED_RETURN GstPad* webkitGstGhostPadFromStaticTemplate(GstStaticPadTempl +@@ -137,6 +137,25 @@ static GstClockTime s_webkitGstInitTime; } #if ENABLE(VIDEO) @@ -135,7 +140,7 @@ index 419190b917b5..c7b0dacfc117 100644 bool getVideoSizeAndFormatFromCaps(const GstCaps* caps, WebCore::IntSize& size, GstVideoFormat& format, int& pixelAspectRatioNumerator, int& pixelAspectRatioDenominator, int& stride, double& frameRate, PlatformVideoColorSpace& colorSpace) { if (!doCapsHaveType(caps, GST_VIDEO_CAPS_TYPE_PREFIX)) { -@@ -695,31 +714,6 @@ void deinitializeGStreamer() +@@ -725,31 +744,6 @@ void deinitializeGStreamer() teardownVideoEncoderSingleton(); teardownGStreamerImageDecoders(); #endif @@ -144,7 +149,7 @@ index 419190b917b5..c7b0dacfc117 100644 - auto activeTracers = gst_tracing_get_active_tracers(); - while (activeTracers) { - auto tracer = adoptGRef(GST_TRACER_CAST(activeTracers->data)); -- if (!isLeaksTracerActive && !g_strcmp0(G_OBJECT_TYPE_NAME(G_OBJECT(tracer.get())), "GstLeaksTracer")) +- if (!isLeaksTracerActive && equal(unsafeSpan(G_OBJECT_TYPE_NAME(G_OBJECT(tracer.get()))), "GstLeaksTracer"_s)) - isLeaksTracerActive = true; - activeTracers = g_list_delete_link(activeTracers, activeTracers); - } @@ -166,8 +171,26 @@ index 419190b917b5..c7b0dacfc117 100644 - gst_deinit(); } - unsigned getGstPlayFlag(const char* nick) -@@ -1495,6 +1489,36 @@ String gstStructureToJSONString(const GstStructure* structure) + unsigned getGstPlayFlag(ASCIILiteral nick) +@@ -839,7 +833,7 @@ GstMappedFrame::GstMappedFrame(const GRefPtr& sample, GstMapFlags fla + return; + + gst_video_alignment_reset(&m_alignment); +- gst_video_info_align_full(&info, &m_alignment, m_planeSizes.data()); ++ gst_video_info_align(&info, &m_alignment); + } + + GstMappedFrame::~GstMappedFrame() +@@ -918,6 +912,8 @@ int GstMappedFrame::planeStride(uint32_t planeIndex) const + return GST_VIDEO_FRAME_PLANE_STRIDE(&m_frame, planeIndex); + } + ++#define GST_VIDEO_INFO_PLANE_HEIGHT(i,p,sizes) ((i)->stride[p] == 0 ? 0 : sizes[p] / (i)->stride[p]) ++ + size_t GstMappedFrame::planeHeight(uint32_t planeIndex) const + { + RELEASE_ASSERT(isValid()); +@@ -1611,6 +1607,36 @@ String gstStructureToJSONString(const GstStructure* structure) return value->toJSONString(); } @@ -204,7 +227,7 @@ index 419190b917b5..c7b0dacfc117 100644 GstClockTime webkitGstInitTime() { return s_webkitGstInitTime; -@@ -1552,6 +1576,7 @@ PlatformVideoColorSpace videoColorSpaceFromInfo(const GstVideoInfo& info) +@@ -1668,6 +1694,7 @@ PlatformVideoColorSpace videoColorSpaceFromInfo(const GstVideoInfo& info) case GST_VIDEO_TRANSFER_BT709: colorSpace.transfer = PlatformVideoTransferCharacteristics::Bt709; break; @@ -212,7 +235,7 @@ index 419190b917b5..c7b0dacfc117 100644 case GST_VIDEO_TRANSFER_BT601: colorSpace.transfer = PlatformVideoTransferCharacteristics::Smpte170m; break; -@@ -1564,6 +1589,7 @@ PlatformVideoColorSpace videoColorSpaceFromInfo(const GstVideoInfo& info) +@@ -1680,6 +1707,7 @@ PlatformVideoColorSpace videoColorSpaceFromInfo(const GstVideoInfo& info) case GST_VIDEO_TRANSFER_BT2020_10: colorSpace.transfer = PlatformVideoTransferCharacteristics::Bt2020_10bit; break; @@ -220,7 +243,7 @@ index 419190b917b5..c7b0dacfc117 100644 case GST_VIDEO_TRANSFER_BT2020_12: colorSpace.transfer = PlatformVideoTransferCharacteristics::Bt2020_12bit; break; -@@ -1682,6 +1708,7 @@ void fillVideoInfoColorimetryFromColorSpace(GstVideoInfo* info, const PlatformVi +@@ -1798,6 +1826,7 @@ void fillVideoInfoColorimetryFromColorSpace(GstVideoInfo* info, const PlatformVi case PlatformVideoTransferCharacteristics::Bt709: GST_VIDEO_INFO_COLORIMETRY(info).transfer = GST_VIDEO_TRANSFER_BT709; break; @@ -228,7 +251,7 @@ index 419190b917b5..c7b0dacfc117 100644 case PlatformVideoTransferCharacteristics::Smpte170m: GST_VIDEO_INFO_COLORIMETRY(info).transfer = GST_VIDEO_TRANSFER_BT601; break; -@@ -1694,6 +1721,7 @@ void fillVideoInfoColorimetryFromColorSpace(GstVideoInfo* info, const PlatformVi +@@ -1810,6 +1839,7 @@ void fillVideoInfoColorimetryFromColorSpace(GstVideoInfo* info, const PlatformVi case PlatformVideoTransferCharacteristics::Bt2020_10bit: GST_VIDEO_INFO_COLORIMETRY(info).transfer = GST_VIDEO_TRANSFER_BT2020_10; break; @@ -237,12 +260,12 @@ index 419190b917b5..c7b0dacfc117 100644 GST_VIDEO_INFO_COLORIMETRY(info).transfer = GST_VIDEO_TRANSFER_BT2020_12; break; diff --git a/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h b/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h -index 49e031a72585..c7680e1a49c5 100644 +index b4fd887c4036..79873050f8d9 100644 --- a/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h +++ b/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h -@@ -74,6 +74,14 @@ inline bool webkitGstCheckVersion(guint major, guint minor, guint micro) - return true; +@@ -78,6 +78,14 @@ inline bool gst_check_version(guint major, guint minor, guint micro) } + #endif +#if !GST_CHECK_VERSION(1, 18, 0) +// gst_video_format_info_component() is GStreamer 1.18 API, so for older versions we use a local @@ -255,7 +278,7 @@ index 49e031a72585..c7680e1a49c5 100644 #define GST_VIDEO_CAPS_TYPE_PREFIX "video/"_s #define GST_AUDIO_CAPS_TYPE_PREFIX "audio/"_s #define GST_TEXT_CAPS_TYPE_PREFIX "text/"_s -@@ -303,6 +311,13 @@ Vector gstStructureGetList(const GstStructure*, ASCIILiteral key); +@@ -317,6 +325,13 @@ Vector gstStructureGetList(const GstStructure*, CStringView key); String gstStructureToJSONString(const GstStructure*); @@ -270,10 +293,10 @@ index 49e031a72585..c7680e1a49c5 100644 PlatformVideoColorSpace videoColorSpaceFromCaps(const GstCaps*); diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp -index f504e21e0e3f..6bc8f319bbcd 100644 +index 34a8785843bb..ecf19035a27d 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp -@@ -624,8 +624,6 @@ bool MediaPlayerPrivateGStreamer::doSeek(const SeekTarget& target, float rate, b +@@ -630,8 +630,6 @@ bool MediaPlayerPrivateGStreamer::doSeek(const SeekTarget& target, float rate, b auto seekStop = toGstClockTime(endTime); auto event = adoptGRef(gst_event_new_seek(rate, GST_FORMAT_TIME, seekFlags, GST_SEEK_TYPE_SET, seekStart, GST_SEEK_TYPE_SET, seekStop)); @@ -281,8 +304,8 @@ index f504e21e0e3f..6bc8f319bbcd 100644 - if (isAsync) { auto data = createAsyncSeekData(); - data->event = WTFMove(event); -@@ -4330,26 +4328,7 @@ void MediaPlayerPrivateGStreamer::setStreamVolumeElement(GstStreamVolume* volume + data->event = WTF::move(event); +@@ -4428,33 +4426,7 @@ void MediaPlayerPrivateGStreamer::setStreamVolumeElement(GstStreamVolume* volume bool MediaPlayerPrivateGStreamer::updateVideoSinkStatistics() { @@ -296,8 +319,9 @@ index f504e21e0e3f..6bc8f319bbcd 100644 - - auto totalVideoFrames = gstStructureGet(stats.get(), "rendered"_s); - auto droppedVideoFrames = gstStructureGet(stats.get(), "dropped"_s); +- auto averageRate = gstStructureGet(stats.get(), "average-rate"_s); - -- if (!totalVideoFrames || !droppedVideoFrames) +- if (!totalVideoFrames || !droppedVideoFrames || !averageRate) - return false; - - // Caching is required so that metrics queries performed after EOS still return valid values. @@ -305,16 +329,68 @@ index f504e21e0e3f..6bc8f319bbcd 100644 - m_totalVideoFrames = *totalVideoFrames; - if (*droppedVideoFrames) - m_droppedVideoFrames = *droppedVideoFrames; +- +- if (*averageRate && m_videoInfo) { +- double frameRate; +- gst_util_fraction_to_double(GST_VIDEO_INFO_FPS_N(&m_videoInfo->info), GST_VIDEO_INFO_FPS_D(&m_videoInfo->info), &frameRate); +- m_averageFrameRate = *averageRate * frameRate; +- } - return true; + return false; } std::optional MediaPlayerPrivateGStreamer::videoPlaybackQualityMetrics() +diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayerBufferVideo.cpp b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayerBufferVideo.cpp +index b9905616d55f..ec1e8c4ab19e 100644 +--- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayerBufferVideo.cpp ++++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayerBufferVideo.cpp +@@ -103,7 +103,7 @@ std::unique_ptr CoordinatedPlatformLayerBufferVi + // When not having a texture, we map the frame here and upload the pixels to a texture in the + // compositor thread, in paintToTextureMapper(), which also allows us to use the texture mapper + // bitmap texture pool. +- auto caps = adoptGRef(gst_video_info_to_caps(videoInfo)); ++ auto caps = adoptGRef(gst_video_info_to_caps((GstVideoInfo *)videoInfo)); + auto sample = adoptGRef(gst_sample_new(buffer, caps.get(), nullptr, nullptr)); + m_videoFrame.emplace(GstMappedFrame(sample, GST_MAP_READ)); + if (!*m_videoFrame) { +@@ -190,10 +190,7 @@ std::unique_ptr CoordinatedPlatformLayerBufferVi + colorSpace = DMABufBuffer::ColorSpace::Bt709; + else if (gst_video_colorimetry_matches(&GST_VIDEO_INFO_COLORIMETRY(videoInfo), GST_VIDEO_COLORIMETRY_BT2020)) + colorSpace = DMABufBuffer::ColorSpace::Bt2020; +- else if (gst_video_colorimetry_matches(&GST_VIDEO_INFO_COLORIMETRY(videoInfo), GST_VIDEO_COLORIMETRY_BT2100_PQ)) { +- colorSpace = DMABufBuffer::ColorSpace::Bt2020; +- transferFunction = DMABufBuffer::TransferFunction::Pq; +- } else if (gst_video_colorimetry_matches(&GST_VIDEO_INFO_COLORIMETRY(videoInfo), GST_VIDEO_COLORIMETRY_SMPTE240M)) ++ else if (gst_video_colorimetry_matches(&GST_VIDEO_INFO_COLORIMETRY(videoInfo), GST_VIDEO_COLORIMETRY_SMPTE240M)) + colorSpace = DMABufBuffer::ColorSpace::Smpte240M; + dmabuf->setColorSpace(colorSpace); + dmabuf->setTransferFunction(transferFunction); +@@ -210,7 +207,7 @@ std::unique_ptr CoordinatedPlatformLayerBufferVi + #if USE(GSTREAMER_GL) + std::unique_ptr CoordinatedPlatformLayerBufferVideo::createBufferFromGLMemory(GstBuffer* buffer, const GstVideoInfo* videoInfo) + { +- auto caps = adoptGRef(gst_video_info_to_caps(videoInfo)); ++ auto caps = adoptGRef(gst_video_info_to_caps((GstVideoInfo *)videoInfo)); + auto sample = adoptGRef(gst_sample_new(buffer, caps.get(), nullptr, nullptr)); + m_videoFrame.emplace(GstMappedFrame(sample, static_cast(GST_MAP_READ | GST_MAP_GL))); + if (!*m_videoFrame) { +@@ -255,10 +252,7 @@ std::unique_ptr CoordinatedPlatformLayerBufferVi + yuvToRgbColorSpace = CoordinatedPlatformLayerBufferYUV::YuvToRgbColorSpace::Bt709; + else if (gst_video_colorimetry_matches(&GST_VIDEO_INFO_COLORIMETRY(m_videoFrame->info()), GST_VIDEO_COLORIMETRY_BT2020)) + yuvToRgbColorSpace = CoordinatedPlatformLayerBufferYUV::YuvToRgbColorSpace::Bt2020; +- else if (gst_video_colorimetry_matches(&GST_VIDEO_INFO_COLORIMETRY(m_videoFrame->info()), GST_VIDEO_COLORIMETRY_BT2100_PQ)) { +- yuvToRgbColorSpace = CoordinatedPlatformLayerBufferYUV::YuvToRgbColorSpace::Bt2020; +- transferFunction = CoordinatedPlatformLayerBufferYUV::TransferFunction::Pq; +- } else if (gst_video_colorimetry_matches(&GST_VIDEO_INFO_COLORIMETRY(m_videoFrame->info()), GST_VIDEO_COLORIMETRY_SMPTE240M)) ++ else if (gst_video_colorimetry_matches(&GST_VIDEO_INFO_COLORIMETRY(m_videoFrame->info()), GST_VIDEO_COLORIMETRY_SMPTE240M)) + yuvToRgbColorSpace = CoordinatedPlatformLayerBufferYUV::YuvToRgbColorSpace::Smpte240M; + + return CoordinatedPlatformLayerBufferYUV::create(numberOfPlanes, WTF::move(planes), WTF::move(yuvPlane), WTF::move(yuvPlaneOffset), yuvToRgbColorSpace, transferFunction, m_size, m_flags, nullptr); diff --git a/Source/WebCore/platform/gstreamer/GStreamerCodecUtilities.cpp b/Source/WebCore/platform/gstreamer/GStreamerCodecUtilities.cpp -index 52be1e0338bd..7eb0d67108f1 100644 +index 643ef5a67982..b5e35f09bcf1 100644 --- a/Source/WebCore/platform/gstreamer/GStreamerCodecUtilities.cpp +++ b/Source/WebCore/platform/gstreamer/GStreamerCodecUtilities.cpp -@@ -256,9 +256,10 @@ static std::pair, GRefPtr> vpxCapsFromCodecString(cons +@@ -254,9 +254,10 @@ static std::pair, GRefPtr> vpxCapsFromCodecString(cons GST_VIDEO_INFO_COLORIMETRY(&info).transfer = GST_VIDEO_TRANSFER_BT709; else if (transfer == VPConfigurationTransferCharacteristics::BT_470_7_BG) GST_VIDEO_INFO_COLORIMETRY(&info).transfer = GST_VIDEO_TRANSFER_GAMMA28; @@ -328,7 +404,7 @@ index 52be1e0338bd..7eb0d67108f1 100644 GST_VIDEO_INFO_COLORIMETRY(&info).transfer = GST_VIDEO_TRANSFER_SMPTE240M; else if (transfer == VPConfigurationTransferCharacteristics::Linear) GST_VIDEO_INFO_COLORIMETRY(&info).transfer = GST_VIDEO_TRANSFER_GAMMA10; -@@ -271,17 +272,21 @@ static std::pair, GRefPtr> vpxCapsFromCodecString(cons +@@ -269,17 +270,21 @@ static std::pair, GRefPtr> vpxCapsFromCodecString(cons else if (transfer == VPConfigurationTransferCharacteristics::IEC_61966_2_1) { GST_WARNING("VPConfigurationTransferCharacteristics::IEC_61966_2_1 not supported"); GST_VIDEO_INFO_COLORIMETRY(&info).transfer = GST_VIDEO_TRANSFER_UNKNOWN; @@ -396,10 +472,10 @@ index 52be1e0338bd..7eb0d67108f1 100644 }; diff --git a/Source/WebCore/platform/gstreamer/VideoEncoderPrivateGStreamer.cpp b/Source/WebCore/platform/gstreamer/VideoEncoderPrivateGStreamer.cpp -index 4e57c2422148..993357fdb9ca 100644 +index ceb958629a20..2dac345cdbc5 100644 --- a/Source/WebCore/platform/gstreamer/VideoEncoderPrivateGStreamer.cpp +++ b/Source/WebCore/platform/gstreamer/VideoEncoderPrivateGStreamer.cpp -@@ -857,22 +857,6 @@ static void webkit_video_encoder_class_init(WebKitVideoEncoderClass* klass) +@@ -889,22 +889,6 @@ static void webkit_video_encoder_class_init(WebKitVideoEncoderClass* klass) "temporal-scalability-rate-decimator", decimators.get(), "temporal-scalability-target-bitrate", bitrates.get(), nullptr); @@ -423,19 +499,18 @@ index 4e57c2422148..993357fdb9ca 100644 }); diff --git a/Source/cmake/GStreamerChecks.cmake b/Source/cmake/GStreamerChecks.cmake -index af7ad6df1f8f..465e9264cbee 100644 +index 0472cde8df37..aabca8479f22 100644 --- a/Source/cmake/GStreamerChecks.cmake +++ b/Source/cmake/GStreamerChecks.cmake -@@ -1,7 +1,7 @@ - if (ENABLE_VIDEO OR ENABLE_WEB_AUDIO OR ENABLE_WEB_CODECS) - SET_AND_EXPOSE_TO_BUILD(USE_GSTREAMER TRUE) +@@ -1,6 +1,6 @@ + if (USE_GSTREAMER) if (USE_GSTREAMER_FULL) - find_package(GStreamer 1.18.4 REQUIRED COMPONENTS full) + find_package(GStreamer 1.16.1 REQUIRED COMPONENTS full) if (NOT PC_GSTREAMER_FULL_FOUND) message(FATAL_ERROR "GStreamer static library libgstreamer-full-1.0 not found") else () -@@ -25,7 +25,7 @@ if (ENABLE_VIDEO OR ENABLE_WEB_AUDIO OR ENABLE_WEB_CODECS) +@@ -20,7 +20,7 @@ if (USE_GSTREAMER) list(APPEND GSTREAMER_COMPONENTS webrtc) endif () @@ -445,5 +520,5 @@ index af7ad6df1f8f..465e9264cbee 100644 if (ENABLE_WEB_AUDIO) if (NOT PC_GSTREAMER_AUDIO_FOUND OR NOT PC_GSTREAMER_FFT_FOUND) -- -2.52.0 +2.53.0 diff --git a/harfbuzz-1.7.5.patch b/harfbuzz-1.7.5.patch index b419af3..039b8e2 100644 --- a/harfbuzz-1.7.5.patch +++ b/harfbuzz-1.7.5.patch @@ -1,4 +1,4 @@ -From 4d81f51a0d3ddd85ec8eac48b3093d9818c97907 Mon Sep 17 00:00:00 2001 +From d2017cd8ab51b24dcd3bda6fb90fec686b9a86ad Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Tue, 23 Sep 2025 15:48:27 -0500 Subject: [PATCH] Build against harfbuzz 1.7.5 @@ -6,10 +6,11 @@ Subject: [PATCH] Build against harfbuzz 1.7.5 --- .../skia/modules/skshaper/src/SkShaper_harfbuzz.cpp | 11 ++++------- .../platform/graphics/skia/SkiaHarfBuzzFont.cpp | 8 +++++--- - 2 files changed, 9 insertions(+), 10 deletions(-) + Source/cmake/OptionsGTK.cmake | 2 +- + 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Source/ThirdParty/skia/modules/skshaper/src/SkShaper_harfbuzz.cpp b/Source/ThirdParty/skia/modules/skshaper/src/SkShaper_harfbuzz.cpp -index c40b01d85ab4..79c883dd1380 100644 +index 67c475c0bb54..14a644865348 100644 --- a/Source/ThirdParty/skia/modules/skshaper/src/SkShaper_harfbuzz.cpp +++ b/Source/ThirdParty/skia/modules/skshaper/src/SkShaper_harfbuzz.cpp @@ -275,13 +275,10 @@ HBFace create_hb_face(const SkTypeface& typeface) { @@ -31,10 +32,10 @@ index c40b01d85ab4..79c883dd1380 100644 } if (!face) { diff --git a/Source/WebCore/platform/graphics/skia/SkiaHarfBuzzFont.cpp b/Source/WebCore/platform/graphics/skia/SkiaHarfBuzzFont.cpp -index dbbb5cc21cb6..8818343d3b57 100644 +index 37930ac270ae..90f66d8b63bb 100644 --- a/Source/WebCore/platform/graphics/skia/SkiaHarfBuzzFont.cpp +++ b/Source/WebCore/platform/graphics/skia/SkiaHarfBuzzFont.cpp -@@ -101,9 +101,10 @@ static HbUniquePtr createHarfBuzzFace(SkTypeface& typeface) +@@ -104,9 +104,10 @@ static HbUniquePtr createHarfBuzzFace(SkTypeface& typeface) HbUniquePtr blob(hb_blob_create(reinterpret_cast(memory), size, HB_MEMORY_MODE_READONLY, stream.release(), [](void* data) { delete reinterpret_cast(data); })); @@ -48,14 +49,27 @@ index dbbb5cc21cb6..8818343d3b57 100644 } } -@@ -126,6 +127,7 @@ SkiaHarfBuzzFont::SkiaHarfBuzzFont(SkTypeface& typeface) +@@ -130,6 +131,7 @@ SkiaHarfBuzzFont::SkiaHarfBuzzFont(SkTypeface& typeface) { auto hbFace = createHarfBuzzFace(typeface); HbUniquePtr hbFont(hb_font_create(hbFace.get())); + hb_ot_font_set_funcs(hbFont.get()); - if (int axisCount = typeface.getVariationDesignPosition(nullptr, 0)) { + if (int axisCount = typeface.getVariationDesignPosition({ }); axisCount > 0) { Vector axisValues(axisCount); +diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake +index eea6eb87ad4b..6d5f17debcc7 100644 +--- a/Source/cmake/OptionsGTK.cmake ++++ b/Source/cmake/OptionsGTK.cmake +@@ -13,7 +13,7 @@ find_package(Cairo 1.14.0 REQUIRED) + find_package(LibGcrypt 1.7.0 REQUIRED) + find_package(Soup3 3.0.0 REQUIRED) + find_package(Tasn1 REQUIRED) +-find_package(HarfBuzz 2.7.4 REQUIRED COMPONENTS ICU) ++find_package(HarfBuzz 1.7.5 REQUIRED COMPONENTS ICU) + find_package(ICU 70.1 REQUIRED COMPONENTS data i18n uc) + find_package(JPEG REQUIRED) + find_package(Epoxy 1.5.4 REQUIRED) -- -2.51.0 +2.53.0 diff --git a/icu60.patch b/icu60.patch index 5b7e906..bc56a27 100644 --- a/icu60.patch +++ b/icu60.patch @@ -1,24 +1,22 @@ -From be79a15040dd992cdac91c59d481fea5d7209df3 Mon Sep 17 00:00:00 2001 +From 0bfb64461f6c6b59011068858d1ff79c88d48df5 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Thu, 27 Mar 2025 15:56:41 -0500 Subject: [PATCH 1/5] Revert "[CMake] Update minimum ICU version to 70.1" This reverts commit 95d71be25d5b838b1171e6b9b2cd526190118fba. --- - Source/cmake/OptionsGTK.cmake | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) + Source/cmake/OptionsGTK.cmake | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake -index 285ab3737bfa..83377867f3b1 100644 +index 85189edccdba..a393ffc105cb 100644 --- a/Source/cmake/OptionsGTK.cmake +++ b/Source/cmake/OptionsGTK.cmake -@@ -10,11 +10,11 @@ set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string") - find_package(Cairo 1.14.0 REQUIRED) +@@ -13,10 +13,10 @@ find_package(Cairo 1.14.0 REQUIRED) find_package(LibGcrypt 1.7.0 REQUIRED) - find_package(Libtasn1 REQUIRED) --find_package(HarfBuzz 2.7.4 REQUIRED COMPONENTS ICU) + find_package(Tasn1 REQUIRED) + find_package(HarfBuzz 1.7.5 REQUIRED COMPONENTS ICU) -find_package(ICU 70.1 REQUIRED COMPONENTS data i18n uc) -+find_package(HarfBuzz 1.4.2 REQUIRED COMPONENTS ICU) +find_package(ICU 61.2 REQUIRED COMPONENTS data i18n uc) find_package(JPEG REQUIRED) find_package(Epoxy 1.5.4 REQUIRED) @@ -28,10 +26,10 @@ index 285ab3737bfa..83377867f3b1 100644 find_package(SQLite3 REQUIRED) find_package(Threads REQUIRED) -- -2.51.0 +2.53.0 -From 4c60130350756d48e7f8ed85b4d86d2b049da332 Mon Sep 17 00:00:00 2001 +From 3a19acb5d6bb8cb1b2874f4aa428366957b8769b Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Fri, 28 Mar 2025 14:45:03 -0500 Subject: [PATCH 2/5] Revert "[JSC] Remove unnecessary ICU version checks" @@ -44,7 +42,7 @@ This reverts commit af62f09a1fad0b72293a7f0d082704d92116cb9a. 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp b/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp -index 9bf431425007..17c5b1b848d7 100644 +index 7be0a6a2b047..d87992a36119 100644 --- a/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp +++ b/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp @@ -457,7 +457,7 @@ static Vector collectElements(JSGlobalObject* globalObject, const IntlD @@ -57,10 +55,10 @@ index 9bf431425007..17c5b1b848d7 100644 skeletonBuilder.append("00"_s); else diff --git a/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp b/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp -index b05c7813294c..c16e6bcee859 100644 +index a1b08f5470ed..f34684cf7fcf 100644 --- a/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp +++ b/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp -@@ -496,10 +496,14 @@ void IntlNumberFormat::initializeNumberFormat(JSGlobalObject* globalObject, JSVa +@@ -503,10 +503,14 @@ void IntlNumberFormat::initializeNumberFormat(JSGlobalObject* globalObject, JSVa skeletonBuilder.append(" sign-except-zero"_s); break; case SignDisplay::Negative: @@ -80,10 +78,10 @@ index b05c7813294c..c16e6bcee859 100644 } diff --git a/Source/JavaScriptCore/runtime/IntlNumberFormatInlines.h b/Source/JavaScriptCore/runtime/IntlNumberFormatInlines.h -index c640b73cc891..e678978e453d 100644 +index 8f8444163fc4..81b7c3322fcb 100644 --- a/Source/JavaScriptCore/runtime/IntlNumberFormatInlines.h +++ b/Source/JavaScriptCore/runtime/IntlNumberFormatInlines.h -@@ -200,12 +200,24 @@ void appendNumberFormatDigitOptionsToSkeleton(IntlType* intlInstance, StringBuil +@@ -201,12 +201,24 @@ void appendNumberFormatDigitOptionsToSkeleton(IntlType* intlInstance, StringBuil case RoundingMode::Trunc: skeletonBuilder.append(" rounding-mode-down"_s); break; @@ -112,7 +110,7 @@ index c640b73cc891..e678978e453d 100644 case RoundingMode::HalfExpand: skeletonBuilder.append(" rounding-mode-half-up"_s); break; -@@ -218,7 +230,7 @@ void appendNumberFormatDigitOptionsToSkeleton(IntlType* intlInstance, StringBuil +@@ -219,7 +231,7 @@ void appendNumberFormatDigitOptionsToSkeleton(IntlType* intlInstance, StringBuil } // https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#integer-width @@ -121,7 +119,7 @@ index c640b73cc891..e678978e453d 100644 for (unsigned i = 0; i < intlInstance->m_minimumIntegerDigits; ++i) skeletonBuilder.append('0'); -@@ -256,19 +268,23 @@ void appendNumberFormatDigitOptionsToSkeleton(IntlType* intlInstance, StringBuil +@@ -257,19 +269,23 @@ void appendNumberFormatDigitOptionsToSkeleton(IntlType* intlInstance, StringBuil } case IntlRoundingType::MorePrecision: case IntlRoundingType::LessPrecision: @@ -158,7 +156,7 @@ index c640b73cc891..e678978e453d 100644 break; } } -@@ -279,7 +295,10 @@ void appendNumberFormatDigitOptionsToSkeleton(IntlType* intlInstance, StringBuil +@@ -280,7 +296,10 @@ void appendNumberFormatDigitOptionsToSkeleton(IntlType* intlInstance, StringBuil case IntlTrailingZeroDisplay::Auto: break; case IntlTrailingZeroDisplay::StripIfInteger: @@ -171,10 +169,10 @@ index c640b73cc891..e678978e453d 100644 } } -- -2.51.0 +2.53.0 -From 6f52a2ff3327c5ef714fb385f647daceeab1680f Mon Sep 17 00:00:00 2001 +From 004d72aaf71b66aa1bf324c957af49cc7b141667 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Fri, 28 Mar 2025 15:01:00 -0500 Subject: [PATCH 3/5] Revert "[JSC] TimeZone Cache should be per-process level" @@ -185,7 +183,7 @@ This reverts commit c779aa30eced87609c7c808d672a8f23c5c4821d. 1 file changed, 21 insertions(+), 40 deletions(-) diff --git a/Source/JavaScriptCore/runtime/JSDateMath.cpp b/Source/JavaScriptCore/runtime/JSDateMath.cpp -index 96993af52d33..c40f917fc99f 100644 +index 1bcd8fab40ea..14c4d65a9696 100644 --- a/Source/JavaScriptCore/runtime/JSDateMath.cpp +++ b/Source/JavaScriptCore/runtime/JSDateMath.cpp @@ -453,12 +453,9 @@ String DateCache::timeZoneDisplayName(bool isDST) @@ -234,7 +232,7 @@ index 96993af52d33..c40f917fc99f 100644 - if (canonical.isNull() || isUTCEquivalent(canonical)) - canonical = "UTC"_s; - -- globalCache.get() = std::tuple { canonical.isolatedCopy(), WTFMove(timeZoneID), currentID }; +- globalCache.get() = std::tuple { canonical.isolatedCopy(), WTF::move(timeZoneID), currentID }; - } - return std::tuple { std::get<0>(globalCache.get()).isolatedCopy(), std::get<1>(globalCache.get()) }; -} @@ -251,7 +249,7 @@ index 96993af52d33..c40f917fc99f 100644 + Vector timeZoneID; + getTimeZoneOverride(timeZoneID); auto* cache = new OpaqueICUTimeZone; -- cache->m_canonicalTimeZoneID = WTFMove(canonical); +- cache->m_canonicalTimeZoneID = WTF::move(canonical); + + String canonical; UErrorCode status = U_ZERO_ERROR; @@ -268,7 +266,7 @@ index 96993af52d33..c40f917fc99f 100644 + } + if (canonical.isNull() || isUTCEquivalent(canonical)) + canonical = "UTC"_s; -+ cache->m_canonicalTimeZoneID = WTFMove(canonical); ++ cache->m_canonicalTimeZoneID = WTF::move(canonical); + + status = U_ZERO_ERROR; + cache->m_calendar = std::unique_ptr>(ucal_open(timeZoneID.data(), timeZoneID.size(), "", UCAL_DEFAULT, &status)); @@ -276,10 +274,10 @@ index 96993af52d33..c40f917fc99f 100644 ucal_setGregorianChange(cache->m_calendar.get(), minECMAScriptTime, &status); // Ignore "unsupported" error. m_timeZoneCache = std::unique_ptr(cache); -- -2.51.0 +2.53.0 -From c5fb088366f855f23a2920b31744740edb5506a2 Mon Sep 17 00:00:00 2001 +From 0a84e39e2e0c90784a70ea8931725e84f276853c Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Fri, 28 Mar 2025 15:01:11 -0500 Subject: [PATCH 4/5] Revert "[JSC] Rebaseline Intl implementation based on @@ -306,7 +304,7 @@ This reverts commit 31a358087be7e5e70c7a03bdfcf89de35628a2a2. 16 files changed, 479 insertions(+), 16 deletions(-) diff --git a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp -index 202e266c55da..9a413dc037a7 100644 +index 4eb85711f506..e37be067520b 100644 --- a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp +++ b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp @@ -42,12 +42,16 @@ @@ -326,7 +324,7 @@ index 202e266c55da..9a413dc037a7 100644 WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN -@@ -1430,6 +1434,8 @@ UDateIntervalFormat* IntlDateTimeFormat::createDateIntervalFormatIfNecessary(JSG +@@ -1453,6 +1457,8 @@ UDateIntervalFormat* IntlDateTimeFormat::createDateIntervalFormatIfNecessary(JSG return m_dateIntervalFormat.get(); } @@ -335,7 +333,7 @@ index 202e266c55da..9a413dc037a7 100644 static std::unique_ptr> formattedValueFromDateRange(UDateIntervalFormat& dateIntervalFormat, UDateFormat& dateFormat, double startDate, double endDate, UErrorCode& status) { auto result = std::unique_ptr>(udtitvfmt_openResult(&status)); -@@ -1508,6 +1514,8 @@ static bool dateFieldsPracticallyEqual(const UFormattedValue* formattedValue, UE +@@ -1531,6 +1537,8 @@ static bool dateFieldsPracticallyEqual(const UFormattedValue* formattedValue, UE return !hasSpan; } @@ -344,7 +342,7 @@ index 202e266c55da..9a413dc037a7 100644 JSValue IntlDateTimeFormat::formatRange(JSGlobalObject* globalObject, double startDate, double endDate) { ASSERT(m_dateFormat); -@@ -1526,6 +1534,7 @@ JSValue IntlDateTimeFormat::formatRange(JSGlobalObject* globalObject, double sta +@@ -1549,6 +1557,7 @@ JSValue IntlDateTimeFormat::formatRange(JSGlobalObject* globalObject, double sta auto* dateIntervalFormat = createDateIntervalFormatIfNecessary(globalObject); RETURN_IF_EXCEPTION(scope, { }); @@ -352,10 +350,10 @@ index 202e266c55da..9a413dc037a7 100644 UErrorCode status = U_ZERO_ERROR; auto result = formattedValueFromDateRange(*dateIntervalFormat, *m_dateFormat, startDate, endDate, status); if (U_FAILURE(status)) { -@@ -1563,6 +1572,17 @@ JSValue IntlDateTimeFormat::formatRange(JSGlobalObject* globalObject, double sta +@@ -1586,6 +1595,17 @@ JSValue IntlDateTimeFormat::formatRange(JSGlobalObject* globalObject, double sta replaceNarrowNoBreakSpaceOrThinSpaceWithNormalSpace(buffer); - return jsString(vm, String(WTFMove(buffer))); + return jsString(vm, String(WTF::move(buffer))); +#else + Vector buffer; + auto status = callBufferProducingFunction(udtitvfmt_format, dateIntervalFormat, startDate, endDate, buffer, nullptr); @@ -365,12 +363,12 @@ index 202e266c55da..9a413dc037a7 100644 + } + replaceNarrowNoBreakSpaceOrThinSpaceWithNormalSpace(buffer); + -+ return jsString(vm, String(WTFMove(buffer))); ++ return jsString(vm, String(WTF::move(buffer))); +#endif } JSValue IntlDateTimeFormat::formatRangeToParts(JSGlobalObject* globalObject, double startDate, double endDate) -@@ -1572,6 +1592,7 @@ JSValue IntlDateTimeFormat::formatRangeToParts(JSGlobalObject* globalObject, dou +@@ -1595,6 +1615,7 @@ JSValue IntlDateTimeFormat::formatRangeToParts(JSGlobalObject* globalObject, dou VM& vm = globalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); @@ -378,7 +376,7 @@ index 202e266c55da..9a413dc037a7 100644 // http://tc39.es/proposal-intl-DateTimeFormat-formatRange/#sec-partitiondatetimerangepattern startDate = timeClip(startDate); endDate = timeClip(endDate); -@@ -1775,6 +1796,12 @@ JSValue IntlDateTimeFormat::formatRangeToParts(JSGlobalObject* globalObject, dou +@@ -1798,6 +1819,12 @@ JSValue IntlDateTimeFormat::formatRangeToParts(JSGlobalObject* globalObject, dou } return parts; @@ -434,7 +432,7 @@ index 7a739f61e2c1..da457ad03212 100644 } diff --git a/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp b/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp -index 17c5b1b848d7..c066e80ab130 100644 +index d87992a36119..ba46191c620f 100644 --- a/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp +++ b/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp @@ -36,14 +36,21 @@ @@ -496,13 +494,13 @@ index 17c5b1b848d7..c066e80ab130 100644 auto scope = DECLARE_THROW_SCOPE(vm); +#if HAVE(ICU_U_LIST_FORMATTER) - auto elements = collectElements(globalObject, this, WTFMove(duration)); + auto elements = collectElements(globalObject, this, WTF::move(duration)); RETURN_IF_EXCEPTION(scope, { }); @@ -676,6 +694,10 @@ JSValue IntlDurationFormat::format(JSGlobalObject* globalObject, ISO8601::Durati return throwTypeError(globalObject, scope, "failed to format list of strings"_s); - return jsString(vm, String(WTFMove(result))); + return jsString(vm, String(WTF::move(result))); +#else + UNUSED_PARAM(duration); + return throwTypeError(globalObject, scope, "failed to format list of strings"_s); @@ -515,7 +513,7 @@ index 17c5b1b848d7..c066e80ab130 100644 auto scope = DECLARE_THROW_SCOPE(vm); +#if HAVE(ICU_U_LIST_FORMATTER) - auto elements = collectElements(globalObject, this, WTFMove(duration)); + auto elements = collectElements(globalObject, this, WTF::move(duration)); RETURN_IF_EXCEPTION(scope, { }); @@ -836,6 +859,10 @@ JSValue IntlDurationFormat::formatToParts(JSGlobalObject* globalObject, ISO8601: @@ -544,7 +542,7 @@ index 69e64f9c8332..b3f781a54ad4 100644 String m_numberingSystem; CString m_dataLocaleWithExtensions; diff --git a/Source/JavaScriptCore/runtime/IntlListFormat.cpp b/Source/JavaScriptCore/runtime/IntlListFormat.cpp -index 8bc64220a7c7..c24073ce3171 100644 +index bcaa44af1fbd..b565a532cb0e 100644 --- a/Source/JavaScriptCore/runtime/IntlListFormat.cpp +++ b/Source/JavaScriptCore/runtime/IntlListFormat.cpp @@ -33,12 +33,19 @@ @@ -608,7 +606,7 @@ index 8bc64220a7c7..c24073ce3171 100644 @@ -176,6 +191,10 @@ JSValue IntlListFormat::format(JSGlobalObject* globalObject, JSValue list) const return throwTypeError(globalObject, scope, "failed to format list of strings"_s); - return jsString(vm, String(WTFMove(result))); + return jsString(vm, String(WTF::move(result))); +#else + UNUSED_PARAM(list); + return throwTypeError(globalObject, scope, "failed to format list of strings"_s); @@ -653,7 +651,7 @@ index 2d071949e06f..af6f2c2e7b0a 100644 namespace JSC { diff --git a/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp b/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp -index c16e6bcee859..1fc664fab1e5 100644 +index f34684cf7fcf..e5c9f5850e46 100644 --- a/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp +++ b/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp @@ -43,8 +43,12 @@ @@ -720,7 +718,7 @@ index c16e6bcee859..1fc664fab1e5 100644 // These should not show up because there is no way to specify them in NumberFormat options. // If they do, they don't fit well into any of known part types, so consider it an "unknown". case UNUM_PERMILL_FIELD: -@@ -399,6 +411,7 @@ void IntlNumberFormat::initializeNumberFormat(JSGlobalObject* globalObject, JSVa +@@ -406,6 +418,7 @@ void IntlNumberFormat::initializeNumberFormat(JSGlobalObject* globalObject, JSVa // Options are obtained. Configure formatter here. @@ -728,7 +726,7 @@ index c16e6bcee859..1fc664fab1e5 100644 // Constructing ICU Number Skeletons to configure UNumberFormatter. // https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md -@@ -536,11 +549,120 @@ void IntlNumberFormat::initializeNumberFormat(JSGlobalObject* globalObject, JSVa +@@ -543,11 +556,120 @@ void IntlNumberFormat::initializeNumberFormat(JSGlobalObject* globalObject, JSVa return; } @@ -849,7 +847,7 @@ index c16e6bcee859..1fc664fab1e5 100644 } // https://tc39.es/ecma402/#sec-formatnumber -@@ -552,6 +674,7 @@ JSValue IntlNumberFormat::format(JSGlobalObject* globalObject, double value) con +@@ -559,6 +681,7 @@ JSValue IntlNumberFormat::format(JSGlobalObject* globalObject, double value) con value = purifyNaN(value); Vector buffer; @@ -857,7 +855,7 @@ index c16e6bcee859..1fc664fab1e5 100644 ASSERT(m_numberFormatter); UErrorCode status = U_ZERO_ERROR; auto formattedNumber = std::unique_ptr>(unumf_openResult(&status)); -@@ -563,6 +686,12 @@ JSValue IntlNumberFormat::format(JSGlobalObject* globalObject, double value) con +@@ -570,6 +693,12 @@ JSValue IntlNumberFormat::format(JSGlobalObject* globalObject, double value) con status = callBufferProducingFunction(unumf_resultToString, formattedNumber.get(), buffer); if (U_FAILURE(status)) return throwTypeError(globalObject, scope, "Failed to format a number."_s); @@ -867,10 +865,10 @@ index c16e6bcee859..1fc664fab1e5 100644 + if (U_FAILURE(status)) + return throwTypeError(globalObject, scope, "Failed to format a number."_s); +#endif - return jsString(vm, String(WTFMove(buffer))); + return jsString(vm, String(WTF::move(buffer))); } -@@ -576,6 +705,7 @@ JSValue IntlNumberFormat::format(JSGlobalObject* globalObject, IntlMathematicalV +@@ -583,6 +712,7 @@ JSValue IntlNumberFormat::format(JSGlobalObject* globalObject, IntlMathematicalV const auto& string = value.getString(); Vector buffer; @@ -878,7 +876,7 @@ index c16e6bcee859..1fc664fab1e5 100644 ASSERT(m_numberFormatter); UErrorCode status = U_ZERO_ERROR; auto formattedNumber = std::unique_ptr>(unumf_openResult(&status)); -@@ -587,9 +717,16 @@ JSValue IntlNumberFormat::format(JSGlobalObject* globalObject, IntlMathematicalV +@@ -594,9 +724,16 @@ JSValue IntlNumberFormat::format(JSGlobalObject* globalObject, IntlMathematicalV status = callBufferProducingFunction(unumf_resultToString, formattedNumber.get(), buffer); if (U_FAILURE(status)) return throwTypeError(globalObject, scope, "Failed to format a BigInt."_s); @@ -888,14 +886,14 @@ index c16e6bcee859..1fc664fab1e5 100644 + if (U_FAILURE(status)) + return throwTypeError(globalObject, scope, "Failed to format a BigInt."_s); +#endif - return jsString(vm, String(WTFMove(buffer))); + return jsString(vm, String(WTF::move(buffer))); } +#if HAVE(ICU_U_NUMBER_RANGE_FORMATTER) JSValue IntlNumberFormat::formatRange(JSGlobalObject* globalObject, double start, double end) const { VM& vm = globalObject->vm(); -@@ -657,6 +794,7 @@ JSValue IntlNumberFormat::formatRange(JSGlobalObject* globalObject, IntlMathemat +@@ -664,6 +801,7 @@ JSValue IntlNumberFormat::formatRange(JSGlobalObject* globalObject, IntlMathemat return jsString(vm, String({ string, static_cast(length) })); } @@ -903,7 +901,7 @@ index c16e6bcee859..1fc664fab1e5 100644 static constexpr int32_t literalField = -1; struct IntlNumberFormatField { -@@ -769,6 +907,7 @@ static Vector flattenFields(Vector +@@ -776,6 +914,7 @@ static Vector flattenFields(Vector return flatten; } @@ -911,7 +909,7 @@ index c16e6bcee859..1fc664fab1e5 100644 static bool numberFieldsPracticallyEqual(const UFormattedValue* formattedValue, UErrorCode& status) { auto iterator = std::unique_ptr>(ucfpos_open(&status)); -@@ -1010,6 +1149,7 @@ JSValue IntlNumberFormat::formatRangeToParts(JSGlobalObject* globalObject, IntlM +@@ -1017,6 +1156,7 @@ JSValue IntlNumberFormat::formatRangeToParts(JSGlobalObject* globalObject, IntlM return parts; } @@ -919,7 +917,7 @@ index c16e6bcee859..1fc664fab1e5 100644 ASCIILiteral IntlNumberFormat::styleString(Style style) { -@@ -1307,6 +1447,7 @@ JSValue IntlNumberFormat::formatToParts(JSGlobalObject* globalObject, double val +@@ -1314,6 +1454,7 @@ JSValue IntlNumberFormat::formatToParts(JSGlobalObject* globalObject, double val return throwTypeError(globalObject, scope, "failed to open field position iterator"_s); Vector result; @@ -927,7 +925,7 @@ index c16e6bcee859..1fc664fab1e5 100644 ASSERT(m_numberFormatter); auto formattedNumber = std::unique_ptr>(unumf_openResult(&status)); if (U_FAILURE(status)) -@@ -1321,6 +1462,13 @@ JSValue IntlNumberFormat::formatToParts(JSGlobalObject* globalObject, double val +@@ -1328,6 +1469,13 @@ JSValue IntlNumberFormat::formatToParts(JSGlobalObject* globalObject, double val if (U_FAILURE(status)) return throwTypeError(globalObject, scope, "Failed to format a number."_s); IntlFieldIterator iterator(*fieldItr.get()); @@ -939,9 +937,9 @@ index c16e6bcee859..1fc664fab1e5 100644 + IntlFieldIterator iterator(*fieldItr.get()); +#endif - auto resultString = String(WTFMove(result)); + auto resultString = String(WTF::move(result)); -@@ -1334,6 +1482,7 @@ JSValue IntlNumberFormat::formatToParts(JSGlobalObject* globalObject, double val +@@ -1341,6 +1489,7 @@ JSValue IntlNumberFormat::formatToParts(JSGlobalObject* globalObject, double val return parts; } @@ -949,7 +947,7 @@ index c16e6bcee859..1fc664fab1e5 100644 JSValue IntlNumberFormat::formatToParts(JSGlobalObject* globalObject, IntlMathematicalValue&& value, JSString* sourceType) const { VM& vm = globalObject->vm(); -@@ -1378,6 +1527,7 @@ JSValue IntlNumberFormat::formatToParts(JSGlobalObject* globalObject, IntlMathem +@@ -1385,6 +1534,7 @@ JSValue IntlNumberFormat::formatToParts(JSGlobalObject* globalObject, IntlMathem return parts; } @@ -1042,7 +1040,7 @@ index 65a6795b013f..29d197e462fb 100644 String m_locale; String m_numberingSystem; diff --git a/Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp b/Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp -index d951aa27c715..4e3615ba7242 100644 +index 23ea9bf1ce04..92e9dcad1127 100644 --- a/Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp +++ b/Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp @@ -35,12 +35,18 @@ @@ -1104,7 +1102,7 @@ index d951aa27c715..4e3615ba7242 100644 VM& vm = globalObject->vm(); @@ -163,6 +174,7 @@ JSC_DEFINE_HOST_FUNCTION(intlNumberFormatPrototypeFuncFormatRange, (JSGlobalObje - RELEASE_AND_RETURN(scope, JSValue::encode(numberFormat->formatRange(globalObject, WTFMove(start), WTFMove(end)))); + RELEASE_AND_RETURN(scope, JSValue::encode(numberFormat->formatRange(globalObject, WTF::move(start), WTF::move(end)))); } +#endif @@ -1121,7 +1119,7 @@ index d951aa27c715..4e3615ba7242 100644 @@ -184,8 +197,15 @@ JSC_DEFINE_HOST_FUNCTION(intlNumberFormatPrototypeFuncFormatToParts, (JSGlobalOb RELEASE_AND_RETURN(scope, JSValue::encode(numberFormat->formatToParts(globalObject, number.value()))); - RELEASE_AND_RETURN(scope, JSValue::encode(numberFormat->formatToParts(globalObject, WTFMove(value)))); + RELEASE_AND_RETURN(scope, JSValue::encode(numberFormat->formatToParts(globalObject, WTF::move(value)))); +#else + double value = callFrame->argument(0).toNumber(globalObject); + RETURN_IF_EXCEPTION(scope, { }); @@ -1136,14 +1134,14 @@ index d951aa27c715..4e3615ba7242 100644 VM& vm = globalObject->vm(); @@ -215,6 +235,7 @@ JSC_DEFINE_HOST_FUNCTION(intlNumberFormatPrototypeFuncFormatRangeToParts, (JSGlo - RELEASE_AND_RETURN(scope, JSValue::encode(numberFormat->formatRangeToParts(globalObject, WTFMove(start), WTFMove(end)))); + RELEASE_AND_RETURN(scope, JSValue::encode(numberFormat->formatRangeToParts(globalObject, WTF::move(start), WTF::move(end)))); } +#endif JSC_DEFINE_HOST_FUNCTION(intlNumberFormatPrototypeFuncResolvedOptions, (JSGlobalObject* globalObject, CallFrame* callFrame)) { diff --git a/Source/JavaScriptCore/runtime/IntlObject.cpp b/Source/JavaScriptCore/runtime/IntlObject.cpp -index 8ef1ee678063..f8413f12dec7 100644 +index a79aba3e7717..899ea323a08a 100644 --- a/Source/JavaScriptCore/runtime/IntlObject.cpp +++ b/Source/JavaScriptCore/runtime/IntlObject.cpp @@ -169,8 +169,6 @@ namespace JSC { @@ -1170,7 +1168,7 @@ index 8ef1ee678063..f8413f12dec7 100644 Structure* IntlObject::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) diff --git a/Source/JavaScriptCore/runtime/IntlPluralRules.cpp b/Source/JavaScriptCore/runtime/IntlPluralRules.cpp -index b3e58fc6453f..c451478086f7 100644 +index 54feb0061675..884bd1c96e4e 100644 --- a/Source/JavaScriptCore/runtime/IntlPluralRules.cpp +++ b/Source/JavaScriptCore/runtime/IntlPluralRules.cpp @@ -36,8 +36,12 @@ @@ -1242,7 +1240,7 @@ index b3e58fc6453f..c451478086f7 100644 @@ -245,8 +276,17 @@ JSValue IntlPluralRules::select(JSGlobalObject* globalObject, double value) cons if (U_FAILURE(status)) return throwTypeError(globalObject, scope, "failed to select plural value"_s); - return jsString(vm, String(WTFMove(buffer))); + return jsString(vm, String(WTF::move(buffer))); +#else + Vector result(8); + auto length = uplrules_selectWithFormat(m_pluralRules.get(), value, m_numberFormat.get(), result.data(), result.size(), &status); @@ -1259,7 +1257,7 @@ index b3e58fc6453f..c451478086f7 100644 ASSERT(m_numberRangeFormatter); @@ -272,5 +312,6 @@ JSValue IntlPluralRules::selectRange(JSGlobalObject* globalObject, double start, return throwTypeError(globalObject, scope, "failed to select plural value"_s); - return jsString(vm, String(WTFMove(buffer))); + return jsString(vm, String(WTF::move(buffer))); } +#endif @@ -1379,7 +1377,7 @@ index c6c1fa0cd228..85d7e85469a7 100644 } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSDateMath.cpp b/Source/JavaScriptCore/runtime/JSDateMath.cpp -index c40f917fc99f..755337022004 100644 +index 14c4d65a9696..fce7e787f9fc 100644 --- a/Source/JavaScriptCore/runtime/JSDateMath.cpp +++ b/Source/JavaScriptCore/runtime/JSDateMath.cpp @@ -74,6 +74,7 @@ @@ -1517,7 +1515,7 @@ index c40f917fc99f..755337022004 100644 { @@ -447,6 +514,21 @@ String DateCache::timeZoneDisplayName(bool isDST) if (U_SUCCESS(status)) - m_timeZoneDSTDisplayNameCache = String::adopt(WTFMove(dstDisplayNameBuffer)); + m_timeZoneDSTDisplayNameCache = String::adopt(WTF::move(dstDisplayNameBuffer)); } +#else + auto& timeZoneCache = *toICUTimeZone(this->timeZoneCache()); @@ -1561,10 +1559,10 @@ index c40f917fc99f..755337022004 100644 void DateCache::resetIfNecessarySlow() -- -2.51.0 +2.53.0 -From 294fbe4a1e2d4a142696597ee8f2d1f748480691 Mon Sep 17 00:00:00 2001 +From bc5d5cb86a3ba99bec46ca4b0bd519227ef2a615 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Wed, 2 Apr 2025 15:56:18 -0500 Subject: [PATCH 5/5] Build against ICU 60 @@ -1586,7 +1584,7 @@ Subject: [PATCH 5/5] Build against ICU 60 13 files changed, 45 insertions(+), 13 deletions(-) diff --git a/Source/JavaScriptCore/runtime/IntlCache.cpp b/Source/JavaScriptCore/runtime/IntlCache.cpp -index d099acc9f2f4..26331b92cf84 100644 +index 0bf726012dd4..04a0fef64ecc 100644 --- a/Source/JavaScriptCore/runtime/IntlCache.cpp +++ b/Source/JavaScriptCore/runtime/IntlCache.cpp @@ -26,6 +26,7 @@ @@ -1635,7 +1633,7 @@ index 2b31dc1bdd9c..36adaac47e9a 100644 private: UDateTimePatternGenerator* getSharedPatternGenerator(const CString& locale, UErrorCode& status) diff --git a/Source/JavaScriptCore/runtime/IntlDisplayNames.cpp b/Source/JavaScriptCore/runtime/IntlDisplayNames.cpp -index 3742d05523f6..e8f6317d68b9 100644 +index 6dce21592deb..2ab89a8a81fb 100644 --- a/Source/JavaScriptCore/runtime/IntlDisplayNames.cpp +++ b/Source/JavaScriptCore/runtime/IntlDisplayNames.cpp @@ -106,6 +106,7 @@ void IntlDisplayNames::initializeDisplayNames(JSGlobalObject* globalObject, JSVa @@ -1668,7 +1666,7 @@ index 3742d05523f6..e8f6317d68b9 100644 @@ -346,6 +352,11 @@ JSValue IntlDisplayNames::of(JSGlobalObject* globalObject, JSValue codeValue) co return throwTypeError(globalObject, scope, "Failed to query a display name."_s); } - return jsString(vm, String(WTFMove(buffer))); + return jsString(vm, String(WTF::move(buffer))); +#else + UNUSED_PARAM(codeValue); + throwTypeError(globalObject, scope, "failed to initialize Intl.DisplayNames since feature is not supported by the ICU version"_s); @@ -1696,7 +1694,7 @@ index 17f257cb04a5..883825ed93f4 100644 enum class RelevantExtensionKey : uint8_t; diff --git a/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp b/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp -index c066e80ab130..6161997d3461 100644 +index ba46191c620f..fe148279c676 100644 --- a/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp +++ b/Source/JavaScriptCore/runtime/IntlDurationFormat.cpp @@ -42,7 +42,6 @@ @@ -1716,7 +1714,7 @@ index c066e80ab130..6161997d3461 100644 WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN diff --git a/Source/JavaScriptCore/runtime/IntlObject.cpp b/Source/JavaScriptCore/runtime/IntlObject.cpp -index f8413f12dec7..7041f19dfbbd 100644 +index 899ea323a08a..84ab0e584090 100644 --- a/Source/JavaScriptCore/runtime/IntlObject.cpp +++ b/Source/JavaScriptCore/runtime/IntlObject.cpp @@ -168,7 +168,6 @@ namespace JSC { @@ -1740,11 +1738,11 @@ index f8413f12dec7..7041f19dfbbd 100644 putDirectWithoutTransition(vm, vm.propertyNames->DurationFormat, createDurationFormatConstructor(vm, this), static_cast(PropertyAttribute::DontEnum)); putDirectWithoutTransition(vm, vm.propertyNames->ListFormat, createListFormatConstructor(vm, this), static_cast(PropertyAttribute::DontEnum)); diff --git a/Source/JavaScriptCore/runtime/IntlPluralRules.cpp b/Source/JavaScriptCore/runtime/IntlPluralRules.cpp -index c451478086f7..76461d3c8bcd 100644 +index 884bd1c96e4e..44d2ec41ba3a 100644 --- a/Source/JavaScriptCore/runtime/IntlPluralRules.cpp +++ b/Source/JavaScriptCore/runtime/IntlPluralRules.cpp @@ -278,11 +278,11 @@ JSValue IntlPluralRules::select(JSGlobalObject* globalObject, double value) cons - return jsString(vm, String(WTFMove(buffer))); + return jsString(vm, String(WTF::move(buffer))); #else Vector result(8); - auto length = uplrules_selectWithFormat(m_pluralRules.get(), value, m_numberFormat.get(), result.data(), result.size(), &status); @@ -1758,7 +1756,7 @@ index c451478086f7..76461d3c8bcd 100644 } diff --git a/Source/JavaScriptCore/runtime/JSDateMath.cpp b/Source/JavaScriptCore/runtime/JSDateMath.cpp -index 755337022004..d4b61acb3d13 100644 +index fce7e787f9fc..c4bb091d554e 100644 --- a/Source/JavaScriptCore/runtime/JSDateMath.cpp +++ b/Source/JavaScriptCore/runtime/JSDateMath.cpp @@ -177,7 +177,7 @@ LocalTimeOffset DateCache::calculateLocalTimeOffset(double millisecondsFromEpoch @@ -1780,7 +1778,7 @@ index 755337022004..d4b61acb3d13 100644 } // Do not use icu::TimeZone::createDefault. ICU internally has a cache for timezone and createDefault returns this cached value. diff --git a/Source/WTF/wtf/URLHelpers.cpp b/Source/WTF/wtf/URLHelpers.cpp -index e984a4356715..7e0748f03722 100644 +index ab3b2cdb51d0..0bc3320f96b5 100644 --- a/Source/WTF/wtf/URLHelpers.cpp +++ b/Source/WTF/wtf/URLHelpers.cpp @@ -866,7 +866,9 @@ static String escapeUnsafeCharacters(const String& sourceBuffer) @@ -1795,7 +1793,7 @@ index e984a4356715..7e0748f03722 100644 for (size_t j = 0; j < offset; ++j) { diff --git a/Source/WTF/wtf/URLParser.cpp b/Source/WTF/wtf/URLParser.cpp -index 6325d2a26ba3..b3b292536be5 100644 +index 3875c15e7ef8..5fa7ef50fb43 100644 --- a/Source/WTF/wtf/URLParser.cpp +++ b/Source/WTF/wtf/URLParser.cpp @@ -516,7 +516,7 @@ ALWAYS_INLINE void URLParser::utf8PercentEncode(const CodePointIterator iterator) -> H +@@ -2880,7 +2880,7 @@ auto URLParser::parseHostAndPort(CodePointIterator iterator) -> H std::array buffer; size_t offset = 0; UBool isError = false; @@ -1826,11 +1824,11 @@ index 6325d2a26ba3..b3b292536be5 100644 return HostParsingResult::InvalidHost; utf8Encoded.append(std::span { buffer }.first(offset)); diff --git a/Source/WTF/wtf/unicode/UTF8Conversion.cpp b/Source/WTF/wtf/unicode/UTF8Conversion.cpp -index a86aefecd09c..c599c6727b53 100644 +index edfa0b83890d..4c66ef7ede32 100644 --- a/Source/WTF/wtf/unicode/UTF8Conversion.cpp +++ b/Source/WTF/wtf/unicode/UTF8Conversion.cpp -@@ -78,7 +78,9 @@ template<> char32_t next(std::sp - template<> bool append(std::span characters, size_t& offset, char32_t character) +@@ -79,7 +79,9 @@ template<> char32_t next(std::sp + template<> bool append(std::span characters, size_t& offset, char32_t character) { UBool sawError = false; - U8_APPEND(characters, offset, characters.size(), character, sawError); @@ -1854,18 +1852,18 @@ index fe8694cfce9d..7d8b5ad2e3c9 100644 break; if (U_IS_BMP(token)) diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake -index 83377867f3b1..aa0941950559 100644 +index a393ffc105cb..ee74e1326632 100644 --- a/Source/cmake/OptionsGTK.cmake +++ b/Source/cmake/OptionsGTK.cmake -@@ -11,7 +11,7 @@ find_package(Cairo 1.14.0 REQUIRED) +@@ -13,7 +13,7 @@ find_package(Cairo 1.14.0 REQUIRED) find_package(LibGcrypt 1.7.0 REQUIRED) - find_package(Libtasn1 REQUIRED) - find_package(HarfBuzz 1.4.2 REQUIRED COMPONENTS ICU) + find_package(Tasn1 REQUIRED) + find_package(HarfBuzz 1.7.5 REQUIRED COMPONENTS ICU) -find_package(ICU 61.2 REQUIRED COMPONENTS data i18n uc) +find_package(ICU 60 REQUIRED COMPONENTS data i18n uc) find_package(JPEG REQUIRED) find_package(Epoxy 1.5.4 REQUIRED) find_package(LibXml2 2.8.0 REQUIRED) -- -2.51.0 +2.53.0 diff --git a/libsoup2.patch b/libsoup2.patch new file mode 100644 index 0000000..ff51895 --- /dev/null +++ b/libsoup2.patch @@ -0,0 +1,3178 @@ +From 6b251bc34ceb8a76c1a3ca5671c5228f1dcf745b Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Mon, 6 Apr 2026 13:29:22 -0500 +Subject: [PATCH 1/2] Revert "[CMake] Use imported targets in the libsoup + find-module" + +This reverts commit d543d84262845ff88577c8fc6bdc8baf64edec51. +--- + Source/WebCore/platform/Soup.cmake | 8 +- + Source/WebDriver/PlatformGTK.cmake | 9 ++- + Source/WebKit/PlatformGTK.cmake | 1 + + Source/cmake/FindLibSoup.cmake | 67 ++++++++++++++++ + Source/cmake/FindSoup3.cmake | 100 ------------------------ + Tools/MiniBrowser/gtk/CMakeLists.txt | 7 ++ + Tools/TestWebKitAPI/PlatformGTK.cmake | 2 + + Tools/TestWebKitAPI/glib/CMakeLists.txt | 4 +- + 8 files changed, 95 insertions(+), 103 deletions(-) + create mode 100644 Source/cmake/FindLibSoup.cmake + delete mode 100644 Source/cmake/FindSoup3.cmake + +diff --git a/Source/WebCore/platform/Soup.cmake b/Source/WebCore/platform/Soup.cmake +index aec21d344da1..1280075b2eac 100644 +--- a/Source/WebCore/platform/Soup.cmake ++++ b/Source/WebCore/platform/Soup.cmake +@@ -19,4 +19,10 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS + platform/network/soup/URLSoup.h + ) + +-list(APPEND WebCore_LIBRARIES Soup3::Soup3) ++list(APPEND WebCore_SYSTEM_INCLUDE_DIRECTORIES ++ ${LIBSOUP_INCLUDE_DIRS} ++) ++ ++list(APPEND WebCore_LIBRARIES ++ ${LIBSOUP_LIBRARIES} ++) +diff --git a/Source/WebDriver/PlatformGTK.cmake b/Source/WebDriver/PlatformGTK.cmake +index fe7f5f864c28..ee960b85aabe 100644 +--- a/Source/WebDriver/PlatformGTK.cmake ++++ b/Source/WebDriver/PlatformGTK.cmake +@@ -2,6 +2,11 @@ set(WebDriver_OUTPUT_NAME WebKitWebDriver) + + add_definitions(-DLIBEXECDIR="${CMAKE_INSTALL_FULL_LIBEXECDIR}") + ++list(APPEND WebDriver_SYSTEM_INCLUDE_DIRECTORIES ++ "${GLIB_INCLUDE_DIRS}" ++ "${LIBSOUP_INCLUDE_DIRS}" ++) ++ + list(APPEND WebDriver_SOURCES + glib/SessionHostGlib.cpp + glib/WebDriverServiceGLib.cpp +@@ -17,4 +22,6 @@ if (ENABLE_WEBDRIVER_BIDI) + list(APPEND WebDriver_SOURCES soup/WebSocketServerSoup.cpp) + endif () + +-list(APPEND WebDriver_LIBRARIES Soup3::Soup3) ++list(APPEND WebDriver_LIBRARIES ++ ${LIBSOUP_LIBRARIES} ++) +diff --git a/Source/WebKit/PlatformGTK.cmake b/Source/WebKit/PlatformGTK.cmake +index 1985f6a66df2..9c2217af158e 100644 +--- a/Source/WebKit/PlatformGTK.cmake ++++ b/Source/WebKit/PlatformGTK.cmake +@@ -341,6 +341,7 @@ list(APPEND WebKit_PRIVATE_INCLUDE_DIRECTORIES + list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES + ${GSTREAMER_INCLUDE_DIRS} + ${GSTREAMER_PBUTILS_INCLUDE_DIRS} ++ ${LIBSOUP_INCLUDE_DIRS} + ) + + list(APPEND WebKit_INTERFACE_INCLUDE_DIRECTORIES +diff --git a/Source/cmake/FindLibSoup.cmake b/Source/cmake/FindLibSoup.cmake +new file mode 100644 +index 000000000000..cfc236b1496a +--- /dev/null ++++ b/Source/cmake/FindLibSoup.cmake +@@ -0,0 +1,67 @@ ++# - Try to find LibSoup 2.4 ++# This module defines the following variables: ++# ++# LIBSOUP_FOUND - LibSoup 2.4 was found ++# LIBSOUP_INCLUDE_DIRS - the LibSoup 2.4 include directories ++# LIBSOUP_LIBRARIES - link these to use LibSoup 2.4 ++# ++# Copyright (C) 2012 Raphael Kubo da Costa ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions ++# are met: ++# 1. Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# 2. Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in the ++# documentation and/or other materials provided with the distribution. ++# ++# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS ++# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ++# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS ++# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ++# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ++# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ++# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ++# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR ++# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ++# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ ++if (NOT DEFINED LibSoup_FIND_VERSION) ++ message(FATAL_ERROR "No LibSoup version specified") ++endif () ++ ++if (LibSoup_FIND_VERSION VERSION_LESS 2.91) ++ set(LIBSOUP_API_VERSION "2.4") ++else () ++ set(LIBSOUP_API_VERSION "3.0") ++endif () ++ ++# LibSoup does not provide an easy way to retrieve its version other than its ++# .pc file, so we need to rely on PC_LIBSOUP_VERSION and REQUIRE the .pc file ++# to be found. ++find_package(PkgConfig QUIET) ++pkg_check_modules(PC_LIBSOUP QUIET "libsoup-${LIBSOUP_API_VERSION}") ++ ++find_path(LIBSOUP_INCLUDE_DIRS ++ NAMES libsoup/soup.h ++ HINTS ${PC_LIBSOUP_INCLUDEDIR} ++ ${PC_LIBSOUP_INCLUDE_DIRS} ++ PATH_SUFFIXES "libsoup-${LIBSOUP_API_VERSION}" ++) ++ ++find_library(LIBSOUP_LIBRARIES ++ NAMES "soup-${LIBSOUP_API_VERSION}" ++ HINTS ${PC_LIBSOUP_LIBDIR} ++ ${PC_LIBSOUP_LIBRARY_DIRS} ++) ++ ++include(FindPackageHandleStandardArgs) ++FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibSoup REQUIRED_VARS LIBSOUP_INCLUDE_DIRS LIBSOUP_LIBRARIES ++ VERSION_VAR PC_LIBSOUP_VERSION) ++ ++mark_as_advanced( ++ LIBSOUP_INCLUDE_DIRS ++ LIBSOUP_LIBRARIES ++) +diff --git a/Source/cmake/FindSoup3.cmake b/Source/cmake/FindSoup3.cmake +deleted file mode 100644 +index 85c5db4b2015..000000000000 +--- a/Source/cmake/FindSoup3.cmake ++++ /dev/null +@@ -1,100 +0,0 @@ +-# Copyright (C) 2025 Igalia S.L. +-# Copyright (C) 2012 Raphael Kubo da Costa +-# +-# Redistribution and use in source and binary forms, with or without +-# modification, are permitted provided that the following conditions +-# are met: +-# 1. Redistributions of source code must retain the above copyright +-# notice, this list of conditions and the following disclaimer. +-# 2. Redistributions in binary form must reproduce the above copyright +-# notice, this list of conditions and the following disclaimer in the +-# documentation and/or other materials provided with the distribution. +-# +-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS +-# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS +-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- +-#[=======================================================================[.rst: +-FindSoup3 +---------- +- +-Find the libsoup 3 headers and libraries. +- +-Imported Targets +-^^^^^^^^^^^^^^^^ +- +-``Soup3::Soup3`` +- The libsoup 3 library, if found. +- +-Result Variables +-^^^^^^^^^^^^^^^^ +- +-This will define the following variables in your project: +- +-``Soup3_FOUND`` +- true if (the requested version of) libsoup 3 is available. +-``Soup3_VERSION`` +- Version of libsoup 3. +- +-#]=======================================================================] +- +-find_package(PkgConfig QUIET) +-pkg_check_modules(PC_Soup3 QUIET libsoup-3.0) +-set(Soup3_COMPILE_OPTIONS ${PC_Soup3_CFLAGS_OTHER}) +-set(Soup3_VERSION ${PC_Soup3_VERSION}) +- +-find_library(Soup3_LIBRARY +- NAMES soup-3.0 +- HINTS ${PC_Soup3_LIBDIR} +- ${PC_Soup3_LIBRARY_DIRS} +-) +- +-find_path(Soup3_INCLUDE_DIR +- NAMES libsoup/soup.h +- HINTS ${PC_Soup3_INCLUDEDIR} +- ${PC_Soup3_INCLUDE_DIRS} +- PATH_SUFFIXES libsoup-3.0 +-) +- +-if (Soup3_INCLUDE_DIR AND NOT Soup3_VERSION AND EXISTS "${Soup3_INCLUDE_DIR}/libsoup/soup-version.h") +- file(READ "${Soup3_INCLUDE_DIR}/libsoup/soup-version.h" Soup3_VERSION_CONTENT) +- +- string(REGEX MATCH "#define[\t ]+SOUP_MAJOR_VERSION[\t ]+\(([0-9]+)\)" _dummy "${Soup3_VERSION_CONTENT}") +- set(Soup3_VERSION_MAJOR "${CMAKE_MATCH_1}") +- +- string(REGEX MATCH "#define[\t ]+SOUP_MINOR_VERSION[\t ]+\(([0-9]+)\)" _dummy "${Soup3_VERSION_CONTENT}") +- set(Soup3_VERSION_MINOR "${CMAKE_MATCH_1}") +- +- string(REGEX MATCH "#define[\t ]+SOUP_MICRO_VERSION[\t ]+\(([0-9]+)\)" _dummy "${Soup3_VERSION_CONTENT}") +- set(Soup3_VERSION_MICRO "${CMAKE_MATCH_1}") +- +- set(Soup3_VERSION "${Soup3_VERSION_MAJOR}.${Soup3_VERSION_MINOR}.${Soup3_VERSION_MICRO}") +-endif () +- +-include(FindPackageHandleStandardArgs) +-find_package_handle_standard_args(Soup3 +- REQUIRED_VARS Soup3_LIBRARY Soup3_INCLUDE_DIR +- VERSION_VAR Soup3_VERSION +-) +- +-if (Soup3_LIBRARY AND NOT TARGET Soup3::Soup3) +- add_library(Soup3::Soup3 UNKNOWN IMPORTED GLOBAL) +- set_target_properties(Soup3::Soup3 PROPERTIES +- IMPORTED_LOCATION "${Soup3_LIBRARY}" +- INTERFACE_COMPILE_OPTIONS "${Soup3_COMPILE_OPTIONS}" +- INTERFACE_INCLUDE_DIRECTORIES "${Soup3_INCLUDE_DIR}" +- ) +-endif () +- +-mark_as_advanced( +- Soup3_INCLUDE_DIR +- Soup3_LIBRARY +-) +diff --git a/Tools/MiniBrowser/gtk/CMakeLists.txt b/Tools/MiniBrowser/gtk/CMakeLists.txt +index d3ecfb882422..4acc6c8458d3 100644 +--- a/Tools/MiniBrowser/gtk/CMakeLists.txt ++++ b/Tools/MiniBrowser/gtk/CMakeLists.txt +@@ -26,8 +26,15 @@ set(MiniBrowser_PRIVATE_INCLUDE_DIRECTORIES + ${CMAKE_SOURCE_DIR}/Source + ) + ++set(MiniBrowser_SYSTEM_INCLUDE_DIRECTORIES ++ ${GLIB_INCLUDE_DIRS} ++ ${LIBSOUP_INCLUDE_DIRS} ++) ++ + set(MiniBrowser_PRIVATE_LIBRARIES ++ ${GLIB_LIBRARIES} + ${JavaScriptCore_LIBRARY_NAME} ++ ${LIBSOUP_LIBRARIES} + GTK::GTK + WebKit::WebKit + ) +diff --git a/Tools/TestWebKitAPI/PlatformGTK.cmake b/Tools/TestWebKitAPI/PlatformGTK.cmake +index 957aef111692..ba1be041abca 100644 +--- a/Tools/TestWebKitAPI/PlatformGTK.cmake ++++ b/Tools/TestWebKitAPI/PlatformGTK.cmake +@@ -52,10 +52,12 @@ list(APPEND TestWebCore_SOURCES + ) + + list(APPEND TestWebCore_SYSTEM_INCLUDE_DIRECTORIES ++ ${GLIB_INCLUDE_DIRS} + ${GSTREAMER_INCLUDE_DIRS} + ${GSTREAMER_AUDIO_INCLUDE_DIRS} + ${GSTREAMER_PBUTILS_INCLUDE_DIRS} + ${GSTREAMER_VIDEO_INCLUDE_DIRS} ++ ${LIBSOUP_INCLUDE_DIRS} + ) + + list(APPEND TestWebCore_LIBRARIES +diff --git a/Tools/TestWebKitAPI/glib/CMakeLists.txt b/Tools/TestWebKitAPI/glib/CMakeLists.txt +index f981707b11dc..6a5b4d3bda61 100644 +--- a/Tools/TestWebKitAPI/glib/CMakeLists.txt ++++ b/Tools/TestWebKitAPI/glib/CMakeLists.txt +@@ -33,6 +33,7 @@ endif () + set(WebKitGLibAPITests_SYSTEM_INCLUDE_DIRECTORIES + ${GSTREAMER_AUDIO_INCLUDE_DIRS} + ${GSTREAMER_INCLUDE_DIRS} ++ ${LIBSOUP_INCLUDE_DIRS} + ) + + set(WebKitAPITest_LIBRARIES +@@ -44,8 +45,8 @@ set(WebKitGLibAPITestsCore_LIBRARIES + ) + + set(WebKitGLibAPITest_LIBRARIES ++ ${LIBSOUP_LIBRARIES} + ${WebKitAPITest_LIBRARIES} +- Soup3::Soup3 + WebKitGLibAPITestsCore + ) + +@@ -203,6 +204,7 @@ if (PORT STREQUAL "WPE" AND ENABLE_WPE_QT_API) + ${CMAKE_BINARY_DIR} + ${JavaScriptCoreGLib_DERIVED_SOURCES_DIR} + ${JavaScriptCoreGLib_FRAMEWORK_HEADERS_DIR} ++ ${LIBSOUP_INCLUDE_DIRS} + ${TOOLS_DIR}/TestWebKitAPI + ${WEBKIT_DIR}/WPEPlatform + ${WPEPlatform_DERIVED_SOURCES_DIR} +-- +2.53.0 + + +From 467479cc8d7eb8754e50e89acbc46f34d03f25ec Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Mon, 6 Apr 2026 13:26:24 -0500 +Subject: [PATCH 2/2] Revert "[GTK] Remove support for building against + libsoup2" + +This reverts commit 6153cafaf3bd0db47a50f088e752e73a39d40921. +--- + Source/WTF/wtf/Platform.h | 4 + + Source/WTF/wtf/PlatformEnableGlib.h | 4 - + Source/WebCore/platform/Soup.cmake | 1 + + .../network/soup/AuthenticationChallenge.h | 6 + + .../soup/AuthenticationChallengeSoup.cpp | 14 + + .../platform/network/soup/CookieSoup.cpp | 32 ++- + .../platform/network/soup/GUniquePtrSoup.h | 9 + + .../soup/NetworkStorageSessionSoup.cpp | 30 ++ + .../network/soup/ResourceErrorSoup.cpp | 17 +- + .../platform/network/soup/ResourceRequest.h | 4 + + .../network/soup/ResourceRequestSoup.cpp | 48 ++++ + .../network/soup/ResourceResponseSoup.cpp | 3 + + .../network/soup/SoupNetworkSession.cpp | 29 ++ + .../platform/network/soup/SoupVersioning.h | 168 +++++++++++ + .../WebCore/platform/network/soup/URLSoup.cpp | 32 +++ + .../WebCore/platform/network/soup/URLSoup.h | 5 + + Source/WebDriver/soup/HTTPServerSoup.cpp | 20 ++ + Source/WebDriver/soup/WebSocketServerSoup.cpp | 26 ++ + .../soup/NetworkDataTaskSoup.cpp | 260 +++++++++++++++++- + .../NetworkProcess/soup/NetworkDataTaskSoup.h | 31 +++ + .../soup/NetworkSessionSoup.cpp | 26 ++ + .../NetworkProcess/soup/WebSocketTaskSoup.cpp | 31 ++- + Source/WebKit/PlatformGTK.cmake | 4 +- + .../glib/RemoteInspectorHTTPServer.cpp | 13 + + .../gtk/webkitgtk-web-process-extension.pc.in | 2 +- + Source/WebKit/gtk/webkitgtk.pc.in | 2 +- + Source/cmake/OptionsGTK.cmake | 35 ++- + Source/cmake/WebKitFeatures.cmake | 1 + + .../Tests/WebKitGLib/TestAuthentication.cpp | 45 +++ + .../Tests/WebKitGLib/TestBackForwardList.cpp | 5 + + .../Tests/WebKitGLib/TestCookieManager.cpp | 9 + + .../Tests/WebKitGLib/TestDownloads.cpp | 13 + + .../Tests/WebKitGLib/TestLoaderClient.cpp | 5 + + .../TestNetworkProcessMemoryPressure.cpp | 5 + + .../Tests/WebKitGLib/TestResources.cpp | 21 ++ + .../Tests/WebKitGLib/TestSSL.cpp | 17 ++ + .../WebKitGLib/TestWebKitFaviconDatabase.cpp | 5 + + .../WebKitGLib/TestWebKitPolicyClient.cpp | 5 + + .../Tests/WebKitGLib/TestWebKitSettings.cpp | 5 + + .../TestWebKitUserContentManager.cpp | 5 + + .../Tests/WebKitGLib/TestWebKitWebContext.cpp | 34 +++ + .../Tests/WebKitGLib/TestWebKitWebView.cpp | 5 + + .../Tests/WebKitGLib/TestWebKitWebXR.cpp | 4 + + .../Tests/WebKitGLib/TestWebsiteData.cpp | 11 + + .../Tests/WebKitGtk/TestContextMenu.cpp | 9 + + .../glib/WebKitGLib/WebKitTestServer.cpp | 6 + + .../glib/WebKitGLib/WebKitTestServer.h | 4 + + 47 files changed, 1053 insertions(+), 17 deletions(-) + create mode 100644 Source/WebCore/platform/network/soup/SoupVersioning.h + +diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h +index 57a1b5126290..2ac1c519ed9a 100644 +--- a/Source/WTF/wtf/Platform.h ++++ b/Source/WTF/wtf/Platform.h +@@ -104,8 +104,12 @@ + #endif + + #if USE(SOUP) ++#if USE(SOUP2) ++#define SOUP_VERSION_MIN_REQUIRED SOUP_VERSION_2_54 ++#else + #define SOUP_VERSION_MIN_REQUIRED SOUP_VERSION_3_0 + #endif ++#endif + + #if PLATFORM(COCOA) + /* Cocoa defines a series of platform macros for debugging. */ +diff --git a/Source/WTF/wtf/PlatformEnableGlib.h b/Source/WTF/wtf/PlatformEnableGlib.h +index a50993596280..0faf3134ae84 100644 +--- a/Source/WTF/wtf/PlatformEnableGlib.h ++++ b/Source/WTF/wtf/PlatformEnableGlib.h +@@ -55,10 +55,6 @@ + #define ENABLE_OPENTYPE_VERTICAL 1 + #endif + +-#if !defined(ENABLE_SERVER_PRECONNECT) +-#define ENABLE_SERVER_PRECONNECT 1 +-#endif +- + #if !defined(ENABLE_SCROLLING_THREAD) && USE(COORDINATED_GRAPHICS) + #define ENABLE_SCROLLING_THREAD 1 + #endif +diff --git a/Source/WebCore/platform/Soup.cmake b/Source/WebCore/platform/Soup.cmake +index 1280075b2eac..8ea3b022bb3e 100644 +--- a/Source/WebCore/platform/Soup.cmake ++++ b/Source/WebCore/platform/Soup.cmake +@@ -16,6 +16,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS + platform/network/soup/ResourceResponse.h + platform/network/soup/SoupNetworkProxySettings.h + platform/network/soup/SoupNetworkSession.h ++ platform/network/soup/SoupVersioning.h + platform/network/soup/URLSoup.h + ) + +diff --git a/Source/WebCore/platform/network/soup/AuthenticationChallenge.h b/Source/WebCore/platform/network/soup/AuthenticationChallenge.h +index e6a6b94e5010..c2183b06cd83 100644 +--- a/Source/WebCore/platform/network/soup/AuthenticationChallenge.h ++++ b/Source/WebCore/platform/network/soup/AuthenticationChallenge.h +@@ -56,6 +56,9 @@ public: + AuthenticationChallenge(SoupMessage*, GTlsClientConnection*); + AuthenticationChallenge(SoupMessage*, GTlsPassword*); + AuthenticationClient* authenticationClient() const { RELEASE_ASSERT_NOT_REACHED(); } ++#if USE(SOUP2) ++ SoupMessage* soupMessage() const { return m_soupMessage.get(); } ++#endif + SoupAuth* soupAuth() const { return m_soupAuth.get(); } + GTlsPassword* tlsPassword() const { return m_tlsPassword.get(); } + void setProposedCredential(const Credential& credential) { m_proposedCredential = credential; } +@@ -70,6 +73,9 @@ private: + friend class AuthenticationChallengeBase; + static bool platformCompare(const AuthenticationChallenge&, const AuthenticationChallenge&); + ++#if USE(SOUP2) ++ GRefPtr m_soupMessage; ++#endif + GRefPtr m_soupAuth; + GRefPtr m_tlsPassword; + uint32_t m_tlsPasswordFlags { 0 }; +diff --git a/Source/WebCore/platform/network/soup/AuthenticationChallengeSoup.cpp b/Source/WebCore/platform/network/soup/AuthenticationChallengeSoup.cpp +index 7ea935d22bd9..c717860d54f3 100644 +--- a/Source/WebCore/platform/network/soup/AuthenticationChallengeSoup.cpp ++++ b/Source/WebCore/platform/network/soup/AuthenticationChallengeSoup.cpp +@@ -62,9 +62,16 @@ static ProtectionSpace protectionSpaceFromSoupAuthAndURL(SoupAuth* soupAuth, con + else + scheme = ProtectionSpace::AuthenticationScheme::Unknown; + ++#if USE(SOUP2) ++ auto host = url.host(); ++ auto port = url.port(); ++ if (!port) ++ port = defaultPortForProtocol(url.protocol()); ++#else + URL authURL({ }, makeString("http://"_s, unsafeSpan(soup_auth_get_authority(soupAuth)))); + auto host = authURL.host(); + auto port = authURL.port(); ++#endif + + return ProtectionSpace(host.toString(), static_cast(port.value_or(0)), + protectionSpaceServerTypeFromURL(url, soup_auth_is_for_proxy(soupAuth)), +@@ -77,6 +84,9 @@ AuthenticationChallenge::AuthenticationChallenge(SoupMessage* soupMessage, SoupA + , retrying ? 1 : 0 // previousFailureCount + , soupMessage // failureResponse + , ResourceError::authenticationError(soupMessage)) ++#if USE(SOUP2) ++ , m_soupMessage(soupMessage) ++#endif + , m_soupAuth(soupAuth) + { + } +@@ -130,6 +140,10 @@ bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, + if (a.tlsPasswordFlags() != b.tlsPasswordFlags()) + return false; + ++#if USE(SOUP2) ++ return a.soupMessage() == b.soupMessage(); ++#endif ++ + return true; + } + +diff --git a/Source/WebCore/platform/network/soup/CookieSoup.cpp b/Source/WebCore/platform/network/soup/CookieSoup.cpp +index ce2a688eb3fc..9bb9c7124d40 100644 +--- a/Source/WebCore/platform/network/soup/CookieSoup.cpp ++++ b/Source/WebCore/platform/network/soup/CookieSoup.cpp +@@ -32,6 +32,7 @@ + + namespace WebCore { + ++#if SOUP_CHECK_VERSION(2, 69, 90) + static Cookie::SameSitePolicy coreSameSitePolicy(SoupSameSitePolicy policy) + { + switch (policy) { +@@ -61,19 +62,40 @@ static SoupSameSitePolicy soupSameSitePolicy(Cookie::SameSitePolicy policy) + ASSERT_NOT_REACHED(); + return SOUP_SAME_SITE_POLICY_NONE; + } ++#endif + + Cookie::Cookie(SoupCookie* cookie) + : name(String::fromUTF8(soup_cookie_get_name(cookie))) + , value(String::fromUTF8(soup_cookie_get_value(cookie))) + , domain(String::fromUTF8(soup_cookie_get_domain(cookie))) + , path(String::fromUTF8(soup_cookie_get_path(cookie))) ++#if USE(SOUP2) ++ , expires(soup_cookie_get_expires(cookie) ? std::make_optional(static_cast(soup_date_to_time_t(soup_cookie_get_expires(cookie))) * 1000) : std::nullopt) ++#else + , expires(soup_cookie_get_expires(cookie) ? std::make_optional(static_cast(g_date_time_to_unix(soup_cookie_get_expires(cookie))) * 1000) : std::nullopt) ++#endif + , httpOnly(soup_cookie_get_http_only(cookie)) + , secure(soup_cookie_get_secure(cookie)) + , session(!soup_cookie_get_expires(cookie)) +- , sameSite(coreSameSitePolicy(soup_cookie_get_same_site_policy(cookie))) ++ + { ++#if SOUP_CHECK_VERSION(2, 69, 90) ++ sameSite = coreSameSitePolicy(soup_cookie_get_same_site_policy(cookie)); ++#endif ++} ++ ++#if USE(SOUP2) ++static SoupDate* msToSoupDate(double ms) ++{ ++ int year = msToYear(ms); ++ int dayOfYear = dayInYear(ms, year); ++ bool leapYear = isLeapYear(year); ++ ++ // monthFromDayInYear() returns a value in the [0,11] range, while soup_date_new() expects ++ // a value in the [1,12] range, meaning we have to manually adjust the month value. ++ return soup_date_new(year, monthFromDayInYear(dayOfYear, leapYear) + 1, dayInMonthFromDayInYear(dayOfYear, leapYear), msToHours(ms), msToMinutes(ms), static_cast(ms / 1000) % 60); + } ++#endif + + SoupCookie* Cookie::toSoupCookie() const + { +@@ -85,11 +107,19 @@ SoupCookie* Cookie::toSoupCookie() const + + soup_cookie_set_http_only(soupCookie, httpOnly); + soup_cookie_set_secure(soupCookie, secure); ++#if SOUP_CHECK_VERSION(2, 69, 90) + soup_cookie_set_same_site_policy(soupCookie, soupSameSitePolicy(sameSite)); ++#endif + + if (!session && expires) { ++#if USE(SOUP2) ++ SoupDate* date = msToSoupDate(*expires); ++ soup_cookie_set_expires(soupCookie, date); ++ soup_date_free(date); ++#else + GRefPtr date = adoptGRef(g_date_time_new_from_unix_utc(*expires / 1000.)); + soup_cookie_set_expires(soupCookie, date.get()); ++#endif + } + + return soupCookie; +diff --git a/Source/WebCore/platform/network/soup/GUniquePtrSoup.h b/Source/WebCore/platform/network/soup/GUniquePtrSoup.h +index 843b56c646bd..6bbe61e05e6a 100644 +--- a/Source/WebCore/platform/network/soup/GUniquePtrSoup.h ++++ b/Source/WebCore/platform/network/soup/GUniquePtrSoup.h +@@ -29,8 +29,17 @@ + namespace WTF { + + WTF_DEFINE_GPTR_DELETER(SoupCookie, soup_cookie_free) ++#if SOUP_CHECK_VERSION(2, 67, 1) + WTF_DEFINE_GPTR_DELETER(SoupHSTSPolicy, soup_hsts_policy_free) ++#endif ++#if USE(SOUP2) ++WTF_DEFINE_GPTR_DELETER(SoupURI, soup_uri_free) ++#endif ++#if SOUP_CHECK_VERSION(2, 99, 3) + WTF_DEFINE_GPTR_DELETER(SoupMessageHeaders, soup_message_headers_unref) ++#else ++WTF_DEFINE_GPTR_DELETER(SoupMessageHeaders, soup_message_headers_free) ++#endif + + } // namespace WTF + +diff --git a/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp b/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp +index a2a6da86c7d9..a5cbe1c7d4b4 100644 +--- a/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp ++++ b/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp +@@ -353,8 +353,12 @@ void NetworkStorageSession::setCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) + soupPolicy = SOUP_COOKIE_JAR_ACCEPT_NEVER; + break; + case HTTPCookieAcceptPolicy::OnlyFromMainDocumentDomain: ++#if SOUP_CHECK_VERSION(2, 71, 0) + soupPolicy = SOUP_COOKIE_JAR_ACCEPT_GRANDFATHERED_THIRD_PARTY; + break; ++#else ++ [[fallthrough]]; ++#endif + case HTTPCookieAcceptPolicy::ExclusivelyFromMainDocumentDomain: + soupPolicy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY; + break; +@@ -370,8 +374,10 @@ HTTPCookieAcceptPolicy NetworkStorageSession::cookieAcceptPolicy() const + return HTTPCookieAcceptPolicy::AlwaysAccept; + case SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY: + return HTTPCookieAcceptPolicy::ExclusivelyFromMainDocumentDomain; ++#if SOUP_CHECK_VERSION(2, 71, 0) + case SOUP_COOKIE_JAR_ACCEPT_GRANDFATHERED_THIRD_PARTY: + return HTTPCookieAcceptPolicy::OnlyFromMainDocumentDomain; ++#endif + case SOUP_COOKIE_JAR_ACCEPT_NEVER: + return HTTPCookieAcceptPolicy::Never; + } +@@ -443,13 +449,21 @@ void NetworkStorageSession::setCookiesFromDOM(const URL& firstParty, const SameS + // Cap lifetime of persistent, client-side cookies to a week. + if (cappedLifetime) { + if (auto* expiresDate = soup_cookie_get_expires(cookie.get())) { ++#if USE(SOUP2) ++ auto timeIntervalSinceNow = Seconds(static_cast(soup_date_to_time_t(expiresDate))) - WallTime::now().secondsSinceEpoch(); ++#else + auto timeIntervalSinceNow = Seconds(static_cast(g_date_time_to_unix(expiresDate))) - WallTime::now().secondsSinceEpoch(); ++#endif + if (timeIntervalSinceNow > cappedLifetime.value()) + soup_cookie_set_max_age(cookie.get(), cappedLifetime->secondsAs()); + } + } + ++#if SOUP_CHECK_VERSION(2, 67, 1) + soup_cookie_jar_add_cookie_full(jar, cookie.release(), origin.get(), firstPartyURI.get()); ++#else ++ soup_cookie_jar_add_cookie_with_first_party(jar, firstPartyURI.get(), cookie.release()); ++#endif + } + + soup_cookies_free(existingCookies); +@@ -483,7 +497,12 @@ bool NetworkStorageSession::setCookieFromDOM(const URL& firstParty, const SameSi + } + soup_cookies_free(existingCookies); + ++#if SOUP_CHECK_VERSION(2, 67, 1) + soup_cookie_jar_add_cookie_full(cookieStorage(), soupCookie.release(), uri.get(), firstPartyURI.get()); ++#else ++ soup_cookie_jar_add_cookie_with_first_party(cookieStorage(), firstPartyURI.get(), soupCookie.release()); ++ UNUSED_PARAM(uri); ++#endif + + return true; + } +@@ -491,9 +510,16 @@ bool NetworkStorageSession::setCookieFromDOM(const URL& firstParty, const SameSi + void NetworkStorageSession::setCookies(const Vector& cookies, const URL& url, const URL& firstParty) + { + for (auto cookie : cookies) { ++#if SOUP_CHECK_VERSION(2, 67, 1) + auto origin = urlToSoupURI(url); + auto firstPartyURI = urlToSoupURI(firstParty); ++ + soup_cookie_jar_add_cookie_full(cookieStorage(), cookie.toSoupCookie(), origin.get(), firstPartyURI.get()); ++#else ++ UNUSED_PARAM(url); ++ UNUSED_PARAM(firstParty); ++ soup_cookie_jar_add_cookie(cookieStorage(), cookie.toSoupCookie()); ++#endif + } + } + +@@ -669,6 +695,7 @@ static std::optional lookupCookies(const NetworkStorageSession& sess + if (!uri) + return std::nullopt; + ++#if SOUP_CHECK_VERSION(2, 69, 90) + auto firstPartyURI = urlToSoupURI(firstParty); + if (!firstPartyURI) + return std::nullopt; +@@ -676,6 +703,9 @@ static std::optional lookupCookies(const NetworkStorageSession& sess + auto cookieURI = sameSiteInfo.isSameSite ? urlToSoupURI(url) : nullptr; + CookieList cookies(soup_cookie_jar_get_cookie_list_with_same_site_info(session.cookieStorage(), uri.get(), firstPartyURI.get(), cookieURI.get(), forHTTPHeader == ForHTTPHeader::Yes, + sameSiteInfo.isSafeHTTPMethod, sameSiteInfo.isTopSite)); ++#else ++ CookieList cookies(soup_cookie_jar_get_cookie_list(session.cookieStorage(), uri.get(), forHTTPHeader == ForHTTPHeader::Yes)); ++#endif + if (!cookies) + return nullptr; + +diff --git a/Source/WebCore/platform/network/soup/ResourceErrorSoup.cpp b/Source/WebCore/platform/network/soup/ResourceErrorSoup.cpp +index efb31f2c864d..db0725eddd21 100644 +--- a/Source/WebCore/platform/network/soup/ResourceErrorSoup.cpp ++++ b/Source/WebCore/platform/network/soup/ResourceErrorSoup.cpp +@@ -36,6 +36,12 @@ + + namespace WebCore { + ++#if USE(SOUP2) ++#define SOUP_HTTP_ERROR_DOMAIN SOUP_HTTP_ERROR ++#else ++#define SOUP_HTTP_ERROR_DOMAIN SOUP_SESSION_ERROR ++#endif ++ + ResourceError::ResourceError(const String& domain, int errorCode, const URL& failingURL, const String& localizedDescription, Type type, IsSanitized isSanitized) + : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription, type, isSanitized) + { +@@ -77,20 +83,29 @@ auto ResourceError::ipcData() const -> std::optional + + ResourceError ResourceError::transportError(const URL& failingURL, int statusCode, const String& reasonPhrase) + { +- return ResourceError(String::fromLatin1(g_quark_to_string(SOUP_SESSION_ERROR)), statusCode, failingURL, reasonPhrase); ++ return ResourceError(String::fromLatin1(g_quark_to_string(SOUP_HTTP_ERROR_DOMAIN)), statusCode, failingURL, reasonPhrase); + } + + ResourceError ResourceError::httpError(SoupMessage* message, GError* error) + { + ASSERT(message); ++#if USE(SOUP2) ++ if (SOUP_STATUS_IS_TRANSPORT_ERROR(message->status_code)) ++ return transportError(soupURIToURL(soup_message_get_uri(message)), message->status_code, String::fromUTF8(message->reason_phrase)); ++#endif + return genericGError(soupURIToURL(soup_message_get_uri(message)), error); + } + + ResourceError ResourceError::authenticationError(SoupMessage* message) + { + ASSERT(message); ++#if USE(SOUP2) ++ return ResourceError(String::fromLatin1(g_quark_to_string(SOUP_HTTP_ERROR_DOMAIN)), message->status_code, ++ soupURIToURL(soup_message_get_uri(message)), String::fromUTF8(message->reason_phrase)); ++#else + return ResourceError(String::fromLatin1(g_quark_to_string(SOUP_SESSION_ERROR)), soup_message_get_status(message), + soup_message_get_uri(message), String::fromUTF8(soup_message_get_reason_phrase(message))); ++#endif + } + + ResourceError ResourceError::genericGError(const URL& failingURL, GError* error) +diff --git a/Source/WebCore/platform/network/soup/ResourceRequest.h b/Source/WebCore/platform/network/soup/ResourceRequest.h +index 98e8c082c695..ab7ed161b9f7 100644 +--- a/Source/WebCore/platform/network/soup/ResourceRequest.h ++++ b/Source/WebCore/platform/network/soup/ResourceRequest.h +@@ -101,7 +101,11 @@ public: + private: + friend class ResourceRequestBase; + ++#if USE(SOUP2) ++ GUniquePtr createSoupURI() const; ++#else + GRefPtr createSoupURI() const; ++#endif + + void doUpdatePlatformRequest() { } + void doUpdateResourceRequest() { } +diff --git a/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp b/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp +index bca32f9cb362..fd8c094594c7 100644 +--- a/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp ++++ b/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp +@@ -29,6 +29,7 @@ + #include "MIMETypeRegistry.h" + #include "RegistrableDomain.h" + #include "SharedBuffer.h" ++#include "SoupVersioning.h" + #include "URLSoup.h" + #include "WebKitFormDataInputStream.h" + #include +@@ -71,6 +72,7 @@ GRefPtr ResourceRequest::createSoupMessage(BlobRegistryImpl& blobRe + soup_message_set_first_party(soupMessage.get(), firstParty.get()); + } + ++#if SOUP_CHECK_VERSION(2, 69, 90) + if (!isSameSiteUnspecified()) { + if (isSameSite()) { + auto siteForCookies = urlToSoupURI(m_requestData.m_url); +@@ -78,6 +80,7 @@ GRefPtr ResourceRequest::createSoupMessage(BlobRegistryImpl& blobRe + } + soup_message_set_is_top_level_navigation(soupMessage.get(), isTopSite()); + } ++#endif + + if (!acceptEncoding()) + soup_message_disable_feature(soupMessage.get(), SOUP_TYPE_CONTENT_DECODER); +@@ -99,8 +102,12 @@ void ResourceRequest::updateSoupMessageBody(SoupMessage* soupMessage, BlobRegist + auto& elements = formData->elements(); + if (elements.size() == 1 && !formData->alwaysStream()) { + if (auto* vector = std::get_if>(&elements[0].data)) { ++#if USE(SOUP2) ++ soup_message_body_append(soupMessage->request_body, SOUP_MEMORY_TEMPORARY, vector->span().data(), vector->size()); ++#else + GRefPtr bytes = adoptGRef(g_bytes_new_static(vector->span().data(), vector->size())); + soup_message_set_request_body_from_bytes(soupMessage, nullptr, bytes.get()); ++#endif + return; + } + } +@@ -118,7 +125,19 @@ void ResourceRequest::updateSoupMessageBody(SoupMessage* soupMessage, BlobRegist + return; + + GRefPtr stream = webkitFormDataInputStreamNew(WTF::move(resolvedFormData)); ++#if USE(SOUP2) ++ if (GBytes* data = webkitFormDataInputStreamReadAll(WEBKIT_FORM_DATA_INPUT_STREAM(stream.get()))) { ++ soup_message_body_set_accumulate(soupMessage->request_body, FALSE); ++ auto* soupBuffer = soup_buffer_new_with_owner(g_bytes_get_data(data, nullptr), ++ g_bytes_get_size(data), data, reinterpret_cast(g_bytes_unref)); ++ soup_message_body_append_buffer(soupMessage->request_body, soupBuffer); ++ soup_buffer_free(soupBuffer); ++ } ++ ASSERT(length == static_cast(soupMessage->request_body->length)); ++#else + soup_message_set_request_body(soupMessage, nullptr, stream.get(), length); ++#endif ++ + } + + GRefPtr ResourceRequest::createBodyStream() const +@@ -164,10 +183,39 @@ unsigned initializeMaximumHTTPConnectionCountPerHost() + return 10000; + } + ++#if USE(SOUP2) ++GUniquePtr ResourceRequest::createSoupURI() const ++{ ++ // WebKit does not support fragment identifiers in data URLs, but soup does. ++ // Before passing the URL to soup, we should make sure to urlencode any '#' ++ // characters, so that soup does not interpret them as fragment identifiers. ++ // See http://wkbug.com/68089 ++ if (m_requestData.m_url.protocolIsData()) { ++ String urlString = makeStringByReplacingAll(m_requestData.m_url.string(), '#', "%23"_s); ++ return GUniquePtr(soup_uri_new(urlString.utf8().data())); ++ } ++ ++ GUniquePtr soupURI = urlToSoupURI(m_requestData.m_url); ++ ++ // Versions of libsoup prior to 2.42 have a soup_uri_new that will convert empty passwords that are not ++ // prefixed by a colon into null. Some parts of soup like the SoupAuthenticationManager will only be active ++ // when both the username and password are non-null. When we have credentials, empty usernames and passwords ++ // should be empty strings instead of null. ++ String urlUser = m_requestData.m_url.user(); ++ String urlPass = m_requestData.m_url.password(); ++ if (!urlUser.isEmpty() || !urlPass.isEmpty()) { ++ soup_uri_set_user(soupURI.get(), urlUser.utf8().data()); ++ soup_uri_set_password(soupURI.get(), urlPass.utf8().data()); ++ } ++ ++ return soupURI; ++} ++#else + GRefPtr ResourceRequest::createSoupURI() const + { + return m_requestData.m_url.createGUri(); + } ++#endif + + void ResourceRequest::updateFromDelegatePreservingOldProperties(const ResourceRequest& delegateProvidedRequest) + { +diff --git a/Source/WebCore/platform/network/soup/ResourceResponseSoup.cpp b/Source/WebCore/platform/network/soup/ResourceResponseSoup.cpp +index 5aea30714a01..1ae165956629 100644 +--- a/Source/WebCore/platform/network/soup/ResourceResponseSoup.cpp ++++ b/Source/WebCore/platform/network/soup/ResourceResponseSoup.cpp +@@ -28,6 +28,7 @@ + #include "HTTPHeaderNames.h" + #include "HTTPParsers.h" + #include "MIMETypeRegistry.h" ++#include "SoupVersioning.h" + #include "URLSoup.h" + #include + #include +@@ -46,9 +47,11 @@ ResourceResponse::ResourceResponse(SoupMessage* soupMessage, const CString& snif + case SOUP_HTTP_1_1: + m_httpVersion = "HTTP/1.1"_s; + break; ++#if SOUP_CHECK_VERSION(2, 99, 3) + case SOUP_HTTP_2_0: + m_httpVersion = "HTTP/2"_s; + break; ++#endif + } + + m_httpStatusCode = soup_message_get_status(soupMessage); +diff --git a/Source/WebCore/platform/network/soup/SoupNetworkSession.cpp b/Source/WebCore/platform/network/soup/SoupNetworkSession.cpp +index 4ffd156d0275..70664cf1b41b 100644 +--- a/Source/WebCore/platform/network/soup/SoupNetworkSession.cpp ++++ b/Source/WebCore/platform/network/soup/SoupNetworkSession.cpp +@@ -32,6 +32,7 @@ + #include "AuthenticationChallenge.h" + #include "GUniquePtrSoup.h" + #include "Logging.h" ++#include "SoupVersioning.h" + #include "WebKitAutoconfigProxyResolver.h" + #include + #include +@@ -111,8 +112,12 @@ SoupNetworkSession::SoupNetworkSession(PAL::SessionID sessionID) + + soup_session_add_feature_by_type(m_soupSession.get(), SOUP_TYPE_CONTENT_SNIFFER); + soup_session_add_feature_by_type(m_soupSession.get(), SOUP_TYPE_AUTH_NTLM); ++#if SOUP_CHECK_VERSION(2, 67, 1) + soup_session_add_feature_by_type(m_soupSession.get(), SOUP_TYPE_HSTS_ENFORCER); ++#endif ++#if SOUP_CHECK_VERSION(2, 67, 90) + soup_session_add_feature_by_type(m_soupSession.get(), SOUP_TYPE_WEBSOCKET_EXTENSION_MANAGER); ++#endif + + if (!initialAcceptLanguages().isNull()) + setAcceptLanguages(initialAcceptLanguages()); +@@ -149,7 +154,11 @@ void SoupNetworkSession::setupLogger() + if (LogNetwork.state != WTFLogChannelState::On || soup_session_get_feature(m_soupSession.get(), SOUP_TYPE_LOGGER)) + return; + ++#if USE(SOUP2) ++ GRefPtr logger = adoptGRef(soup_logger_new(SOUP_LOGGER_LOG_BODY, -1)); ++#else + GRefPtr logger = adoptGRef(soup_logger_new(SOUP_LOGGER_LOG_BODY)); ++#endif + soup_session_add_feature(m_soupSession.get(), SOUP_SESSION_FEATURE(logger.get())); + soup_logger_set_printer(logger.get(), soupLogPrinter, nullptr, nullptr); + #endif +@@ -172,6 +181,7 @@ void SoupNetworkSession::setHSTSPersistentStorage(const String& directory) + if (m_sessionID.isEphemeral()) + return; + ++#if SOUP_CHECK_VERSION(2, 67, 1) + if (!FileSystem::makeAllDirectories(directory)) { + RELEASE_LOG_ERROR(Network, "Unable to create the HSTS storage directory \"%s\". Using a memory enforcer instead.", directory.utf8().data()); + return; +@@ -182,10 +192,14 @@ void SoupNetworkSession::setHSTSPersistentStorage(const String& directory) + GRefPtr enforcer = adoptGRef(soup_hsts_enforcer_db_new(dbFilename.get())); + soup_session_remove_feature_by_type(m_soupSession.get(), SOUP_TYPE_HSTS_ENFORCER); + soup_session_add_feature(m_soupSession.get(), SOUP_SESSION_FEATURE(enforcer.get())); ++#else ++ UNUSED_PARAM(directory); ++#endif + } + + void SoupNetworkSession::getHostNamesWithHSTSCache(HashSet& hostNames) + { ++#if SOUP_CHECK_VERSION(2, 67, 91) + auto* enforcer = SOUP_HSTS_ENFORCER(soup_session_get_feature(m_soupSession.get(), SOUP_TYPE_HSTS_ENFORCER)); + ASSERT(enforcer); + +@@ -194,10 +208,14 @@ void SoupNetworkSession::getHostNamesWithHSTSCache(HashSet& hostNames) + GUniquePtr domain(static_cast(iter->data)); + hostNames.add(String::fromUTF8(domain.get())); + } ++#else ++ UNUSED_PARAM(hostNames); ++#endif + } + + void SoupNetworkSession::deleteHSTSCacheForHostNames(const Vector& hostNames) + { ++#if SOUP_CHECK_VERSION(2, 67, 1) + auto* enforcer = SOUP_HSTS_ENFORCER(soup_session_get_feature(m_soupSession.get(), SOUP_TYPE_HSTS_ENFORCER)); + ASSERT(enforcer); + +@@ -205,22 +223,33 @@ void SoupNetworkSession::deleteHSTSCacheForHostNames(const Vector& hostN + GUniquePtr policy(soup_hsts_policy_new(hostName.utf8().data(), SOUP_HSTS_POLICY_MAX_AGE_PAST, FALSE)); + soup_hsts_enforcer_set_policy(enforcer, policy.get()); + } ++#else ++ UNUSED_PARAM(hostNames); ++#endif + } + + void SoupNetworkSession::clearHSTSCache(WallTime modifiedSince) + { ++#if SOUP_CHECK_VERSION(2, 67, 91) + auto* enforcer = SOUP_HSTS_ENFORCER(soup_session_get_feature(m_soupSession.get(), SOUP_TYPE_HSTS_ENFORCER)); + ASSERT(enforcer); + + GUniquePtr policies(soup_hsts_enforcer_get_policies(enforcer, FALSE)); + for (GList* iter = policies.get(); iter != nullptr; iter = iter->next) { + GUniquePtr policy(static_cast(iter->data)); ++#if USE(SOUP2) ++ auto modified = soup_date_to_time_t(policy.get()->expires) - policy.get()->max_age; ++#else + auto modified = g_date_time_to_unix(soup_hsts_policy_get_expires(policy.get())) - soup_hsts_policy_get_max_age(policy.get()); ++#endif + if (modified >= modifiedSince.secondsSinceEpoch().seconds()) { + GUniquePtr newPolicy(soup_hsts_policy_new(soup_hsts_policy_get_domain(policy.get()), SOUP_HSTS_POLICY_MAX_AGE_PAST, FALSE)); + soup_hsts_enforcer_set_policy(enforcer, newPolicy.get()); + } + } ++#else ++ UNUSED_PARAM(modifiedSince); ++#endif + } + + static inline bool stringIsNumeric(const std::string_view& str) +diff --git a/Source/WebCore/platform/network/soup/SoupVersioning.h b/Source/WebCore/platform/network/soup/SoupVersioning.h +new file mode 100644 +index 000000000000..4895e0c69900 +--- /dev/null ++++ b/Source/WebCore/platform/network/soup/SoupVersioning.h +@@ -0,0 +1,168 @@ ++/* ++ * Copyright (C) 2021 Igalia S.L. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Library General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Library General Public License for more details. ++ * ++ * You should have received a copy of the GNU Library General Public License ++ * along with this library; see the file COPYING.LIB. If not, write to ++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ++ * Boston, MA 02110-1301, USA. ++ */ ++ ++#pragma once ++ ++#include ++ ++#if USE(SOUP2) ++ ++static inline const char* ++soup_message_get_method(SoupMessage* message) ++{ ++ g_return_val_if_fail(SOUP_IS_MESSAGE(message), nullptr); ++ return message->method; ++} ++ ++static inline const char* ++soup_server_message_get_method(SoupMessage* message) ++{ ++ return soup_message_get_method(message); ++} ++ ++static inline SoupStatus ++soup_message_get_status(SoupMessage* message) ++{ ++ g_return_val_if_fail(SOUP_IS_MESSAGE(message), SOUP_STATUS_NONE); ++ return static_cast(message->status_code); ++} ++ ++static inline void ++soup_server_message_set_status(SoupMessage* message, unsigned statusCode, const char* reasonPhrase) ++{ ++ if (reasonPhrase) ++ soup_message_set_status_full(message, statusCode, reasonPhrase); ++ else ++ soup_message_set_status(message, statusCode); ++} ++ ++static inline const char* ++soup_message_get_reason_phrase(SoupMessage* message) ++{ ++ g_return_val_if_fail(SOUP_IS_MESSAGE(message), nullptr); ++ return message->reason_phrase; ++} ++ ++static inline SoupMessageHeaders* ++soup_message_get_request_headers(SoupMessage* message) ++{ ++ g_return_val_if_fail(SOUP_IS_MESSAGE(message), nullptr); ++ return message->request_headers; ++} ++ ++static inline SoupMessageHeaders* ++soup_server_message_get_request_headers(SoupMessage* message) ++{ ++ return soup_message_get_request_headers(message); ++} ++ ++static inline SoupMessageHeaders* ++soup_message_get_response_headers(SoupMessage* message) ++{ ++ g_return_val_if_fail(SOUP_IS_MESSAGE(message), nullptr); ++ return message->response_headers; ++} ++ ++static inline SoupMessageHeaders* ++soup_server_message_get_response_headers(SoupMessage* message) ++{ ++ return soup_message_get_response_headers(message); ++} ++ ++static inline SoupMessageBody* ++soup_server_message_get_response_body(SoupMessage* message) ++{ ++ g_return_val_if_fail(SOUP_IS_MESSAGE(message), nullptr); ++ return message->response_body; ++} ++ ++static inline void ++soup_server_message_set_response(SoupMessage* message, const char* contentType, SoupMemoryUse memoryUse, const char* responseBody, gsize length) ++{ ++ return soup_message_set_response(message, contentType, memoryUse, responseBody, length); ++} ++ ++static inline SoupURI* ++soup_server_message_get_uri(SoupMessage* message) ++{ ++ return soup_message_get_uri(message); ++} ++ ++static inline GTlsCertificate* ++soup_message_get_tls_peer_certificate(SoupMessage* message) ++{ ++ g_return_val_if_fail(SOUP_IS_MESSAGE(message), nullptr); ++ GTlsCertificate* certificate = nullptr; ++ soup_message_get_https_status(message, &certificate, nullptr); ++ return certificate; ++} ++ ++static inline GTlsCertificateFlags ++soup_message_get_tls_peer_certificate_errors(SoupMessage* message) ++{ ++ g_return_val_if_fail(SOUP_IS_MESSAGE(message), static_cast(0)); ++ GTlsCertificateFlags flags = static_cast(0); ++ soup_message_get_https_status(message, nullptr, &flags); ++ return flags; ++} ++ ++static inline void ++soup_session_send_async(SoupSession* session, SoupMessage* message, int, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) ++{ ++ soup_session_send_async(session, message, cancellable, callback, userData); ++} ++ ++static inline void ++soup_session_websocket_connect_async(SoupSession* session, SoupMessage* message, const char* origin, char** protocols, int, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) ++{ ++ soup_session_websocket_connect_async(session, message, origin, protocols, cancellable, callback, userData); ++} ++ ++static inline void ++soup_auth_cancel(SoupAuth*) ++{ ++} ++ ++static inline void ++soup_session_set_proxy_resolver(SoupSession* session, GProxyResolver* resolver) ++{ ++ g_object_set(session, "proxy-resolver", resolver, nullptr); ++} ++ ++static inline GProxyResolver* ++soup_session_get_proxy_resolver(SoupSession* session) ++{ ++ GRefPtr resolver; ++ g_object_get(session, "proxy-resolver", &resolver.outPtr(), nullptr); ++ return resolver.get(); ++} ++ ++static inline void ++soup_session_set_accept_language(SoupSession* session, const char* acceptLanguage) ++{ ++ g_object_set(session, "accept-language", acceptLanguage, nullptr); ++} ++ ++static inline void ++soup_session_set_tls_database(SoupSession *session, GTlsDatabase *tls_database) ++{ ++ g_object_set(session, "tls-database", tls_database, NULL); ++} ++ ++#endif // USE(SOUP2) +diff --git a/Source/WebCore/platform/network/soup/URLSoup.cpp b/Source/WebCore/platform/network/soup/URLSoup.cpp +index 9b2f7b06c41e..351e52893399 100644 +--- a/Source/WebCore/platform/network/soup/URLSoup.cpp ++++ b/Source/WebCore/platform/network/soup/URLSoup.cpp +@@ -30,6 +30,37 @@ + + namespace WebCore { + ++#if USE(SOUP2) ++URL soupURIToURL(SoupURI* soupURI) ++{ ++ if (!soupURI) ++ return URL(); ++ ++ GUniquePtr urlString(soup_uri_to_string(soupURI, FALSE)); ++ URL url { String::fromUTF8(urlString.get()) }; ++ if (url.isValid()) { ++ // Motivated by https://bugs.webkit.org/show_bug.cgi?id=38956. libsoup ++ // does not add the password to the URL when calling ++ // soup_uri_to_string, and thus the requests are not properly ++ // built. Fixing soup_uri_to_string is a no-no as the maintainer does ++ // not want to break compatibility with previous implementations ++ if (soupURI->password) ++ url.setPassword(String::fromUTF8(soupURI->password)); ++ } ++ ++ return url; ++} ++ ++GUniquePtr urlToSoupURI(const URL& url) ++{ ++ if (!url.isValid()) ++ return nullptr; ++ ++ return GUniquePtr(soup_uri_new(url.string().utf8().data())); ++} ++ ++#else // !USE(SOUP2) ++ + URL soupURIToURL(GUri* uri) + { + return uri; +@@ -39,5 +70,6 @@ GRefPtr urlToSoupURI(const URL& url) + { + return url.createGUri(); + } ++#endif // USE(SOUP2) + + } // namespace WebCore +diff --git a/Source/WebCore/platform/network/soup/URLSoup.h b/Source/WebCore/platform/network/soup/URLSoup.h +index ac87352f192c..64b62035235b 100644 +--- a/Source/WebCore/platform/network/soup/URLSoup.h ++++ b/Source/WebCore/platform/network/soup/URLSoup.h +@@ -33,6 +33,11 @@ class URL; + } + + namespace WebCore { ++#if USE(SOUP2) ++URL soupURIToURL(SoupURI*); ++GUniquePtr urlToSoupURI(const URL&); ++#else + URL soupURIToURL(GUri*); + GRefPtr urlToSoupURI(const URL&); ++#endif + } // namespace WebCore +diff --git a/Source/WebDriver/soup/HTTPServerSoup.cpp b/Source/WebDriver/soup/HTTPServerSoup.cpp +index 86ac0010dcc9..45188492faf7 100644 +--- a/Source/WebDriver/soup/HTTPServerSoup.cpp ++++ b/Source/WebDriver/soup/HTTPServerSoup.cpp +@@ -60,6 +60,25 @@ bool HTTPServer::listen(const std::optional& host, unsigned port) + return false; + } + ++#if USE(SOUP2) ++ soup_server_add_handler(m_soupServer.get(), nullptr, [](SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer userData) { ++ auto* httpServer = static_cast(userData); ++ GRefPtr protectedMessage = message; ++ soup_server_pause_message(server, message); ++ httpServer->m_requestHandler.handleRequest({ String::fromUTF8(message->method), String::fromUTF8(path), message->request_body->data, static_cast(message->request_body->length) }, ++ [server, message = WTF::move(protectedMessage)](HTTPRequestHandler::Response&& response) { ++ soup_message_set_status(message.get(), response.statusCode); ++ if (!response.data.isNull()) { ++ // §6.3 Processing Model. ++ // https://w3c.github.io/webdriver/webdriver-spec.html#dfn-send-a-response ++ soup_message_headers_append(message->response_headers, "Content-Type", response.contentType.utf8().data()); ++ soup_message_headers_append(message->response_headers, "Cache-Control", "no-cache"); ++ soup_message_body_append(message->response_body, SOUP_MEMORY_COPY, response.data.data(), response.data.length()); ++ } ++ soup_server_unpause_message(server, message.get()); ++ }); ++ }, this, nullptr); ++#else + soup_server_add_handler(m_soupServer.get(), nullptr, [](SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer userData) { + auto& httpServer = *static_cast(userData); + GRefPtr protectedMessage = message; +@@ -86,6 +105,7 @@ bool HTTPServer::listen(const std::optional& host, unsigned port) + soup_server_unpause_message(server, message.get()); + }); + }, this, nullptr); ++#endif + + return true; + } +diff --git a/Source/WebDriver/soup/WebSocketServerSoup.cpp b/Source/WebDriver/soup/WebSocketServerSoup.cpp +index 9bd92c8a4ce4..bb743aa45831 100644 +--- a/Source/WebDriver/soup/WebSocketServerSoup.cpp ++++ b/Source/WebDriver/soup/WebSocketServerSoup.cpp +@@ -41,6 +41,8 @@ + + namespace WebDriver { + ++#if !USE(SOUP2) ++ + static bool soupServerListen(SoupServer* server, const String& host, unsigned port, GError** error) + { + static const auto options = static_cast(0); +@@ -134,9 +136,17 @@ static void handleWebSocketConnection(SoupServer*, SoupServerMessage*, const cha + + g_signal_connect(connection, "message", G_CALLBACK(handleWebSocketMessage), webSocketServer); + } ++#endif // !USE(SOUP2) + + std::optional WebSocketServer::listen(const String& host, unsigned port) + { ++#if USE(SOUP2) ++ UNUSED_PARAM(host); ++ UNUSED_PARAM(port); ++ RELEASE_LOG(WebDriverBiDi, "WebSockets support not implemented yet with libsoup2"); ++ return std::nullopt; ++#else ++ + m_soupServer = adoptGRef(soup_server_new("server-header", "WebKitWebDriver-WSS", nullptr)); + GUniqueOutPtr error; + if (!soupServerListen(m_soupServer.get(), host, port, &error.outPtr())) { +@@ -158,18 +168,28 @@ std::optional WebSocketServer::listen(const String& host, unsigned port) + { "/session"_s } + ); + return getWebSocketURL(m_listener, nullString()); ++#endif + } + + void WebSocketServer::sendMessage(WebSocketMessageHandler::Connection connection, const String& message) + { ++#if USE(SOUP2) ++ UNUSED_PARAM(connection); ++ UNUSED_PARAM(message); ++ RELEASE_LOG(WebDriverBiDi, "WebSockets support not implemented yet with libsoup2"); ++#else + ASSERT(connection); + RELEASE_LOG(WebDriverBiDi, "Sending message: %s", message.utf8().data()); + GRefPtr rawMessage = adoptGRef(g_bytes_new(message.utf8().data(), message.utf8().length())); + soup_websocket_connection_send_message(connection.get(), SOUP_WEBSOCKET_DATA_TEXT, rawMessage.get()); ++#endif + } + + void WebSocketServer::disconnect() + { ++#if USE(SOUP2) ++ RELEASE_LOG(WebDriverBiDi, "WebSockets support not implemented yet with libsoup2"); ++#else + if (!m_soupServer) + return; + +@@ -181,16 +201,22 @@ void WebSocketServer::disconnect() + + soup_server_disconnect(m_soupServer.get()); + m_soupServer = nullptr; ++#endif + } + + void WebSocketServer::disconnectSession(const String& sessionId) + { ++#if USE(SOUP2) ++ UNUSED_PARAM(sessionId); ++ RELEASE_LOG(WebDriverBiDi, "WebSockets support not implemented yet with libsoup2"); ++#else + auto connection = this->connection(sessionId); + if (!connection || !connection->get()) + return; + + soup_websocket_connection_close(connection->get(), SOUP_WEBSOCKET_CLOSE_NORMAL, nullptr); + g_signal_handlers_disconnect_by_data(connection->get(), this); ++#endif + } + + } // namespace WebDriver +diff --git a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp +index 76fdb1c19f39..d2b8b2b27073 100644 +--- a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp ++++ b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -66,6 +67,10 @@ NetworkDataTaskSoup::NetworkDataTaskSoup(NetworkSession& session, NetworkDataTas + { + auto request = parameters.request; + if (request.url().protocolIsInHTTPFamily()) { ++#if USE(SOUP2) ++ m_networkLoadMetrics.fetchStart = MonotonicTime::now(); ++ m_networkLoadMetrics.redirectStart = m_networkLoadMetrics.fetchStart; ++#endif + auto url = request.url(); + if (m_storedCredentialsPolicy == StoredCredentialsPolicy::Use) { + m_user = url.user(); +@@ -156,18 +161,28 @@ void NetworkDataTaskSoup::createRequest(ResourceRequest&& request, WasBlockingCo + } + + if (m_shouldPreconnectOnly == PreconnectOnly::Yes) { ++#if !USE(SOUP2) + g_signal_connect(m_soupMessage.get(), "accept-certificate", G_CALLBACK(acceptCertificateCallback), this); ++#endif + return; + } + + m_networkLoadMetrics.redirectCount = m_currentRequest.redirectCount(); + + unsigned messageFlags = SOUP_MESSAGE_NO_REDIRECT; ++#if !USE(SOUP2) + messageFlags |= SOUP_MESSAGE_COLLECT_METRICS; ++#endif + if (m_shouldContentSniff == ContentSniffingPolicy::DoNotSniffContent) + soup_message_disable_feature(m_soupMessage.get(), SOUP_TYPE_CONTENT_SNIFFER); + if (m_user.isEmpty() && m_password.isEmpty() && m_storedCredentialsPolicy == StoredCredentialsPolicy::DoNotUse) { ++#if SOUP_CHECK_VERSION(2, 57, 1) + messageFlags |= SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE; ++#else ++ // In case credential is not available and credential storage should not to be used, ++ // disable authentication manager so that credentials stored in libsoup are not used. ++ soup_message_disable_feature(m_soupMessage.get(), SOUP_TYPE_AUTH_MANAGER); ++#endif + } + soup_message_set_flags(m_soupMessage.get(), static_cast(soup_message_get_flags(m_soupMessage.get()) | messageFlags)); + +@@ -180,18 +195,37 @@ void NetworkDataTaskSoup::createRequest(ResourceRequest&& request, WasBlockingCo + soup_message_disable_feature(m_soupMessage.get(), SOUP_TYPE_COOKIE_JAR); + m_isBlockingCookies = shouldBlockCookies; + ++#if SOUP_CHECK_VERSION(2, 67, 1) + if ((m_currentRequest.url().protocolIs("https"_s) && !shouldAllowHSTSPolicySetting()) || (m_currentRequest.url().protocolIs("http"_s) && !shouldAllowHSTSProtocolUpgrade())) + soup_message_disable_feature(m_soupMessage.get(), SOUP_TYPE_HSTS_ENFORCER); +- else ++ else { ++#if USE(SOUP2) ++ g_signal_connect(soup_session_get_feature(static_cast(*m_session).soupSession(), SOUP_TYPE_HSTS_ENFORCER), "hsts-enforced", G_CALLBACK(hstsEnforced), this); ++#else + g_signal_connect(m_soupMessage.get(), "hsts-enforced", G_CALLBACK(hstsEnforced), this); ++#endif ++ } ++#endif + + // Make sure we have an Accept header for subresources; some sites want this to serve some of their subresources. + auto* requestHeaders = soup_message_get_request_headers(m_soupMessage.get()); + if (!soup_message_headers_get_one(requestHeaders, "Accept")) + soup_message_headers_append(requestHeaders, "Accept", "*/*"); + ++#if USE(SOUP2) ++ // In the case of XHR .send() and .send("") explicitly tell libsoup to send a zero content-lenght header ++ // for consistency with other UA implementations like Firefox. It's done in the backend here instead of ++ // in XHR code since in XHR CORS checking prevents us from this kind of late header manipulation. ++ if ((m_soupMessage->method == SOUP_METHOD_POST || m_soupMessage->method == SOUP_METHOD_PUT) && !m_soupMessage->request_body->length) ++ soup_message_headers_set_content_length(m_soupMessage->request_headers, 0); ++#endif ++ + g_signal_connect(m_soupMessage.get(), "got-headers", G_CALLBACK(gotHeadersCallback), this); + g_signal_connect(m_soupMessage.get(), "wrote-body-data", G_CALLBACK(wroteBodyDataCallback), this); ++#if USE(SOUP2) ++ g_signal_connect(static_cast(*m_session).soupSession(), "authenticate", G_CALLBACK(authenticateCallback), this); ++ g_signal_connect(m_soupMessage.get(), "network-event", G_CALLBACK(networkEventCallback), this); ++#else + g_signal_connect(m_soupMessage.get(), "authenticate", G_CALLBACK(authenticateCallback), this); + g_signal_connect(m_soupMessage.get(), "accept-certificate", G_CALLBACK(acceptCertificateCallback), this); + g_signal_connect(m_soupMessage.get(), "got-body", G_CALLBACK(gotBodyCallback), this); +@@ -201,6 +235,7 @@ void NetworkDataTaskSoup::createRequest(ResourceRequest&& request, WasBlockingCo + } + g_signal_connect(m_soupMessage.get(), "request-certificate", G_CALLBACK(requestCertificateCallback), this); + g_signal_connect(m_soupMessage.get(), "request-certificate-password", G_CALLBACK(requestCertificatePasswordCallback), this); ++#endif + g_signal_connect(m_soupMessage.get(), "restarted", G_CALLBACK(restartedCallback), this); + g_signal_connect(m_soupMessage.get(), "starting", G_CALLBACK(startingCallback), this); + if (m_shouldContentSniff == ContentSniffingPolicy::SniffContent) +@@ -226,14 +261,27 @@ void NetworkDataTaskSoup::clearRequest() + m_isBlockingCookies = false; + if (m_soupMessage) { + g_signal_handlers_disconnect_matched(m_soupMessage.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this); ++#if USE(SOUP2) ++ if (m_session) ++ soup_session_cancel_message(static_cast(*m_session).soupSession(), m_soupMessage.get(), SOUP_STATUS_CANCELLED); ++#else + if (m_networkLoadMetrics.fetchStart && !m_networkLoadMetrics.responseEnd) { + auto* metrics = soup_message_get_metrics(m_soupMessage.get()); + auto responseEnd = Seconds::fromMicroseconds(soup_message_metrics_get_response_end(metrics)); + m_networkLoadMetrics.responseEnd = MonotonicTime::fromRawSeconds(responseEnd.seconds()); + m_networkLoadMetrics.markComplete(); + } ++#endif + m_soupMessage = nullptr; + } ++ if (m_session) { ++#if USE(SOUP2) ++ g_signal_handlers_disconnect_matched(static_cast(*m_session).soupSession(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this); ++#if SOUP_CHECK_VERSION(2, 67, 1) ++ g_signal_handlers_disconnect_by_data(soup_session_get_feature(static_cast(*m_session).soupSession(), SOUP_TYPE_HSTS_ENFORCER), this); ++#endif ++#endif ++ } + } + + void NetworkDataTaskSoup::resume() +@@ -250,8 +298,12 @@ void NetworkDataTaskSoup::resume() + if (m_soupMessage && !m_cancellable) { + m_cancellable = adoptGRef(g_cancellable_new()); + if (m_shouldPreconnectOnly == PreconnectOnly::Yes) { ++#if !USE(SOUP2) + soup_session_preconnect_async(static_cast(*m_session).soupSession(), m_soupMessage.get(), RunLoopSourcePriority::AsyncIONetwork, m_cancellable.get(), + reinterpret_cast(preconnectCallback), protectedThis.leakRef()); ++#else ++ RELEASE_ASSERT_NOT_REACHED(); ++#endif + } else { + // We need to protect cancellable here, because soup_session_send_async uses it after emitting SoupSession::request-queued, and we + // might cancel the operation in a feature callback emitted on request-queued, for example hsts-enforced. +@@ -259,8 +311,12 @@ void NetworkDataTaskSoup::resume() + soup_session_send_async(static_cast(*m_session).soupSession(), m_soupMessage.get(), RunLoopSourcePriority::AsyncIONetwork, m_cancellable.get(), + reinterpret_cast(sendRequestCallback), new SendRequestData({ m_soupMessage, WTF::move(protectedThis) })); + if (!g_cancellable_is_cancelled(protectCancellable.get()) && !m_networkLoadMetrics.fetchStart) { ++#if USE(SOUP2) ++ m_networkLoadMetrics.fetchStart = MonotonicTime::now(); ++#else + auto* metrics = soup_message_get_metrics(m_soupMessage.get()); + m_networkLoadMetrics.fetchStart = MonotonicTime::fromRawSeconds(Seconds::fromMicroseconds(soup_message_metrics_get_fetch_start(metrics)).seconds()); ++#endif + if (!m_networkLoadMetrics.redirectStart) + m_networkLoadMetrics.redirectStart = m_networkLoadMetrics.fetchStart; + } +@@ -302,6 +358,11 @@ void NetworkDataTaskSoup::cancel() + + m_state = State::Canceling; + ++#if USE(SOUP2) ++ if (m_soupMessage) ++ soup_session_cancel_message(static_cast(*m_session).soupSession(), m_soupMessage.get(), SOUP_STATUS_CANCELLED); ++#endif ++ + g_cancellable_cancel(m_cancellable.get()); + + if (isDownload()) +@@ -396,6 +457,10 @@ void NetworkDataTaskSoup::didSendRequest(GRefPtr&& inputStream) + else + m_inputStream = WTF::move(inputStream); + ++#if USE(SOUP2) ++ m_networkLoadMetrics.responseStart = MonotonicTime::now(); ++#endif ++ + dispatchDidReceiveResponse(); + } + +@@ -440,6 +505,7 @@ void NetworkDataTaskSoup::dispatchDidReceiveResponse() + }); + } + ++#if !USE(SOUP2) + void NetworkDataTaskSoup::preconnectCallback(SoupSession* session, GAsyncResult* result, NetworkDataTaskSoup* task) + { + RefPtr protectedThis = adoptRef(task); +@@ -455,12 +521,33 @@ void NetworkDataTaskSoup::preconnectCallback(SoupSession* session, GAsyncResult* + task->clearRequest(); + task->dispatchDidCompleteWithError(resourceError); + } ++#endif + + void NetworkDataTaskSoup::dispatchDidCompleteWithError(const ResourceError& error) + { ++#if USE(SOUP2) ++ m_networkLoadMetrics.responseEnd = MonotonicTime::now(); ++ m_networkLoadMetrics.markComplete(); ++#endif ++ + m_client->didCompleteWithError(error, m_networkLoadMetrics); + } + ++#if USE(SOUP2) ++gboolean NetworkDataTaskSoup::tlsConnectionAcceptCertificateCallback(GTlsConnection* connection, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkDataTaskSoup* task) ++{ ++ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) { ++ task->clearRequest(); ++ return FALSE; ++ } ++ ++ auto* connectionMessage = g_object_get_data(G_OBJECT(connection), "wk-soup-message"); ++ if (connectionMessage != task->m_soupMessage.get()) ++ return FALSE; ++ ++ return task->acceptCertificate(certificate, errors); ++} ++#else + gboolean NetworkDataTaskSoup::acceptCertificateCallback(SoupMessage* message, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkDataTaskSoup* task) + { + if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) +@@ -470,6 +557,7 @@ gboolean NetworkDataTaskSoup::acceptCertificateCallback(SoupMessage* message, GT + + return task->acceptCertificate(certificate, errors); + } ++#endif + + bool NetworkDataTaskSoup::acceptCertificate(GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors) + { +@@ -534,6 +622,26 @@ void NetworkDataTaskSoup::applyAuthenticationToRequest(ResourceRequest& request) + m_password = String(); + } + ++#if USE(SOUP2) ++void NetworkDataTaskSoup::authenticateCallback(SoupSession* session, SoupMessage* soupMessage, SoupAuth* soupAuth, gboolean retrying, NetworkDataTaskSoup* task) ++{ ++ ASSERT(session == static_cast(*task->m_session).soupSession()); ++ ++ // We don't return early here in case the given soupMessage is different to m_soupMessage when ++ // it's proxy authentication and the request URL is HTTPS, because in that case libsoup uses a ++ // tunnel internally and the SoupMessage used for the authentication is the tunneling one. ++ // See https://bugs.webkit.org/show_bug.cgi?id=175378. ++ if (soupMessage != task->m_soupMessage.get() && (soupMessage->status_code != SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED || !task->m_currentRequest.url().protocolIs("https"_s))) ++ return; ++ ++ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) { ++ task->clearRequest(); ++ return; ++ } ++ ++ task->authenticate(AuthenticationChallenge(soupMessage, soupAuth, retrying)); ++} ++#else + gboolean NetworkDataTaskSoup::authenticateCallback(SoupMessage* soupMessage, SoupAuth* soupAuth, gboolean retrying, NetworkDataTaskSoup* task) + { + if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) { +@@ -545,6 +653,7 @@ gboolean NetworkDataTaskSoup::authenticateCallback(SoupMessage* soupMessage, Sou + task->authenticate(AuthenticationChallenge(soupMessage, soupAuth, retrying)); + return TRUE; + } ++#endif + + static inline bool isAuthenticationFailureStatusCode(int httpStatusCode) + { +@@ -564,13 +673,21 @@ void NetworkDataTaskSoup::completeAuthentication(const AuthenticationChallenge& + soup_auth_authenticate(challenge.soupAuth(), credential.user().utf8().data(), credential.password().utf8().data()); + break; + case ProtectionSpace::AuthenticationScheme::ClientCertificatePINRequested: { ++#if USE(SOUP2) ++ ASSERT_NOT_REACHED(); ++#else + CString password = credential.password().utf8(); + g_tls_password_set_value(challenge.tlsPassword(), reinterpret_cast(password.data()), password.length()); + soup_message_tls_client_certificate_password_request_complete(m_soupMessage.get()); ++#endif + break; + } + case ProtectionSpace::AuthenticationScheme::ClientCertificateRequested: ++#if USE(SOUP2) ++ ASSERT_NOT_REACHED(); ++#else + soup_message_set_tls_client_certificate(m_soupMessage.get(), credential.certificate()); ++#endif + break; + case ProtectionSpace::AuthenticationScheme::ServerTrustEvaluationRequested: + case ProtectionSpace::AuthenticationScheme::Unknown: +@@ -591,10 +708,18 @@ void NetworkDataTaskSoup::cancelAuthentication(const AuthenticationChallenge& ch + soup_auth_cancel(challenge.soupAuth()); + break; + case ProtectionSpace::AuthenticationScheme::ClientCertificatePINRequested: ++#if USE(SOUP2) ++ ASSERT_NOT_REACHED(); ++#else + soup_message_tls_client_certificate_password_request_complete(m_soupMessage.get()); ++#endif + break; + case ProtectionSpace::AuthenticationScheme::ClientCertificateRequested: ++#if USE(SOUP2) ++ ASSERT_NOT_REACHED(); ++#else + soup_message_set_tls_client_certificate(m_soupMessage.get(), nullptr); ++#endif + break; + case ProtectionSpace::AuthenticationScheme::ServerTrustEvaluationRequested: + case ProtectionSpace::AuthenticationScheme::Unknown: +@@ -629,6 +754,10 @@ void NetworkDataTaskSoup::authenticate(AuthenticationChallenge&& challenge) + } + } + ++#if USE(SOUP2) ++ soup_session_pause_message(static_cast(*m_session).soupSession(), challenge.soupMessage()); ++#endif ++ + // We could also do this before we even start the request, but that would be at the expense + // of all request latency, versus a one-time latency for the small subset of requests that + // use HTTP authentication. In the end, this doesn't matter much, because persistent credentials +@@ -683,6 +812,10 @@ void NetworkDataTaskSoup::continueAuthenticate(AuthenticationChallenge&& challen + completeAuthentication(challenge, credential); + } else + cancelAuthentication(challenge); ++ ++#if USE(SOUP2) ++ soup_session_unpause_message(static_cast(*m_session).soupSession(), challenge.soupMessage()); ++#endif + }); + } + +@@ -769,7 +902,11 @@ void NetworkDataTaskSoup::continueHTTPRedirection() + + static const unsigned maxRedirects = 20; + if (m_currentRequest.redirectCount() > maxRedirects) { ++#if USE(SOUP2) ++ didFail(ResourceError::transportError(m_currentRequest.url(), SOUP_STATUS_TOO_MANY_REDIRECTS, "Too many redirects"_s)); ++#else + didFail(ResourceError(String::fromLatin1(g_quark_to_string(SOUP_SESSION_ERROR)), SOUP_SESSION_ERROR_TOO_MANY_REDIRECTS, m_currentRequest.url(), String::fromUTF8("Too many redirects"))); ++#endif + return; + } + +@@ -847,8 +984,10 @@ void NetworkDataTaskSoup::continueHTTPRedirection() + auto request = newRequest; + if (request.url().protocolIsInHTTPFamily()) { + m_networkLoadMetrics.fetchStart = { }; ++#if !USE(SOUP2) + m_networkLoadMetrics.responseEnd = { }; + m_networkLoadMetrics.complete = false; ++#endif + applyAuthenticationToRequest(request); + + if (!request.hasHTTPHeaderField(HTTPHeaderName::UserAgent)) +@@ -1022,13 +1161,16 @@ static AtomString soupHTTPVersionToString(SoupHTTPVersion version) + return "http/1.0"_s; + case SOUP_HTTP_1_1: + return "http/1.1"_s; ++#if SOUP_CHECK_VERSION(2, 99, 3) + case SOUP_HTTP_2_0: + return "h2"_s; ++#endif + } + + return { }; + } + ++#if !USE(SOUP2) + static String tlsProtocolVersionToString(GTlsProtocolVersion version) + { + switch (version) { +@@ -1052,6 +1194,7 @@ static String tlsProtocolVersionToString(GTlsProtocolVersion version) + + return { }; + } ++#endif + + WebCore::AdditionalNetworkLoadMetricsForWebInspector& NetworkDataTaskSoup::additionalNetworkLoadMetricsForWebInspector() + { +@@ -1060,6 +1203,15 @@ WebCore::AdditionalNetworkLoadMetricsForWebInspector& NetworkDataTaskSoup::addit + return *m_networkLoadMetrics.additionalNetworkLoadMetricsForWebInspector; + } + ++#if USE(SOUP2) ++static void addHeaderSizes(const char *name, const char *value, gpointer pointer) ++{ ++ uint64_t* size = static_cast(pointer); ++ // Each header is formatted as ": \r\n" ++ *size += strlen(name) + strlen(value) + 4; ++} ++#endif ++ + void NetworkDataTaskSoup::didGetHeaders() + { + // We are a bit more conservative with the persistent credential storage than the session store, +@@ -1073,6 +1225,7 @@ void NetworkDataTaskSoup::didGetHeaders() + m_credentialForPersistentStorage = Credential(); + } + ++#if !USE(SOUP2) + auto* metrics = soup_message_get_metrics(m_soupMessage.get()); + auto responseStart = Seconds::fromMicroseconds(soup_message_metrics_get_response_start(metrics)); + auto responseStartTime = MonotonicTime::fromRawSeconds(responseStart.seconds()); +@@ -1090,6 +1243,7 @@ void NetworkDataTaskSoup::didGetHeaders() + } + + m_networkLoadMetrics.responseStart = responseStartTime; ++#endif + + // Soup adds more headers to the request after starting signal is emitted, and got-headers + // is the first one we receive after starting, so we use it also to get information about the +@@ -1107,6 +1261,7 @@ void NetworkDataTaskSoup::didGetHeaders() + additionalMetrics.requestHeaders = WTF::move(requestHeaders); + + additionalMetrics.priority = toNetworkLoadPriority(soup_message_get_priority(m_soupMessage.get())); ++#if !USE(SOUP2) + additionalMetrics.connectionIdentifier = String::number(soup_message_get_connection_id(m_soupMessage.get())); + auto* address = soup_message_get_remote_address(m_soupMessage.get()); + if (G_IS_INET_SOCKET_ADDRESS(address)) { +@@ -1116,11 +1271,27 @@ void NetworkDataTaskSoup::didGetHeaders() + additionalMetrics.tlsProtocol = tlsProtocolVersionToString(soup_message_get_tls_protocol_version(m_soupMessage.get())); + additionalMetrics.tlsCipher = String::fromUTF8(soup_message_get_tls_ciphersuite_name(m_soupMessage.get())); + additionalMetrics.responseHeaderBytesReceived = soup_message_metrics_get_response_header_bytes_received(metrics); ++#else ++ { ++ auto* requestHeaders = soup_message_get_request_headers(m_soupMessage.get()); ++ uint64_t requestHeadersSize = 0; ++ soup_message_headers_foreach(requestHeaders, addHeaderSizes, &requestHeadersSize); ++ additionalMetrics.requestHeaderBytesSent = requestHeadersSize; ++ } ++ ++ { ++ auto* responseHeaders = soup_message_get_response_headers(m_soupMessage.get()); ++ uint64_t responseHeadersSize = 0; ++ soup_message_headers_foreach(responseHeaders, addHeaderSizes, &responseHeadersSize); ++ additionalMetrics.responseHeaderBytesReceived = responseHeadersSize; ++ } ++#endif + } + + m_networkLoadMetrics.protocol = soupHTTPVersionToString(soup_message_get_http_version(m_soupMessage.get())); + } + ++#if !USE(SOUP2) + void NetworkDataTaskSoup::wroteHeadersCallback(SoupMessage* soupMessage, NetworkDataTaskSoup* task) + { + if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) { +@@ -1176,22 +1347,35 @@ gboolean NetworkDataTaskSoup::requestCertificatePasswordCallback(SoupMessage* so + task->authenticate(AuthenticationChallenge(soupMessage, tlsPassword)); + return TRUE; + } ++#endif + ++#if USE(SOUP2) ++void NetworkDataTaskSoup::wroteBodyDataCallback(SoupMessage* soupMessage, SoupBuffer* buffer, NetworkDataTaskSoup* task) ++#else + void NetworkDataTaskSoup::wroteBodyDataCallback(SoupMessage* soupMessage, unsigned length, NetworkDataTaskSoup* task) ++#endif + { + if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) { + task->clearRequest(); + return; + } + ASSERT(task->m_soupMessage.get() == soupMessage); ++#if USE(SOUP2) ++ task->didWriteBodyData(buffer->length); ++#else + task->didWriteBodyData(length); ++#endif + } + + void NetworkDataTaskSoup::didWriteBodyData(uint64_t bytesSent) + { + RefPtr protectedThis(this); + m_bodyDataTotalBytesSent += bytesSent; ++#if USE(SOUP2) ++ m_client->didSendData(m_bodyDataTotalBytesSent, m_soupMessage->request_body->length); ++#else + m_client->didSendData(m_bodyDataTotalBytesSent, soup_message_headers_get_content_length(soup_message_get_request_headers(m_soupMessage.get()))); ++#endif + } + + void NetworkDataTaskSoup::download() +@@ -1334,6 +1518,62 @@ void NetworkDataTaskSoup::didFail(const ResourceError& error) + dispatchDidCompleteWithError(error); + } + ++#if USE(SOUP2) ++void NetworkDataTaskSoup::networkEventCallback(SoupMessage* soupMessage, GSocketClientEvent event, GIOStream* stream, NetworkDataTaskSoup* task) ++{ ++ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) ++ return; ++ ++ ASSERT(task->m_soupMessage.get() == soupMessage); ++ task->networkEvent(event, stream); ++} ++ ++void NetworkDataTaskSoup::networkEvent(GSocketClientEvent event, GIOStream* stream) ++{ ++ auto time = MonotonicTime::now(); ++ switch (event) { ++ case G_SOCKET_CLIENT_RESOLVING: ++ m_networkLoadMetrics.domainLookupStart = time; ++ break; ++ case G_SOCKET_CLIENT_RESOLVED: ++ m_networkLoadMetrics.domainLookupEnd = time; ++ break; ++ case G_SOCKET_CLIENT_CONNECTING: ++ m_networkLoadMetrics.connectStart = time; ++ break; ++ case G_SOCKET_CLIENT_CONNECTED: ++ if (shouldCaptureExtraNetworkLoadMetrics() && G_IS_SOCKET_CONNECTION(stream)) { ++ GRefPtr address = adoptGRef(g_socket_connection_get_remote_address(G_SOCKET_CONNECTION(stream), nullptr)); ++ if (G_IS_INET_SOCKET_ADDRESS(address.get())) { ++ GUniquePtr ipAddress(g_inet_address_to_string(g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(address.get())))); ++ additionalNetworkLoadMetricsForWebInspector().remoteAddress = makeString(unsafeSpan(ipAddress.get()), ':', g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(address.get()))); ++ } ++ } ++ // Web Timing considers that connection time involves dns, proxy & TLS negotiation... ++ // so we better pick G_SOCKET_CLIENT_COMPLETE for connectEnd. ++ break; ++ case G_SOCKET_CLIENT_PROXY_NEGOTIATING: ++ break; ++ case G_SOCKET_CLIENT_PROXY_NEGOTIATED: ++ break; ++ case G_SOCKET_CLIENT_TLS_HANDSHAKING: ++ m_networkLoadMetrics.secureConnectionStart = time; ++ RELEASE_ASSERT(G_IS_TLS_CONNECTION(stream)); ++ g_object_set_data(G_OBJECT(stream), "wk-soup-message", m_soupMessage.get()); ++ g_signal_connect(stream, "accept-certificate", G_CALLBACK(tlsConnectionAcceptCertificateCallback), this); ++ break; ++ case G_SOCKET_CLIENT_TLS_HANDSHAKED: ++ break; ++ case G_SOCKET_CLIENT_COMPLETE: ++ m_networkLoadMetrics.connectEnd = time; ++ break; ++ default: ++ ASSERT_NOT_REACHED(); ++ break; ++ } ++} ++#endif ++ + void NetworkDataTaskSoup::startingCallback(SoupMessage* soupMessage, NetworkDataTaskSoup* task) + { + if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) +@@ -1343,6 +1583,8 @@ void NetworkDataTaskSoup::startingCallback(SoupMessage* soupMessage, NetworkData + task->didStartRequest(); + } + ++#if SOUP_CHECK_VERSION(2, 67, 1) ++ + bool NetworkDataTaskSoup::shouldAllowHSTSPolicySetting() const + { + // Follow Apple's HSTS abuse mitigation 1: +@@ -1366,7 +1608,11 @@ void NetworkDataTaskSoup::protocolUpgradedViaHSTS(SoupMessage* soupMessage) + continueHTTPRedirection(); + } + ++#if USE(SOUP2) ++void NetworkDataTaskSoup::hstsEnforced(SoupHSTSEnforcer*, SoupMessage* soupMessage, NetworkDataTaskSoup* task) ++#else + void NetworkDataTaskSoup::hstsEnforced(SoupMessage* soupMessage, NetworkDataTaskSoup* task) ++#endif + { + if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) { + task->clearRequest(); +@@ -1377,8 +1623,15 @@ void NetworkDataTaskSoup::hstsEnforced(SoupMessage* soupMessage, NetworkDataTask + task->protocolUpgradedViaHSTS(soupMessage); + } + ++#endif ++ + void NetworkDataTaskSoup::didStartRequest() + { ++#if USE(SOUP2) ++ m_networkLoadMetrics.requestStart = MonotonicTime::now(); ++ if (!m_networkLoadMetrics.secureConnectionStart && m_currentRequest.url().protocolIs("https"_s)) ++ m_networkLoadMetrics.secureConnectionStart = WebCore::reusedTLSConnectionSentinel; ++#else + auto* metrics = soup_message_get_metrics(m_soupMessage.get()); + auto domainLookupStart = Seconds::fromMicroseconds(soup_message_metrics_get_dns_start(metrics)); + auto domainLookupEnd = Seconds::fromMicroseconds(soup_message_metrics_get_dns_end(metrics)); +@@ -1396,6 +1649,7 @@ void NetworkDataTaskSoup::didStartRequest() + else + m_networkLoadMetrics.secureConnectionStart = MonotonicTime::fromRawSeconds(secureConnectionStart.seconds()); + m_networkLoadMetrics.requestStart = MonotonicTime::fromRawSeconds(requestStart.seconds()); ++#endif + } + + void NetworkDataTaskSoup::restartedCallback(SoupMessage* soupMessage, NetworkDataTaskSoup* task) +@@ -1412,9 +1666,13 @@ void NetworkDataTaskSoup::restartedCallback(SoupMessage* soupMessage, NetworkDat + void NetworkDataTaskSoup::didRestart() + { + m_networkLoadMetrics = NetworkLoadMetrics::emptyMetrics(); ++#if USE(SOUP2) ++ m_networkLoadMetrics.fetchStart = MonotonicTime::now(); ++#else + auto* metrics = soup_message_get_metrics(m_soupMessage.get()); + m_networkLoadMetrics.fetchStart = MonotonicTime::fromRawSeconds(Seconds::fromMicroseconds(soup_message_metrics_get_fetch_start(metrics)).seconds()); + m_currentRequest.updateSoupMessageBody(m_soupMessage.get(), m_session->blobRegistry()); ++#endif + m_networkLoadMetrics.redirectStart = m_networkLoadMetrics.fetchStart; + } + +diff --git a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h +index d88360a343c0..3f20fc786cd1 100644 +--- a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h ++++ b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h +@@ -79,9 +79,15 @@ private: + void dispatchDidReceiveResponse(); + void dispatchDidCompleteWithError(const WebCore::ResourceError&); + ++#if !USE(SOUP2) + static void preconnectCallback(SoupSession*, GAsyncResult*, NetworkDataTaskSoup*); ++#endif + ++#if USE(SOUP2) ++ static gboolean tlsConnectionAcceptCertificateCallback(GTlsConnection*, GTlsCertificate*, GTlsCertificateFlags, NetworkDataTaskSoup*); ++#else + static gboolean acceptCertificateCallback(SoupMessage*, GTlsCertificate*, GTlsCertificateFlags, NetworkDataTaskSoup*); ++#endif + bool acceptCertificate(GTlsCertificate*, GTlsCertificateFlags); + + static void didSniffContentCallback(SoupMessage*, const char* contentType, GHashTable* parameters, NetworkDataTaskSoup*); +@@ -89,7 +95,11 @@ private: + + bool persistentCredentialStorageEnabled() const; + void applyAuthenticationToRequest(WebCore::ResourceRequest&); ++#if USE(SOUP2) ++ static void authenticateCallback(SoupSession*, SoupMessage*, SoupAuth*, gboolean retrying, NetworkDataTaskSoup*); ++#else + static gboolean authenticateCallback(SoupMessage*, SoupAuth*, gboolean retrying, NetworkDataTaskSoup*); ++#endif + void authenticate(WebCore::AuthenticationChallenge&&); + void continueAuthenticate(WebCore::AuthenticationChallenge&&); + void completeAuthentication(const WebCore::AuthenticationChallenge&, const WebCore::Credential&); +@@ -114,14 +124,20 @@ private: + static void gotHeadersCallback(SoupMessage*, NetworkDataTaskSoup*); + void didGetHeaders(); + ++#if USE(SOUP2) ++ static void wroteBodyDataCallback(SoupMessage*, SoupBuffer*, NetworkDataTaskSoup*); ++#else + static void wroteBodyDataCallback(SoupMessage*, unsigned, NetworkDataTaskSoup*); ++#endif + void didWriteBodyData(uint64_t bytesSent); + ++#if !USE(SOUP2) + static void wroteHeadersCallback(SoupMessage*, NetworkDataTaskSoup*); + static void wroteBodyCallback(SoupMessage*, NetworkDataTaskSoup*); + static void gotBodyCallback(SoupMessage*, NetworkDataTaskSoup*); + static gboolean requestCertificateCallback(SoupMessage*, GTlsClientConnection*, NetworkDataTaskSoup*); + static gboolean requestCertificatePasswordCallback(SoupMessage*, GTlsPassword*, NetworkDataTaskSoup*); ++#endif + + void download(); + static void writeDownloadCallback(GOutputStream*, GAsyncResult*, NetworkDataTaskSoup*); +@@ -133,11 +149,26 @@ private: + + void didFail(const WebCore::ResourceError&); + ++#if USE(SOUP2) ++ static void networkEventCallback(SoupMessage*, GSocketClientEvent, GIOStream*, NetworkDataTaskSoup*); ++ void networkEvent(GSocketClientEvent, GIOStream*); ++#endif ++ ++#if SOUP_CHECK_VERSION(2, 49, 91) + static void startingCallback(SoupMessage*, NetworkDataTaskSoup*); ++#else ++ static void requestStartedCallback(SoupSession*, SoupMessage*, SoupSocket*, NetworkDataTaskSoup*); ++#endif ++#if SOUP_CHECK_VERSION(2, 67, 1) + bool shouldAllowHSTSPolicySetting() const; + bool shouldAllowHSTSProtocolUpgrade() const; + void protocolUpgradedViaHSTS(SoupMessage*); ++#if USE(SOUP2) ++ static void hstsEnforced(SoupHSTSEnforcer*, SoupMessage*, NetworkDataTaskSoup*); ++#else + static void hstsEnforced(SoupMessage*, NetworkDataTaskSoup*); ++#endif ++#endif + void didStartRequest(); + static void restartedCallback(SoupMessage*, NetworkDataTaskSoup*); + void didRestart(); +diff --git a/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp +index fffd039135be..4b9cc36b7f65 100644 +--- a/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp ++++ b/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp +@@ -95,9 +95,31 @@ void NetworkSessionSoup::setCookiePersistentStorage(const String& storagePath, S + + void NetworkSessionSoup::clearCredentials(WallTime) + { ++#if SOUP_CHECK_VERSION(2, 57, 1) + soup_auth_manager_clear_cached_credentials(SOUP_AUTH_MANAGER(soup_session_get_feature(soupSession(), SOUP_TYPE_AUTH_MANAGER))); ++#endif + } + ++#if USE(SOUP2) ++static gboolean webSocketAcceptCertificateCallback(GTlsConnection* connection, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkSessionSoup* session) ++{ ++ if (DeprecatedGlobalSettings::allowsAnySSLCertificate()) ++ return TRUE; ++ ++ auto* soupMessage = static_cast(g_object_get_data(G_OBJECT(connection), "wk-soup-message")); ++ return !session->soupNetworkSession().checkTLSErrors(soupURIToURL(soup_message_get_uri(soupMessage)), certificate, errors); ++} ++ ++static void webSocketMessageNetworkEventCallback(SoupMessage* soupMessage, GSocketClientEvent event, GIOStream* connection, NetworkSessionSoup* session) ++{ ++ if (event != G_SOCKET_CLIENT_TLS_HANDSHAKING) ++ return; ++ ++ g_object_set_data(G_OBJECT(connection), "wk-soup-message", soupMessage); ++ g_signal_connect(connection, "accept-certificate", G_CALLBACK(webSocketAcceptCertificateCallback), session); ++} ++#endif ++ + RefPtr NetworkSessionSoup::createWebSocketTask(WebPageProxyIdentifier webPageProxyID, std::optional frameID, std::optional pageID, NetworkSocketChannel& channel, const ResourceRequest& request, const String& protocol, const ClientOrigin&, bool, bool, OptionSet, StoredCredentialsPolicy) + { + GRefPtr soupMessage = request.createSoupMessage(blobRegistry()); +@@ -105,12 +127,16 @@ RefPtr NetworkSessionSoup::createWebSocketTask(WebPageProxyIdenti + return nullptr; + + if (request.url().protocolIs("wss"_s)) { ++#if USE(SOUP2) ++ g_signal_connect(soupMessage.get(), "network-event", G_CALLBACK(webSocketMessageNetworkEventCallback), this); ++#else + g_signal_connect(soupMessage.get(), "accept-certificate", G_CALLBACK(+[](SoupMessage* message, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkSessionSoup* session) -> gboolean { + if (DeprecatedGlobalSettings::allowsAnySSLCertificate()) + return TRUE; + + return !session->soupNetworkSession().checkTLSErrors(soup_message_get_uri(message), certificate, errors); + }), this); ++#endif + } + + bool shouldBlockCookies = checkedNetworkStorageSession()->shouldBlockCookies(request, frameID, pageID, networkProcess().shouldRelaxThirdPartyCookieBlockingForPage(webPageProxyID), WebCore::IsKnownCrossSiteTracker::No); +diff --git a/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.cpp b/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.cpp +index 667a9ab1a197..8917771f4e55 100644 +--- a/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.cpp ++++ b/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.cpp +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -43,10 +44,17 @@ + + namespace WebKit { + +-static inline bool isConnectionError(GError* error) ++static inline bool isConnectionError(GError* error, SoupMessage* message) + { ++#if USE(SOUP2) ++ return g_error_matches(error, SOUP_WEBSOCKET_ERROR, SOUP_WEBSOCKET_ERROR_NOT_WEBSOCKET) ++ && message ++ && (message->status_code == SOUP_STATUS_CANT_CONNECT || message->status_code == SOUP_STATUS_CANT_CONNECT_PROXY); ++#else ++ UNUSED_PARAM(message); + // If not a SOUP_WEBSOCKET_ERROR_NOT_WEBSOCKET, then it's a connection error. + return error && !g_error_matches(error, SOUP_WEBSOCKET_ERROR, SOUP_WEBSOCKET_ERROR_NOT_WEBSOCKET); ++#endif + } + + WTF_MAKE_TZONE_ALLOCATED_IMPL(WebSocketTask); +@@ -73,6 +81,12 @@ WebSocketTask::WebSocketTask(NetworkSocketChannel& channel, const WebCore::Resou + protocolsSpan[i++] = g_strdup(subprotocol.trim(isASCIIWhitespaceWithoutFF).utf8().data()); + } + ++#if USE(SOUP2) ++ // Ensure a new connection is used for WebSockets. ++ // FIXME: this is done by libsoup since 2.69.1 and 2.68.4, so it can be removed when bumping the libsoup requirement. ++ // See https://bugs.webkit.org/show_bug.cgi?id=203404 ++ soup_message_set_flags(msg, static_cast(soup_message_get_flags(msg) | SOUP_MESSAGE_NEW_CONNECTION)); ++#else + { + // No need to subscribe to the "request-certificate" signal, just set the client certificate upfront. + auto protectionSpace = WebCore::AuthenticationChallenge::protectionSpaceForClientCertificate(WebCore::soupURIToURL(soup_message_get_uri(msg))); +@@ -87,6 +101,7 @@ WebSocketTask::WebSocketTask(NetworkSocketChannel& channel, const WebCore::Resou + soup_message_tls_client_certificate_password_request_complete(msg); + return TRUE; + }), this); ++#endif + + soup_session_websocket_connect_async(session, msg, nullptr, protocols.get(), RunLoopSourcePriority::AsyncIONetwork, m_cancellable.get(), + [] (GObject* session, GAsyncResult* result, gpointer userData) { +@@ -95,7 +110,7 @@ WebSocketTask::WebSocketTask(NetworkSocketChannel& channel, const WebCore::Resou + if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + auto* task = static_cast(userData); +- if (isConnectionError(error.get())) { ++ if (isConnectionError(error.get(), task->m_handshakeMessage.get())) { + task->m_delayErrorMessage = String::fromUTF8(error->message); + task->m_delayFailTimer.startOneShot(NetworkProcess::randomClosedPortDelay()); + return; +@@ -127,6 +142,7 @@ RefPtr WebSocketTask::protectedChannel() const + + String WebSocketTask::acceptedExtensions() const + { ++#if SOUP_CHECK_VERSION(2, 67, 90) + StringBuilder result; + GList* extensions = soup_websocket_connection_get_extensions(m_connection.get()); + for (auto* it = extensions; it; it = g_list_next(it)) { +@@ -141,15 +157,20 @@ String WebSocketTask::acceptedExtensions() const + result.append(String::fromUTF8(params.get())); + } + return result.toStringPreserveCapacity(); ++#else ++ return { }; ++#endif + } + + void WebSocketTask::didConnect(GRefPtr&& connection) + { + m_connection = WTF::move(connection); + ++#if SOUP_CHECK_VERSION(2, 56, 0) + // Use the same maximum payload length as WebKit internal implementation for backwards compatibility. + static const uint64_t maxPayloadLength = UINT64_C(0x7FFFFFFFFFFFFFFF); + soup_websocket_connection_set_max_incoming_payload_size(m_connection.get(), maxPayloadLength); ++#endif + + g_signal_connect_swapped(m_connection.get(), "message", reinterpret_cast(didReceiveMessageCallback), this); + g_signal_connect_swapped(m_connection.get(), "error", reinterpret_cast(didReceiveErrorCallback), this); +@@ -234,9 +255,13 @@ void WebSocketTask::didClose(unsigned short code, const String& reason) + void WebSocketTask::sendString(std::span utf8, CompletionHandler&& callback) + { + if (m_connection && soup_websocket_connection_get_state(m_connection.get()) == SOUP_WEBSOCKET_STATE_OPEN) { ++#if SOUP_CHECK_VERSION(2, 67, 3) + // Soup is going to copy the data immediately, so we can use g_bytes_new_static() here to avoid more data copies. + GRefPtr bytes = adoptGRef(g_bytes_new_static(utf8.data(), utf8.size())); + soup_websocket_connection_send_message(m_connection.get(), SOUP_WEBSOCKET_DATA_TEXT, bytes.get()); ++#else ++ soup_websocket_connection_send_text(m_connection.get(), CString(utf8).data()); ++#endif + } + callback(); + } +@@ -259,8 +284,10 @@ void WebSocketTask::close(int32_t code, const String& reason) + return; + } + ++#if SOUP_CHECK_VERSION(2, 67, 90) + if (code == WebCore::ThreadableWebSocketChannel::CloseEventCodeNotSpecified) + code = SOUP_WEBSOCKET_CLOSE_NO_STATUS; ++#endif + + if (soup_websocket_connection_get_state(m_connection.get()) == SOUP_WEBSOCKET_STATE_OPEN) + soup_websocket_connection_close(m_connection.get(), code, reason.utf8().data()); +diff --git a/Source/WebKit/PlatformGTK.cmake b/Source/WebKit/PlatformGTK.cmake +index 9c2217af158e..47ffc9626f0d 100644 +--- a/Source/WebKit/PlatformGTK.cmake ++++ b/Source/WebKit/PlatformGTK.cmake +@@ -615,7 +615,7 @@ GI_INTROSPECT(WebKit${WEBKITGTK_API_INFIX} ${WEBKITGTK_API_VERSION} webkit${WEBK + DEPENDENCIES + JavaScriptCore + Gtk-${GTK_API_VERSION}.0:${GTK_PKGCONFIG_PACKAGE} +- Soup-3.0:libsoup-3.0 ++ Soup-${SOUP_API_VERSION}:libsoup-${SOUP_API_VERSION} + SOURCES + ${WebKitGTK_INSTALLED_HEADERS} + ${WEBKITGTK_SOURCES_FOR_INTROSPECTION} +@@ -651,7 +651,7 @@ GI_INTROSPECT(${WEBKITGTK_WEB_PROCESS_EXTENSION_API_NAME} ${WEBKITGTK_API_VERSIO + DEPENDENCIES + JavaScriptCore + Gtk-${GTK_API_VERSION}.0:${GTK_PKGCONFIG_PACKAGE} +- Soup-3.0:libsoup-3.0 ++ Soup-${SOUP_API_VERSION}:libsoup-${SOUP_API_VERSION} + SOURCES + ${WebKitDOM_SOURCES_FOR_INTROSPECTION} + ${WebKitWebProcessExtension_INSTALLED_HEADERS} +diff --git a/Source/WebKit/UIProcess/Inspector/glib/RemoteInspectorHTTPServer.cpp b/Source/WebKit/UIProcess/Inspector/glib/RemoteInspectorHTTPServer.cpp +index 75b2e7373b5d..601f58788871 100644 +--- a/Source/WebKit/UIProcess/Inspector/glib/RemoteInspectorHTTPServer.cpp ++++ b/Source/WebKit/UIProcess/Inspector/glib/RemoteInspectorHTTPServer.cpp +@@ -29,6 +29,7 @@ + #if ENABLE(REMOTE_INSPECTOR) + + #include "RemoteInspectorClient.h" ++#include + #include + #include + #include +@@ -56,14 +57,22 @@ bool RemoteInspectorHTTPServer::start(GRefPtr&& socketAddress, u + } + + soup_server_add_handler(m_server.get(), nullptr, ++#if USE(SOUP2) ++ [](SoupServer*, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer userData) { ++#else + [](SoupServer*, SoupServerMessage* message, const char* path, GHashTable*, gpointer userData) { ++#endif + auto& httpServer = *static_cast(userData); + auto status = httpServer.handleRequest(path, soup_server_message_get_response_headers(message), soup_server_message_get_response_body(message)); + soup_server_message_set_status(message, status, nullptr); + }, this, nullptr); + + soup_server_add_websocket_handler(m_server.get(), "/socket", nullptr, nullptr, ++#if USE(SOUP2) ++ [](SoupServer*, SoupWebsocketConnection* connection, const char* path, SoupClientContext*, gpointer userData) { ++#else + [](SoupServer*, SoupServerMessage*, const char* path, SoupWebsocketConnection* connection, gpointer userData) { ++#endif + auto& httpServer = *static_cast(userData); + httpServer.handleWebSocket(path, connection); + }, this, nullptr); +@@ -146,8 +155,12 @@ void RemoteInspectorHTTPServer::sendMessageToFrontend(uint64_t connectionID, uin + + auto utf8 = message.utf8(); + // Soup is going to copy the data immediately, so we can use g_bytes_new_static() here to avoid more data copies. ++#if SOUP_CHECK_VERSION(2, 67, 3) + GRefPtr bytes = adoptGRef(g_bytes_new_static(utf8.data(), utf8.length())); + soup_websocket_connection_send_message(webSocketConnection, SOUP_WEBSOCKET_DATA_TEXT, bytes.get()); ++#else ++ soup_websocket_connection_send_text(webSocketConnection, CString(utf8).data()); ++#endif + } + + void RemoteInspectorHTTPServer::targetDidClose(uint64_t connectionID, uint64_t targetID) +diff --git a/Source/WebKit/gtk/webkitgtk-web-process-extension.pc.in b/Source/WebKit/gtk/webkitgtk-web-process-extension.pc.in +index f1d7cabb175f..9d066b5f484f 100644 +--- a/Source/WebKit/gtk/webkitgtk-web-process-extension.pc.in ++++ b/Source/WebKit/gtk/webkitgtk-web-process-extension.pc.in +@@ -8,6 +8,6 @@ Name: WebKitGTK web process extensions + Description: Web content engine for GTK - web process extensions + URL: https://webkitgtk.org + Version: @PROJECT_VERSION@ +-Requires: glib-2.0 @GTK_PC_NAME@ libsoup-3.0 javascriptcoregtk-@WEBKITGTK_API_VERSION@ ++Requires: glib-2.0 @GTK_PC_NAME@ libsoup-2.4 javascriptcoregtk-@WEBKITGTK_API_VERSION@ + Libs: -L${libdir} -lwebkit@WEBKITGTK_API_INFIX@gtk-@WEBKITGTK_API_VERSION@ + Cflags: -I${includedir}/webkitgtk-@WEBKITGTK_API_VERSION@ +diff --git a/Source/WebKit/gtk/webkitgtk.pc.in b/Source/WebKit/gtk/webkitgtk.pc.in +index db0fb001f327..8d7c3e9d086d 100644 +--- a/Source/WebKit/gtk/webkitgtk.pc.in ++++ b/Source/WebKit/gtk/webkitgtk.pc.in +@@ -8,6 +8,6 @@ Name: WebKitGTK + Description: Web content engine for GTK + URL: https://webkitgtk.org + Version: @PROJECT_VERSION@ +-Requires: glib-2.0 @GTK_PC_NAME@ libsoup-3.0 javascriptcoregtk-@WEBKITGTK_API_VERSION@ ++Requires: glib-2.0 @GTK_PC_NAME@ libsoup-2.4 javascriptcoregtk-@WEBKITGTK_API_VERSION@ + Libs: -L${libdir} -lwebkit@WEBKITGTK_API_INFIX@gtk-@WEBKITGTK_API_VERSION@ + Cflags: -I${includedir}/webkitgtk-@WEBKITGTK_API_VERSION@ +diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake +index 6d5f17debcc7..a856d1ffd945 100644 +--- a/Source/cmake/OptionsGTK.cmake ++++ b/Source/cmake/OptionsGTK.cmake +@@ -11,7 +11,6 @@ set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string") + find_package(GLib 2.56.0 REQUIRED COMPONENTS GioUnix Thread Module) + find_package(Cairo 1.14.0 REQUIRED) + find_package(LibGcrypt 1.7.0 REQUIRED) +-find_package(Soup3 3.0.0 REQUIRED) + find_package(Tasn1 REQUIRED) + find_package(HarfBuzz 1.7.5 REQUIRED COMPONENTS ICU) + find_package(ICU 70.1 REQUIRED COMPONENTS data i18n uc) +@@ -58,6 +57,7 @@ WEBKIT_OPTION_DEFINE(USE_LIBDRM "Whether to enable usage of libdrm." PUBLIC ON) + WEBKIT_OPTION_DEFINE(USE_LIBHYPHEN "Whether to enable the default automatic hyphenation implementation." PUBLIC ON) + WEBKIT_OPTION_DEFINE(USE_LIBSECRET "Whether to enable the persistent credential storage using libsecret." PUBLIC ON) + WEBKIT_OPTION_DEFINE(USE_SKIA_OPENTYPE_SVG "Whether to use the Skia built-in support for OpenType SVG fonts." PUBLIC ON) ++WEBKIT_OPTION_DEFINE(USE_SOUP2 "Whether to enable usage of Soup 2 instead of Soup 3." PUBLIC OFF) + WEBKIT_OPTION_DEFINE(USE_SYSTEM_SYSPROF_CAPTURE "Whether to use a system-provided libsysprof-capture" PUBLIC ON) + WEBKIT_OPTION_DEFINE(ENABLE_JSC_RESTRICTED_OPTIONS_BY_DEFAULT "Whether to enable dangerous development options in JSC by default." PRIVATE OFF) + +@@ -65,6 +65,8 @@ WEBKIT_OPTION_DEPEND(ENABLE_DOCUMENTATION ENABLE_INTROSPECTION) + WEBKIT_OPTION_DEPEND(USE_GBM USE_LIBDRM) + WEBKIT_OPTION_DEPEND(USE_SKIA_OPENTYPE_SVG USE_SKIA) + ++WEBKIT_OPTION_CONFLICT(USE_GTK4 USE_SOUP2) ++ + # Private options specific to the GTK port. Changing these options is + # completely unsupported. They are intended for use only by WebKit developers. + WEBKIT_OPTION_DEFINE(USE_SPIEL "Whether to enable usage of LibSpiel for speech synthesis." PRIVATE OFF) +@@ -181,10 +183,32 @@ if (ENABLE_WAYLAND_TARGET AND NOT ${GTK_SUPPORTS_WAYLAND}) + set(ENABLE_WAYLAND_TARGET OFF) + endif () + ++if (USE_SOUP2) ++ set(SOUP_MINIMUM_VERSION 2.54.0) ++ set(SOUP_API_VERSION 2.4) ++else () ++ set(SOUP_MINIMUM_VERSION 3.0.0) ++ set(SOUP_API_VERSION 3.0) ++ set(ENABLE_SERVER_PRECONNECT ON) ++endif () ++find_package(LibSoup ${SOUP_MINIMUM_VERSION}) ++ ++if (NOT LibSoup_FOUND) ++if (USE_SOUP2) ++ message(FATAL_ERROR "libsoup is required.") ++else () ++ message(FATAL_ERROR "libsoup 3 is required. Enable USE_SOUP2 to use libsoup 2 (disables HTTP/2)") ++endif () ++endif () ++ + if (USE_GTK4) + set(WEBKITGTK_API_INFIX "") + set(WEBKITGTK_API_VERSION "6.0") + SET_AND_EXPOSE_TO_BUILD(ENABLE_2022_GLIB_API ON) ++elseif (USE_SOUP2) ++ set(WEBKITGTK_API_INFIX "2") ++ set(WEBKITGTK_API_VERSION "4.0") ++ SET_AND_EXPOSE_TO_BUILD(ENABLE_2022_GLIB_API OFF) + else () + set(WEBKITGTK_API_INFIX "2") + set(WEBKITGTK_API_VERSION "4.1") +@@ -201,9 +225,12 @@ find_package(GLIB ${GLIB_MINIMUM_VERSION} REQUIRED COMPONENTS gio gio-unix gobje + EXPOSE_STRING_VARIABLE_TO_BUILD(WEBKITGTK_API_INFIX) + EXPOSE_STRING_VARIABLE_TO_BUILD(WEBKITGTK_API_VERSION) + +-if (WEBKITGTK_API_VERSION VERSION_EQUAL "4.1") +- CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(WEBKIT 21 7 21) +- CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(JAVASCRIPTCORE 10 11 10) ++if (WEBKITGTK_API_VERSION VERSION_EQUAL "4.0") ++ CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(WEBKIT 112 0 75) ++ CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(JAVASCRIPTCORE 47 0 29) ++elseif (WEBKITGTK_API_VERSION VERSION_EQUAL "4.1") ++ CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(WEBKIT 20 0 20) ++ CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(JAVASCRIPTCORE 10 0 10) + elseif (WEBKITGTK_API_VERSION VERSION_EQUAL "6.0") + CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(WEBKIT 20 7 16) + CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(JAVASCRIPTCORE 8 11 7) +diff --git a/Source/cmake/WebKitFeatures.cmake b/Source/cmake/WebKitFeatures.cmake +index d4046bf679b2..821eed4b9eaf 100644 +--- a/Source/cmake/WebKitFeatures.cmake ++++ b/Source/cmake/WebKitFeatures.cmake +@@ -212,6 +212,7 @@ macro(WEBKIT_OPTION_BEGIN) + WEBKIT_OPTION_DEFINE(ENABLE_RESOURCE_USAGE "Toggle resource usage support" PRIVATE OFF) + WEBKIT_OPTION_DEFINE(ENABLE_SAMPLING_PROFILER "Toggle sampling profiler support" PRIVATE ${ENABLE_SAMPLING_PROFILER_DEFAULT}) + WEBKIT_OPTION_DEFINE(ENABLE_SANDBOX_EXTENSIONS "Toggle sandbox extensions support" PRIVATE OFF) ++ WEBKIT_OPTION_DEFINE(ENABLE_SERVER_PRECONNECT "Toggle server preconnect support" PRIVATE OFF) + WEBKIT_OPTION_DEFINE(ENABLE_SERVICE_CONTROLS "Toggle service controls support" PRIVATE OFF) + WEBKIT_OPTION_DEFINE(ENABLE_SHAREABLE_RESOURCE "Toggle network shareable resources support" PRIVATE OFF) + WEBKIT_OPTION_DEFINE(ENABLE_SMOOTH_SCROLLING "Toggle smooth scrolling" PRIVATE ON) +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestAuthentication.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestAuthentication.cpp +index 10bcc6bab0ea..1e04128918ae 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestAuthentication.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestAuthentication.cpp +@@ -20,6 +20,7 @@ + #include "config.h" + #include "LoadTrackingTest.h" + #include "WebKitTestServer.h" ++#include + #include + + static WebKitTestServer* kServer; +@@ -347,7 +348,11 @@ static void testWebViewAuthenticationEmptyRealm(AuthenticationTest* test, gconst + class Tunnel { + WTF_DEPRECATED_MAKE_FAST_ALLOCATED(Tunnel); + public: ++#if USE(SOUP2) ++ Tunnel(SoupServer* server, SoupMessage* message) ++#else + Tunnel(SoupServer* server, SoupServerMessage* message) ++#endif + : m_server(server) + , m_message(message) + { +@@ -364,8 +369,13 @@ public: + m_completionHandler = WTF::move(completionHandler); + GRefPtr client = adoptGRef(g_socket_client_new()); + auto* uri = soup_server_message_get_uri(m_message.get()); ++#if USE(SOUP2) ++ const char* host = uri->host; ++ int port = uri->port; ++#else + const char* host = g_uri_get_host(uri); + int port = std::max(g_uri_get_port(uri), 0); ++#endif + g_socket_client_connect_to_host_async(client.get(), host, port, nullptr, [](GObject* source, GAsyncResult* result, gpointer userData) { + auto* tunnel = static_cast(userData); + GUniqueOutPtr error; +@@ -381,15 +391,28 @@ public: + } + + GRefPtr m_server; ++#if USE(SOUP2) ++ GRefPtr m_message; ++#else + GRefPtr m_message; ++#endif + Function m_completionHandler; + }; + + unsigned gProxyServerPort; + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext* context, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { ++#if USE(SOUP2) ++ unsigned port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(soup_client_context_get_local_address(context))); ++#else + unsigned port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(soup_server_message_get_local_address(message))); ++#endif ++ + if (soup_server_message_get_method(message) == SOUP_METHOD_CONNECT) { + g_assert_cmpuint(port, ==, gProxyServerPort); + auto tunnel = makeUnique(server, message); +@@ -482,8 +505,14 @@ static void testWebViewAuthenticationProxy(ProxyAuthenticationTest* test, gconst + { + test->loadURI(kServer->getURIForPath("/proxy/auth-test.html").data()); + WebKitAuthenticationRequest* request = test->waitForAuthenticationRequest(); ++#if USE(SOUP2) ++ // FIXME: the uri and host should the proxy ones, not the requested ones. ++ ASSERT_CMP_CSTRING(webkit_authentication_request_get_host(request), ==, kServer->baseURL().host().toString().utf8()); ++ g_assert_cmpuint(webkit_authentication_request_get_port(request), ==, kServer->port()); ++#else + ASSERT_CMP_CSTRING(webkit_authentication_request_get_host(request), ==, test->m_proxyServer.baseURL().host().toString().utf8()); + g_assert_cmpuint(webkit_authentication_request_get_port(request), ==, test->m_proxyServer.port()); ++#endif + g_assert_cmpstr(webkit_authentication_request_get_realm(request), ==, "Proxy realm"); + g_assert_cmpint(webkit_authentication_request_get_scheme(request), ==, WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC); + g_assert_true(webkit_authentication_request_is_for_proxy(request)); +@@ -491,8 +520,13 @@ static void testWebViewAuthenticationProxy(ProxyAuthenticationTest* test, gconst + auto* origin = webkit_authentication_request_get_security_origin(request); + g_assert_nonnull(origin); + ASSERT_CMP_CSTRING(webkit_security_origin_get_protocol(origin), ==, kServer->baseURL().protocol().toString().utf8()); ++#if USE(SOUP2) ++ ASSERT_CMP_CSTRING(webkit_security_origin_get_host(origin), ==, kServer->baseURL().host().toString().utf8()); ++ g_assert_cmpuint(webkit_security_origin_get_port(origin), ==, kServer->port()); ++#else + ASSERT_CMP_CSTRING(webkit_security_origin_get_host(origin), ==, test->m_proxyServer.baseURL().host().toString().utf8()); + g_assert_cmpuint(webkit_security_origin_get_port(origin), ==, test->m_proxyServer.port()); ++#endif + webkit_security_origin_unref(origin); + } + +@@ -503,8 +537,14 @@ static void testWebViewAuthenticationProxyHTTPS(ProxyAuthenticationTest* test, g + + test->loadURI(httpsServer->getURIForPath("/proxy/auth-test.html").data()); + WebKitAuthenticationRequest* request = test->waitForAuthenticationRequest(); ++#if USE(SOUP2) ++ // FIXME: the uri and host should the proxy ones, not the requested ones. ++ ASSERT_CMP_CSTRING(webkit_authentication_request_get_host(request), ==, httpsServer->baseURL().host().toString().utf8()); ++ g_assert_cmpuint(webkit_authentication_request_get_port(request), ==, httpsServer->port()); ++#else + ASSERT_CMP_CSTRING(webkit_authentication_request_get_host(request), ==, test->m_proxyServer.baseURL().host().toString().utf8()); + g_assert_cmpuint(webkit_authentication_request_get_port(request), ==, test->m_proxyServer.port()); ++#endif + g_assert_cmpstr(webkit_authentication_request_get_realm(request), ==, "Proxy realm"); + g_assert_cmpint(webkit_authentication_request_get_scheme(request), ==, WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC); + g_assert_true(webkit_authentication_request_is_for_proxy(request)); +@@ -512,8 +552,13 @@ static void testWebViewAuthenticationProxyHTTPS(ProxyAuthenticationTest* test, g + auto* origin = webkit_authentication_request_get_security_origin(request); + g_assert_nonnull(origin); + ASSERT_CMP_CSTRING(webkit_security_origin_get_protocol(origin), ==, httpsServer->baseURL().protocol().toString().utf8()); ++#if USE(SOUP2) ++ ASSERT_CMP_CSTRING(webkit_security_origin_get_host(origin), ==, httpsServer->baseURL().host().toString().utf8()); ++ g_assert_cmpuint(webkit_security_origin_get_port(origin), ==, httpsServer->port()); ++#else + ASSERT_CMP_CSTRING(webkit_security_origin_get_host(origin), ==, test->m_proxyServer.baseURL().host().toString().utf8()); + g_assert_cmpuint(webkit_security_origin_get_port(origin), ==, test->m_proxyServer.port()); ++#endif + webkit_security_origin_unref(origin); + } + +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestBackForwardList.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestBackForwardList.cpp +index 689f3c551c7c..52c0affc768d 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestBackForwardList.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestBackForwardList.cpp +@@ -21,6 +21,7 @@ + + #include "WebKitTestServer.h" + #include "WebViewTest.h" ++#include + #include + #include + +@@ -29,7 +30,11 @@ static const int kBackForwardListLimit = 100; + + static WebKitTestServer* kServer; + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* msg, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* msg, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(msg) != SOUP_METHOD_GET) { + soup_server_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestCookieManager.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestCookieManager.cpp +index b71c0b6431a6..31aafecfa6ab 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestCookieManager.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestCookieManager.cpp +@@ -23,6 +23,7 @@ + #include "WebKitTestServer.h" + #include "WebViewTest.h" + #include ++#include + #include + + static WebKitTestServer* kServer; +@@ -844,7 +845,11 @@ static void testCookieManagerLongExpires(CookieManagerTest* test, gconstpointer) + SoupCookie* cookie = static_cast(cookies->data); + auto* cookiesExpires = soup_cookie_get_expires(cookie); + g_assert_nonnull(cookiesExpires); ++#if USE(SOUP2) ++ g_assert_cmpint(g_date_time_to_unix(expires.get()), ==, soup_date_to_time_t(cookiesExpires)); ++#else + g_assert_cmpint(g_date_time_to_unix(expires.get()), ==, g_date_time_to_unix(cookiesExpires)); ++#endif + + test->deleteAllCookies(); + g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); +@@ -900,7 +905,11 @@ static void testCookieSyncWithWebView(CookiePersistentStorageTest* test, gconstp + g_assert_cmpstr(cookieString.get(), ==, "baz=value"); + } + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestDownloads.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestDownloads.cpp +index f256a3b7eedc..898b76af1bba 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestDownloads.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestDownloads.cpp +@@ -21,6 +21,7 @@ + + #include "WebKitTestServer.h" + #include "WebViewTest.h" ++#include + #include + #include + #include +@@ -401,13 +402,21 @@ static WebKitTestServer* kServer; + static const char* kServerSuggestedFilename = "webkit-downloaded-file"; + static HashMap s_userAgentMap; + ++#if USE(SOUP2) ++static void addContentDispositionHTTPHeaderToResponse(SoupMessage* message) ++#else + static void addContentDispositionHTTPHeaderToResponse(SoupServerMessage* message) ++#endif + { + GUniquePtr contentDisposition(g_strdup_printf("attachment; filename=%s", kServerSuggestedFilename)); + soup_message_headers_append(soup_server_message_get_response_headers(message), "Content-Disposition", contentDisposition.get()); + } + ++#if USE(SOUP2) ++static void writeNextChunk(SoupMessage* message) ++#else + static void writeNextChunk(SoupServerMessage* message) ++#endif + { + /* We need a big enough chunk for the sniffer to not block the load */ + static const char* chunk = "Testing!Testing!Testing!Testing!Testing!Testing!Testing!" +@@ -420,7 +429,11 @@ static void writeNextChunk(SoupServerMessage* message) + soup_message_body_append(soup_server_message_get_response_body(message), SOUP_MEMORY_STATIC, chunk, strlen(chunk)); + } + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp +index 72461e02d71a..05e6c6692f69 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp +@@ -24,6 +24,7 @@ + #include "LoadTrackingTest.h" + #include "WebKitTestServer.h" + #include "WebViewTest.h" ++#include + #include + #include + #include +@@ -725,7 +726,11 @@ static void testUserAgent(WebViewTest* test, gconstpointer) + s_userAgentMap.clear(); + } + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + static const char* responseString = "Testing!Testing!Testing!Testing!Testing!Testing!Testing!" + "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!" +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestNetworkProcessMemoryPressure.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestNetworkProcessMemoryPressure.cpp +index 175df404d1b2..6af5b3f5746f 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestNetworkProcessMemoryPressure.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestNetworkProcessMemoryPressure.cpp +@@ -21,10 +21,15 @@ + + #include "WebKitTestServer.h" + #include "WebViewTest.h" ++#include + + static WebKitTestServer* kServer; + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestResources.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestResources.cpp +index fbd4e25e7f5c..5177ed6edb1b 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestResources.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestResources.cpp +@@ -21,6 +21,7 @@ + + #include "WebKitTestServer.h" + #include "WebViewTest.h" ++#include + #include + #include + #include +@@ -753,6 +754,21 @@ static void testWebViewSyncRequestOnMaxConns(SyncRequestOnMaxConnsTest* test, gc + g_source_remove(context.unlockServerSourceID); + } + ++#if USE(SOUP2) ++static void addCacheHTTPHeadersToResponse(SoupMessage* message) ++{ ++ // The actual date doesn't really matter. ++ SoupDate* soupDate = soup_date_new_from_now(0); ++ GUniquePtr date(soup_date_to_string(soupDate, SOUP_DATE_HTTP)); ++ soup_message_headers_append(message->response_headers, "Last-Modified", date.get()); ++ soup_date_free(soupDate); ++ soup_message_headers_append(message->response_headers, "Cache-control", "public, max-age=31536000"); ++ soupDate = soup_date_new_from_now(3600); ++ date.reset(soup_date_to_string(soupDate, SOUP_DATE_HTTP)); ++ soup_message_headers_append(message->response_headers, "Expires", date.get()); ++ soup_date_free(soupDate); ++} ++#else + static void addCacheHTTPHeadersToResponse(SoupServerMessage* message) + { + // The actual date doesn't really matter. +@@ -765,8 +781,13 @@ static void addCacheHTTPHeadersToResponse(SoupServerMessage* message) + date.reset(soup_date_time_to_string(dateTime.get(), SOUP_DATE_HTTP)); + soup_message_headers_append(responseHeaders, "Expires", date.get()); + } ++#endif + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestSSL.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestSSL.cpp +index eb863ece3eec..fa88350fb9da 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestSSL.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestSSL.cpp +@@ -21,6 +21,7 @@ + + #include "LoadTrackingTest.h" + #include "WebKitTestServer.h" ++#include + + static WebKitTestServer* kHttpsServer; + static WebKitTestServer* kHttpServer; +@@ -392,7 +393,11 @@ public: + " socket.removeEventListener('open', onOpen);" + "}"; + ++#if USE(SOUP2) ++ static void serverWebSocketCallback(SoupServer*, SoupWebsocketConnection*, const char*, SoupClientContext*, gpointer userData) ++#else + static void serverWebSocketCallback(SoupServer*, SoupServerMessage*, const char*, SoupWebsocketConnection*, gpointer userData) ++#endif + { + static_cast(userData)->m_events |= WebSocketTest::EventFlags::DidServerCompleteHandshake; + } +@@ -490,6 +495,7 @@ static void testTLSErrorsEphemeral(EphemeralSSLTest* test, gconstpointer) + g_assert_false(test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted)); + } + ++#if !USE(SOUP2) + class ClientSideCertificateTestBase { + public: + static gboolean acceptCertificateCallback(SoupServerMessage* message, GTlsCertificate* certificate, GTlsCertificateFlags errors, ClientSideCertificateTestBase* test) +@@ -704,8 +710,13 @@ static void testWebSocketClientSideCertificate(WebSocketClientSideCertificateTes + g_assert_true(events & WebSocketTest::EventFlags::DidOpen); + g_assert_false(events & WebSocketTest::EventFlags::DidClose); + } ++#endif + ++#if USE(SOUP2) ++static void httpsServerCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void httpsServerCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +@@ -743,7 +754,11 @@ static void httpsServerCallback(SoupServer* server, SoupServerMessage* message, + soup_server_message_set_status(message, SOUP_STATUS_NOT_FOUND, nullptr); + } + ++#if USE(SOUP2) ++static void httpServerCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void httpServerCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +@@ -797,8 +812,10 @@ void beforeAll() + TLSErrorsTest::add("WebKitWebView", "load-failed-with-tls-errors", testLoadFailedWithTLSErrors); + WebSocketTest::add("WebKitWebView", "web-socket-tls-errors", testWebSocketTLSErrors); + EphemeralSSLTest::add("WebKitWebView", "ephemeral-tls-errors", testTLSErrorsEphemeral); ++#if !USE(SOUP2) + ClientSideCertificateTest::add("WebKitWebView", "client-side-certificate", testClientSideCertificate); + WebSocketClientSideCertificateTest::add("WebKitWebView", "web-socket-client-side-certificate", testWebSocketClientSideCertificate); ++#endif + } + + void afterAll() +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitFaviconDatabase.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitFaviconDatabase.cpp +index 00c1d159f34a..0fe820ae9b18 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitFaviconDatabase.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitFaviconDatabase.cpp +@@ -23,6 +23,7 @@ + + #include "WebKitTestServer.h" + #include "WebViewTest.h" ++#include + #include + #include + #include +@@ -201,7 +202,11 @@ public: + bool m_waitingForFaviconURI { false }; + }; + ++#if USE(SOUP2) ++static void serverCallback(SoupServer*, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer*, SoupServerMessage* message, const char* path, GHashTable* query, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitPolicyClient.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitPolicyClient.cpp +index 7ba9d99adbdf..c619a8afa176 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitPolicyClient.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitPolicyClient.cpp +@@ -23,6 +23,7 @@ + #include "LoadTrackingTest.h" + #include "WebKitTestServer.h" + #include "WebKitWebsitePolicies.h" ++#include + #include + #include + +@@ -301,7 +302,11 @@ static void testNewWindowPolicy(PolicyClientTest* test, gconstpointer) + g_assert_false(data.triedToOpenWindow); + } + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitSettings.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitSettings.cpp +index 38c0da74d007..577409b9249f 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitSettings.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitSettings.cpp +@@ -33,6 +33,7 @@ + #include "TestMain.h" + #include "WebKitTestServer.h" + #include "WebViewTest.h" ++#include + #include + #include + #include +@@ -659,7 +660,11 @@ static void testWebKitSettingsJavaScriptMarkup(WebViewTest* test, gconstpointer) + webkit_settings_set_enable_javascript_markup(webkit_web_view_get_settings(test->webView()), TRUE); + } + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitUserContentManager.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitUserContentManager.cpp +index d9d8a6e86aca..8e79ad040362 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitUserContentManager.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitUserContentManager.cpp +@@ -21,6 +21,7 @@ + + #include "WebKitTestServer.h" + #include "WebViewTest.h" ++#include + #include + #include + #include +@@ -657,7 +658,11 @@ static void testUserContentManagerContentFilter(WebViewTest* test, gconstpointer + webkit_user_content_filter_unref(filter); + } + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr); + auto* responseBody = soup_server_message_get_response_body(message); +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp +index b60b425a4c03..699acbe7fabb 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp +@@ -22,6 +22,7 @@ + #include "LoadTrackingTest.h" + #include "WebKitTestServer.h" + #include "WebKitWebViewInternal.h" ++#include + #include + #include + #include +@@ -505,7 +506,11 @@ static void testWebContextLanguages(WebViewTest* test, gconstpointer) + g_assert_cmpstr(locale.get(), !=, "A"); + } + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext* context, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +@@ -525,7 +530,11 @@ static void serverCallback(SoupServer* server, SoupServerMessage* message, const + soup_message_body_complete(responseBody); + soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr); + } else if (g_str_equal(path, "/echoPort")) { ++#if USE(SOUP2) ++ char* port = g_strdup_printf("%u", g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(soup_client_context_get_local_address(context)))); ++#else + char* port = g_strdup_printf("%u", g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(soup_server_message_get_local_address(message)))); ++#endif + soup_message_body_append(responseBody, SOUP_MEMORY_TAKE, port, strlen(port)); + soup_message_body_complete(responseBody); + soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr); +@@ -700,16 +709,22 @@ class ProxyTest : public WebViewTest { + public: + MAKE_GLIB_TEST_FIXTURE(ProxyTest); + ++#if SOUP_CHECK_VERSION(2, 61, 90) + enum class WebSocketServerType { + Unknown, + NoProxy, + Proxy + }; + ++#if USE(SOUP2) ++ static void webSocketProxyServerCallback(SoupServer*, SoupWebsocketConnection*, const char* path, SoupClientContext*, gpointer userData) ++#else + static void webSocketProxyServerCallback(SoupServer*, SoupServerMessage*, const char* path, SoupWebsocketConnection*, gpointer userData) ++#endif + { + static_cast(userData)->webSocketConnected(ProxyTest::WebSocketServerType::Proxy); + } ++#endif + + ProxyTest() + { +@@ -720,8 +735,10 @@ public: + // work, not whether we can write a soup proxy server. + m_proxyServer.run(serverCallback); + g_assert_false(m_proxyServer.baseURL().isNull()); ++#if SOUP_CHECK_VERSION(2, 61, 90) + m_proxyServer.addWebSocketHandler(webSocketProxyServerCallback, this); + g_assert_false(m_proxyServer.baseWebSocketURL().isNull()); ++#endif + } + + CString loadURIAndGetMainResourceData(const char* uri) +@@ -739,6 +756,7 @@ public: + return port; + } + ++#if SOUP_CHECK_VERSION(2, 61, 90) + void webSocketConnected(WebSocketServerType serverType) + { + m_webSocketRequestReceived = serverType; +@@ -752,16 +770,26 @@ public: + runJavaScriptAndWait(createWebSocket.get()); + return m_webSocketRequestReceived; + } ++#endif + + WebKitTestServer m_proxyServer; ++ ++#if SOUP_CHECK_VERSION(2, 61, 90) + WebSocketServerType m_webSocketRequestReceived { WebSocketServerType::Unknown }; ++#endif + }; + + #if !ENABLE(2022_GLIB_API) ++#if SOUP_CHECK_VERSION(2, 61, 90) ++#if USE(SOUP2) ++static void webSocketServerCallback(SoupServer*, SoupWebsocketConnection*, const char*, SoupClientContext*, gpointer userData) ++#else + static void webSocketServerCallback(SoupServer*, SoupServerMessage*, const char*, SoupWebsocketConnection*, gpointer userData) ++#endif + { + static_cast(userData)->webSocketConnected(ProxyTest::WebSocketServerType::NoProxy); + } ++#endif + + static void ephemeralViewloadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent, WebViewTest* test) + { +@@ -778,10 +806,12 @@ static void testWebContextProxySettings(ProxyTest* test, gconstpointer) + auto mainResourceData = test->loadURIAndGetMainResourceData(kServer->getURIForPath("/echoPort").data()); + ASSERT_CMP_CSTRING(mainResourceData, ==, serverPortAsString.get()); + ++#if SOUP_CHECK_VERSION(2, 61, 90) + // WebSocket requests should also be received by kServer. + kServer->addWebSocketHandler(webSocketServerCallback, test); + auto serverType = test->createWebSocketAndWaitUntilConnected(); + g_assert_true(serverType == ProxyTest::WebSocketServerType::NoProxy); ++#endif + + // Set default proxy URI to point to proxyServer. Requests to kServer should be received by proxyServer instead. + WebKitNetworkProxySettings* settings = webkit_network_proxy_settings_new(test->m_proxyServer.baseURL().string().utf8().data(), nullptr); +@@ -792,9 +822,11 @@ static void testWebContextProxySettings(ProxyTest* test, gconstpointer) + ASSERT_CMP_CSTRING(mainResourceData, ==, proxyServerPortAsString.get()); + webkit_network_proxy_settings_free(settings); + ++#if SOUP_CHECK_VERSION(2, 61, 90) + // WebSocket requests should also be received by proxyServer. + serverType = test->createWebSocketAndWaitUntilConnected(); + g_assert_true(serverType == ProxyTest::WebSocketServerType::Proxy); ++#endif + + // Proxy settings also affect ephemeral web views. + auto webView = test->createWebView("is-ephemeral", TRUE, nullptr); +@@ -851,7 +883,9 @@ static void testWebContextProxySettings(ProxyTest* test, gconstpointer) + mainResourceData = test->loadURIAndGetMainResourceData(kServer->getURIForPath("/echoPort").data()); + ASSERT_CMP_CSTRING(mainResourceData, ==, serverPortAsString.get()); + ++#if SOUP_CHECK_VERSION(2, 61, 90) + kServer->removeWebSocketHandler(); ++#endif + } + #endif + +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp +index bfb6dd1c95fa..3acc7a129c21 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp +@@ -21,6 +21,7 @@ + #include "config.h" + #include "WebKitTestServer.h" + #include "WebViewTest.h" ++#include + #include + #include + #include +@@ -2246,7 +2247,11 @@ static void testWebViewLoadAlternateHTMLFromPageWithCSP(WebViewTest* test, gcons + g_assert_no_error(error.get()); + } + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebXR.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebXR.cpp +index 0c67013d9caa..7af715c860e5 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebXR.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebXR.cpp +@@ -117,7 +117,11 @@ WebXRTest::WebXRTest() + relaxDMABufRequirement(defaultSettings); + } + ++#if USE(SOUP2) ++static void serverCallback(SoupServer*, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer*, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + g_assert(soup_server_message_get_method(message) == SOUP_METHOD_GET); + +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebsiteData.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebsiteData.cpp +index 5061abe6e49c..973277430604 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebsiteData.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebsiteData.cpp +@@ -22,11 +22,16 @@ + #include "WebKitTestServer.h" + #include "WebViewTest.h" + #include ++#include + #include + + static WebKitTestServer* kServer; + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +@@ -587,6 +592,7 @@ static void testWebsiteDataDatabases(WebsiteDataTest* test, gconstpointer) + g_assert_null(dataList); + } + ++#if SOUP_CHECK_VERSION(2, 67, 91) + static void prepopulateHstsData() + { + // HSTS headers will be ignored in this test because the spec forbids STS policies from being honored for hosts with +@@ -628,6 +634,7 @@ static void testWebsiteDataHsts(WebsiteDataTest* test, gconstpointer) + test->clear(WEBKIT_WEBSITE_DATA_HSTS_CACHE, 0); + g_assert_null(test->fetch(WEBKIT_WEBSITE_DATA_HSTS_CACHE)); + } ++#endif + + static void testWebsiteDataCookies(WebsiteDataTest* test, gconstpointer) + { +@@ -894,7 +901,9 @@ void beforeAll() + kServer = new WebKitTestServer(); + kServer->run(serverCallback); + ++#if SOUP_CHECK_VERSION(2, 67, 91) + prepopulateHstsData(); ++#endif + + WebsiteDataTest::add("WebKitWebsiteData", "configuration", testWebsiteDataConfiguration); + WebViewTest::add("WebKitWebsiteData", "ephemeral", testWebsiteDataEphemeral); +@@ -902,7 +911,9 @@ void beforeAll() + WebsiteDataTest::add("WebKitWebsiteData", "storage", testWebsiteDataStorage); + WebsiteDataTest::add("WebKitWebsiteData", "databases", testWebsiteDataDatabases); + WebsiteDataTest::add("WebKitWebsiteData", "cookies", testWebsiteDataCookies); ++#if SOUP_CHECK_VERSION(2, 67, 91) + WebsiteDataTest::add("WebKitWebsiteData", "hsts", testWebsiteDataHsts); ++#endif + WebsiteDataTest::add("WebKitWebsiteData", "deviceidhashsalt", testWebsiteDataDeviceIdHashSalt); + WebsiteDataTest::add("WebKitWebsiteData", "itp", testWebsiteDataITP); + WebsiteDataTest::add("WebKitWebsiteData", "service-worker-registrations", testWebsiteDataServiceWorkerRegistrations); +diff --git a/Tools/TestWebKitAPI/Tests/WebKitGtk/TestContextMenu.cpp b/Tools/TestWebKitAPI/Tests/WebKitGtk/TestContextMenu.cpp +index a91f6afced9b..84854657b78f 100644 +--- a/Tools/TestWebKitAPI/Tests/WebKitGtk/TestContextMenu.cpp ++++ b/Tools/TestWebKitAPI/Tests/WebKitGtk/TestContextMenu.cpp +@@ -21,6 +21,7 @@ + + #include "WebKitTestServer.h" + #include "WebViewTest.h" ++#include + #include + #include + +@@ -1107,7 +1108,11 @@ static void testContextMenuWebExtensionNode(ContextMenuWebExtensionNodeTest* tes + g_assert_cmpstr(test->m_node.parentName.data(), ==, "A"); + } + ++#if USE(SOUP2) ++static void writeNextChunk(SoupMessage* message) ++#else + static void writeNextChunk(SoupServerMessage* message) ++#endif + { + auto* responseBody = soup_server_message_get_response_body(message); + GUniquePtr filePath(g_build_filename(Test::getResourcesDir().data(), "silence.webm", nullptr)); +@@ -1123,7 +1128,11 @@ static void writeNextChunk(SoupServerMessage* message) + soup_message_body_complete(responseBody); + } + ++#if USE(SOUP2) ++static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) ++#else + static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer) ++#endif + { + if (soup_server_message_get_method(message) != SOUP_METHOD_GET) { + soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr); +diff --git a/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.cpp b/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.cpp +index 47375e39b5e3..2691e97b1ed8 100644 +--- a/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.cpp ++++ b/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.cpp +@@ -62,8 +62,14 @@ void WebKitTestServer::run(SoupServerCallback serverCallback) + + GSList* uris = soup_server_get_uris(m_soupServer.get()); + g_assert_nonnull(uris); ++#if USE(SOUP2) ++ GUniquePtr urlString(soup_uri_to_string(static_cast(uris->data), FALSE)); ++ m_baseURL = URL({ }, String::fromUTF8(urlString.get())); ++ g_slist_free_full(uris, reinterpret_cast(soup_uri_free)); ++#else + m_baseURL = static_cast(uris->data); + g_slist_free_full(uris, reinterpret_cast(g_uri_unref)); ++#endif + } + + void WebKitTestServer::addWebSocketHandler(SoupServerWebsocketCallback callback, gpointer userData) +diff --git a/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.h b/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.h +index a0ab5439a86d..1e80c652dbc0 100644 +--- a/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.h ++++ b/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.h +@@ -46,14 +46,18 @@ public: + CString getURIForPath(const char* path) const; + void run(SoupServerCallback); + ++#if SOUP_CHECK_VERSION(2, 50, 0) + void addWebSocketHandler(SoupServerWebsocketCallback, gpointer userData); + void removeWebSocketHandler(); + const URL& baseWebSocketURL() const { return m_baseWebSocketURL; } + CString getWebSocketURIForPath(const char* path) const; ++#endif + + private: + GRefPtr m_soupServer; + URL m_baseURL; ++#if SOUP_CHECK_VERSION(2, 50, 0) + URL m_baseWebSocketURL; ++#endif + RefPtr m_queue; + }; +-- +2.53.0 + diff --git a/sources b/sources index 7475e78..58d5865 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (webkitgtk-2.50.4.tar.xz) = e7b8a6d93f91cd63f00567c886f21853b3fd8e9e48ac21a61b4a841a096b472c3ad0ef0aea45d3c6b8a6bf13790683bdeb3c57f1ba4c949861e9599af4a0051c -SHA512 (webkitgtk-2.50.4.tar.xz.asc) = 2315affcf0c5f49bc0ff53301ecd625d4d46bf4ca3732af847594be34d85e2ca364233e22295b6a19c6f02aaa7adb6620e82aa0916a101c6c0ce5af270ca06bf +SHA512 (webkitgtk-2.52.3.tar.xz) = 8007688e4eb5b465a6f50e05e89858f970f7bbaed45844b8f97175de1fb24e41e6d88f4f6b6299d5ae2ad4e19483da371ac16257d787626da29de7551fbd2a3c +SHA512 (webkitgtk-2.52.3.tar.xz.asc) = cb7f6dc0e2d65c763988e9a18c48ee6810d60a8d2351912bdd33358dcd2d46b994ba34f85c6f8315a34d5b5cb78bd2f0dcb78d076af58e657d1817fdd56f005d diff --git a/webkit2gtk3.spec b/webkit2gtk3.spec index ed92036..50119d6 100644 --- a/webkit2gtk3.spec +++ b/webkit2gtk3.spec @@ -6,7 +6,7 @@ cp -p %1 _license_files/$(echo '%1' | sed -e 's!/!.!g') Name: webkit2gtk3 -Version: 2.50.4 +Version: 2.52.3 Release: 1%{?dist} Summary: GTK Web content engine library @@ -36,22 +36,26 @@ Patch201: evolution-sandbox-warning.patch ## Patches to support older or missing build dependencies ## -Patch300: cairo-1.15.patch -Patch301: glib-2.56.patch +Patch300: glib-2.56.patch +Patch301: cairo-1.15.patch Patch302: gstreamer-1.16.patch Patch303: harfbuzz-1.7.5.patch -Patch304: icu60.patch +Patch304: libsoup2.patch +Patch305: icu60.patch +Patch306: g-ir-scanner-nonfatal.patch ## ## Upstream patches to remove, hopefully after next update ## -# No patches currently! :) +# https://github.com/WebKit/WebKit/pull/58096 +Patch400: aarch64-build.patch BuildRequires: bison BuildRequires: clang BuildRequires: cmake BuildRequires: flex +BuildRequires: gcc-toolset-14-libatomic-devel BuildRequires: gettext BuildRequires: git BuildRequires: gnupg2 @@ -217,8 +221,6 @@ rm -rf Source/ThirdParty/qunit/ %global optflags %(echo %{optflags} | sed 's/-g /-g1 /') %endif -# -DUSE_SYSTEM_MALLOC=ON is really bad for security, but libpas requires -# __atomic_compare_exchange_16 which is not available in RHEL 8. %cmake \ -GNinja \ -DPORT=GTK \ @@ -237,12 +239,14 @@ rm -rf Source/ThirdParty/qunit/ -DUSE_JPEGXL=OFF \ -DUSE_LIBBACKTRACE=OFF \ -DUSE_SOUP2=ON \ - -DUSE_SYSTEM_MALLOC=ON \ -DUSE_SYSTEM_SYSPROF_CAPTURE=OFF \ %if 0%{?rhel} %ifarch aarch64 -DUSE_64KB_PAGE_BLOCK=ON \ %endif +%ifarch aarch64 s390x + -DENABLE_SPELLCHECK=OFF \ +%endif %endif %{nil} @@ -313,6 +317,9 @@ export NINJA_STATUS="[%f/%t][%e] " %{_datadir}/gir-1.0/JavaScriptCore-4.0.gir %changelog +* Wed Apr 22 2026 Michael Catanzaro - 2.52.3-1 +- Update to 2.52.3 + * Thu Dec 18 2025 Tomas Popela - 2.50.4-1 - Update to 2.50.4