Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
a4cc356
[VCPKG] Add feature mirror
Jul 22, 2020
2b3e855
Correct build script, add mirror addr to cmake args
Jul 22, 2020
d7cd136
clang-format
Jul 22, 2020
881fbe0
suitable mirror in cmake file, add code in vcpkg internal, fix vcxproj
Jul 22, 2020
d17ae85
Correct shell
Jul 22, 2020
874a6bd
Correct shell
Jul 23, 2020
6b92077
Add macro USE_MIRROR and VCPKG_MIRROR to CMakeLists.txt
Jul 23, 2020
d108534
Change the tools download address to the mirror address
Jul 23, 2020
849377c
Add mirror command
Jul 23, 2020
f04daea
Switch build option to environment VCPKG_EXPERIMENTAL_MIRROR_URL, fil…
Jul 24, 2020
83fe7f9
remove useless macro
Jul 24, 2020
f4e3e42
improve environment code
Jul 24, 2020
e34006a
clang-format
Jul 24, 2020
1481205
Correct archive hash algorithm
Jul 27, 2020
fc78256
fix crash
Jul 31, 2020
ec07566
clang-format
Aug 3, 2020
7650258
Merge branch 'master' of https://github.com/microsoft/vcpkg into dev/…
Aug 17, 2020
ee17142
Merge branch 'master' of https://github.com/microsoft/vcpkg into dev/…
Aug 17, 2020
067e40b
Revert mistake changes about vcxproj
Aug 17, 2020
4711530
correct configure file and clang-format
Aug 17, 2020
1f403ba
clang-format
Aug 17, 2020
248ebb8
correct code
Aug 17, 2020
c74d73d
Merge remote-tracking branch 'origin/master' into dev/jack/vcpkg_mirror
BillyONeal Aug 18, 2020
b6eafe0
Fix crash
Aug 18, 2020
66a6485
Merge branch 'master' of https://github.com/microsoft/vcpkg into dev/…
Aug 18, 2020
1e0e45c
Merge branch 'dev/jack/vcpkg_mirror' of https://github.com/JackBoosY/…
Aug 18, 2020
acf8198
Merge branch 'master' of https://github.com/microsoft/vcpkg into dev/…
Aug 19, 2020
8a03f8b
Remove sln
Aug 19, 2020
d54eb30
Restore vcpkg.props
Aug 19, 2020
bf18e5f
Restore vcpkgmetricsuploader.vcxproj
Aug 19, 2020
de5c3e5
Correct environment judgment
Aug 19, 2020
d840763
Revert incorrect changes
Aug 19, 2020
5d2b39b
Merge branch 'master' of https://github.com/microsoft/vcpkg into dev/…
Aug 20, 2020
3be7d69
Fix build
Aug 20, 2020
a3f7c26
clang-format
Aug 20, 2020
afe4d52
Fix crash
Aug 20, 2020
b716b5b
update test case
Aug 20, 2020
5c23abb
Rework commands.mirror
Sep 1, 2020
d26bcde
Reduce include files
Sep 1, 2020
f5843c4
Reduce include files
Sep 1, 2020
942b8dd
Remove vcpkg_use_mirror, fix VCPKG_EXPERIMENTAL_MIRROR_URL judgment
Sep 1, 2020
1ca45af
Re-fix VCPKG_EXPERIMENTAL_MIRROR_URL judgment
Sep 1, 2020
9edf845
clang-format
Sep 2, 2020
d9313de
clang-format
Sep 2, 2020
940f46c
Merge branch 'master' of https://github.com/microsoft/vcpkg into dev/…
Sep 8, 2020
e190ce6
Merge master branch
Sep 8, 2020
cf59c08
Merge branch 'master' of https://github.com/microsoft/vcpkg into dev/…
Sep 18, 2020
a306414
Restore vcpkg.vcxporj
Sep 18, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions scripts/cmake/vcpkg_download_distfile.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ function(vcpkg_download_distfile VAR)
message(FATAL_ERROR "vcpkg_download_distfile must not be passed both SHA512 and SKIP_SHA512.")
endif()
endif()

