summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-10-13 11:25:41 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2015-11-03 08:10:29 -0800
commit7fafde632580f75ff3647ddf9e1e92ee388f317e (patch)
treed5ca0c2de9d73d24313366d89110c2d7c0b17a7a
parentd39f643a0a09336ad77f04b7037cbc1c486bdd50 (diff)
downloadlibgit2-cmn/tls-register.tar.gz
stream: allow registering a user-provided TLS constructorcmn/tls-register
This allows the application to use their own TLS stream, regardless of the capabilities of libgit2 itself.
-rw-r--r--CHANGELOG.md5
-rw-r--r--include/git2/sys/stream.h13
-rw-r--r--src/tls_stream.c13
-rw-r--r--tests/core/stream.c47
4 files changed, 78 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0b2e43308..dec40e49e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,11 +17,16 @@ v0.23 + 1
the opportunity for concurrent operations and not committing any
changes until the unlock.
+
* `git_diff_options` added a new callback `progress_cb` to report on the
progress of the diff as files are being compared. The documentation of
the existing callback `notify_cb` was updated to reflect that it only
gets called when new deltas are added to the diff.
+* `git_stream_register_tls()` lets you register a callback to be used
+ as the constructor for a TLS stream instead of the libgit2 built-in
+ one.
+
### API removals
### Breaking API changes
diff --git a/include/git2/sys/stream.h b/include/git2/sys/stream.h
index 55a714bbb..2b4ff7fd8 100644
--- a/include/git2/sys/stream.h
+++ b/include/git2/sys/stream.h
@@ -39,6 +39,19 @@ typedef struct git_stream {
void (*free)(struct git_stream *);
} git_stream;
+typedef int (*git_stream_cb)(git_stream **out, const char *host, const char *port);
+
+/**
+ * Register a TLS stream constructor for the library to use
+ *
+ * If a constructor is already set, it will be overwritten. Pass
+ * `NULL` in order to deregister the current constructor.
+ *
+ * @param ctor the constructor to use
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_stream_register_tls(git_stream_cb ctor);
+
GIT_END_DECL
#endif
diff --git a/src/tls_stream.c b/src/tls_stream.c
index 39a8ce343..83e2d064a 100644
--- a/src/tls_stream.c
+++ b/src/tls_stream.c
@@ -11,8 +11,21 @@
#include "openssl_stream.h"
#include "stransport_stream.h"
+static git_stream_cb tls_ctor;
+
+int git_stream_register_tls(git_stream_cb ctor)
+{
+ tls_ctor = ctor;
+
+ return 0;
+}
+
int git_tls_stream_new(git_stream **out, const char *host, const char *port)
{
+
+ if (tls_ctor)
+ return tls_ctor(out, host, port);
+
#ifdef GIT_SECURE_TRANSPORT
return git_stransport_stream_new(out, host, port);
#elif defined(GIT_OPENSSL)
diff --git a/tests/core/stream.c b/tests/core/stream.c
new file mode 100644
index 000000000..ace6a05da
--- /dev/null
+++ b/tests/core/stream.c
@@ -0,0 +1,47 @@
+#include "clar_libgit2.h"
+#include "git2/sys/stream.h"
+#include "tls_stream.h"
+#include "stream.h"
+
+static git_stream test_stream;
+static int ctor_called;
+
+static int test_ctor(git_stream **out, const char *host, const char *port)
+{
+ GIT_UNUSED(host);
+ GIT_UNUSED(port);
+
+ ctor_called = 1;
+ *out = &test_stream;
+
+ return 0;
+}
+
+void test_core_stream__register_tls(void)
+{
+ git_stream *stream;
+ int error;
+
+ ctor_called = 0;
+ cl_git_pass(git_stream_register_tls(test_ctor));
+ cl_git_pass(git_tls_stream_new(&stream, "localhost", "443"));
+ cl_assert_equal_i(1, ctor_called);
+ cl_assert_equal_p(&test_stream, stream);
+
+ ctor_called = 0;
+ stream = NULL;
+ cl_git_pass(git_stream_register_tls(NULL));
+ error = git_tls_stream_new(&stream, "localhost", "443");
+
+ /* We don't have arbitrary TLS stream support on Windows */
+#if GIT_WIN32
+ cl_git_fail_with(-1, error);
+#else
+ cl_git_pass(error);
+#endif
+
+ cl_assert_equal_i(0, ctor_called);
+ cl_assert(&test_stream != stream);
+
+ git_stream_free(stream);
+}