Search code examples
bazel

Debug authentication of Bazel's http_file


I want to fetch some data in Bazel over HTTP. There's a http_file method that looks like what I want. The remote server I'm fetching from uses authentication, so I've written it as

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")

http_file(
    name = "data_file",
    urls = ["https://example.com/data.0.1.2"],
    sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    downloaded_file_path = "data_file",
)

When I try the build, I get

WARNING: Download from https://example.com/data.0.1.2 failed: class com.google.devtools.build.lib.bazel.repository.downloader.UnrecoverableHttpException GET returned 401 Unauthorized

Followed by fatal errors because the file doesn't exist.

The error makes me think that I'm not authenticating correctly. I have a .netrc file and curl is able to use it to fetch the file.

Is there a way for me to debug? If it was curl, I would pass -v and see the auth header being sent with the request. I'm not sure if bazel is failing to send any authentication or if it's incorrect.

Running Bazel 3.2.0 on Mac OS (Darwin 19.6.0) and on Linux (Ubuntu 18.04).


Solution

  • HTTP 401 indeed sounds like incorrectly or not at all authenticated. .netrc should be supported and recognized. If not explicitly specified with netrc attribute, ${HOME}/.netrc would be tried if HOME is in the environment and bazel runs on non-Windows host (this has been the case since bazel 1.1; and shortly in 0.29) or %USERPROFILE%/.netrc if the variable is in the environment and running on Windows (this has been the case since 3.1). At the risk of stating the obvious, the .netrc should be owned by the same UID under which the process using it runs and its permbits should be 0600. If authentication methods other then http basic are needed, auth_patterns attribute needs to be used to configure that.

    I am not aware of there being any ready made repository rule debugging facility such as CLI flag, but in this case it should be viable to copy the implementation of of the rule and functions it uses from tools/build_defs/repo, instrument it to get debugging info from it and use that for the purpose. For starters perhaps just print(auth) of what auth = _get_auth(ctx, all_urls) yielded to see if the that rule got the right idea about how to talk to host in question. It should be a dict with type, login, password information for each individual urls entries. The magic itself happens in use_netrc.