winget-cli icon indicating copy to clipboard operation
winget-cli copied to clipboard

Adding Azure DevOps based Microsoft.PreIndexed.Package Source fails

Open Kjakster opened this issue 3 years ago • 2 comments

Brief description of your issue

When adding a Microsoft.PreIndexed.Package based HTTPS source a HTTP HEAD operation is attemped to retrieve file size of Source.MSIX. This fails due to lack of HEAD method support on the Azure DevOps.

I've tested both git and tfsgit providers with same result.

Source Add Exception 0x80190195 : Method not allowed (405).

Relevant Log Entries [REPO] Initializing source from: core => https://dev.azure.com/Tryll/DevTestLabs/_apis/git/repositories/Software-Repository/items?resolveLfs=true&%24format=octetStream&api-version=5.0&download=true&path=/source.msix [FAIL] WindowsPackageManager.dll!00007FF970FA3022: ReturnHr(1) tid(1e4) 80190195 Method not allowed (405). Msg:[D:\a_work\1\s\external\pkg\src\AppInstallerCommonCore\HttpStream\HttpClientWrapper.cpp(50)\WindowsPackageManager.dll!00007FF970F8F58A: (caller: 00007FF970E88BA9) Exception(1) tid(1e4) 80190195 Method not allowed (405). ]

[FAIL] WindowsPackageManager.dll!00007FF970E367C7: LogHr(1) tid(1e4) 80190195 Method not allowed (405).

HttpClientWrapper.cpp suggestion HttpClientWrapper::PopulateInfoAsync() in src/AppInstallerCommonCore/HttpStream/HttpClientWrapper.cpp : already supports a non determined file size, but throws immediately on HTTP response other than HttpStatusCode::Ok. It should rather go directly for a GET operation with co_await SendHttpRequestAsync(0, 1);

Steps to reproduce

winget source add --verbose-logs -n core -a "https://dev.azure.com/Tryll/DevTestLabs/_apis/git/repositories/Software-Repository/items?resolveLfs=true&%24format=octetStream&api-version=5.0&download=true&path=" Adding source: core -> https://dev.azure.com/Tryll/DevTestLabs/_apis/git/repositories/Software-Repository/items?resolveLfs=true&%24format=octetStream&api-version=5.0&download=true&path= An unexpected error occurred while executing the command: 0x80190195 : Method not allowed (405).

Expected behavior

Source is added.

Actual behavior

winget source add --verbose-logs -n core -a "https://dev.azure.com/Tryll/DevTestL abs/_apis/git/repositories/a352abf2-74c3-486c-8558-5eb0f525f163/items?path=" Adding source: core -> https://dev.azure.com/Tryll/DevTestLabs/_apis/git/repositories/a352abf2-74c3-486c-8558-5eb0f525f163/items?path= An unexpected error occurred while executing the command: 0x80190195 : Method not allowed (405).

Environment

Windows Package Manager v1.3.2691
Copyright (c) Microsoft Corporation. All rights reserved.

Windows: Windows.Desktop v10.0.22000.1098
System Architecture: X64
Package: Microsoft.DesktopAppInstaller v1.18.2691.0

Logs: %LOCALAPPDATA%\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\DiagOutputDir

Links               
---------------------------------------------------------------------------
Privacy Statement   https://aka.ms/winget-privacy
License Agreement   https://aka.ms/winget-license
Third Party Notices https://aka.ms/winget-3rdPartyNotice
Homepage            https://aka.ms/winget
Windows Store Terms https://www.microsoft.com/en-us/storedocs/terms-of-sale

Kjakster avatar Nov 03 '22 18:11 Kjakster

This works fine with a github based project https://github.com/Tryll/Software-Repository

winget source add --verbose-logs -n core -a https://raw.githubusercontent.com/Tryll/Software-Repository/master Adding source: core -> https://raw.githubusercontent.com/Tryll/Software-Repository/master ██████████████████████████████ 100% Done

Kjakster avatar Nov 03 '22 19:11 Kjakster

I looked abit more into this.

The purpose of HttpClientWrapper class is to enable ranged downloading, by first identifying file size. Where both HEAD and Range inspection is not supported by the hosting web server (like Azure DevOps) download fails completely.

Tested I compiled HttpClientWrapper::PopulateInfoAsync() with an exception allowing for MethodNotAllowed and it turns out Azure Devops repositories ("items" and "blobs") also does not support Ranged lookups/inspection either. "Content-Length" is not returned and full content is available resulting in crash at response.Content().ReadAsBufferAsync() in HttpClientWrapper::SendHttpRequestAsync.

Feature request If HEAD and Range=bytes=0-0 is not able to detect filesize, there should be a fall-back for a single full download. Supporting full download is the only option for HTTP hosts without HEAD or Range support (like Azure Devops).

Conclusion Maybe this is more of a feature request and not directly a bug; though PopulateInfoAsync should forward MethodNotAllowed results to SendHttpRequestAsync to attempt the Range approach, to determine file size and allow for ranged downloading.

Kjakster avatar Nov 04 '22 09:11 Kjakster