10000 Introduce `git_libgit2_feature_backend` API · libgit2/libgit2@75b6665 · GitHub
[go: up one dir, main page]

Skip to content

Commit 75b6665

Browse files
committed
Introduce git_libgit2_feature_backend API
Provide a mechanism to understand the backend provider for feature within libgit2. For example, one can query the mechanism that provides HTTPS by asking for the backend for the `GIT_FEATURE_HTTPS`. This is particularly useful for features that are not completely isomorphic; the HTTPS providers may have slightly different functionality that can be controlled (eg, certificates or cipher support). And the SSH feature is _very_ different between libssh2 and OpenSSH. It may also be useful to understand the support for things like the SHA1 or SHA256 backends to ensure that sha1dc is used, or that FIPS mode is enabled.
1 parent 097a0a5 commit 75b6665

File tree

3 files changed

+428
-37
lines changed

3 files changed

+428
-37
lines changed

include/git2/common.h

+61-37
Original file line numberDiff line numberDiff line change
@@ -130,56 +130,80 @@ GIT_EXTERN(int) git_libgit2_version(int *major, int *minor, int *rev);
130130
GIT_EXTERN(const char *) git_libgit2_prerelease(void);
131131

132132
/**
133-
* Combinations of these values describe the features with which libgit2
134-
* was compiled
133+
* Configurable features of libgit2; either optional settings (like
134+
* threading), or features that can be enabled by one of a number of
135+
* different backend "providers" (like HTTPS, which can be provided by
136+
* OpenSSL, mbedTLS, or system libraries).
135137
*/
136138
typedef enum {
137-
/**
138-
* If set, libgit2 was built thread-aware and can be safely used from multiple
139-
* threads.
140-
*/
141-
GIT_FEATURE_THREADS = (1 << 0),
142-
/**
143-
* If set, libgit2 was built with and linked against a TLS implementation.
144-
* Custom TLS streams may still be added by the user to support HTTPS
145-
* regardless of this.
146-
*/
147-
GIT_FEATURE_HTTPS = (1 << 1),
148-
/**
149-
* If set, libgit2 was built with and linked against libssh2. A custom
150-
* transport may still be added by the user to support libssh2 regardless of
151-
* this.
152-
*/
153-
GIT_FEATURE_SSH = (1 << 2),
154-
/**
155-
* If set, libgit2 was built with support for sub-second resolution in file
156-
* modification times.
157-
*/
158-
GIT_FEATURE_NSEC = (1 << 3)
139+
/**
140+
* libgit2 is thread-aware and can be used from multiple threads
141+
* (as described in the documentation).
142+
*/
143+
GIT_FEATURE_THREADS = (1 << 0),
144+
145+
/** HTTPS remotes */
146+
GIT_FEATURE_HTTPS = (1 << 1),
147+
148+
/** SSH remotes */
149+
GIT_FEATURE_SSH = (1 << 2),
150+
151+
/** Sub-second resolution in index timestamps */
152+
GIT_FEATURE_NSEC = (1 << 3),
153+
154+
/** HTTP parsing; always available */
155+
GIT_FEATURE_HTTP_PARSER = (1 << 4),
156+
157+
/** Regular expression support; always available */
158+
GIT_FEATURE_REGEX = (1 << 5),
159+
160+
/** Internationalization support for filename translation */
161+
GIT_FEATURE_I18N = (1 << 6),
162+
163+
/** NTLM support over HTTPS */
164+
GIT_FEATURE_AUTH_NTLM = (1 << 7),
165+
166+
/** Kerberos (SPNEGO) authentication support over HTTPS */
167+
GIT_FEATURE_AUTH_NEGOTIATE = (1 << 8),
168+
169+
/** zlib support; always available */
170+
GIT_FEATURE_COMPRESSION = (1 << 9),
171+
172+
/** SHA1 object support; always available */
173+
GIT_FEATURE_SHA1 = (1 << 10),
174+
175+
/** SHA256 object support */
176+
GIT_FEATURE_SHA256 = (1 << 11)
159177
} git_feature_t;
160178

