Make http_archive accept a .netrc file

Change http_archive and related functions accept a .netrc file
to be used for authentication.

Change-Id: Icbe9d3e308e6756170d74a7438bf77e84743b901
PiperOrigin-RevId: 256530442
diff --git a/tools/build_defs/repo/http.bzl b/tools/build_defs/repo/http.bzl
index 2293e44..61df5ba 100644
--- a/tools/build_defs/repo/http.bzl
+++ b/tools/build_defs/repo/http.bzl
@@ -30,7 +30,23 @@
 replace the native rules.
 """
 
-load(":utils.bzl", "patch", "update_attrs", "workspace_and_buildfile")
+load(
+    ":utils.bzl",
+    "patch",
+    "read_netrc",
+    "update_attrs",
+    "use_netrc",
+    "workspace_and_buildfile",
+)
+
+def _get_auth(ctx, urls):
+    """Given the list of URLs obtain the correct auth dict."""
+    if ctx.attr.netrc:
+        netrc = read_netrc(ctx, ctx.attr.netrc)
+        return use_netrc(netrc, urls)
+
+    # TODO: use ~/.netrc instead, if it exists and is readable
+    return {}
 
 def _http_archive_impl(ctx):
     """Implementation of the http_archive rule."""
@@ -45,6 +61,8 @@
     if ctx.attr.url:
         all_urls = [ctx.attr.url] + all_urls
 
+    auth = _get_auth(ctx, all_urls)
+
     download_info = ctx.download_and_extract(
         all_urls,
         "",
@@ -52,6 +70,7 @@
         ctx.attr.type,
         ctx.attr.strip_prefix,
         canonical_id = ctx.attr.canonical_id,
+        auth = auth,
     )
     patch(ctx)
     workspace_and_buildfile(ctx)
@@ -82,11 +101,13 @@
     download_path = ctx.path("file/" + downloaded_file_path)
     if download_path in forbidden_files or not str(download_path).startswith(str(repo_root)):
         fail("'%s' cannot be used as downloaded_file_path in http_file" % ctx.attr.downloaded_file_path)
+    auth = _get_auth(ctx, ctx.attr.urls)
     download_info = ctx.download(
         ctx.attr.urls,
         "file/" + downloaded_file_path,
         ctx.attr.sha256,
         ctx.attr.executable,
+        auth = auth,
     )
     ctx.file("WORKSPACE", "workspace(name = \"{name}\")".format(name = ctx.name))
     ctx.file("file/BUILD", _HTTP_FILE_BUILD.format(downloaded_file_path))
@@ -117,7 +138,13 @@
         all_urls = ctx.attr.urls
     if ctx.attr.url:
         all_urls = [ctx.attr.url] + all_urls
-    download_info = ctx.download(all_urls, "jar/downloaded.jar", ctx.attr.sha256)
+    auth = _get_auth(ctx, all_urls)
+    download_info = ctx.download(
+        all_urls,
+        "jar/downloaded.jar",
+        ctx.attr.sha256,
+        auth = auth,
+    )
     ctx.file("WORKSPACE", "workspace(name = \"{name}\")".format(name = ctx.name))
     ctx.file("jar/BUILD", _HTTP_JAR_BUILD)
     return update_attrs(ctx.attr, _http_jar_attrs.keys(), {"sha256": download_info.sha256})
@@ -150,6 +177,9 @@
 field will make your build non-hermetic. It is optional to make development
 easier but should be set before shipping.""",
     ),
+    "netrc": attr.string(
+        doc = "Location of the .netrc file to use for authentication",
+    ),
     "canonical_id": attr.string(
         doc = """A canonical id of the archive downloaded
 
@@ -309,6 +339,9 @@
 Each entry must be a file, http or https URL. Redirections are followed.
 Authentication is not supported.""",
     ),
+    "netrc": attr.string(
+        doc = "Location of the .netrc file to use for authentication",
+    ),
 }
 
 http_file = repository_rule(
@@ -350,6 +383,9 @@
             "A list of URLS the jar can be fetched from. They have to end " +
             "in `.jar`.",
     ),
+    "netrc": attr.string(
+        doc = "Location of the .netrc file to use for authentication",
+    ),
 }
 
 http_jar = repository_rule(