Skip to content

Commit 02bb39f

Browse files
committed
stream registration: take an enum type
Accept an enum (`git_stream_t`) during custom stream registration that indicates whether the registration structure should be used for standard (non-TLS) streams or TLS streams.
1 parent 52478d7 commit 02bb39f

File tree

6 files changed

+83
-27
lines changed

6 files changed

+83
-27
lines changed

include/git2/sys/stream.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,32 @@ typedef struct {
7171
int (*wrap)(git_stream **out, git_stream *in, const char *host);
7272
} git_stream_registration;
7373

74+
/**
75+
* The type of stream to register.
76+
*/
77+
typedef enum {
78+
/** A standard (non-TLS) socket. */
79+
GIT_STREAM_STANDARD = 1,
80+
81+
/** A TLS-encrypted socket. */
82+
GIT_STREAM_TLS = 2,
83+
} git_stream_t;
84+
7485
/**
7586
* Register stream constructors for the library to use
7687
*
7788
* If a registration structure is already set, it will be overwritten.
7889
* Pass `NULL` in order to deregister the current constructor and return
7990
* to the system defaults.
8091
*
92+
* The type parameter may be a bitwise AND of types.
93+
*
94+
* @param type the type or types of stream to register
8195
* @param registration the registration data
82-
* @param tls 1 if the registration is for TLS streams, 0 for regular
83-
* (insecure) sockets
8496
* @return 0 or an error code
8597
*/
8698
GIT_EXTERN(int) git_stream_register(
87-
int tls, git_stream_registration *registration);
99+
git_stream_t type, git_stream_registration *registration);
88100

89101
/** @name Deprecated TLS Stream Registration Functions
90102
*

src/streams/registry.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,51 @@ int git_stream_registry_global_init(void)
3636
return 0;
3737
}
3838

39-
int git_stream_registry_lookup(git_stream_registration *out, int tls)
39+
GIT_INLINE(void) stream_registration_cpy(
40+
git_stream_registration *target,
41+
git_stream_registration *src)
4042
{
41-
git_stream_registration *target = tls ?
42-
&stream_registry.callbacks :
43-
&stream_registry.tls_callbacks;
43+
if (src)
44+
memcpy(target, src, sizeof(git_stream_registration));
45+
else
46+
memset(target, 0, sizeof(git_stream_registration));
47+
}
48+
49+
int git_stream_registry_lookup(git_stream_registration *out, git_stream_t type)
50+
{
51+
git_stream_registration *target;
4452
int error = GIT_ENOTFOUND;
4553

4654
assert(out);
4755

56+
switch(type) {
57+
case GIT_STREAM_STANDARD:
58+
target = &stream_registry.callbacks;
59+
break;
60+
case GIT_STREAM_TLS:
61+
target = &stream_registry.tls_callbacks;
62+
break;
63+
default:
64+
assert(0);
65+
return -1;
66+
}
67+
4868
if (git_rwlock_rdlock(&stream_registry.lock) < 0) {
4969
giterr_set(GITERR_OS, "failed to lock stream registry");
5070
return -1;
5171
}
5272

5373
if (target->init) {
54-
memcpy(out, target, sizeof(git_stream_registration));
74+
stream_registration_cpy(out, target);
5575
error = 0;
5676
}
5777

5878
git_rwlock_rdunlock(&stream_registry.lock);
5979
return error;
6080
}
6181

62-
int git_stream_register(int tls, git_stream_registration *registration)
82+
int git_stream_register(git_stream_t type, git_stream_registration *registration)
6383
{
64-
git_stream_registration *target = tls ?
65-
&stream_registry.callbacks :
66-
&stream_registry.tls_callbacks;
67-
6884
assert(!registration || registration->init);
6985

7086
GITERR_CHECK_VERSION(registration, GIT_STREAM_VERSION, "stream_registration");
@@ -74,10 +90,11 @@ int git_stream_register(int tls, git_stream_registration *registration)
7490
return -1;
7591
}
7692

77-
if (registration)
78-
memcpy(target, registration, sizeof(git_stream_registration));
79-
else
80-
memset(target, 0, sizeof(git_stream_registration));
93+
if ((type & GIT_STREAM_STANDARD) == GIT_STREAM_STANDARD)
94+
stream_registration_cpy(&stream_registry.callbacks, registration);
95+
96+
if ((type & GIT_STREAM_TLS) == GIT_STREAM_TLS)
97+
stream_registration_cpy(&stream_registry.tls_callbacks, registration);
8198

8299
git_rwlock_wrunlock(&stream_registry.lock);
83100
return 0;
@@ -92,8 +109,8 @@ int git_stream_register_tls(git_stream_cb ctor)
92109
registration.init = ctor;
93110
registration.wrap = NULL;
94111

95-
return git_stream_register(1, &registration);
112+
return git_stream_register(GIT_STREAM_TLS, &registration);
96113
} else {
97-
return git_stream_register(1, NULL);
114+
return git_stream_register(GIT_STREAM_TLS, NULL);
98115
}
99116
}

src/streams/registry.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
int git_stream_registry_global_init(void);
1515

1616
/** Lookup a stream registration. */
17-
extern int git_stream_registry_lookup(git_stream_registration *out, int tls);
17+
extern int git_stream_registry_lookup(git_stream_registration *out, git_stream_t type);
1818

