microsoft / vcpkg

C++ Library Manager for Windows, Linux, and MacOS
MIT License
22.85k stars 6.3k forks source link

Curl error with http binary caching and windows 11 #40538

Open petersteneteg opened 1 month ago

petersteneteg commented 1 month ago

When using binary caching with a http server VCPKG will use curl to fetch files and passes -w "5ec47b8e-6776-4d70-b9b3-ac2a57bc0a1c%{http_code}\n" to curl here: https://github.com/microsoft/vcpkg-tool/blob/4063a94150c5d691a4fb39353bd9d48dc940b22b/src/vcpkg/base/downloads.cpp#L388C78-L388C93

On windows vcpkg will use the built in curl in C:\Windows\System32\curl.exe

and after a recent windows update that curl version was update to version:

curl 8.8.0 (Windows) libcurl/8.8.0 Schannel zlib/1.3 WinIDN Release-Date: 2024-05-22

which as a bug related to the -w flag, Where curl will fail with error code 43. See https://github.com/curl/curl/issues/13958

This is now fixed in more recent curl versions.

But there is no way to instruct vcpkg to use a different curl version. Curl is invoked using CreateProcessW with a nullptr for environment variable. So even if I add a new curl to the path it will not be found.

But CreateProcessW will also look in the same directory as the executable, before looking at C:\Windows\System32 So putting a copy of curl into the vcpkg directly works, and makes vcpkg use that version instead.

Environment

To Reproduce Steps to reproduce the behavior:

  1. Update windows to the affected version.
  2. run .\vcpkg.exe install --debug --binarysource="clear;http,>somehttpserver>/{sha},read"
  3. See error
    [DEBUG] 1007: CreateProcessW(curl --create-dirs -L -w "5ec47b8e-6776-4d70-b9b3-ac2a57bc0a1c%{http_code}\n" https://jenkins.inviwo.org/cache/0e3e27cd89e8bd151287289236de87c0df4ccc3dd1e8d44dda973529e9ce9c44 -o "C:\Users\petst55.AD\Projects\vcpkg\buildtrees\fast-float\x64-windows.zip")
    [DEBUG] 1007: cmd_execute_and_stream_data() returned 43 after   112188 us
    error: command:
    curl --create-dirs -L -w "5ec47b8e-6776-4d70-b9b3-ac2a57bc0a1c%{http_code}\n" https://jenkins.inviwo.org/cache/0e3e27cd89e8bd151287289236de87c0df4ccc3dd1e8d44dda973529e9ce9c44 -o "C:\Users\petst55.AD\Projects\vcpkg\buildtrees\fast-float\x64-windows.zip"
    failed with exit code 43 and the following output:
    [DEBUG] D:\a\_work\1\s\src\vcpkg\base\downloads.cpp(420):

Expected behavior successful installation

Failure logs -(please attached failure logs)

Additional context Add any other context about the problem here.

greenozon commented 1 month ago

Not all Windows builds have curl utility as a native component

petersteneteg commented 1 month ago

Seems to be quite common at least https://curl.se/windows/microsoft.html

On December 19 2017, Microsoft announced that since insider build 17063 of Windows 10, curl is a default component.

greenozon commented 1 month ago

agree, but the strange thing happens if you click the 1st URL on the curl page :0

PS had to use time-machine to read that MS page :(

https://web.archive.org/web/20240114164407/https://learn.microsoft.com/en-us/virtualization/community/team-blog/2017/20171219-tar-and-curl-come-to-windows

autoantwort commented 1 month ago

But there is no way to instruct vcpkg to use a different curl version.

IIRC it uses curl from the PATH.

petersteneteg commented 1 month ago

It does not use the path env variable In the end the CreateProcessW get called to create the process and that will Look in the following dirs

1 The directory from which the application loaded. 2 The current directory for the parent process. 3 The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. 4 The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System. 5 The Windows directory. Use the GetWindowsDirectory function to get the path of this directory. 6 The directories that are listed in the PATH environment variable. Note that this function does not search the per-application path specified by the App Paths registry key. To include this per-application path in the search sequence, use the ShellExecute function.

https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw

And since there is a Curl in sytem32 that will always be picked before any PATH ones. :(