diff --git a/LibGit2Sharp/Core/GitPushOptionsWrapper.cs b/LibGit2Sharp/Core/GitPushOptionsWrapper.cs
new file mode 100644
index 000000000..680839d38
--- /dev/null
+++ b/LibGit2Sharp/Core/GitPushOptionsWrapper.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace LibGit2Sharp.Core
+{
+ ///
+ /// Git push options wrapper. Disposable wrapper for .
+ ///
+ internal class GitPushOptionsWrapper : IDisposable
+ {
+ public GitPushOptionsWrapper() : this(new GitPushOptions()) { }
+
+ public GitPushOptionsWrapper(GitPushOptions pushOptions)
+ {
+ this.Options = pushOptions;
+ }
+
+ public GitPushOptions Options { get; private set; }
+
+ #region IDisposable
+ private bool disposedValue = false; // To detect redundant calls
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposedValue)
+ return;
+
+ this.Options.CustomHeaders.Dispose();
+ disposedValue = true;
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/LibGit2Sharp/Network.cs b/LibGit2Sharp/Network.cs
index d5f032058..825f3c886 100644
--- a/LibGit2Sharp/Network.cs
+++ b/LibGit2Sharp/Network.cs
@@ -365,18 +365,27 @@ public virtual void Push(Remote remote, IEnumerable pushRefSpecs, PushOp
// Load the remote.
using (RemoteHandle remoteHandle = Proxy.git_remote_lookup(repository.Handle, remote.Name, true))
+
+ // Create a git options wrapper so managed strings are disposed.
+ using (var pushOptionsWrapper = new GitPushOptionsWrapper())
{
var callbacks = new RemoteCallbacks(pushOptions);
GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks();
+ var gitPushOptions = pushOptionsWrapper.Options;
+ gitPushOptions.PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism;
+ gitPushOptions.RemoteCallbacks = gitCallbacks;
+ gitPushOptions.ProxyOptions = new GitProxyOptions { Version = 1 };
+
+ // If there are custom headers, create a managed string array.
+ if (pushOptions.CustomHeaders != null && pushOptions.CustomHeaders.Length > 0)
+ {
+ gitPushOptions.CustomHeaders = GitStrArrayManaged.BuildFrom(pushOptions.CustomHeaders);
+ }
+
Proxy.git_remote_push(remoteHandle,
pushRefSpecs,
- new GitPushOptions()
- {
- PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism,
- RemoteCallbacks = gitCallbacks,
- ProxyOptions = new GitProxyOptions { Version = 1 },
- });
+ gitPushOptions);
}
}
diff --git a/LibGit2Sharp/PushOptions.cs b/LibGit2Sharp/PushOptions.cs
index 99c65dd8b..b406b2350 100644
--- a/LibGit2Sharp/PushOptions.cs
+++ b/LibGit2Sharp/PushOptions.cs
@@ -51,5 +51,25 @@ public sealed class PushOptions
/// information about what updates will be performed.
///
public PrePushHandler OnNegotiationCompletedBeforePush { get; set; }
+
+ ///
+ /// Get/Set the custom headers.
+ ///
+ /// This allows you to set custom headers (e.g. X-Forwarded-For,
+ /// X-Request-Id, etc),
+ ///
+ ///
+ ///
+ /// Libgit2 sets some headers for HTTP requests (User-Agent, Host,
+ /// Accept, Content-Type, Transfer-Encoding, Content-Length, Accept) that
+ /// cannot be overriden.
+ ///
+ ///
+ /// var pushOptions - new PushOptions() {
+ /// CustomHeaders = new String[] {"X-Request-Id: 12345"}
+ /// };
+ ///
+ /// The custom headers string array
+ public string[] CustomHeaders { get; set; }
}
}