8000 Merge pull request #2052 from James-LG/master · darkthread/libgit2sharp@ae59ffa · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ae59ffa

Browse files
authored
Merge pull request libgit2#2052 from James-LG/master
feat: Add CustomHeaders to PushOptions
2 parents 8c32b61 + 714a426 commit ae59ffa

File tree

4 files changed

+98
-6
lines changed

4 files changed

+98
-6
lines changed

LibGit2Sharp.Tests/PushFixture.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,33 @@ public void CanForcePush()
196196
}
197197
}
198198

199+
[Fact]
200+
public void CanPushWithCustomHeaders()
201+
{
202+
const string knownHeader = "X-Hello: mygit-201";
203+
var options = new PushOptions { CustomHeaders = new string[] { knownHeader } };
204+
AssertPush(repo =>
205+
repo.Network.Push(repo.Network.Remotes["origin"], "HEAD", @"refs/heads/master", options));
206+
}
207+
208+
[Fact]
209+
public void CannotPushWithForbiddenCustomHeaders()
210+
{
211+
const string knownHeader = "User-Agent: mygit-201";
212+
var options = new PushOptions { CustomHeaders = new string[] { knownHeader } };
213+
Assert.Throws<LibGit2SharpException>(
214+
() => AssertPush(repo => repo.Network.Push(repo.Network.Remotes["origin"], "HEAD", @"refs/heads/master", options)));
215+
}
216+
217+
[Fact]
218+
public void CannotPushWithMalformedCustomHeaders()
219+
{
220+
const string knownHeader = "Hello world";
221+
var options = new PushOptions { CustomHeaders = new string[] { knownHeader } };
222+
Assert.Throws<LibGit2SharpException>(
223+
() => AssertPush(repo => repo.Network.Push(repo.Network.Remotes["origin"], "HEAD", @"refs/heads/master", options)));
224+
}
225+
199226
private static void AssertRemoteHeadTipEquals(IRepository localRepo, string sha)
200227
{
201228
var remoteReferences = localRepo.Network.ListReferences(localRepo.Network.Remotes.Single());
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
3+
namespace LibGit2Sharp.Core
4+
{
5+
/// <summary>
6+
/// Git push options wrapper. Disposable wrapper for <see cref="GitPushOptions"/>.
7+
/// </summary>
8+
internal class GitPushOptionsWrapper : IDisposable
9+
{
10+
public GitPushOptionsWrapper() : this(new GitPushOptions()) { }
11+
12+
public GitPushOptionsWrapper(GitPushOptions pushOptions)
13+
{
14+
this.Options = pushOptions;
15+
}
16+
17+
public GitPushOptions Options { get; private set; }
18+
19+
#region IDisposable
20+
private bool disposedValue = false; // To detect redundant calls
21+
protected virtual void Dispose(bool disposing)
22+
{
23+
if (disposedValue)
24+
return;
25+
26+
this.Options.CustomHeaders.Dispose();
27+
disposedValue = true;
28+
}
29+
30+
public void Dispose()
31+
{
32+
Dispose(true);
33+
}
34+
#endregion
35+
}
36+
}

LibGit2Sharp/Network.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -365,18 +365,27 @@ public virtual void Push(Remote remote, IEnumerable<string> pushRefSpecs, PushOp
365365

366366
// Load the remote.
367367
using (RemoteHandle remoteHandle = Proxy.git_remote_lookup(repository.Handle, remote.Name, true))
368+
369+
// Create a git options wrapper so managed strings are disposed.
370+
using (var pushOptionsWrapper = new GitPushOptionsWrapper())
368371
{
369372
var callbacks = new RemoteCallbacks(pushOptions);
370373
GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks();
371374

375+
var gitPushOptions = pushOptionsWrapper.Options;
376+
gitPushOptions.PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism;
377+
gitPushOptions.RemoteCallbacks = gitCallbacks;
378+
gitPushOptions.ProxyOptions = new GitProxyOptions { Version = 1 };
379+
380+
// If there are custom headers, create a managed string array.
381+
if (pushOptions.CustomHeaders != null && pushOptions.CustomHeaders.Length > 0)
382+
{
383+
gitPushOptions.CustomHeaders = GitStrArrayManaged.BuildFrom(pushOptions.CustomHeaders);
384+
}
385+
372386
Proxy.git_remote_push(remoteHandle,
373387
pushRefSpecs,
374-
new GitPushOptions()
375-
{
376-
PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism,
377-
RemoteCallbacks = gitCallbacks,
378-
ProxyOptions = new GitProxyOptions { Version = 1 },
379-
});
388+
gitPushOptions);
380389
}
381390
}
382391

LibGit2Sharp/PushOptions.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,25 @@ public sealed class PushOptions
5151
/// information about what updates will be performed.
5252
/// </summary>
5353
public PrePushHandler OnNegotiationCompletedBeforePush { get; set; }
54+
55+
/// <summary>
56+
/// Get/Set the custom headers.
57+
/// <para>
58+
/// This allows you to set custom headers (e.g. X-Forwarded-For,
59+
/// X-Request-Id, etc),
60+
/// </para>
61+
/// </summary>
62+
/// <remarks>
63+
/// Libgit2 sets some headers for HTTP requests (User-Agent, Host,
64+
/// Accept, Content-Type, Transfer-Encoding, Content-Length, Accept) that
65+
/// cannot be overriden.
66+
/// </remarks>
67+
/// <example>
68+
/// var pushOptions - new PushOptions() {
69+
/// CustomHeaders = new String[] {"X-Request-Id: 12345"}
70+
/// };
71+
/// </example>
72+
/// <value>The custom headers string array</value>
73+
public string[] CustomHeaders { get; set; }
5474
}
5575
}

0 commit comments

Comments
 (0)
0