diff --git a/.github/scripts/run-with-timeout.ps1 b/.github/scripts/run-with-timeout.ps1
new file mode 100644
index 000000000..cfbf13e33
--- /dev/null
+++ b/.github/scripts/run-with-timeout.ps1
@@ -0,0 +1,253 @@
+[CmdletBinding()]
+param(
+ [Parameter(Mandatory = $true)]
+ [ValidateNotNullOrEmpty()]
+ [string]$FilePath,
+
+ [ValidateRange(1, 86400)]
+ [int]$TimeoutSeconds = 600,
+
+ [ValidateRange(1, 16)]
+ [int]$ProcessCount = 1,
+
+ [ValidateNotNullOrEmpty()]
+ [string]$DiagnosticsDirectory = "test-diagnostics",
+
+ [ValidateNotNullOrEmpty()]
+ [string]$Label = [System.IO.Path]::GetFileNameWithoutExtension($FilePath),
+
+ [string]$ProcessArguments = ""
+)
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference = "Stop"
+
+if (-not ("RunWithTimeout.NativeMethods" -as [type])) {
+ Add-Type -TypeDefinition @"
+namespace RunWithTimeout
+{
+ using System;
+ using System.Runtime.InteropServices;
+
+ public static class NativeMethods
+ {
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool IsWow64Process(
+ IntPtr processHandle,
+ [MarshalAs(UnmanagedType.Bool)] out bool wow64Process);
+ }
+}
+"@
+}
+
+function Stop-RunningProcess {
+ param(
+ [Parameter(Mandatory = $true)]
+ [System.Diagnostics.Process]$Process
+ )
+
+ if (-not $Process.HasExited) {
+ try {
+ Stop-Process -Id $Process.Id
+ }
+ catch {
+ $Process.Refresh()
+ if (-not $Process.HasExited) {
+ throw
+ }
+ }
+ $Process.WaitForExit()
+ }
+}
+
+function Get-DumpSystemDirectory {
+ param(
+ [Parameter(Mandatory = $true)]
+ [System.Diagnostics.Process]$Process
+ )
+
+ if (-not [Environment]::Is64BitOperatingSystem) {
+ return (Join-Path $env:WINDIR "System32")
+ }
+
+ $isWow64 = $false
+ if (-not [RunWithTimeout.NativeMethods]::IsWow64Process($Process.Handle, [ref]$isWow64)) {
+ $errorCode = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
+ throw "Unable to determine the architecture of process $($Process.Id) (Win32 error $errorCode)."
+ }
+
+ if ($isWow64) {
+ return (Join-Path $env:WINDIR "SysWOW64")
+ }
+
+ if (-not [Environment]::Is64BitProcess) {
+ return (Join-Path $env:WINDIR "Sysnative")
+ }
+
+ return (Join-Path $env:WINDIR "System32")
+}
+
+function Save-ProcessDump {
+ param(
+ [Parameter(Mandatory = $true)]
+ [System.Diagnostics.Process]$Process,
+
+ [Parameter(Mandatory = $true)]
+ [string]$DumpPath
+ )
+
+ $dumpProcess = $null
+ $procdump = Get-Command procdump.exe -ErrorAction SilentlyContinue
+ if ($null -ne $procdump) {
+ # A minidump contains the thread stacks and module list needed for a
+ # deadlock diagnosis without copying arbitrary process memory into CI
+ # artifacts.
+ $arguments = "-accepteula -mm $($Process.Id) `"$DumpPath`""
+ $dumpProcess = Start-Process -FilePath $procdump.Source -ArgumentList $arguments -PassThru -NoNewWindow
+ }
+ else {
+ # The dump writer must match the target process architecture. A
+ # 64-bit helper cannot reliably capture Win32 thread context, and a
+ # 32-bit helper cannot inspect a 64-bit target.
+ $systemDirectory = Get-DumpSystemDirectory -Process $Process
+ $powershell = Join-Path $systemDirectory "WindowsPowerShell\v1.0\powershell.exe"
+ $dumpScript = Join-Path $PSScriptRoot "write-minidump.ps1"
+ $arguments = "-NoLogo -NoProfile -ExecutionPolicy Bypass -File `"$dumpScript`" -ProcessId $($Process.Id) -DumpPath `"$DumpPath`""
+ $dumpProcess = Start-Process -FilePath $powershell -ArgumentList $arguments -PassThru -NoNewWindow
+ }
+
+ if (-not $dumpProcess.WaitForExit(30000)) {
+ Stop-RunningProcess -Process $dumpProcess
+ throw "Timed out while capturing dump for process $($Process.Id)."
+ }
+ $dumpProcess.WaitForExit()
+ $dumpProcess.Refresh()
+
+ if ($dumpProcess.ExitCode -ne 0) {
+ throw "Dump capture for process $($Process.Id) exited with code $($dumpProcess.ExitCode)."
+ }
+
+ if (-not (Test-Path -LiteralPath $DumpPath -PathType Leaf)) {
+ throw "Dump capture for process $($Process.Id) did not create $DumpPath."
+ }
+
+ $dumpFile = Get-Item -LiteralPath $DumpPath -ErrorAction SilentlyContinue
+ if ($null -eq $dumpFile -or $dumpFile.Length -eq 0) {
+ throw "Dump capture for process $($Process.Id) created an empty dump."
+ }
+}
+
+$resolvedFilePath = (Resolve-Path -LiteralPath $FilePath).Path
+$resolvedDiagnosticsDirectory = [System.IO.Path]::GetFullPath($DiagnosticsDirectory)
+New-Item -ItemType Directory -Path $resolvedDiagnosticsDirectory -Force | Out-Null
+
+$safeLabel = $Label -replace '[^A-Za-z0-9_.-]', '_'
+$statusPath = Join-Path $resolvedDiagnosticsDirectory "$safeLabel-status.txt"
+$startedAt = Get-Date
+@(
+ "Command: $resolvedFilePath"
+ "Arguments: $ProcessArguments"
+ "Process count: $ProcessCount"
+ "Timeout seconds: $TimeoutSeconds"
+ "Started: $($startedAt.ToString('o'))"
+) | Set-Content -LiteralPath $statusPath
+
+$processes = @()
+try {
+ for ($index = 0; $index -lt $ProcessCount; $index++) {
+ $startInfo = New-Object System.Diagnostics.ProcessStartInfo
+ $startInfo.FileName = $resolvedFilePath
+ $startInfo.Arguments = $ProcessArguments
+ $startInfo.UseShellExecute = $false
+
+ $process = New-Object System.Diagnostics.Process
+ $process.StartInfo = $startInfo
+ if (-not $process.Start()) {
+ throw "Failed to start $resolvedFilePath."
+ }
+ $processes += $process
+ }
+}
+catch {
+ foreach ($process in $processes) {
+ Stop-RunningProcess -Process $process
+ }
+ throw
+}
+
+$deadline = $startedAt.AddSeconds($TimeoutSeconds)
+while ($true) {
+ $failedProcess = $null
+ $failedExitCode = 0
+ $running = @()
+ foreach ($process in $processes) {
+ if ($process.HasExited) {
+ # WaitForExit() populates ExitCode reliably for processes that can
+ # finish before the first polling iteration.
+ $process.WaitForExit()
+ $process.Refresh()
+ if ($process.ExitCode -ne 0 -and $null -eq $failedProcess) {
+ $failedProcess = $process
+ $failedExitCode = $process.ExitCode
+ }
+ }
+ else {
+ $running += $process
+ }
+ }
+
+ if ($null -ne $failedProcess) {
+ foreach ($process in $processes) {
+ Stop-RunningProcess -Process $process
+ }
+ Add-Content -LiteralPath $statusPath -Value @(
+ "Completed: $((Get-Date).ToString('o'))"
+ "Result: failed"
+ "Exit code: $failedExitCode"
+ )
+ exit $failedExitCode
+ }
+
+ if ($running.Count -eq 0) {
+ Add-Content -LiteralPath $statusPath -Value @(
+ "Completed: $((Get-Date).ToString('o'))"
+ "Result: passed"
+ "Exit code: 0"
+ )
+ exit 0
+ }
+
+ if ((Get-Date) -ge $deadline) {
+ Write-Host "::error::$Label exceeded its $TimeoutSeconds-second timeout."
+ Add-Content -LiteralPath $statusPath -Value @(
+ "Completed: $((Get-Date).ToString('o'))"
+ "Result: timed out"
+ "Exit code: 124"
+ )
+
+ foreach ($process in $running) {
+ try {
+ if (-not $process.HasExited) {
+ $detailsPath = Join-Path $resolvedDiagnosticsDirectory "$safeLabel-$($process.Id).txt"
+ Get-Process -Id $process.Id |
+ Format-List Id, ProcessName, StartTime, TotalProcessorTime, Threads, HandleCount |
+ Out-File -LiteralPath $detailsPath
+
+ $dumpPath = Join-Path $resolvedDiagnosticsDirectory "$safeLabel-$($process.Id).dmp"
+ Save-ProcessDump -Process $process -DumpPath $dumpPath
+ Write-Host "Captured $dumpPath"
+ }
+ }
+ catch {
+ Write-Warning $_
+ }
+ finally {
+ Stop-RunningProcess -Process $process
+ }
+ }
+ exit 124
+ }
+
+ Start-Sleep -Milliseconds 200
+}
diff --git a/.github/scripts/write-minidump.ps1 b/.github/scripts/write-minidump.ps1
new file mode 100644
index 000000000..9ff613062
--- /dev/null
+++ b/.github/scripts/write-minidump.ps1
@@ -0,0 +1,63 @@
+[CmdletBinding()]
+param(
+ [Parameter(Mandatory = $true)]
+ [ValidateRange(1, [int]::MaxValue)]
+ [int]$ProcessId,
+
+ [Parameter(Mandatory = $true)]
+ [ValidateNotNullOrEmpty()]
+ [string]$DumpPath
+)
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference = "Stop"
+
+Add-Type -TypeDefinition @"
+namespace WriteMiniDump
+{
+ using System;
+ using System.Runtime.InteropServices;
+ using Microsoft.Win32.SafeHandles;
+
+ public static class NativeMethods
+ {
+ [DllImport("dbghelp.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool MiniDumpWriteDump(
+ IntPtr processHandle,
+ uint processId,
+ SafeFileHandle fileHandle,
+ uint dumpType,
+ IntPtr exceptionParameters,
+ IntPtr userStreamParameters,
+ IntPtr callbackParameters);
+ }
+}
+"@
+
+$process = Get-Process -Id $ProcessId
+$resolvedDumpPath = [System.IO.Path]::GetFullPath($DumpPath)
+$dumpStream = [System.IO.File]::Open(
+ $resolvedDumpPath,
+ [System.IO.FileMode]::Create,
+ [System.IO.FileAccess]::Write,
+ [System.IO.FileShare]::None)
+
+try {
+ $created = [WriteMiniDump.NativeMethods]::MiniDumpWriteDump(
+ $process.Handle,
+ [uint32]$process.Id,
+ $dumpStream.SafeFileHandle,
+ 0,
+ [IntPtr]::Zero,
+ [IntPtr]::Zero,
+ [IntPtr]::Zero)
+ if (-not $created) {
+ $errorCode = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
+ throw "MiniDumpWriteDump failed for process $ProcessId (Win32 error $errorCode)."
+ }
+}
+finally {
+ $dumpStream.Dispose()
+ $process.Dispose()
+}
diff --git a/.github/workflows/test-vcpkg.yml b/.github/workflows/test-vcpkg.yml
index 59961ce53..98ef86429 100644
--- a/.github/workflows/test-vcpkg.yml
+++ b/.github/workflows/test-vcpkg.yml
@@ -24,7 +24,11 @@ concurrency:
jobs:
windows:
runs-on: windows-latest
- name: Windows (x64-windows-static)
+ name: Windows (x64-windows-static, ${{ matrix.transport }})
+ strategy:
+ fail-fast: false
+ matrix:
+ transport: [WinHTTP, WinInet]
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
@@ -35,7 +39,12 @@ jobs:
shell: pwsh
- name: Run vcpkg port test
- run: .\tests\vcpkg\test-vcpkg-windows.ps1 -VcpkgRoot "${{ runner.temp }}\vcpkg"
+ run: |
+ $arguments = @{ VcpkgRoot = "${{ runner.temp }}\vcpkg" }
+ if ("${{ matrix.transport }}" -eq "WinInet") {
+ $arguments.WinInet = $true
+ }
+ .\tests\vcpkg\test-vcpkg-windows.ps1 @arguments
shell: pwsh
linux:
diff --git a/.github/workflows/test-win-latest.yml b/.github/workflows/test-win-latest.yml
index 2a77d5e2a..66261d1e6 100644
--- a/.github/workflows/test-win-latest.yml
+++ b/.github/workflows/test-win-latest.yml
@@ -32,28 +32,47 @@ concurrency:
jobs:
test:
- name: Test on Windows ${{ matrix.arch }}-${{ matrix.build }}
+ name: Test on Windows ${{ matrix.arch }}-${{ matrix.build }}${{ matrix.transport == 'WinInet' && ' (WinInet)' || '' }}
runs-on: ${{ matrix.os }}
+ timeout-minutes: 30
strategy:
+ fail-fast: false
matrix:
arch: [Win32, x64]
build: [Release, Debug]
+ transport: [WinHTTP, WinInet]
os: [windows-2022]
+ exclude:
+ - build: Debug
+ transport: WinInet
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- continue-on-error: true
- name: setup-msbuild
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2.0.0
with:
vs-version: '[17,)'
- - name: Test ${{ matrix.arch }} ${{ matrix.build }}
+ - name: Test ${{ matrix.transport }} ${{ matrix.arch }} ${{ matrix.build }}
shell: cmd
- run: build-tests.cmd ${{ matrix.arch }} ${{ matrix.build }}
+ run: build-tests.cmd ${{ matrix.arch }} ${{ matrix.build }} "" ${{ matrix.transport }}
+
+ - name: Upload test failure diagnostics
+ if: failure() || cancelled()
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
+ with:
+ name: windows-test-failure-${{ matrix.transport }}-${{ matrix.arch }}-${{ matrix.build }}
+ path: |
+ test-diagnostics
+ Solutions/out/${{ matrix.build }}/${{ matrix.arch }}/UnitTests/*.pdb
+ Solutions/out/${{ matrix.build }}/${{ matrix.arch }}/UnitTests/*.map
+ Solutions/out/${{ matrix.build }}/${{ matrix.arch }}/FuncTests/*.pdb
+ Solutions/out/${{ matrix.build }}/${{ matrix.arch }}/FuncTests/*.map
+ if-no-files-found: ignore
+ retention-days: 7
public-headers:
name: Public header gate (MSVC)
diff --git a/Solutions/win32-dll/win32-dll.vcxproj b/Solutions/win32-dll/win32-dll.vcxproj
index b01b9e690..a7cae0a5e 100644
--- a/Solutions/win32-dll/win32-dll.vcxproj
+++ b/Solutions/win32-dll/win32-dll.vcxproj
@@ -211,7 +211,7 @@
Windows
true
- uuid.lib;wininet.lib;crypt32.lib;version.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;version.lib;%(AdditionalDependencies)
runtimeobject.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
@@ -233,7 +233,7 @@
true
- wininet.lib;user32.lib;shell32.lib;Advapi32.lib;Ole32.lib
+ wininet.lib;winhttp.lib;user32.lib;shell32.lib;Advapi32.lib;Ole32.lib
%(AdditionalLibraryDirectories)
@@ -297,7 +297,7 @@
true
true
true
- uuid.lib;wininet.lib;crypt32.lib;version.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;version.lib;%(AdditionalDependencies)
runtimeobject.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
@@ -322,7 +322,7 @@
true
- wininet.lib;user32.lib;shell32.lib;Advapi32.lib;Ole32.lib
+ wininet.lib;winhttp.lib;user32.lib;shell32.lib;Advapi32.lib;Ole32.lib
%(AdditionalLibraryDirectories)
diff --git a/Solutions/win32-lib/win32-lib.vcxproj b/Solutions/win32-lib/win32-lib.vcxproj
index 1b9fb6a7c..dd1a24cb3 100644
--- a/Solutions/win32-lib/win32-lib.vcxproj
+++ b/Solutions/win32-lib/win32-lib.vcxproj
@@ -279,7 +279,7 @@
Windows
true
- uuid.lib;wininet.lib;crypt32.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
false
@@ -347,7 +347,7 @@
Windows
true
- uuid.lib;wininet.lib;crypt32.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
false
@@ -425,7 +425,7 @@
true
true
true
- uuid.lib;wininet.lib;crypt32.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
@@ -501,7 +501,7 @@
true
true
true
- uuid.lib;wininet.lib;crypt32.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
diff --git a/Solutions/win32-mini-dll/win32-mini-dll.vcxproj b/Solutions/win32-mini-dll/win32-mini-dll.vcxproj
index fe923aee2..2b8c67fef 100644
--- a/Solutions/win32-mini-dll/win32-mini-dll.vcxproj
+++ b/Solutions/win32-mini-dll/win32-mini-dll.vcxproj
@@ -240,7 +240,7 @@
Windows
true
- uuid.lib;wininet.lib;crypt32.lib;version.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;version.lib;%(AdditionalDependencies)
runtimeobject.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
@@ -268,7 +268,7 @@
true
- wininet.lib;user32.lib;shell32.lib;Advapi32.lib;Ole32.lib
+ wininet.lib;winhttp.lib;user32.lib;shell32.lib;Advapi32.lib;Ole32.lib
%(AdditionalLibraryDirectories)
@@ -357,7 +357,7 @@
true
true
true
- uuid.lib;wininet.lib;crypt32.lib;version.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;version.lib;%(AdditionalDependencies)
runtimeobject.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
@@ -385,7 +385,7 @@
true
- wininet.lib;user32.lib;shell32.lib;Advapi32.lib;Ole32.lib
+ wininet.lib;winhttp.lib;user32.lib;shell32.lib;Advapi32.lib;Ole32.lib
%(AdditionalLibraryDirectories)
diff --git a/Solutions/win32-mini-lib/win32-mini-lib.vcxproj b/Solutions/win32-mini-lib/win32-mini-lib.vcxproj
index 700623d89..18ab5abb0 100644
--- a/Solutions/win32-mini-lib/win32-mini-lib.vcxproj
+++ b/Solutions/win32-mini-lib/win32-mini-lib.vcxproj
@@ -321,7 +321,7 @@
Windows
true
- uuid.lib;wininet.lib;crypt32.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
false
@@ -427,7 +427,7 @@
Windows
true
- uuid.lib;wininet.lib;crypt32.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
false
@@ -534,7 +534,7 @@
true
true
true
- uuid.lib;wininet.lib;crypt32.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
@@ -642,7 +642,7 @@
true
true
true
- uuid.lib;wininet.lib;crypt32.lib;%(AdditionalDependencies)
+ uuid.lib;wininet.lib;winhttp.lib;crypt32.lib;%(AdditionalDependencies)
%(AdditionalLibraryDirectories)
api-ms-win-core-winrt-l1-1-0.dll;api-ms-win-core-winrt-string-l1-1-0.dll
diff --git a/build-tests.cmd b/build-tests.cmd
index 7f3d0a0ba..12b74e59a 100644
--- a/build-tests.cmd
+++ b/build-tests.cmd
@@ -2,6 +2,18 @@
cd %~dp0
@setlocal ENABLEEXTENSIONS
+set TRANSPORT=%~4
+if not defined TRANSPORT set TRANSPORT=WinHTTP
+if /I "%TRANSPORT%"=="WinInet" (
+ set TRANSPORT_PROPERTY=/p:MATSDK_USE_WININET=true
+) else if /I "%TRANSPORT%"=="WinHTTP" (
+ set TRANSPORT_PROPERTY=/p:MATSDK_USE_WININET=false
+) else (
+ echo ERROR: Unknown HTTP transport "%TRANSPORT%". Expected WinHTTP or WinInet.
+ exit /b 2
+)
+echo HTTP transport: %TRANSPORT%
+
set CUSTOM_PROPS=
if not "%~3"=="" (
if not exist "%~f3" (
@@ -52,11 +64,11 @@ set CONFIGURATION=%2
set MAXCPUCOUNT=%NUMBER_OF_PROCESSORS%
set SOLUTION=Solutions\MSTelemetrySDK.sln
-msbuild %SOLUTION% /target:sqlite:Rebuild,zlib:Rebuild,Tests\gmock:Rebuild,Tests\gtest:Rebuild,Tests\UnitTests:Rebuild,Tests\FuncTests:Rebuild /p:BuildProjectReferences=true /maxcpucount:%MAXCPUCOUNT% /detailedsummary /p:Configuration=%CONFIGURATION% /p:Platform=%PLAT% %CUSTOM_PROPS%
+msbuild %SOLUTION% /target:sqlite:Rebuild,zlib:Rebuild,Tests\gmock:Rebuild,Tests\gtest:Rebuild,Tests\UnitTests:Rebuild,Tests\FuncTests:Rebuild /p:BuildProjectReferences=true /maxcpucount:%MAXCPUCOUNT% /detailedsummary /p:Configuration=%CONFIGURATION% /p:Platform=%PLAT% %TRANSPORT_PROPERTY% %CUSTOM_PROPS%
if not "%ERRORLEVEL%"=="0" exit /b %ERRORLEVEL%
-Solutions\out\%CONFIGURATION%\%PLAT%\UnitTests\UnitTests.exe
+powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .github\scripts\run-with-timeout.ps1 -FilePath Solutions\out\%CONFIGURATION%\%PLAT%\UnitTests\UnitTests.exe -TimeoutSeconds 600 -Label UnitTests-%CONFIGURATION%-%PLAT%-%TRANSPORT%
if not "%ERRORLEVEL%"=="0" exit /b %ERRORLEVEL%
-Solutions\out\%CONFIGURATION%\%PLAT%\FuncTests\FuncTests.exe
+powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .github\scripts\run-with-timeout.ps1 -FilePath Solutions\out\%CONFIGURATION%\%PLAT%\FuncTests\FuncTests.exe -TimeoutSeconds 600 -Label FuncTests-%CONFIGURATION%-%PLAT%-%TRANSPORT%
if not "%ERRORLEVEL%"=="0" exit /b %ERRORLEVEL%
-powershell -NoProfile -ExecutionPolicy Bypass -Command "$path = Join-Path (Get-Location) 'Solutions\out\%CONFIGURATION%\%PLAT%\FuncTests\FuncTests.exe'; $args = '--gtest_filter=MultipleLogManagersTests.MultiProcessesLogManager'; $p1 = Start-Process -FilePath $path -ArgumentList $args -PassThru; $p2 = Start-Process -FilePath $path -ArgumentList $args -PassThru; $p1.WaitForExit(); $p2.WaitForExit(); if ($p1.ExitCode -ne 0 -or $p2.ExitCode -ne 0) { exit 1 }"
+powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .github\scripts\run-with-timeout.ps1 -FilePath Solutions\out\%CONFIGURATION%\%PLAT%\FuncTests\FuncTests.exe -ProcessArguments "--gtest_filter=MultipleLogManagersTests.MultiProcessesLogManager" -ProcessCount 2 -TimeoutSeconds 600 -Label FuncTests-concurrent-%CONFIGURATION%-%PLAT%-%TRANSPORT%
if not "%ERRORLEVEL%"=="0" exit /b %ERRORLEVEL%
diff --git a/cmake/MatsdkOptions.cmake b/cmake/MatsdkOptions.cmake
index a56e468c6..3cb213ef8 100644
--- a/cmake/MatsdkOptions.cmake
+++ b/cmake/MatsdkOptions.cmake
@@ -42,6 +42,8 @@ option(MATSDK_BUILD_AZMON
"Build Azure Monitor / Application Insights support" ON)
option(MATSDK_BUILD_APPLE_HTTP
"Build the Apple-native HTTP client" "${APPLE}")
+option(MATSDK_USE_WININET
+ "Use WinInet instead of WinHTTP as the Win32 desktop HTTP client" OFF)
set(_matsdk_android_http_client_predefined OFF)
if(DEFINED MATSDK_ANDROID_HTTP_CLIENT)
diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md
index 8cdb27c69..a4aa85a3c 100644
--- a/docs/building-with-vcpkg.md
+++ b/docs/building-with-vcpkg.md
@@ -220,18 +220,27 @@ On Linux, libcurl is provided by the default `curl-openssl` feature;
`curl-mbedtls` swaps in the mbedTLS backend — see
[Choose the Linux HTTP client / TLS backend](#choose-the-linux-http-client--tls-backend-largest-lever-on-linux).
-Windows and macOS/iOS use platform-native HTTP clients (WinInet and
+Windows and macOS/iOS use platform-native HTTP clients (WinHTTP and
NSURLSession respectively). Android defaults to the platform Java/JNI HTTP
bridge; native curl is available only through explicit `android-curl-*` features.
> **Note (Windows):** The port targets the MSVC/`WIN32` PAL on Windows, which
-> uses WinInet, so the default `curl` dependency is declared for Linux only
+> uses WinHTTP, so the default `curl` dependency is declared for Linux only
> (Android has separate explicit `android-curl-*` features). A MinGW /
> non-MSVC Windows triplet — or forcing `-DPAL_IMPLEMENTATION=CPP11` on Windows —
> selects the curl HTTP client, which the port does not provision on Windows
> (broadening `curl` to `windows` would pull an unused curl into every MSVC
> build, since vcpkg platform expressions can't key off the PAL). Use a standard
> MSVC triplet such as `x64-windows-static` for Windows vcpkg builds.
+>
+> Consumers that require WinInet's IE-integrated proxy or cookie behavior can
+> opt in with the `wininet` feature, for example
+> `"features": ["wininet", "system-sqlite"]`.
+> WinHTTP uses automatic or machine-level proxy configuration rather than the
+> logged-on user's Internet Explorer settings, does not answer authentication
+> challenges with ambient user credentials, and reports WinHTTP error codes.
+> Consumers that depend on the prior WinInet behavior should select the feature
+> explicitly before updating.
## Optional: SIMD-Optimized zlib with zlib-ng
@@ -303,7 +312,7 @@ export table pins its symbols and defeats `/OPT:REF`.
### Choose the Linux HTTP client / TLS backend (largest lever on Linux)
On Linux the built-in HTTP client is libcurl, and curl's TLS backend dominates
-the SDK's footprint. (Windows uses WinInet, Apple uses NSURLSession, and Android
+the SDK's footprint. (Windows uses WinHTTP by default, Apple uses NSURLSession, and Android
uses the Java/JNI bridge by default, so this section does not apply there.) The
port exposes the Linux TLS backend as two mutually-exclusive features; pick the
one that matches what your application already has:
diff --git a/examples/c/SampleC/SampleC.vcxproj b/examples/c/SampleC/SampleC.vcxproj
index d307939cf..8dc8948f1 100644
--- a/examples/c/SampleC/SampleC.vcxproj
+++ b/examples/c/SampleC/SampleC.vcxproj
@@ -1,4 +1,4 @@
-
+
@@ -43,7 +43,7 @@
false
- $(MSBuildProjectDirectory)\lib\$(Configuration)\$(Platform);$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib
+ $(LibraryPath)
$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include;$(MSBuildProjectDirectory)\include
@@ -53,7 +53,7 @@
Level3
Disabled
HAVE_DYNAMIC_C_LIB;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
- $(SolutionDir)\..\lib\include\public
+ $(ProjectDir)\..\..\..\lib\include\public
Console
@@ -80,7 +80,7 @@
- $(SolutionDir)\..\lib\include\public
+ $(ProjectDir)\..\..\..\lib\include\public
Console
@@ -102,10 +102,10 @@
-
-
-
-
+
+
+
+
diff --git a/examples/c/SampleC/SampleC.vcxproj.filters b/examples/c/SampleC/SampleC.vcxproj.filters
index ec99270d2..bc6cb1d50 100644
--- a/examples/c/SampleC/SampleC.vcxproj.filters
+++ b/examples/c/SampleC/SampleC.vcxproj.filters
@@ -1,4 +1,4 @@
-
+
@@ -20,16 +20,16 @@
-
+
Header Files
-
+
Header Files
-
+
Header Files
-
+
Header Files
diff --git a/examples/cpp/SampleCpp/SampleCpp.vcxproj b/examples/cpp/SampleCpp/SampleCpp.vcxproj
index a8548808f..6f340fec9 100644
--- a/examples/cpp/SampleCpp/SampleCpp.vcxproj
+++ b/examples/cpp/SampleCpp/SampleCpp.vcxproj
@@ -244,7 +244,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
@@ -252,37 +252,37 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
true
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
@@ -290,19 +290,19 @@
true
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
true
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
true
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
@@ -310,37 +310,37 @@
true
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
true
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
true
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
true
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
true
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
@@ -348,13 +348,13 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
@@ -461,7 +461,7 @@
true
true
true
- wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
@@ -546,7 +546,7 @@
true
true
true
- wininet.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
@@ -666,7 +666,7 @@
Console
true
- wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
@@ -818,7 +818,7 @@
Console
true
- wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
@@ -894,7 +894,7 @@
Console
true
- wininet.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
@@ -1013,7 +1013,7 @@
true
true
true
- wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
diff --git a/examples/cpp/SampleCppLogManagers/SampleCppLogManagers.vcxproj b/examples/cpp/SampleCppLogManagers/SampleCppLogManagers.vcxproj
index 7f6b47434..def42ce22 100644
--- a/examples/cpp/SampleCppLogManagers/SampleCppLogManagers.vcxproj
+++ b/examples/cpp/SampleCppLogManagers/SampleCppLogManagers.vcxproj
@@ -67,7 +67,7 @@
true
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public;$(SolutionDir)\..\lib\pal\
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public;$(SolutionDir)\..\lib\pal\
$(ProjectDir)
$(Configuration)\
$(LibraryPath)
@@ -75,16 +75,16 @@
true
$(ProjectDir)
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public;$(SolutionDir)\..\lib\pal\
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public;$(SolutionDir)\..\lib\pal\
$(LibraryPath)
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\..\lib\include\public
diff --git a/examples/cpp/SampleCppMini/SampleCppMini.vcxproj b/examples/cpp/SampleCppMini/SampleCppMini.vcxproj
index 424394f7e..cdcc13ea4 100644
--- a/examples/cpp/SampleCppMini/SampleCppMini.vcxproj
+++ b/examples/cpp/SampleCppMini/SampleCppMini.vcxproj
@@ -262,7 +262,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
@@ -272,7 +272,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -280,7 +280,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -288,7 +288,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -296,7 +296,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -304,7 +304,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -312,7 +312,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
@@ -322,7 +322,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -330,7 +330,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -338,7 +338,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
@@ -348,7 +348,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -356,7 +356,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -364,7 +364,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -372,7 +372,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -380,7 +380,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -388,7 +388,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
@@ -398,7 +398,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -406,7 +406,7 @@
false
- $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\lib\include\public
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\lib\include\public
true
@@ -430,7 +430,7 @@
false
false
false
- false
+ Sync
false
Disabled
Size
@@ -452,13 +452,8 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
- wininet.lib;Crypt32.lib;
+ wininet.lib;winhttp.lib;Crypt32.lib;
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
- Copy DLL to target dir
-
@@ -486,7 +481,7 @@
false
false
false
- false
+ Sync
false
Disabled
Size
@@ -508,15 +503,8 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
- wininet.lib;Crypt32.lib;
+ wininet.lib;winhttp.lib;Crypt32.lib;
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -549,7 +537,7 @@
false
false
false
- false
+ Sync
false
Disabled
Size
@@ -563,7 +551,7 @@
true
true
true
- wininet.lib;Crypt32.lib;wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
false
true
true
@@ -571,14 +559,7 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -611,7 +592,7 @@
false
false
false
- false
+ Sync
false
Disabled
Size
@@ -626,7 +607,7 @@
true
true
true
- wininet.lib;Crypt32.lib;libcmt.lib;libvcruntime.lib;libucrt.lib;Version.lib;wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;libcmt.lib;libvcruntime.lib;libucrt.lib;Version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
true
false
true
@@ -635,14 +616,7 @@
/merge:.rdata=.text
false
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -675,7 +649,7 @@
false
false
false
- false
+ Sync
false
Disabled
Size
@@ -689,7 +663,7 @@
true
true
true
- wininet.lib;Crypt32.lib;wininet.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
false
true
true
@@ -697,14 +671,7 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -737,7 +704,7 @@
false
false
false
- false
+ Sync
false
Disabled
Size
@@ -752,7 +719,7 @@
true
true
true
- wininet.lib;Crypt32.lib;libcmt.lib;libvcruntime.lib;libucrt.lib;Version.lib;wininet.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;libcmt.lib;libvcruntime.lib;libucrt.lib;Version.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
true
false
true
@@ -761,14 +728,7 @@
/merge:.rdata=.text
false
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -802,7 +762,7 @@
Default
false
false
- false
+ Sync
Disabled
Size
false
@@ -823,15 +783,8 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
- wininet.lib;Crypt32.lib;
+ wininet.lib;winhttp.lib;Crypt32.lib;
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -866,7 +819,7 @@
Default
false
false
- false
+ Sync
Disabled
Size
false
@@ -877,7 +830,7 @@
Console
true
- wininet.lib;Crypt32.lib;wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
false
true
true
@@ -887,14 +840,7 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -930,7 +876,7 @@
Default
false
false
- false
+ Sync
Disabled
Size
false
@@ -941,7 +887,7 @@
Console
true
- wininet.lib;Crypt32.lib;libucrtd.lib;Version.lib;wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;libucrtd.lib;Version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
false
true
true
@@ -951,14 +897,7 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -990,7 +929,7 @@
Default
false
false
- false
+ Sync
false
Disabled
Size
@@ -1013,15 +952,8 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
- wininet.lib;Crypt32.lib;
+ wininet.lib;winhttp.lib;Crypt32.lib;
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -1054,7 +986,7 @@
Default
false
false
- false
+ Sync
false
Disabled
Size
@@ -1077,15 +1009,8 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
- wininet.lib;Crypt32.lib;
+ wininet.lib;winhttp.lib;Crypt32.lib;
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -1119,7 +1044,7 @@
Default
false
false
- false
+ Sync
false
Disabled
Size
@@ -1132,7 +1057,7 @@
Console
true
- wininet.lib;Crypt32.lib;wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
false
true
true
@@ -1142,14 +1067,7 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -1183,7 +1101,7 @@
Default
false
false
- false
+ Sync
false
Disabled
Size
@@ -1196,7 +1114,7 @@
Console
true
- wininet.lib;Crypt32.lib;libucrtd.lib;Version.lib;wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;libucrtd.lib;Version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
false
true
true
@@ -1206,14 +1124,7 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -1246,7 +1157,7 @@
Default
false
false
- false
+ Sync
false
Disabled
Size
@@ -1259,7 +1170,7 @@
Console
true
- wininet.lib;Crypt32.lib;wininet.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
false
true
true
@@ -1269,14 +1180,7 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -1310,7 +1214,7 @@
Default
false
false
- false
+ Sync
false
Disabled
Size
@@ -1323,7 +1227,7 @@
Console
true
- wininet.lib;Crypt32.lib;libucrtd.lib;Version.lib;wininet.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;libucrtd.lib;Version.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)
false
true
true
@@ -1333,14 +1237,7 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -1370,7 +1267,7 @@
false
false
false
- false
+ Sync
false
Disabled
Size
@@ -1393,15 +1290,8 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
- wininet.lib;Crypt32.lib;
+ wininet.lib;winhttp.lib;Crypt32.lib;
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -1433,7 +1323,7 @@
false
false
false
- false
+ Sync
false
Disabled
Size
@@ -1448,7 +1338,7 @@
true
true
true
- wininet.lib;Crypt32.lib;wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
false
true
true
@@ -1456,14 +1346,7 @@
false
/merge:.rdata=.text
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -1496,7 +1379,7 @@
false
false
false
- false
+ Sync
false
Disabled
Size
@@ -1512,7 +1395,7 @@
true
true
true
- wininet.lib;Crypt32.lib;libcmt.lib;libvcruntime.lib;libucrt.lib;Version.lib;wininet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ wininet.lib;winhttp.lib;Crypt32.lib;libcmt.lib;libvcruntime.lib;libucrt.lib;Version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
true
false
true
@@ -1521,14 +1404,7 @@
/merge:.rdata=.text
false
false
- API-MS-WIN-CORE-WINRT-STRING-L1-1-0;API-MS-WIN-CORE-WINRT-L1-1-0
-
- $(ProjectDir)\deploy-dll.cmd $(PlatformTarget) $(Configuration) $(OutDir)
-
-
- Copy DLL to target dir
-
@@ -1548,13 +1424,12 @@
-
+
-
-
+
{1dc6b38a-b390-34ce-907f-4958807a3d43}
diff --git a/examples/cpp/SampleCppMini/SampleCppMini.vcxproj.filters b/examples/cpp/SampleCppMini/SampleCppMini.vcxproj.filters
index 2df19ab39..ebc2bf270 100644
--- a/examples/cpp/SampleCppMini/SampleCppMini.vcxproj.filters
+++ b/examples/cpp/SampleCppMini/SampleCppMini.vcxproj.filters
@@ -22,7 +22,4 @@
Source Files
-
-
-
\ No newline at end of file
diff --git a/examples/cpp/SampleCppMini/deploy-dll.cmd b/examples/cpp/SampleCppMini/deploy-dll.cmd
deleted file mode 100644
index bd98ed454..000000000
--- a/examples/cpp/SampleCppMini/deploy-dll.cmd
+++ /dev/null
@@ -1,3 +0,0 @@
-copy %3\..\win32-mini-dll\*.dll %3
-copy %3\..\win32-mini-dll\*.pdb %3
-exit /b 0
diff --git a/examples/cpp/SampleCppUWP/SampleCppUWP.vcxproj b/examples/cpp/SampleCppUWP/SampleCppUWP.vcxproj
index a55fbf088..39c8649fe 100644
--- a/examples/cpp/SampleCppUWP/SampleCppUWP.vcxproj
+++ b/examples/cpp/SampleCppUWP/SampleCppUWP.vcxproj
@@ -134,7 +134,7 @@
/bigobj %(AdditionalOptions)
4453;28204
- $(SolutionDir)\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
+ $(ProjectDir)\..\..\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions)
Cdecl
true
@@ -146,7 +146,7 @@
/bigobj %(AdditionalOptions)
4453;28204
- $(SolutionDir)\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
+ $(ProjectDir)\..\..\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions)
Cdecl
true
@@ -159,7 +159,7 @@
/bigobj %(AdditionalOptions)
4453;28204
- $(SolutionDir)\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
+ $(ProjectDir)\..\..\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions)
MinSpace
Size
@@ -173,7 +173,7 @@
/bigobj %(AdditionalOptions)
4453;28204
- $(SolutionDir)\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
+ $(ProjectDir)\..\..\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions)
MinSpace
Size
@@ -188,7 +188,7 @@
/bigobj %(AdditionalOptions)
4453;28204
- $(SolutionDir)\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
+ $(ProjectDir)\..\..\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
_UNICODE;UNICODE;%(PreprocessorDefinitions)
ProgramDatabase
Cdecl
@@ -204,7 +204,7 @@
/bigobj %(AdditionalOptions)
4453;28204
- $(SolutionDir)\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
+ $(ProjectDir)\..\..\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
_UNICODE;UNICODE;%(PreprocessorDefinitions)
MinSpace
Size
@@ -217,7 +217,7 @@
/bigobj %(AdditionalOptions)
4453;28204
- $(SolutionDir)\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
+ $(ProjectDir)\..\..\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
_UNICODE;UNICODE;%(PreprocessorDefinitions)
ProgramDatabase
Cdecl
@@ -229,7 +229,7 @@
/bigobj %(AdditionalOptions)
4453;28204
- $(SolutionDir)\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
+ $(ProjectDir)\..\..\..\lib\include\public;$(ProjectDir);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)
_UNICODE;UNICODE;%(PreprocessorDefinitions)
MinSpace
Size
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index b08fd4537..e1bd6d253 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -299,9 +299,24 @@ target_compile_definitions(matsdk_internal_config INTERFACE
_USRDLL
WINVER=_WIN32_WINNT_WIN7)
target_compile_options(matsdk_internal_config INTERFACE /U_MBCS)
+if(MATSDK_USE_WININET)
+ target_compile_definitions(matsdk_internal_config INTERFACE HAVE_MAT_WININET_HTTP_CLIENT)
+else()
+ target_compile_definitions(matsdk_internal_config INTERFACE HAVE_MAT_WINHTTP_HTTP_CLIENT)
+endif()
+if(MATSDK_USE_WININET)
list(APPEND SRCS
http/HttpClient_WinInet.cpp
http/HttpClient_WinInet.hpp
+ )
+else()
+ list(APPEND SRCS
+ http/HttpClient_WinHttp.cpp
+ http/HttpClient_WinHttp.hpp
+ http/IBoundedHttpClientCancel.hpp
+ )
+endif()
+ list(APPEND SRCS
pal/desktop/WindowsDesktopDeviceInformationImpl.cpp
pal/desktop/WindowsDesktopNetworkInformationImpl.cpp
pal/desktop/WindowsDesktopSystemInformationImpl.cpp
@@ -666,7 +681,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
target_link_libraries(mat PUBLIC log)
endif()
elseif(PAL_IMPLEMENTATION STREQUAL "WIN32")
- target_link_libraries(mat PUBLIC wininet crypt32 ws2_32)
+ if(MATSDK_USE_WININET)
+ target_link_libraries(mat PRIVATE wininet)
+ else()
+ target_link_libraries(mat PRIVATE winhttp)
+ endif()
+ target_link_libraries(mat PRIVATE crypt32)
elseif(APPLE)
target_link_libraries(mat PUBLIC
"-framework CoreFoundation"
diff --git a/lib/http/HttpClientFactory.cpp b/lib/http/HttpClientFactory.cpp
index 5419f161d..b58175e1a 100644
--- a/lib/http/HttpClientFactory.cpp
+++ b/lib/http/HttpClientFactory.cpp
@@ -18,6 +18,8 @@
#include "http/HttpClient_WinRt.hpp"
#elif defined(HAVE_MAT_WININET_HTTP_CLIENT)
#include "http/HttpClient_WinInet.hpp"
+ #elif defined(HAVE_MAT_WINHTTP_HTTP_CLIENT)
+ #include "http/HttpClient_WinHttp.hpp"
#endif
#elif defined(MATSDK_PAL_CPP11)
#if TARGET_OS_IPHONE || (defined(__APPLE__) && defined(APPLE_HTTP))
@@ -49,6 +51,13 @@ namespace MAT_NS_BEGIN {
return std::make_shared();
}
+#elif defined(HAVE_MAT_WINHTTP_HTTP_CLIENT)
+ /* Win32 WinHTTP client (default) */
+ std::shared_ptr HttpClientFactory::Create() {
+ LOG_TRACE("Creating HttpClient_WinHttp");
+ return std::make_shared();
+ }
+
#endif
#elif defined(HAVE_MAT_CURL_HTTP_CLIENT)
std::shared_ptr HttpClientFactory::Create() {
diff --git a/lib/http/HttpClientFactory.hpp b/lib/http/HttpClientFactory.hpp
index c96bc2ab0..ae1fb9681 100644
--- a/lib/http/HttpClientFactory.hpp
+++ b/lib/http/HttpClientFactory.hpp
@@ -25,8 +25,22 @@ class HttpClientFactory
// TODO: [maxgolov] - remove this once there is a better way to pass HTTP client configuration
#if defined(MATSDK_PAL_WIN32) && !defined(_WINRT_DLL)
-#define HAVE_MAT_WININET_HTTP_CLIENT
-#include "http/HttpClient_WinInet.hpp"
+ #if defined(HAVE_MAT_WININET_HTTP_CLIENT) && defined(HAVE_MAT_WINHTTP_HTTP_CLIENT)
+ #error WinInet and WinHTTP cannot both be selected.
+ #endif
+ #if defined(HAVE_MAT_WININET_HTTP_CLIENT)
+ #include "http/HttpClient_WinInet.hpp"
+ #else
+ // WinHTTP is the default Win32 desktop transport: unlike WinInet, it does
+ // not depend on a logged-on interactive user or that user's Internet
+ // Explorer settings, so it works in services and other non-interactive
+ // processes without extra configuration. Define HAVE_MAT_WININET_HTTP_CLIENT
+ // to opt back into WinInet (e.g. for IE-integrated proxy/cookie behavior).
+ #ifndef HAVE_MAT_WINHTTP_HTTP_CLIENT
+ #define HAVE_MAT_WINHTTP_HTTP_CLIENT
+ #endif
+ #include "http/HttpClient_WinHttp.hpp"
+ #endif
#endif
#endif // HAVE_MAT_DEFAULT_HTTP_CLIENT
diff --git a/lib/http/HttpClientManager.cpp b/lib/http/HttpClientManager.cpp
index 3c7d1f809..730f7b341 100644
--- a/lib/http/HttpClientManager.cpp
+++ b/lib/http/HttpClientManager.cpp
@@ -11,6 +11,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -86,11 +88,33 @@ namespace MAT_NS_BEGIN {
m_httpClient(httpClient),
m_taskDispatcher(taskDispatcher)
{
+ int64_t configuredSeconds =
+ logManager.GetLogConfiguration()[CFG_INT_MAX_TEARDOWN_TIME];
+ if (configuredSeconds > 0)
+ {
+ int64_t const maxSeconds =
+ std::chrono::milliseconds::max().count() / 1000;
+ m_cancelDrainTimeout = std::chrono::seconds(
+ std::min(configuredSeconds, maxSeconds));
+ }
}
HttpClientManager::~HttpClientManager() noexcept
{
- cancelAllRequestsAsync();
+ // HttpCallback and scheduled response tasks retain a reference to this
+ // manager, so non-reentrant destruction must be a full callback lifetime
+ // barrier. Reentrant destruction is unsupported because the active
+ // callback itself must still unwind through this object.
+#ifndef NDEBUG
+ {
+ std::lock_guard lock(m_httpCallbacksMtx);
+ for (auto const& active : m_activeHttpCallbacks)
+ {
+ assert(active.second != std::this_thread::get_id());
+ }
+ }
+#endif
+ cancelAllRequests();
}
void HttpClientManager::handleSendRequest(EventsUploadContextPtr const& ctx)
@@ -116,30 +140,54 @@ namespace MAT_NS_BEGIN {
/* This method may get executed synchronously on Windows from handleSendRequest in case of connection failure */
void HttpClientManager::onHttpResponse(HttpCallback* callback)
{
- EventsUploadContextPtr &ctx = callback->m_ctx;
{
- LOCKGUARD(m_httpCallbacksMtx);
+ std::lock_guard lock(m_httpCallbacksMtx);
auto z = std::find(m_httpCallbacks.cbegin(), m_httpCallbacks.cend(), callback);
if (z == m_httpCallbacks.end()) {
- assert(false);
+ LOG_ERROR("Ignoring untracked HTTP callback=%p", callback);
+ return;
}
+ m_activeHttpCallbacks[callback] = std::this_thread::get_id();
+ m_httpCallbacksCV.notify_all();
+ }
+
+ EventsUploadContextPtr &ctx = callback->m_ctx;
#if !defined(NDEBUG) && defined(HAVE_MAT_LOGGING)
- // Response may be null if request got aborted
- if (ctx->httpResponse != nullptr)
- {
- IHttpResponse const& response = (*ctx->httpResponse);
- LOG_TRACE("HTTP response %s: result=%u, status=%u, body=%u bytes",
- response.GetId().c_str(), response.GetResult(), response.GetStatusCode(), static_cast(response.GetBody().size()));
- }
+ // Response may be null if request got aborted
+ if (ctx->httpResponse != nullptr)
+ {
+ IHttpResponse const& response = (*ctx->httpResponse);
+ LOG_TRACE("HTTP response %s: result=%u, status=%u, body=%u bytes",
+ response.GetId().c_str(), response.GetResult(), response.GetStatusCode(), static_cast(response.GetBody().size()));
+ }
#endif
+ // Never hold m_httpCallbacksMtx while calling the transport or
+ // dispatching requestDone(): either path may synchronously re-enter this
+ // manager. Reentrant cancellation recognizes this callback as active
+ // and does not wait for its own stack to unwind.
+ try
+ {
requestDone(ctx);
- // request done should be handled by now
+ }
+ catch (const std::exception& ex)
+ {
+ LOG_ERROR("Unhandled exception in HTTP response callback: %s", ex.what());
+ }
+ catch (...)
+ {
+ LOG_ERROR("Unhandled non-standard exception in HTTP response callback");
+ }
+ // request done should be handled by now
+ {
+ std::lock_guard lock(m_httpCallbacksMtx);
LOG_TRACE("HTTP remove callback=%p", callback);
m_httpCallbacks.remove(callback);
- // Wake cancelAllRequests() waiting for the list to drain.
+ m_activeHttpCallbacks.erase(callback);
+ // Wake cancelAllRequests() waiting for the list to drain while the
+ // condition variable is still guaranteed to be alive.
m_httpCallbacksCV.notify_all();
}
@@ -198,22 +246,45 @@ namespace MAT_NS_BEGIN {
void HttpClientManager::cancelAllRequests(bool bestEffort)
{
- // Use the transport-specific bounded path when available; older clients
- // fall back to cancelling tracked requests individually.
+ if (bestEffort &&
+ m_cancelDrainTimeout <= std::chrono::milliseconds::zero())
+ {
+ return;
+ }
+ // Quiesce the transport before taking m_httpCallbacksMtx. Moving this
+ // call under the mutex deadlocks when a synchronous transport completion
+ // re-enters onHttpResponse().
const auto cancelStart = std::chrono::steady_clock::now();
cancelAllRequestsAsync(bestEffort ? m_cancelDrainTimeout : std::chrono::milliseconds::zero());
// Drain callbacks through the condition variable signaled by onHttpResponse.
- std::unique_lock lock(m_httpCallbacksMtx);
+ std::unique_lock lock(m_httpCallbacksMtx);
+ std::thread::id const callerThread = std::this_thread::get_id();
+ auto callbacksDrainedForCaller = [this, callerThread] {
+ for (auto const& active : m_activeHttpCallbacks)
+ {
+ if (active.second == callerThread)
+ {
+ // A completion running on a single-thread dispatcher cannot
+ // wait for peer completions queued behind itself. Returning
+ // from reentrant cancellation lets this callback unwind and
+ // the dispatcher drain the remaining work.
+ return true;
+ }
+ }
+ return m_httpCallbacks.empty();
+ };
if (bestEffort)
{
- // Keep pause bounded, including time spent in the transport cancel.
+ // Keep pause within the configured soft cap, including time spent
+ // in transport cancellation. A synchronous native handle close
+ // already in progress can finish after the deadline.
const auto elapsed = std::chrono::duration_cast(
std::chrono::steady_clock::now() - cancelStart);
const auto remaining = (elapsed < m_cancelDrainTimeout)
? (m_cancelDrainTimeout - elapsed) : std::chrono::milliseconds::zero();
- if (!m_httpCallbacksCV.wait_for(lock, remaining,
- [this] { return m_httpCallbacks.empty(); }))
+ if (!m_httpCallbacksCV.wait_for(
+ lock, remaining, callbacksDrainedForCaller))
{
LOG_WARN("cancelAllRequests: %zu callback(s) still draining after %lld ms (best-effort)",
m_httpCallbacks.size(), static_cast(m_cancelDrainTimeout.count()));
@@ -221,8 +292,10 @@ namespace MAT_NS_BEGIN {
}
else
{
- // Shutdown/cleanup is the lifetime barrier for callback state, so drain fully.
- m_httpCallbacksCV.wait(lock, [this] { return m_httpCallbacks.empty(); });
+ // Non-reentrant shutdown/cleanup is the lifetime barrier for callback
+ // state. A callback re-entering cancellation must return so its own
+ // stack can unwind; destroying the manager from that stack is unsupported.
+ m_httpCallbacksCV.wait(lock, callbacksDrainedForCaller);
}
}
diff --git a/lib/http/HttpClientManager.hpp b/lib/http/HttpClientManager.hpp
index 4f350e37f..9877c65eb 100644
--- a/lib/http/HttpClientManager.hpp
+++ b/lib/http/HttpClientManager.hpp
@@ -14,6 +14,8 @@
#include
#include
#include
+#include