8000 Wire up proxy options · darkthread/libgit2sharp@4de7c4f · GitHub
[go: up one dir, main page]

Skip to content

Commit 4de7c4f

Browse files
committed
Wire up proxy options
1 parent db161ee commit 4de7c4f

11 files changed

+222
-52
lines changed

LibGit2Sharp/Commands/Fetch.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Collections.Generic;
2-
using LibGit2Sharp;
32
using LibGit2Sharp.Core;
43
using LibGit2Sharp.Core.Handles;
54

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

78-
fetchOptions.ProxyOptions = new GitProxyOptions { Version = 1 };
77+
fetchOptions.ProxyOptions = options.ProxyOptions.CreateGitProxyOptions();
7978

8079
Proxy.git_remote_fetch(remoteHandle, refspecs, fetchOptions, logMessage);
8180
}

LibGit2Sharp/Core/GitFetchOptionsWrapper.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
namespace LibGit2Sharp.Core
44
{
5-
/// <summary>
6-
/// Git fetch options wrapper. Disposable wrapper for GitFetchOptions
5+
/// <summary>
6+
/// Git fetch options wrapper. Disposable wrapper for GitFetchOptions
77
/// </summary>
88
internal class GitFetchOptionsWrapper : IDisposable
99
{
1010
public GitFetchOptionsWrapper() : this(new GitFetchOptions()) { }
1111

1212
public GitFetchOptionsWrapper(GitFetchOptions fetchOptions)
1313
{
14-
this.Options = fetchOptions;
14+
Options = fetchOptions;
1515
}
1616

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

26-
this.Options.CustomHeaders.Dispose();
26+
Options.CustomHeaders.Dispose();
27+
EncodingMarshaler.Cleanup(Options.ProxyOptions.Url);
2728
disposedValue = true;
2829
}
2930

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
3+
namespace LibGit2Sharp.Core
4+
{
5+
internal class GitProxyOptionsWrapper : IDisposable
6+
{
7+
public GitProxyOptionsWrapper() : this(new GitProxyOptions()) { }
8+
9+
public GitProxyOptionsWrapper(GitProxyOptions fetchOptions)
10+
{
11+
Options = fetchOptions;
12+
}
13+
14+
public GitProxyOptions Options { get; private set; }
15+
16+
private bool disposedValue = false;
17+
18+
protected virtual void Dispose(bool disposing)
19+
{
20+
if (disposedValue)
21+
return;
22+
23+
EncodingMarshaler.Cleanup(Options.Url);
24+
disposedValue = true;
25+
}
26+
27+
public void Dispose()
28+
{
29+
Dispose(true);
30+
}
31+
}
32+
}

LibGit2Sharp/Core/GitPushOptionsWrapper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ protected virtual void Dispose(bool disposing)
2424
return;
2525

2626
this.Options.CustomHeaders.Dispose();
27+
EncodingMarshaler.Cleanup(Options.ProxyOptions.Url);
2728
disposedValue = true;
2829
}
2930

LibGit2Sharp/FetchOptionsBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,6 @@ internal FetchOptionsBase()
4949
/// </summary>
5050
public RepositoryOperationCompleted RepositoryOperationCompleted { get; set; }
5151

52-
public ProxyOptions ProxyOptions { get; set; }
52+
public ProxyOptions ProxyOptions { get; set; } = new();
5353
}
5454
}

LibGit2Sharp/LibGit2Sharp.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>net472;net6.0</TargetFrameworks>
5+
<LangVersion>10.0</LangVersion>
56
<GenerateDocumentationFile>true</GenerateDocumentationFile>
67
<Description>LibGit2Sharp brings all the might and speed of libgit2, a native Git implementation, to the managed world of .NET</Description>
78
<Company>LibGit2Sharp contributors</Company>

