14

I see that the download path for a GitHub repo is of the form

https://github.com/{username}/{reponame}/archive/{branchname}.zip

For a private repo, understandably you need to provide credentials in order to download the repo, can anyone provide a C# example on how to provide a HTTPS basic authentication so I can download the repo programmatically?

Thanks,

theburningmonk
  • 15,701
  • 14
  • 61
  • 104

4 Answers4

11

Here is a pure C# way:

var githubToken = "[token]";
var url = "https://github.com/[username]/[repository]/archive/[sha1|tag].zip";
var path = @"[local path]";

using (var client = new System.Net.Http.HttpClient())
{
    var credentials = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}:", githubToken);
    credentials = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(credentials));
    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", credentials);
    var contents = client.GetByteArrayAsync(url).Result;
    System.IO.File.WriteAllBytes(path, contents);
}
Dinesh Bolkensteyn
  • 2,971
  • 1
  • 17
  • 20
  • I realize this is a very old answer, but I'm having trouble getting it to work; it always returns 404 even though it downloads normally when I enter the url in a browser. Is there something I'm missing? – Braeden Orchard Jul 28 '17 at 04:33
  • 1
    @Dinesh Bolkensteyn Where to get `[sha1|tag]` for `var url`? – koverflow Oct 02 '18 at 20:55
  • 1
    @koverflow it's the SHA1 corresponding to the commit you want to download. Alternatively, you can pass the tag or branch name instead – Dinesh Bolkensteyn Oct 06 '18 at 17:06
  • @DineshBolkensteyn I know the answer is seven years old, but I was wondering If there was a way to, lets say call an interrupt every .2 secs to see how much has been downloaded? I don't know much about c# Tasks thats why I'm asking – Kay Steinhoff Nov 16 '22 at 07:11
4

See this guide on creating a personal access token then run the following:

var githubToken = "token";
var request = (HttpWebRequest)WebRequest.Create("https://api.github.com/repos/$OWNER/$REPO/contents/$PATH");
request.Headers.Add(HttpRequestHeader.Authorization, string.Concat("token ", githubToken));
request.Accept = "application/vnd.github.v3.raw";
request.UserAgent = "test app"; //user agent is required https://developer.github.com/v3/#user-agent-required
using (var response = request.GetResponse())
{
    var encoding = System.Text.ASCIIEncoding.UTF8;
    using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
    {
        var fileContent = reader.ReadToEnd();
    }
}
KyleMit
  • 30,350
  • 66
  • 462
  • 664
Alex Radevich
  • 101
  • 1
  • 2
  • 3
0

with CURL:

curl -L -F "login=$USER" -F "token=$TOKEN" https://github.com/$USER/$REPO/$PKGTYPE/$BRANCHorTAG

where $TOKEN is the API token on your github profile, not an oAuth2 token used for communicating with the APIv3.

$USER is the user account the token is connected with, not necessarily the organization/other user the repo belongs to. Second Instance of $USER is the user/account the repo is.

$REPO is the name of the private repository

$PKGTYPE is tarball or zipball and $BRANCHorTAG is a branch, like master, or a tag name for a commit.

The first instance of $USER must have access to the repo belonging to the second instance of $USER.

I could not find this documented ANYWHERE, so I also have a little write up about it if you want anything more detailed.

Freelancer
  • 9,008
  • 7
  • 42
  • 81
  • 1
    I know you can use `curl` from other questions, but I can't assume `curl` is installed on the machine, so have to use basic .Net primitives unfortunately. – theburningmonk Mar 14 '13 at 11:36
-2

I'm looking into the Okctokit.Net currently. Give it a shot. NuGet: Install-Package Octokit