if (DEFINED ENV{VCPKG_EXPERIMENTAL_MIRROR_URL} AND NOT ENV{VCPKG_EXPERIMENTAL_MIRROR_URL} STREQUAL "")
message(STATUS "Use vcpkg mirror $ENV{VCPKG_EXPERIMENTAL_MIRROR_URL}")
set(vcpkg_download_distfile_URLS "ftp://$ENV{VCPKG_EXPERIMENTAL_MIRROR_URL}/${vcpkg_download_distfile_SHA512}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should do something reasonable in the vcpkg_download_distfile_SKIP_SHA512 case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without SHA512, vcpkg_download_distfile cannot splice the download URL.

endif()

set(downloaded_file_path ${DOWNLOADS}/${vcpkg_download_distfile_FILENAME})
set(download_file_path_part "${DOWNLOADS}/temp/${vcpkg_download_distfile_FILENAME}")
Expand Down
1 change: 0 additions & 1 deletion toolsrc/include/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#if defined(_WIN32)
#include <process.h>
#include <shellapi.h>
#include <winhttp.h>
#endif

#include <math.h>
Expand Down
10 changes: 10 additions & 0 deletions toolsrc/include/vcpkg/base/downloads.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@

namespace vcpkg::Downloads
{
void winhttp_download_file(Files::Filesystem& fs,
ZStringView target_file_path,
StringView hostname,
StringView url_path);

void ftp_download_file(Files::Filesystem& fs,
ZStringView target_file_path,
StringView hostname,
StringView url_path);

void verify_downloaded_file_hash(const Files::Filesystem& fs,
const std::string& url,
const fs::path& path,
Expand Down
15 changes: 15 additions & 0 deletions toolsrc/include/vcpkg/commands.mirror.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <vcpkg/build.h>

namespace vcpkg::Commands::Mirror
{
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);

struct MirrorCommand : Commands::TripletCommand
{
virtual void perform_and_exit(const VcpkgCmdArguments& inArgs,
const VcpkgPaths& paths,
Triplet default_triplet) const override;
};
}
17 changes: 17 additions & 0 deletions toolsrc/include/vcpkg/install.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@ namespace vcpkg::Install
const Dependencies::InstallPlanAction* action;
};

struct TrackedPackageInstallGuard
{
SpecSummary* current_summary = nullptr;
Chrono::ElapsedTimer build_timer = Chrono::ElapsedTimer::create_started();

TrackedPackageInstallGuard(const size_t package_count,
std::vector<SpecSummary>& results,
const PackageSpec& spec);

~TrackedPackageInstallGuard();

TrackedPackageInstallGuard(const TrackedPackageInstallGuard&) = delete;
TrackedPackageInstallGuard& operator=(const TrackedPackageInstallGuard&) = delete;
};

struct InstallSummary
{
std::vector<SpecSummary> results;
Expand Down Expand Up @@ -101,6 +116,8 @@ namespace vcpkg::Install

CMakeUsageInfo get_cmake_usage(const BinaryParagraph& bpgh, const VcpkgPaths& paths);

void print_cmake_information(const BinaryParagraph& bpgh, const VcpkgPaths& paths);

extern const CommandStructure COMMAND_STRUCTURE;

void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
Expand Down
4 changes: 4 additions & 0 deletions toolsrc/include/vcpkg/vcpkgcmdarguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ namespace vcpkg
constexpr static StringLiteral WAIT_FOR_LOCK_SWITCH = "x-wait-for-lock";
Optional<bool> wait_for_lock = nullopt;

constexpr static StringLiteral VCPKG_EXPERIMENTAL_MIRROR_URL = "VCPKG_EXPERIMENTAL_MIRROR_URL";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should name the variable EXPERIMENTAL because someday it won't be and there's no reason to force everyone to edit their scripts then?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTOH we can continue respecting the experimental form for backwards compatibility and this makes it clear for users that they are using an unsupported feature. Alternatively, the tool could emit a big yelllow warning at the top every time it's run with this env var set.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We conventionally use lowercase here

Suggested change
constexpr static StringLiteral VCPKG_EXPERIMENTAL_MIRROR_URL = "VCPKG_EXPERIMENTAL_MIRROR_URL";
constexpr static StringLiteral VCPKG_EXPERIMENTAL_MIRROR_URL = "x-mirror-url";

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The environment variable name is set here. Is this correct?

std::unique_ptr<std::string> download_mirror_url;
Optional<bool> use_mirror = nullopt;

constexpr static StringLiteral JSON_SWITCH = "x-json";
Optional<bool> json = nullopt;

Expand Down
2 changes: 2 additions & 0 deletions toolsrc/include/vcpkg/vcpkgpaths.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ namespace vcpkg

fs::path ports_cmake;

std::string vcpkg_mirror_url;

const fs::path& get_tool_exe(const std::string& tool) const;
const std::string& get_tool_version(const std::string& tool) const;

Expand Down
135 changes: 5 additions & 130 deletions toolsrc/src/vcpkg/base/downloads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,134 +10,6 @@

namespace vcpkg::Downloads
{
#if defined(_WIN32)
static void winhttp_download_file(Files::Filesystem& fs,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since winhttp.h has conflict with wininet.h, I split this function into two files.

ZStringView target_file_path,
StringView hostname,
StringView url_path)
{
// Make sure the directories are present, otherwise fopen_s fails
const auto dir = fs::path(target_file_path.c_str()).parent_path();
std::error_code ec;
fs.create_directories(dir, ec);
Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directories %s", fs::u8string(dir));

FILE* f = nullptr;
const errno_t err = fopen_s(&f, target_file_path.c_str(), "wb");
Checks::check_exit(VCPKG_LINE_INFO,
!err,
"Could not download https://%s%s. Failed to open file %s. Error code was %s",
hostname,
url_path,
target_file_path,
std::to_string(err));
ASSUME(f != nullptr);

auto hSession = WinHttpOpen(L"vcpkg/1.0",
IsWindows8Point1OrGreater() ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY
: WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0);
Checks::check_exit(VCPKG_LINE_INFO, hSession, "WinHttpOpen() failed: %d", GetLastError());

// If the environment variable HTTPS_PROXY is set
// use that variable as proxy. This situation might exist when user is in a company network
// with restricted network/proxy settings
auto maybe_https_proxy_env = System::get_environment_variable("HTTPS_PROXY");
if (auto p_https_proxy = maybe_https_proxy_env.get())
{
std::wstring env_proxy_settings = Strings::to_utf16(*p_https_proxy);
WINHTTP_PROXY_INFO proxy;
proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
proxy.lpszProxy = env_proxy_settings.data();
proxy.lpszProxyBypass = nullptr;

WinHttpSetOption(hSession, WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy));
}
// Win7 IE Proxy fallback
else if (IsWindows7OrGreater() && !IsWindows8Point1OrGreater())
{
// First check if any proxy has been found automatically
WINHTTP_PROXY_INFO proxyInfo;
DWORD proxyInfoSize = sizeof(WINHTTP_PROXY_INFO);
auto noProxyFound = !WinHttpQueryOption(hSession, WINHTTP_OPTION_PROXY, &proxyInfo, &proxyInfoSize) ||
proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY;

// If no proxy was found automatically, use IE's proxy settings, if any
if (noProxyFound)
{
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy;
if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr)
{
WINHTTP_PROXY_INFO proxy;
proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
proxy.lpszProxy = ieProxy.lpszProxy;
proxy.lpszProxyBypass = ieProxy.lpszProxyBypass;
WinHttpSetOption(hSession, WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy));
GlobalFree(ieProxy.lpszProxy);
GlobalFree(ieProxy.lpszProxyBypass);
GlobalFree(ieProxy.lpszAutoConfigUrl);
}
}
}

// Use Windows 10 defaults on Windows 7
DWORD secure_protocols(WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 |
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2);
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &secure_protocols, sizeof(secure_protocols));