LibGit2Sharp/Network.cs

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,14 @@ public virtual IEnumerable<Reference> ListReferences(Remote remote)
5252
{
5353
Ensure.ArgumentNotNull(remote, "remote");
5454

55-
return ListReferencesInternal(remote.Url, null);
55+
return ListReferencesInternal(remote.Url, null, new ProxyOptions());
56+
}
57+
58+
public virtual IEnumerable<Reference> ListReferences(Remote remote, ProxyOptions proxyOptions)
59+
{
60+
Ensure.ArgumentNotNull(remote, "remote");
61+
62+
return ListReferencesInternal(remote.Url, null, proxyOptions);
5663
}
5764

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

75-
return ListReferencesInternal(remote.Url, credentialsProvider);
82+
return ListReferencesInternal(remote.Url, credentialsProvider, new ProxyOptions());
83+
}
84+
85+
public virtual IEnumerable<Reference> ListReferences(Remote remote, CredentialsHandler credentialsProvider, ProxyOptions proxyOptions)
86+
{
87+
Ensure.ArgumentNotNull(remote, "remote");
88+
Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider");
89+
90+
return ListReferencesInternal(remote.Url, credentialsProvider, proxyOptions);
7691
}
7792

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

93-
return ListReferencesInternal(url, null);
108+
return ListReferencesInternal(url, null, new ProxyOptions());
109+
}
110+
111+
public virtual IEnumerable<Reference> ListReferences(string url, ProxyOptions proxyOptions)
112+
{
113+
Ensure.ArgumentNotNull(url, "url");
114+
115+
return ListReferencesInternal(url, null, proxyOptions);
94116
}
95117

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

113-
return ListReferencesInternal(url, credentialsProvider);
135+
return ListReferencesInternal(url, credentialsProvider, new ProxyOptions());
114136
}
115137

116-
private IEnumerable<Reference> ListReferencesInternal(string url, CredentialsHandler credentialsProvider)
138+
public virtual IEnumerable<Reference> ListReferences(string url, CredentialsHandler credentialsProvider, ProxyOptions proxyOptions)
117139
{
118-
using (RemoteHandle remoteHandle = BuildRemoteHandle(repository.Handle, url))
119-
{
120-
GitRemoteCallbacks gitCallbacks = new GitRemoteCallbacks { version = 1 };
121-
GitProxyOptions proxyOptions = new GitProxyOptions { Version = 1 };
140+
Ensure.ArgumentNotNull(url, "url");
141+
Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider");
122142

123-
if (credentialsProvider != null)
124-
{
125-
var callbacks = new RemoteCallbacks(credentialsProvider);
126-
gitCallbacks = callbacks.GenerateCallbacks();
127-
}
143+
return ListReferencesInternal(url, credentialsProvider, new ProxyOptions());
144+
}
128145

129-
Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref proxyOptions);
130-
return Proxy.git_remote_ls(repository, remoteHandle);
146+
private IEnumerable<Reference> ListReferencesInternal(string url, CredentialsHandler credentialsProvider, ProxyOptions proxyOptions)
147+
{
148+
proxyOptions ??= new();
149+
150+
using RemoteHandle remoteHandle = BuildRemoteHandle(repository.Handle, url);
151+
using var proxyOptionsWrapper = new GitProxyOptionsWrapper(proxyOptions.CreateGitProxyOptions());
152+
153+
GitRemoteCallbacks gitCallbacks = new GitRemoteCallbacks { version = 1 };
154+
155+
if (credentialsProvider != null)
156+
{
157+
var callbacks = new RemoteCallbacks(credentialsProvider);
158+
gitCallbacks = callbacks.GenerateCallbacks();
131159
}
160+
161+
var gitProxyOptions = proxyOptionsWrapper.Options;
162+
163+
Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref gitProxyOptions);
164+
return Proxy.git_remote_ls(repository, remoteHandle);
132165
}
133166

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

380413
// If there are custom headers, create a managed string array.
381414
if (pushOptions.CustomHeaders != null && pushOptions.CustomHeaders.Length > 0)