1919
#endif

src/streams/socket.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ int git_socket_stream_new(
224224

225225
assert(out && host && port);
226226

227-
if ((error = git_stream_registry_lookup(&custom, 0)) == 0)
227+
if ((error = git_stream_registry_lookup(&custom, GIT_STREAM_STANDARD)) == 0)
228228
init = custom.init;
229229
else if (error == GIT_ENOTFOUND)
230230
init = default_socket_stream_new;

src/streams/tls.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ int git_tls_stream_new(git_stream **out, const char *host, const char *port)
2323

2424
assert(out && host && port);
2525

26-
if ((error = git_stream_registry_lookup(&custom, 1)) == 0) {
26+
if ((error = git_stream_registry_lookup(&custom, GIT_STREAM_TLS)) == 0) {
2727
init = custom.init;
2828
} else if (error == GIT_ENOTFOUND) {
2929
#ifdef GIT_SECURE_TRANSPORT
@@ -52,7 +52,7 @@ int git_tls_stream_wrap(git_stream **out, git_stream *in, const char *host)
5252

5353
assert(out && in);
5454

55-
if (git_stream_registry_lookup(&custom, 1) == 0) {
55+
if (git_stream_registry_lookup(&custom, GIT_STREAM_TLS) == 0) {
5656
wrap = custom.wrap;
5757
} else {
5858
#ifdef GIT_SECURE_TRANSPORT

tests/core/stream.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
static git_stream test_stream;
88
static int ctor_called;
99

10+
void test_core_stream__cleanup(void)
11+
{
12+
cl_git_pass(git_stream_register(GIT_STREAM_TLS | GIT_STREAM_STANDARD, NULL));
13+
}
14+
1015
static int test_stream_init(git_stream **out, const char *host, const char *port)
1116
{
1217
GIT_UNUSED(host);
@@ -39,14 +44,14 @@ void test_core_stream__register_insecure(void)
3944
registration.wrap = test_stream_wrap;
4045

4146
ctor_called = 0;
42-
cl_git_pass(git_stream_register(0, &registration));
47+
cl_git_pass(git_stream_register(GIT_STREAM_STANDARD, &registration));
4348
cl_git_pass(git_socket_stream_new(&stream, "localhost", "80"));
4449
cl_assert_equal_i(1, ctor_called);
4550
cl_assert_equal_p(&test_stream, stream);
4651

4752
ctor_called = 0;
4853
stream = NULL;
49-
cl_git_pass(git_stream_register(0, NULL));
54+
cl_git_pass(git_stream_register(GIT_STREAM_STANDARD, NULL));
5055
cl_git_pass(git_socket_stream_new(&stream, "localhost", "80"));
5156

5257
cl_assert_equal_i(0, ctor_called);
@@ -66,14 +71,14 @@ void test_core_stream__register_tls(void)
6671
registration.wrap = test_stream_wrap;
6772

6873
ctor_called = 0;
69-
cl_git_pass(git_stream_register(1, &registration));
74+
cl_git_pass(git_stream_register(GIT_STREAM_TLS, &registration));
7075
cl_git_pass(git_tls_stream_new(&stream, "localhost", "443"));
7176
cl_assert_equal_i(1, ctor_called);
7277
cl_assert_equal_p(&test_stream, stream);
7378

7479
ctor_called = 0;
7580
stream = NULL;
76-
cl_git_pass(git_stream_register(1, NULL));
81+
cl_git_pass(git_stream_register(GIT_STREAM_TLS, NULL));
7782
error = git_tls_stream_new(&stream, "localhost", "443");
7883

7984
/* We don't have TLS support enabled, or we're on Windows,
@@ -91,6 +96,28 @@ void test_core_stream__register_tls(void)
9196
git_stream_free(stream);
9297
}
9398

99+
void test_core_stream__register_both(void)
100+
{
101+
git_stream *stream;
102+
git_stream_registration registration = {0};
103+
104+
registration.version = 1;
105+
registration.init = test_stream_init;
106+
registration.wrap = test_stream_wrap;
107+
108+
cl_git_pass(git_stream_register(GIT_STREAM_STANDARD | GIT_STREAM_TLS, &registration));
109+
110+
ctor_called = 0;
111+
cl_git_pass(git_tls_stream_new(&stream, "localhost", "443"));
112+
cl_assert_equal_i(1, ctor_called);
113+
cl_assert_equal_p(&test_stream, stream);
114+
115+
ctor_called = 0;
116+
cl_git_pass(git_socket_stream_new(&stream, "localhost", "80"));
117+
cl_assert_equal_i(1, ctor_called);
118+
cl_assert_equal_p(&test_stream, stream);
119+
}
120+
94121
void test_core_stream__register_tls_deprecated(void)
95122
{
96123
git_stream *stream;

0 commit comments

Comments
 (0)