// Specify an HTTP server.
auto hConnect = WinHttpConnect(hSession, Strings::to_utf16(hostname).c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0);
Checks::check_exit(VCPKG_LINE_INFO, hConnect, "WinHttpConnect() failed: %d", GetLastError());

// Create an HTTP request handle.
auto hRequest = WinHttpOpenRequest(hConnect,
L"GET",
Strings::to_utf16(url_path).c_str(),
nullptr,
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE);
Checks::check_exit(VCPKG_LINE_INFO, hRequest, "WinHttpOpenRequest() failed: %d", GetLastError());

// Send a request.
auto bResults =
WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);

Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpSendRequest() failed: %d", GetLastError());

// End the request.
bResults = WinHttpReceiveResponse(hRequest, NULL);
Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpReceiveResponse() failed: %d", GetLastError());

std::vector<char> buf;

size_t total_downloaded_size = 0;
DWORD dwSize = 0;
do
{
DWORD downloaded_size = 0;
bResults = WinHttpQueryDataAvailable(hRequest, &dwSize);
Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpQueryDataAvailable() failed: %d", GetLastError());

if (buf.size() < dwSize) buf.resize(static_cast<size_t>(dwSize) * 2);

bResults = WinHttpReadData(hRequest, (LPVOID)buf.data(), dwSize, &downloaded_size);
Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpReadData() failed: %d", GetLastError());
fwrite(buf.data(), 1, downloaded_size, f);

total_downloaded_size += downloaded_size;
} while (dwSize > 0);

