8000 Add proxy options by bording · Pull Request #2065 · libgit2/libgit2sharp · GitHub
[go: up one dir, main page]

Skip to content

Add proxy options #2065

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 3, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Prev Previous commit
Next Next commit
Wire up proxy options
  • Loading branch information
bording committed Nov 27, 2023
commit 4de7c4f12bbc86b333a54f572fe2f2e8f116fce0
3 changes: 1 addition & 2 deletions LibGit2Sharp/Commands/Fetch.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using LibGit2Sharp;
using LibGit2Sharp.Core;
using LibGit2Sharp.Core.Handles;

Expand Down Expand Up @@ -75,7 +74,7 @@ public static void Fetch(Repository repository, string remote, IEnumerable<strin
fetchOptions.CustomHeaders = GitStrArrayManaged.BuildFrom(options.CustomHeaders);
}

fetchOptions.ProxyOptions = new GitProxyOptions { Version = 1 };
fetchOptions.ProxyOptions = options.ProxyOptions.CreateGitProxyOptions();

Proxy.git_remote_fetch(remoteHandle, refspecs, fetchOptions, logMessage);
}
Expand Down
9 changes: 5 additions & 4 deletions LibGit2Sharp/Core/GitFetchOptionsWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

namespace LibGit2Sharp.Core
{
/// <summary>
/// Git fetch options wrapper. Disposable wrapper for GitFetchOptions
/// <summary>
/// Git fetch options wrapper. Disposable wrapper for GitFetchOptions
/// </summary>
internal class GitFetchOptionsWrapper : IDisposable
{
public GitFetchOptionsWrapper() : this(new GitFetchOptions()) { }

public GitFetchOptionsWrapper(GitFetchOptions fetchOptions)
{
this.Options = fetchOptions;
Options = fetchOptions;
}

public GitFetchOptions Options { get; private set; }
Expand All @@ -23,7 +23,8 @@ protected virtual void Dispose(bool disposing)
if (disposedValue)
return;

this.Options.CustomHeaders.Dispose();
Options.CustomHeaders.Dispose();
EncodingMarshaler.Cleanup(Options.ProxyOptions.Url);
disposedValue = true;
}

Expand Down
32 changes: 32 additions & 0 deletions LibGit2Sharp/Core/GitProxyOptionsWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;

namespace LibGit2Sharp.Core
{
internal class GitProxyOptionsWrapper : IDisposable
{
public GitProxyOptionsWrapper() : this(new GitProxyOptions()) { }

public GitProxyOptionsWrapper(GitProxyOptions fetchOptions)
{
Options = fetchOptions;
}

public GitProxyOptions Options { get; private set; }

private bool disposedValue = false;

protected virtual void Dispose(bool disposing)
{
if (disposedValue)
return;

EncodingMarshaler.Cleanup(Options.Url);
disposedValue = true;
}

public void Dispose()
{
Dispose(true);
}
}
}
1 change: 1 addition & 0 deletions LibGit2Sharp/Core/GitPushOptionsWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ protected virtual void Dispose(bool disposing)
return;

this.Options.CustomHeaders.Dispose();
EncodingMarshaler.Cleanup(Options.ProxyOptions.Url);
disposedValue = true;
}

Expand Down
2 changes: 1 addition & 1 deletion LibGit2Sharp/FetchOptionsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ internal FetchOptionsBase()
/// </summary>
public RepositoryOperationCompleted RepositoryOperationCompleted { get; set; }

public ProxyOptions ProxyOptions { get; set; }
public ProxyOptions ProxyOptions { get; set; } = new();
}
}
1 change: 1 addition & 0 deletions LibGit2Sharp/LibGit2Sharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFrameworks>net472;net6.0</TargetFrameworks>
<LangVersion>10.0</LangVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Description>LibGit2Sharp brings all the might and speed of libgit2, a native Git implementation, to the managed world of .NET</Description>
<Company>LibGit2Sharp contributors</Company>
Expand Down
67 changes: 50 additions & 17 deletions LibGit2Sharp/Network.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@ public virtual IEnumerable<Reference> ListReferences(Remote remote)
{
Ensure.ArgumentNotNull(remote, "remote");

return ListReferencesInternal(remote.Url, null);
return ListReferencesInternal(remote.Url, null, new ProxyOptions());
}