LibGit2Sharp/ProxyOptions.cs

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,103 @@
1-
using LibGit2Sharp.Handlers;
1+
using System;
2+
using LibGit2Sharp.Core;
3+
using LibGit2Sharp.Handlers;
24

35
namespace LibGit2Sharp
46
{
57
public class ProxyOptions
68
{
7-
public ProxyType ProxyType { get; set; }
9+
public ProxyType ProxyType { get; set; } = ProxyType.Auto;
810

911
public string Url { get; set; }
1012

1113
public CredentialsHandler CredentialsProvider { get; set; }
1214

1315
public CertificateCheckHandler CertificateCheck { get; set; }
16+
17+
internal unsafe GitProxyOptions CreateGitProxyOptions()
18+
{
19+
var gitProxyOptions = new GitProxyOptions
20+
{
21+
Version = 1,
22+
Type = (GitProxyType)ProxyType
23+
};
24+
25+
if (Url is not null)
26+
{
27+
gitProxyOptions.Url = StrictUtf8Marshaler.FromManaged(Url);
28+
}
29+
30+
if (CredentialsProvider is not null)
31+
{
32+
gitProxyOptions.Credentials = GitCredentialHandler;
33+
}
34+
35+
if (CertificateCheck is not null)
36+
{
37+
gitProxyOptions.CertificateCheck = GitCertificateCheck;
38+
}
39+
40+
return gitProxyOptions;
41+
}
42+
43+
private int GitCredentialHandler(out IntPtr ptr, IntPtr cUrl, IntPtr usernameFromUrl, GitCredentialType credTypes, IntPtr payload)
44+
{
45+
string url = LaxUtf8Marshaler.FromNative(cUrl);
46+
string username = LaxUtf8Marshaler.FromNative(usernameFromUrl);
47+
48+
SupportedCredentialTypes types = default(SupportedCredentialTypes);
49+
if (credTypes.HasFlag(GitCredentialType.UserPassPlaintext))
50+
{
51+
types |= SupportedCredentialTypes.UsernamePassword;
52+
}
53+
if (credTypes.HasFlag(GitCredentialType.Default))
54+
{
55+
types |= SupportedCredentialTypes.Default;
56+
}
57+
58+
ptr = IntPtr.Zero;
59+
try
60+
{
61+
var cred = CredentialsProvider(url, username, types);
62+
if (cred == null)
63+
{
64+
return (int)GitErrorCode.PassThrough;
65+
}
66+
return cred.GitCredentialHandler(out ptr);
67+
}
68+
catch (Exception exception)
69+
{
70+
Proxy.git_error_set_str(GitErrorCategory.Callback, exception);
71+
return (int)GitErrorCode.Error;
72+
}
73+
}
74+
75+
private unsafe int GitCertificateCheck(git_certificate* certPtr, int valid, IntPtr cHostname, IntPtr payload)
76+
{
77+
string hostname = LaxUtf8Marshaler.FromNative(cHostname);
78+
Certificate cert = null;
79+
80+
switch (certPtr->type)
81+
{
82+
case GitCertificateType.X509:
83+
cert = new CertificateX509((git_certificate_x509*)certPtr);
84+
break;
85+
case GitCertificateType.Hostkey:
86+
cert = new CertificateSsh((git_certificate_ssh*)certPtr);
87+
break;
88+
}
89+
90+
bool result = false;
91+
try
92+
{
93+
result = CertificateCheck(cert, valid != 0, hostname);
94+
}
95+
catch (Exception exception)
96+
{
97+
Proxy.git_error_set_str(GitErrorCategory.Callback, exception);
98+
}
99+
100+
return Proxy.ConvertResultToCancelFlag(result);
101+
}
14102
}
15103
}

LibGit2Sharp/PushOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,7 @@ public sealed class PushOptions
7171
/// </example>
7272
/// <value>The custom headers string array</value>
7373
public string[] CustomHeaders { get; set; }
74+
75+
public ProxyOptions ProxyOptions { get; set; } = new();
7476
}
7577
}

0 commit comments

Comments
 (0)
0