161179
/**
162180
* Query compile time options for libgit2.
163181
*
164182
* @return A combination of GIT_FEATURE_* values.
183+
*/
184+
GIT_EXTERN(int) git_libgit2_features(void);
185+
186+
/**
187+
* Query the backend details for the compile-time feature in libgit2.
165188
*
166-
* - GIT_FEATURE_THREADS
167-
* Libgit2 was compiled with thread support. Note that thread support is
168-
* still to be seen as a 'work in progress' - basic object lookups are
169-
* believed to be threadsafe, but other operations may not be.
189+
* This will return the "backend" for the feature, which is useful for
190+
* things like HTTPS or SSH support, that can have multiple backends
191+
* that could be compiled in.
170192
*
171-
* - GIT_FEATURE_HTTPS
172-
* Libgit2 supports the https:// protocol. This requires the openssl
173-
* library to be found when compiling libgit2.
193+
* For example, when libgit2 is compiled with dynamic OpenSSL support,
194+
* the feature backend will be `openssl-dynamic`. The feature backend
195+
* names reflect the compilation options specified to the build system
196+
* (though in all lower case). The backend _may_ be "builtin" for
197+
* features that are provided by libgit2 itself.
174198
*
175-
* - GIT_FEATURE_SSH
176-
* Libgit2 supports the SSH protocol for network operations. This requires
177-
* the libssh2 library to be found when compiling libgit2
199+
* If the feature is not supported by the library, this API returns
200+
* `NULL`.
178201
*
179-
* - GIT_FEATURE_NSEC
180-
* Libgit2 supports the sub-second resolution in file modification times.
202+
* @param feature the feature to query details for
203+
* @return the provider details, or NULL if the feature is not supported
181204
*/
182-
GIT_EXTERN(int) git_libgit2_features(void);
205+
GIT_EXTERN(const char *) git_libgit2_feature_backend(
206+
git_feature_t feature);
183207