public virtual IEnumerable<Reference> ListReferences(Remote remote, ProxyOptions proxyOptions)
{
Ensure.ArgumentNotNull(remote, "remote");

return ListReferencesInternal(remote.Url, null, proxyOptions);
}

/// <summary>
Expand All @@ -72,7 +79,15 @@ public virtual IEnumerable<Reference> ListReferences(Remote remote, CredentialsH
Ensure.ArgumentNotNull(remote, "remote");
Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider");

return ListReferencesInternal(remote.Url, credentialsProvider);
return ListReferencesInternal(remote.Url, credentialsProvider, new ProxyOptions());
}

public virtual IEnumerable<Reference> ListReferences(Remote remote, CredentialsHandler credentialsProvider, ProxyOptions proxyOptions)
{
Ensure.ArgumentNotNull(remote, "remote");
Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider");

return ListReferencesInternal(remote.Url, credentialsProvider, proxyOptions);
}

/// <summary>
Expand All @@ -90,7 +105,14 @@ public virtual IEnumerable<Reference> ListReferences(string url)
{
Ensure.ArgumentNotNull(url, "url");

return ListReferencesInternal(url, null);
return ListReferencesInternal(url, null, new ProxyOptions());
}

public virtual IEnumerable<Reference> ListReferences(string url, ProxyOptions proxyOptions)
{
Ensure.ArgumentNotNull(url, "url");

return ListReferencesInternal(url, null, proxyOptions);
}

/// <summary>
Expand All @@ -110,25 +132,36 @@ public virtual IEnumerable<Reference> ListReferences(string url, CredentialsHand
Ensure.ArgumentNotNull(url, "url");
Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider");

return ListReferencesInternal(url, credentialsProvider);
return ListReferencesInternal(url, credentialsProvider, new ProxyOptions());
}

private IEnumerable<Reference> ListReferencesInternal(string url, CredentialsHandler credentialsProvider)
public virtual IEnumerable<Reference> ListReferences(string url, CredentialsHandler credentialsProvider, ProxyOptions proxyOptions)
{
using (RemoteHandle remoteHandle = BuildRemoteHandle(repository.Handle, url))
{
GitRemoteCallbacks gitCallbacks = new GitRemoteCallbacks { version = 1 };
GitProxyOptions proxyOptions = new GitProxyOptions { Version = 1 };
Ensure.ArgumentNotNull(url, "url");
Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider");

if (credentialsProvider != null)
{
var callbacks = new RemoteCallbacks(credentialsProvider);
gitCallbacks = callbacks.GenerateCallbacks();
}
return ListReferencesInternal(url, credentialsProvider, new ProxyOptions());
}

Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref proxyOptions);
return Proxy.git_remote_ls(repository, remoteHandle);
private IEnumerable<Reference> ListReferencesInternal(string url, CredentialsHandler credentialsProvider, ProxyOptions proxyOptions)
{
proxyOptions ??= new();

using RemoteHandle remoteHandle = BuildRemoteHandle(repository.Handle, url);
using var proxyOptionsWrapper = new GitProxyOptionsWrapper(proxyOptions.CreateGitProxyOptions());

GitRemoteCallbacks gitCallbacks = new GitRemoteCallbacks { version = 1 };

if (credentialsProvider != null)
{
var callbacks = new RemoteCallbacks(credentialsProvider);
gitCallbacks = callbacks.GenerateCallbacks();
}

var gitProxyOptions = proxyOptionsWrapper.Options;

Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref gitProxyOptions);
return Proxy.git_remote_ls(repository, remoteHandle);
}