WinHttpCloseHandle(hSession);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
fflush(f);
fclose(f);
}
#endif

void verify_downloaded_file_hash(const Files::Filesystem& fs,
const std::string& url,
const fs::path& path,
Expand Down Expand Up @@ -178,12 +50,15 @@ namespace vcpkg::Downloads
fs.remove(download_path, ec);
fs.remove(download_path_part_path, ec);
#if defined(_WIN32)
auto url_no_proto = url.substr(8); // drop https://
auto url_no_proto = url.substr(Strings::starts_with(url, "ftp") ? 6 : 8); // drop ftp:// or https://
auto path_begin = Util::find(url_no_proto, '/');
std::string hostname(url_no_proto.begin(), path_begin);
std::string path(path_begin, url_no_proto.end());

winhttp_download_file(fs, download_path_part, hostname, path);
if (Strings::starts_with(url, "ftp"))
ftp_download_file(fs, download_path_part, hostname, path);
else
winhttp_download_file(fs, download_path_part, hostname, path);
#else
const auto code = System::cmd_execute(
Strings::format(R"(curl -L '%s' --create-dirs --output '%s')", url, download_path_part));
Expand Down
49 changes: 49 additions & 0 deletions toolsrc/src/vcpkg/base/downloads_ftp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "pch.h"

#include <vcpkg/base/downloads.h>
#include <vcpkg/base/hash.h>
#include <vcpkg/base/system.h>
#include <vcpkg/base/system.process.h>
#include <vcpkg/base/util.h>

#if defined(_WIN32)
#include <VersionHelpers.h>
#include <wininet.h>
#pragma comment(lib, "Wininet")
#endif

namespace vcpkg::Downloads
{
#if defined(_WIN32)
void ftp_download_file(Files::Filesystem& fs,
ZStringView target_file_path,
StringView hostname,
StringView url_path)
{
// Make sure the directories are present, otherwise fopen_s fails
const auto dir = fs::path(target_file_path.c_str()).parent_path();
std::error_code ec;
fs.create_directories(dir, ec);
Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directories %s", fs::u8string(dir));

HINTERNET hConnect;
HINTERNET hFtpSession;
hConnect = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
Checks::check_exit(VCPKG_LINE_INFO, hConnect, "InternetOpen() failed: %d", GetLastError());

hFtpSession = InternetConnect(
hConnect, hostname.to_string().c_str(), INTERNET_DEFAULT_FTP_PORT, "", "", INTERNET_SERVICE_FTP, 0, 0);
Checks::check_exit(VCPKG_LINE_INFO, hFtpSession, "InternetConnect() failed: %d", GetLastError());
BOOL bSuc = FtpGetFile(hFtpSession,
url_path.to_string().c_str(),
target_file_path.to_string().c_str(),
FALSE,
FTP_TRANSFER_TYPE_BINARY,
0,
0);
Checks::check_exit(VCPKG_LINE_INFO, bSuc == TRUE, "InternetConnect() failed: %d", GetLastError());
InternetCloseHandle(hFtpSession);
InternetCloseHandle(hConnect);
}
#endif
}
Loading