summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2022-01-11 10:19:40 -0500
committerEdward Thomson <ethomson@edwardthomson.com>2022-01-17 21:06:06 -0500
commite02e6a5cd2484129e88447b2efb061c228a035d2 (patch)
tree409c2cbc1f5990767f077d896ae380c01c61fddd
parent6913422323a5df43020eeb8bd05cb7780228ecc2 (diff)
downloadlibgit2-e02e6a5cd2484129e88447b2efb061c228a035d2.tar.gz
url: introduce git_net_str_is_url
We occasionally need to determine whether a given string is a URL or something else. (The "something else" may be a git path in a different format, like scp formatting, which needs to be handled differently.)
-rw-r--r--src/net.c22
-rw-r--r--src/net.h3
-rw-r--r--tests/network/url/valid.c17
3 files changed, 41 insertions, 1 deletions
diff --git a/src/net.c b/src/net.c
index 1d4a3916b..a76fd1d7c 100644
--- a/src/net.c
+++ b/src/net.c
@@ -20,6 +20,24 @@
#define DEFAULT_PORT_GIT "9418"
#define DEFAULT_PORT_SSH "22"
+bool git_net_str_is_url(const char *str)
+{
+ const char *c;
+
+ for (c = str; *c; c++) {
+ if (*c == ':' && *(c+1) == '/' && *(c+2) == '/')
+ return true;
+
+ if ((*c < 'a' || *c > 'z') &&
+ (*c < 'A' || *c > 'Z') &&
+ (*c < '0' || *c > '9') &&
+ (*c != '+' && *c != '-' && *c != '.'))
+ break;
+ }
+
+ return false;
+}
+
static const char *default_port_for_scheme(const char *scheme)
{
if (strcmp(scheme, "http") == 0)
@@ -28,7 +46,9 @@ static const char *default_port_for_scheme(const char *scheme)
return DEFAULT_PORT_HTTPS;
else if (strcmp(scheme, "git") == 0)
return DEFAULT_PORT_GIT;
- else if (strcmp(scheme, "ssh") == 0)
+ else if (strcmp(scheme, "ssh") == 0 ||
+ strcmp(scheme, "ssh+git") == 0 ||
+ strcmp(scheme, "git+ssh") == 0)
return DEFAULT_PORT_SSH;
return NULL;
diff --git a/src/net.h b/src/net.h
index 739769a39..499315e6c 100644
--- a/src/net.h
+++ b/src/net.h
@@ -21,6 +21,9 @@ typedef struct git_net_url {
#define GIT_NET_URL_INIT { NULL }
+/** Is a given string a url? */
+extern bool git_net_str_is_url(const char *str);
+
/** Duplicate a URL */
extern int git_net_url_dup(git_net_url *out, git_net_url *in);
diff --git a/tests/network/url/valid.c b/tests/network/url/valid.c
new file mode 100644
index 000000000..2b2cb7ba4
--- /dev/null
+++ b/tests/network/url/valid.c
@@ -0,0 +1,17 @@
+#include "clar_libgit2.h"
+#include "net.h"
+
+void test_network_url_valid__test(void)
+{
+ cl_assert(git_net_str_is_url("http://example.com/"));
+ cl_assert(git_net_str_is_url("file://localhost/tmp/foo/"));
+ cl_assert(git_net_str_is_url("ssh://user@host:42/tmp"));
+ cl_assert(git_net_str_is_url("git+ssh://user@host:42/tmp"));
+ cl_assert(git_net_str_is_url("ssh+git://user@host:42/tmp"));
+ cl_assert(git_net_str_is_url("https://user:pass@example.com/foo/bar"));
+
+ cl_assert(!git_net_str_is_url("host:foo.git"));
+ cl_assert(!git_net_str_is_url("host:/foo.git"));
+ cl_assert(!git_net_str_is_url("[host:42]:/foo.git"));
+ cl_assert(!git_net_str_is_url("[user@host:42]:/foo.git"));
+}