static RemoteHandle BuildRemoteHandle(RepositoryHandle repoHandle, string url)
Expand Down Expand Up @@ -375,7 +408,7 @@ public virtual void Push(Remote remote, IEnumerable<string> pushRefSpecs, PushOp
var gitPushOptions = pushOptionsWrapper.Options;
gitPushOptions.PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism;
gitPushOptions.RemoteCallbacks = gitCallbacks;
gitPushOptions.ProxyOptions = new GitProxyOptions { Version = 1 };
gitPushOptions.ProxyOptions = pushOptions.ProxyOptions.CreateGitProxyOptions();

// If there are custom headers, create a managed string array.
if (pushOptions.CustomHeaders != null && pushOptions.CustomHeaders.Length > 0)
Expand Down
92 changes: 90 additions & 2 deletions LibGit2Sharp/ProxyOptions.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,103 @@
using LibGit2Sharp.Handlers;
using System;
using LibGit2Sharp.Core;
using LibGit2Sharp.Handlers;

namespace LibGit2Sharp
{
public class ProxyOptions
{
public ProxyType ProxyType { get; set; }
public ProxyType ProxyType { get; set; } = ProxyType.Auto;

public string Url { get; set; }

public CredentialsHandler CredentialsProvider { get; set; }

public CertificateCheckHandler CertificateCheck { get; set; }

internal unsafe GitProxyOptions CreateGitProxyOptions()
{
var gitProxyOptions = new GitProxyOptions
{
Version = 1,
Type = (GitProxyType)ProxyType
};

if (Url is not null)
{
gitProxyOptions.Url = StrictUtf8Marshaler.FromManaged(Url);
}

if (CredentialsProvider is not null)
{
gitProxyOptions.Credentials = GitCredentialHandler;
}

if (CertificateCheck is not null)
{
gitProxyOptions.CertificateCheck = GitCertificateCheck;
}

return gitProxyOptions;
}

private int GitCredentialHandler(out IntPtr ptr, IntPtr cUrl, IntPtr usernameFromUrl, GitCredentialType credTypes, IntPtr payload)
{
string url = LaxUtf8Marshaler.FromNative(cUrl);
string username = LaxUtf8Marshaler.FromNative(usernameFromUrl);

SupportedCredentialTypes types = default(SupportedCredentialTypes);
if (credTypes.HasFlag(GitCredentialType.UserPassPlaintext))
{
types |= SupportedCredentialTypes.UsernamePassword;
}
if (credTypes.HasFlag(GitCredentialType.Default))
{
types |= SupportedCredentialTypes.Default;
}

ptr = IntPtr.Zero;
try
{
var cred = CredentialsProvider(url, username, types);
if (cred == null)
{
return (int)GitErrorCode.PassThrough;
}
return cred.GitCredentialHandler(out ptr);
}
catch (Exception exception)
{
Proxy.git_error_set_str(GitErrorCategory.Callback, exception);
return (int)GitErrorCode.Error;
}
}

private unsafe int GitCertificateCheck(git_certificate* certPtr, int valid, IntPtr cHostname, IntPtr payload)
{
string hostname = LaxUtf8Marshaler.FromNative(cHostname);
Certificate cert = null;

switch (certPtr->type)
{
case GitCertificateType.X509:
cert = new CertificateX509((git_certificate_x509*)certPtr);
break;
case GitCertificateType.Hostkey:
cert = new CertificateSsh((git_certificate_ssh*)certPtr);
break;
}

bool result = false;
try
{
result = CertificateCheck(cert, valid != 0, hostname);
}
catch (Exception exception)
{
Proxy.git_error_set_str(GitErrorCategory.Callback, exception);
}

return Proxy.ConvertResultToCancelFlag(result);
}
}
}
2 changes: 2 additions & 0 deletions LibGit2Sharp/PushOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,7 @@ public sealed class PushOptions
/// </example>
/// <value>The custom headers string array</value>
public string[] CustomHeaders { get; set; }

public ProxyOptions ProxyOptions { get; set; } = new();
}
}
Loading
0