diff --git a/.gitignore b/.gitignore index f39ad1a..b8de101 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -SOURCES/webkitgtk-2.50.4.tar.xz +SOURCES/webkitgtk-2.52.3.tar.xz SOURCES/webkitgtk-keys.gpg diff --git a/.webkit2gtk3.metadata b/.webkit2gtk3.metadata index 821d34c..8bc4b30 100644 --- a/.webkit2gtk3.metadata +++ b/.webkit2gtk3.metadata @@ -1,2 +1,2 @@ -719c304539cecca945846700cefebc7339eb5924 SOURCES/webkitgtk-2.50.4.tar.xz +17f9b127618040a5f3fcbb70e37ea16ab6d69b0b SOURCES/webkitgtk-2.52.3.tar.xz 04b10b8a486542c4551269c20b18b5c1c6cb4f94 SOURCES/webkitgtk-keys.gpg diff --git a/SOURCES/aarch64-build.patch b/SOURCES/aarch64-build.patch new file mode 100644 index 0000000..aada480 --- /dev/null +++ b/SOURCES/aarch64-build.patch @@ -0,0 +1,329 @@ +From d610a155a3ce63809265b1045d4516778af2ba6a 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/SOURCES/evolution-sandbox-warning.patch b/SOURCES/evolution-sandbox-warning.patch index cc0fdb4..e25398e 100644 --- a/SOURCES/evolution-sandbox-warning.patch +++ b/SOURCES/evolution-sandbox-warning.patch @@ -1,8 +1,17 @@ +From 699439119b1bd70de9e4180f2e8e6e32dd794669 Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Mon, 6 Apr 2026 13:32:19 -0500 +Subject: [PATCH] Suppress WEBKIT_FORCE_SANDBOX warning when using Evolution + +--- + Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + diff --git a/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp b/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp -index a2f3b582dcc5..1faf219c2adb 100644 +index 329dbe6a0281..80b9609a47be 100644 --- a/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp +++ b/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp -@@ -91,7 +91,8 @@ void WebProcessPool::platformInitialize(NeedsGlobalStaticInitialization) +@@ -154,7 +154,8 @@ void WebProcessPool::platformInitialize(NeedsGlobalStaticInitialization) else { static bool once = false; if (!once) { @@ -12,3 +21,6 @@ index a2f3b582dcc5..1faf219c2adb 100644 once = true; } } +-- +2.53.0 + diff --git a/SOURCES/g-ir-scanner-nonfatal.patch b/SOURCES/g-ir-scanner-nonfatal.patch new file mode 100644 index 0000000..1807cf2 --- /dev/null +++ b/SOURCES/g-ir-scanner-nonfatal.patch @@ -0,0 +1,28 @@ +From 1d1143a6f00fae1d1812da3dcdd489c71154d529 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/SOURCES/glib-2-68.patch b/SOURCES/glib-2-68.patch index 9d53830..51ebb3f 100644 --- a/SOURCES/glib-2-68.patch +++ b/SOURCES/glib-2-68.patch @@ -1,12 +1,22 @@ -From d7b007e4c066c098216ebe900902994c99ab9f9a Mon Sep 17 00:00:00 2001 +From e9eb6e9b59fbb92ff30ec88b9a3ff2bd7857c23a Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Fri, 8 Aug 2025 10:55:54 -0500 Subject: [PATCH] Revert "[GLib] Remove all GLIB_CHECK_VERSION conditionals" This partially reverts commit 85b637b69f1c3a6242420b198d1c173477ce0f22. +--- + Source/WTF/wtf/URL.h | 4 ++-- + Source/WTF/wtf/glib/GRefPtr.h | 2 ++ + Source/WTF/wtf/glib/URLGLib.cpp | 2 ++ + Source/WebCore/platform/LowPowerModeNotifier.h | 2 ++ + Source/WebCore/platform/glib/LowPowerModeNotifierGLib.cpp | 8 ++++++++ + .../WebCore/platform/network/soup/CertificateInfoSoup.cpp | 8 ++++++++ + Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp | 6 ++++++ + Source/cmake/OptionsGTK.cmake | 8 ++++++-- + 8 files changed, 36 insertions(+), 4 deletions(-) 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 @@ @@ -28,10 +38,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) @@ -77,7 +87,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 { @@ -85,7 +95,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 @@ -112,7 +122,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 @@ -157,7 +167,7 @@ index f32ecca7a300..e81a5433709d 100644 } // namespace WebCore 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 @@ -202,33 +212,20 @@ index a9ee8507c28a..eae6ab798c8f 100644 issuer = certificate.get(); i++; diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake -index 5222f5ea81ab..da3d1e19a602 100644 +index a5ebd3e3d879..11227320f60b 100644 --- a/Source/cmake/OptionsGTK.cmake +++ b/Source/cmake/OptionsGTK.cmake -@@ -7,8 +7,6 @@ SET_PROJECT_VERSION(2 50 0) +@@ -7,8 +7,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(GLib 2.70.0 REQUIRED COMPONENTS GioUnix Thread Module) ++find_package(GLib 2.56.4 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 +257,11 @@ if (ENABLED_COMPILER_SANITIZERS) set(ENABLE_DOCUMENTATION OFF) endif () @@ -241,5 +238,5 @@ index 5222f5ea81ab..da3d1e19a602 100644 find_package(Manette 0.2.4) if (NOT Manette_FOUND) -- -2.51.0 +2.53.0 diff --git a/SOURCES/icu-67.patch b/SOURCES/icu-67.patch index 91ab4d3..5584943 100644 --- a/SOURCES/icu-67.patch +++ b/SOURCES/icu-67.patch @@ -1,24 +1,22 @@ -From a70af9258c7608afd5d05a475e65dd9c2b8a34dc Mon Sep 17 00:00:00 2001 +From 5d71fb5d4d39f1cbd8d5393ccaaf4a81b0048331 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Thu, 27 Mar 2025 15:56:41 -0500 Subject: [PATCH 1/4] 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 da3d1e19a602..7dc96b5bd53b 100644 +index 6d92a94ec9f0..60d14235789a 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.16.0 REQUIRED) +@@ -12,10 +12,10 @@ find_package(Cairo 1.16.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 2.7.4 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 da3d1e19a602..7dc96b5bd53b 100644 find_package(SQLite3 REQUIRED) find_package(Threads REQUIRED) -- -2.51.0 +2.53.0 -From 27948d5683ad0cfa88b6858455f0c8c719d6b9e9 Mon Sep 17 00:00:00 2001 +From 1633835edcaaade6d8e76582bce3d84f4fb3743a Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Fri, 28 Mar 2025 14:45:03 -0500 Subject: [PATCH 2/4] 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,21 +169,21 @@ index c640b73cc891..e678978e453d 100644 } } -- -2.51.0 +2.53.0 -From b6447cd0b4ff59c8d2095ad0d6079e4d19dcf052 Mon Sep 17 00:00:00 2001 +From 99366b4de20bd0046558e2eacda6dbb69442de01 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Fri, 28 Mar 2025 15:01:00 -0500 Subject: [PATCH 3/4] Revert "[JSC] TimeZone Cache should be per-process level" This reverts commit c779aa30eced87609c7c808d672a8f23c5c4821d. --- - Source/JavaScriptCore/runtime/JSDateMath.cpp | 61 +++++++------------- - 1 file changed, 21 insertions(+), 40 deletions(-) + Source/JavaScriptCore/runtime/JSDateMath.cpp | 59 +++++++------------- + 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/Source/JavaScriptCore/runtime/JSDateMath.cpp b/Source/JavaScriptCore/runtime/JSDateMath.cpp -index 96993af52d33..a269eb1d3736 100644 +index 1bcd8fab40ea..3f28081543f8 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..a269eb1d3736 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()) }; -} @@ -242,7 +240,7 @@ index 96993af52d33..a269eb1d3736 100644 DateCache::~DateCache() = default; Ref DateCache::cachedDateInstanceData(double millisecondsFromEpoch) -@@ -519,11 +482,29 @@ Ref DateCache::cachedDateInstanceData(double millisecondsFromE +@@ -519,10 +482,28 @@ Ref DateCache::cachedDateInstanceData(double millisecondsFromE void DateCache::timeZoneCacheSlow() { ASSERT(!m_timeZoneCache); @@ -251,35 +249,33 @@ index 96993af52d33..a269eb1d3736 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; -- cache->m_calendar = std::unique_ptr>(ucal_open(timeZoneID.span().data(), timeZoneID.size(), "", UCAL_DEFAULT, &status)); + if (timeZoneID.isEmpty()) { + status = callBufferProducingFunction(ucal_getHostTimeZone, timeZoneID); + ASSERT_UNUSED(status, U_SUCCESS(status)); + } + if (U_SUCCESS(status)) { + Vector canonicalBuffer; -+ auto status = callBufferProducingFunction(ucal_getCanonicalTimeZoneID, timeZoneID.data(), timeZoneID.size(), canonicalBuffer, nullptr); ++ auto status = callBufferProducingFunction(ucal_getCanonicalTimeZoneID, timeZoneID.span().data(), timeZoneID.size(), canonicalBuffer, nullptr); + if (U_SUCCESS(status)) + canonical = String(canonicalBuffer); + } + 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)); + cache->m_calendar = std::unique_ptr>(ucal_open(timeZoneID.span().data(), timeZoneID.size(), "", UCAL_DEFAULT, &status)); ASSERT_UNUSED(status, U_SUCCESS(status)); ucal_setGregorianChange(cache->m_calendar.get(), minECMAScriptTime, &status); // Ignore "unsupported" error. - m_timeZoneCache = std::unique_ptr(cache); -- -2.51.0 +2.53.0 -From dda58836d1af2918a32d80d2ef44e8a13d70edb2 Mon Sep 17 00:00:00 2001 +From 8cb673fafaf841ad97b366d183f86954a056c45e Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Fri, 19 Sep 2025 16:25:13 -0500 Subject: [PATCH 4/4] Revert "[JSC] Rebaseline Intl implementation based on @@ -306,7 +302,7 @@ This reverts commit 31a358087be7e5e70c7a03bdfcf89de35628a2a2. 16 files changed, 478 insertions(+), 16 deletions(-) diff --git a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp -index 202e266c55da..9a413dc037a7 100644 +index 4eb85711f506..6cdc4507acd3 100644 --- a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp +++ b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp @@ -42,12 +42,16 @@ @@ -326,7 +322,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 +331,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 +340,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 +348,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 +361,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 +374,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 +430,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 +492,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 +511,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 +540,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 +604,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 +649,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 +716,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 +724,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 +845,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 +853,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 +863,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 +874,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 +884,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 +899,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 +907,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 +915,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 +923,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 +935,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 +945,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 +1038,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 +1100,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 +1117,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 +1132,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 +1166,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 +1238,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 +1255,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 +1375,7 @@ index c6c1fa0cd228..85d7e85469a7 100644 } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSDateMath.cpp b/Source/JavaScriptCore/runtime/JSDateMath.cpp -index a269eb1d3736..a58abd12197a 100644 +index 3f28081543f8..ff26051bf502 100644 --- a/Source/JavaScriptCore/runtime/JSDateMath.cpp +++ b/Source/JavaScriptCore/runtime/JSDateMath.cpp @@ -81,11 +81,24 @@ @@ -1509,7 +1505,7 @@ index a269eb1d3736..a58abd12197a 100644 { @@ -447,6 +513,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()); @@ -1553,5 +1549,5 @@ index a269eb1d3736..a58abd12197a 100644 void DateCache::resetIfNecessarySlow() -- -2.51.0 +2.53.0 diff --git a/SOURCES/libsoup2.patch b/SOURCES/libsoup2.patch new file mode 100644 index 0000000..b06925f --- /dev/null +++ b/SOURCES/libsoup2.patch @@ -0,0 +1,3178 @@ +From 0cc2c581256045052a44f1525a34fc70a937084d 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 a490135f3c1b843f34ee3fe308c4813f13ef0583 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 0c3ba74482f6..b81fc91c687a 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 11227320f60b..6d92a94ec9f0 100644 +--- a/Source/cmake/OptionsGTK.cmake ++++ b/Source/cmake/OptionsGTK.cmake +@@ -10,7 +10,6 @@ set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string") + find_package(GLib 2.56.4 REQUIRED COMPONENTS GioUnix Thread Module) + find_package(Cairo 1.16.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(ICU 70.1 REQUIRED COMPONENTS data i18n uc) +@@ -57,6 +56,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) + +@@ -64,6 +64,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) +@@ -180,10 +182,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") +@@ -193,9 +217,12 @@ endif () + 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/webkitgtk-2.50.4.tar.xz.asc b/SOURCES/webkitgtk-2.50.4.tar.xz.asc deleted file mode 100644 index 35c1ec3..0000000 --- a/SOURCES/webkitgtk-2.50.4.tar.xz.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCgAdFiEEAToBJ6ycZbNP+mJSbBAJtpOXU5MFAmlBXggACgkQbBAJtpOX -U5NxbQ//dZodv6dQ3WRUTgorM7pHee7jHLZXyezL7qRuUvHKSKKKtZd6AnA/jhV9 -J7qRh+5oCdVmZeXNoEgpw4H7eiatHAV8nlM5BYLU8Q0aubxr5IyGQjWarGEbcBSV -DD5r3tR0yywqoUR+uWNDMLOC0jFwvMKusmHZ36rWN28hW192lo8EvhFVza1Jwgnt -PTOvaV32ZVXsLr//WNpBhcxEOWPYIgQW4btAAdFsyWigi8USqwMan0Anc0ok6CdP -r8BNsyYFHl3y/Kx74lsvdLC3nFF21BORjODaHp98FPSwjqnfK5fbhMSLhhuR172J -AXCEdYgzt9i/jIJK8yegJsPMdTFIlEM/d5h3utp1s3Ne0i5wf4NQ4jdhZJ/Lfxqw -KYUg4CCO7p2VMoW3+AOFu+atwi5JpERDvYLfHqxQUcbTLFOv4fURbCicvC94Cr2J -g2QAhipt0ETbYahbkF4GwFTZY3ncJ9fBZ5YrADZjBbU2p6N/BJTqXggtVtq0iWNh -phcooz2JUJx6hZQBzXi2I61XwfeH6uzV9fwY5gV1tSXP6CxXiJo7FvpYuheKxa/W -ZR59aYg6bURJy0yC/PNENH5AkyllxSEwLs9wMPMpTVe+DR/VZs176eJZkchq4Q/L -/HeGL6Wcap8YMJi8cC5Dy60vv0IXp33n8/tu1EdtOdQTqo65hl0= -=Bi4F ------END PGP SIGNATURE----- diff --git a/SOURCES/webkitgtk-2.52.3.tar.xz.asc b/SOURCES/webkitgtk-2.52.3.tar.xz.asc new file mode 100644 index 0000000..90f33b1 --- /dev/null +++ b/SOURCES/webkitgtk-2.52.3.tar.xz.asc @@ -0,0 +1,6 @@ +-----BEGIN PGP SIGNATURE----- + +iF0EABEIAB0WIQRao7wzT9fjNp58d7KRxVnb5MkSOwUCaeFIpQAKCRCRxVnb5MkS +O8UZAJ9EPfX10mIMYGlbhCCd+qxbeyuYTACfYOdgIlth6/ymZ8mJqPdABc8bQQk= +=zK1i +-----END PGP SIGNATURE----- diff --git a/SPECS/webkit2gtk3.spec b/SPECS/webkit2gtk3.spec index 6f4990d..2054011 100644 --- a/SPECS/webkit2gtk3.spec +++ b/SPECS/webkit2gtk3.spec @@ -19,8 +19,8 @@ %endif Name: webkit2gtk3 -Version: 2.50.4 -Release: 1%{?dist} +Version: 2.52.3 +Release: 0%{?dist}.1 Summary: GTK Web content engine library License: LGPLv2 @@ -36,7 +36,9 @@ Source2: webkitgtk-keys.gpg ## Patches to support older or missing build dependencies ## Patch: glib-2-68.patch +Patch: libsoup2.patch Patch: icu-67.patch +Patch: g-ir-scanner-nonfatal.patch ## ## Patches to support older Evolution @@ -46,14 +48,16 @@ Patch: evolution-sandbox-warning.patch ## ## Upstream patches to remove, hopefully after next update ## - -# No patches currently! :) + +# https://github.com/WebKit/WebKit/pull/58096 +Patch: aarch64-build.patch BuildRequires: bison BuildRequires: bubblewrap BuildRequires: clang BuildRequires: cmake BuildRequires: flex +BuildRequires: gcc-toolset-14-libatomic-devel BuildRequires: gettext BuildRequires: git BuildRequires: gnupg2 @@ -325,16 +329,40 @@ export NINJA_STATUS="[%f/%t][%e] " %{_datadir}/gir-1.0/JavaScriptCore-4.0.gir %changelog -* Thu Dec 18 2025 Tomas Popela - 2.50.4-1 +* Mon Apr 20 2026 Michael Catanzaro - 2.52.3-0.1 +- Update to 2.52.1 + +* Fri Dec 19 2025 Ravina Jain - 2.50.4-1 - Update to 2.50.4 +- Fix CVE-2025-43529 with Rebase +- Fix CVE-2025-43531 with Rebase +- Fix CVE-2025-43501 with Rebase +- Fix CVE-2025-43536 with Rebase +- Fix CVE-2025-43535 with Rebase +- Fix CVE-2025-43541 with Rebase -* Thu Dec 04 2025 Michael Catanzaro - 2.50.3-1 +* Fri Dec 05 2025 Kashyap - 2.50.3-1 - Update to 2.50.3 +- Fix CVE-2025-43443 with Rebase +- Fix CVE-2025-43440 with Rebase +- Fix CVE-2025-43434 with Rebase +- Fix CVE-2025-43432 with Rebase +- Fix CVE-2025-43431 with Rebase +- Fix CVE-2025-43430 with Rebase +- Fix CVE-2025-43429 with Rebase +- Fix CVE-2025-43427 with Rebase +- Fix CVE-2025-43425 with Rebase +- Fix CVE-2025-43421 with Rebase +- Fix CVE-2025-43392 with Rebase +- Fix CVE-2025-66287 with Rebase +- Fix CVE-2025-43458 with Rebase +- Fix CVE-2025-13947 with Rebase +- Fix CVE-2025-13502 with Rebase -* Mon Oct 13 2025 Michael Catanzaro - 2.50.1-1 +* Tue Oct 14 2025 Michael Catanzaro - 2.50.1-1 - Update to 2.50.1 -* Mon Sep 22 2025 Michael Catanzaro - 2.50.0-1 +* Wed Oct 01 2025 Michael Catanzaro - 2.50.0-1 - Update to 2.50.0 * Fri Aug 08 2025 Michael Catanzaro - 2.48.5-1 @@ -350,9 +378,12 @@ export NINJA_STATUS="[%f/%t][%e] " * Wed Apr 02 2025 Michael Catanzaro - 2.48.1-1 - Update to 2.48.1 -* Mon Mar 24 2025 Michael Catanzaro - 2.48.0-1 +* Mon Mar 31 2025 Michael Catanzaro - 2.48.0-1 - Update to 2.48.0 +* Thu Mar 13 2025 Michael Catanzaro - 2.46.6-2 +- Add patch for CVE-2025-24201 + * Tue Feb 25 2025 Michael Catanzaro - 2.46.6-1 - Update to 2.46.6