184208
/**
185209
* Global library options

src/libgit2/libgit2.c

+169
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,175 @@ int git_libgit2_features(void)
9292
#endif
9393
#ifdef GIT_USE_NSEC
9494
| GIT_FEATURE_NSEC
95+
#endif
96+
| GIT_FEATURE_HTTP_PARSER
97+
| GIT_FEATURE_REGEX
98+
#ifdef GIT_USE_ICONV
99+
| GIT_FEATURE_I18N
100+
#endif
101+
#if defined(GIT_NTLM) || defined(GIT_WIN32)
102+
| GIT_FEATURE_AUTH_NTLM
103+
#endif
104+
#if defined(GIT_GSSAPI) || defined(GIT_GSSFRAMEWORK) || defined(GIT_WIN32)
105+
| GIT_FEATURE_AUTH_NEGOTIATE
106+
#endif
107+
| GIT_FEATURE_COMPRESSION
108+
| GIT_FEATURE_SHA1
109+
#ifdef GIT_EXPERIMENTAL_SHA256
110+
| GIT_FEATURE_SHA256
95111
#endif
96112
;
97113
}
114+
115+
const char *git_libgit2_feature_backend(git_feature_t feature)
116+
{
117+
switch (feature) {
118+
case GIT_FEATURE_THREADS:
119+
#if defined(GIT_THREADS) && defined(GIT_WIN32)
120+
return "win32";
121+
#elif defined(GIT_THREADS)
122+
return "pthread";
123+
#endif
124+
break;
125+
126+
case GIT_FEATURE_HTTPS:
127+
#if defined(GIT_HTTPS) && defined(GIT_OPENSSL)
128+
return "openssl";
129+
#elif defined(GIT_HTTPS) && defined(GIT_OPENSSL_DYNAMIC)
130+
return "openssl-dynamic";
131+
#elif defined(GIT_HTTPS) && defined(GIT_MBEDTLS)
132+
return "mbedtls";
133+
#elif defined(GIT_HTTPS) && defined(GIT_SECURE_TRANSPORT)
134+
return "securetransport";
135+
#elif defined(GIT_HTTPS) && defined(GIT_SCHANNEL)
136+
return "schannel";
137+
#elif defined(GIT_HTTPS)
138+
GIT_ASSERT_WITH_RETVAL(!"Unknown HTTPS backend", NULL);
139+
#endif
140+
break;
141+
142+
case GIT_FEATURE_SSH:
143+
#if defined(GIT_SSH_EXEC)
144+
return "exec";
145+
#elif defined(GIT_SSH_LIBSSH2)
146+
return "libssh2";
147+
#elif defined(GIT_SSH)
148+
GIT_ASSERT_WITH_RETVAL(!"Unknown SSH backend", NULL);
149+
#endif
150+
break;
151+
152+
case GIT_FEATURE_NSEC:
153+
#if defined(GIT_USE_NSEC) && defined(GIT_USE_STAT_MTIMESPEC)
154+
return "mtimespec";
155+
#elif defined(GIT_USE_NSEC) && defined(GIT_USE_STAT_MTIM)
156+
return "mtim";
157+
#elif defined(GIT_USE_NSEC) && defined(GIT_USE_STAT_MTIME_NSEC)
158+
return "mtime";
159+
#elif defined(GIT_USE_NSEC) && defined(GIT_WIN32)
160+
return "win32";
161+
#elif defined(GIT_USE_NSEC)
162+
GIT_ASSERT_WITH_RETVAL(!"Unknown high-resolution time backend", NULL);
163+
#endif
164+
break;
165+
166+
case GIT_FEATURE_HTTP_PARSER:
167+
#if defined(GIT_HTTPPARSER_HTTPPARSER)
168+
return "httpparser";
169+
#elif defined(GIT_HTTPPARSER_LLHTTP)
170+
return "llhttp";
171+
#elif defined(GIT_HTTPPARSER_BUILTIN)
172+
return "builtin";
173+
#endif
174+
GIT_ASSERT_WITH_RETVAL(!"Unknown HTTP parser backend", NULL);
175+
break;
176+
177+
case GIT_FEATURE_REGEX:
178+
#if defined(GIT_REGEX_REGCOMP_L)
179+
return "regcomp_l";
180+
#elif defined(GIT_REGEX_REGCOMP)
181+
return "regcomp";
182+
#elif defined(GIT_REGEX_PCRE)
183+
return "pcre";
184+
#elif defined(GIT_REGEX_PCRE2)
185+
return "pcre2";
186+
#elif defined(GIT_REGEX_BUILTIN)
187+
return "builtin";
188+
#endif
189+
GIT_ASSERT_WITH_RETVAL(!"Unknown regular expression backend", NULL);
190+
break;
191+
192+
case GIT_FEATURE_I18N:
193+
#if defined(GIT_USE_ICONV)
194+
return "iconv";
195+
#endif
196+
break;
197+
198+
case GIT_FEATURE_AUTH_NTLM:
199+
#if defined(GIT_NTLM)
200+
return "ntlmclient";
201+
#elif defined(GIT_WIN32)
202+
return "sspi";
203+
#endif
204+
break;
205+
206+
case GIT_FEATURE_AUTH_NEGOTIATE:
207+
#if defined(GIT_GSSAPI)
208+
return "gssapi";
209+
#elif defined(GIT_WIN32)
210+
return "sspi";
211+
#endif
212+
break;
213+
214+
case GIT_FEATURE_COMPRESSION:
215+
#if defined(GIT_COMPRESSION_ZLIB)
216+
return "zlib";
217+
#elif defined(GIT_COMPRESSION_BUILTIN)
218+
return "builtin";
219+
#else
220+
GIT_ASSERT_WITH_RETVAL(!"Unknown compression backend", NULL);
221+
#endif
222+
break;
223+
224+
case GIT_FEATURE_SHA1:
225+
#if defined(GIT_SHA1_COLLISIONDETECT)
226+
return "builtin";
227+
#elif defined(GIT_SHA1_OPENSSL)
228+
return "openssl";
229+
#elif defined(GIT_SHA1_OPENSSL_FIPS)
230+
return "openssl-fips";
231+
#elif defined(GIT_SHA1_OPENSSL_DYNAMIC)
232+
return "openssl-dynamic";
233+
#elif defined(GIT_SHA1_MBEDTLS)
234+
return "mbedtls";
235+
#elif defined(GIT_SHA1_COMMON_CRYPTO)
236+
return "commoncrypto";
237+
#elif defined(GIT_SHA1_WIN32)
238+
return "win32";
239+
#else
240+
GIT_ASSERT_WITH_RETVAL(!"Unknown SHA1 backend", NULL);
241+
#endif
242+
break;
243+
244+
case GIT_FEATURE_SHA256:
245+
#if defined(GIT_EXPERIMENTAL_SHA256) && defined(GIT_SHA256_BUILTIN)
246+
return "builtin";
247+
#elif defined(GIT_EXPERIMENTAL_SHA256) && defined(GIT_SHA256_OPENSSL)
248+
return "openssl";
249+
#elif defined(GIT_EXPERIMENTAL_SHA256) && defined(GIT_SHA256_OPENSSL_FIPS)
250+
return "openssl-fips";
251+
#elif defined(GIT_EXPERIMENTAL_SHA256) && defined(GIT_SHA256_OPENSSL_DYNAMIC)
252+
return "openssl-dynamic";
253+
#elif defined(GIT_EXPERIMENTAL_SHA256) && defined(GIT_SHA256_MBEDTLS)
254+
return "mbedtls";
255 80BC +
#elif defined(GIT_EXPERIMENTAL_SHA256) && defined(GIT_SHA256_COMMON_CRYPTO)
256+
return "commoncrypto";
257+
#elif defined(GIT_EXPERIMENTAL_SHA256) && defined(GIT_SHA256_WIN32)
258+
return "win32";
259+
#elif defined(GIT_EXPERIMENTAL_SHA256)
260+
GIT_ASSERT_WITH_RETVAL(!"Unknown SHA256 backend", NULL);
261+
#endif
262+
break;
263+
}
264+
265+
return NULL;
266+
}

0 commit comments

Comments
 (0)
0