From d900cec96c322fb85a810b3476defa8e458fa2a8 Mon Sep 17 00:00:00 2001 From: Chris Bargren Date: Tue, 22 Dec 2015 10:38:16 -0700 Subject: [PATCH 1/7] Updating http parser to accept a `+` in the schema --- deps/http-parser/http_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/http-parser/http_parser.c b/deps/http-parser/http_parser.c index 20353025472..b793d70111e 100644 --- a/deps/http-parser/http_parser.c +++ b/deps/http-parser/http_parser.c @@ -451,7 +451,7 @@ parse_url_char(enum state s, const char ch) break; case s_req_schema: - if (IS_ALPHA(ch)) { + if (IS_ALPHA(ch) || ch == '+') { return s; } From ed21fd745ca9119817e0005080f7dbd0234b7842 Mon Sep 17 00:00:00 2001 From: Chris Bargren Date: Tue, 22 Dec 2015 10:38:31 -0700 Subject: [PATCH 2/7] Handle git+ssh:// and ssh+git:// protocols support --- src/transport.c | 2 ++ src/transports/ssh.c | 50 +++++++++++++++++++++++++++++--------------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/transport.c b/src/transport.c index 5c65c7c06ce..cf785bc8892 100644 --- a/src/transport.c +++ b/src/transport.c @@ -35,6 +35,8 @@ static transport_definition transports[] = { { "file://", git_transport_local, NULL }, #ifdef GIT_SSH { "ssh://", git_transport_smart, &ssh_subtransport_definition }, + { "ssh+git://", git_transport_smart, &ssh_subtransport_definition }, + { "git+ssh://", git_transport_smart, &ssh_subtransport_definition }, #endif { NULL, 0, 0 } }; diff --git a/src/transports/ssh.c b/src/transports/ssh.c index ffa4a24a7e9..c1f97fa4779 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -20,7 +20,9 @@ #define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport) -static const char prefix_ssh[] = "ssh://"; +static const char * ssh_prefixes[] = { "ssh://", "ssh+git://", "git+ssh://" }; +#define SSH_PREFIX_COUNT (sizeof(ssh_prefixes) / sizeof(ssh_prefixes[0])) + static const char cmd_uploadpack[] = "git-upload-pack"; static const char cmd_receivepack[] = "git-receive-pack"; @@ -63,16 +65,23 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url) char *repo; int len; - if (!git__prefixcmp(url, prefix_ssh)) { - url = url + strlen(prefix_ssh); - repo = strchr(url, '/'); - if (repo && repo[1] == '~') - ++repo; - } else { - repo = strchr(url, ':'); - if (repo) repo++; + size_t i = 0; + for (i = 0; i < SSH_PREFIX_COUNT; ++i) { + const char *p = ssh_prefixes[i]; + + if (!git__prefixcmp(url, p)) { + url = url + strlen(p); + repo = strchr(url, '/'); + if (repo && repo[1] == '~') + ++repo; + + goto done; + } } + repo = strchr(url, ':'); + if (repo) repo++; +done: if (!repo) { giterr_set(GITERR_NET, "Malformed git protocol URL"); return -1; @@ -509,16 +518,23 @@ static int _git_ssh_setup_conn( s->session = NULL; s->channel = NULL; - if (!git__prefixcmp(url, prefix_ssh)) { - if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0) - goto done; - } else { - if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0) - goto done; - port = git__strdup(default_port); - GITERR_CHECK_ALLOC(port); + size_t i = 0; + for (i = 0; i < SSH_PREFIX_COUNT; ++i) { + const char *p = ssh_prefixes[i]; + + if (!git__prefixcmp(url, p)) { + if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0) + goto done; + + goto post_extract; + } } + if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0) + goto done; + port = git__strdup(default_port); + GITERR_CHECK_ALLOC(port); +post_extract: if ((error = git_socket_stream_new(&s->io, host, port)) < 0 || (error = git_stream_connect(s->io)) < 0) goto done; From 0c1f56722bbcba16b90d82411ed02f66622fc03a Mon Sep 17 00:00:00 2001 From: Chris Bargren Date: Tue, 22 Dec 2015 10:56:38 -0700 Subject: [PATCH 3/7] Adding spec coverage for ssh+git and git+ssh protocols --- tests/transport/register.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/transport/register.c b/tests/transport/register.c index ea917d5d30d..385ef0a4c30 100644 --- a/tests/transport/register.c +++ b/tests/transport/register.c @@ -44,6 +44,8 @@ void test_transport_register__custom_transport_ssh(void) #ifndef GIT_SSH cl_git_fail_with(git_transport_new(&transport, NULL, "ssh://somehost:somepath"), -1); + cl_git_fail_with(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath"), -1); + cl_git_fail_with(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"), -1); cl_git_fail_with(git_transport_new(&transport, NULL, "git@somehost:somepath"), -1); #else cl_git_pass(git_transport_new(&transport, NULL, "git@somehost:somepath")); @@ -60,6 +62,8 @@ void test_transport_register__custom_transport_ssh(void) #ifndef GIT_SSH cl_git_fail_with(git_transport_new(&transport, NULL, "ssh://somehost:somepath"), -1); + cl_git_fail_with(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath"), -1); + cl_git_fail_with(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"), -1); cl_git_fail_with(git_transport_new(&transport, NULL, "git@somehost:somepath"), -1); #else cl_git_pass(git_transport_new(&transport, NULL, "git@somehost:somepath")); From 0b1e6e42e3cc94e746a3a9453dd9b0702062b757 Mon Sep 17 00:00:00 2001 From: Chris Bargren Date: Mon, 28 Dec 2015 07:40:15 -0700 Subject: [PATCH 4/7] Updating change to http_parser to reflect PR for nodejs/http-parser The parser now also supports digits, '-' and '.'. https://github.com/nodejs/http-parser/pull/276 --- deps/http-parser/http_parser.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/deps/http-parser/http_parser.c b/deps/http-parser/http_parser.c index b793d70111e..27bdd208186 100644 --- a/deps/http-parser/http_parser.c +++ b/deps/http-parser/http_parser.c @@ -99,7 +99,7 @@ do { \ FOR##_mark = NULL; \ } \ } while (0) - + /* Run the data callback FOR and consume the current byte */ #define CALLBACK_DATA(FOR) \ CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) @@ -444,6 +444,9 @@ parse_url_char(enum state s, const char ch) return s_req_path; } + /* The schema must start with an alpha character. After that, it may + * consist of digits, '+', '-' or '.', followed by a ':'. + */ if (IS_ALPHA(ch)) { return s_req_schema; } @@ -451,7 +454,7 @@ parse_url_char(enum state s, const char ch) break; case s_req_schema: - if (IS_ALPHA(ch) || ch == '+') { + if (IS_ALPHANUM(ch) || ch == '+' || ch == '-' || ch == '.') { return s; } From 4df17045c178194c5617c7df24bbc762895a222b Mon Sep 17 00:00:00 2001 From: Chris Bargren Date: Mon, 28 Dec 2015 07:43:24 -0700 Subject: [PATCH 5/7] Removing #define for SSH_PREFIX_COUNT and using ARRAY_SIZE instead Also moving var declarations to top of blocks to support bad old compilers --- src/transports/ssh.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/transports/ssh.c b/src/transports/ssh.c index c1f97fa4779..700998bf060 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -20,8 +20,7 @@ #define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport) -static const char * ssh_prefixes[] = { "ssh://", "ssh+git://", "git+ssh://" }; -#define SSH_PREFIX_COUNT (sizeof(ssh_prefixes) / sizeof(ssh_prefixes[0])) +static const char *ssh_prefixes[] = { "ssh://", "ssh+git://", "git+ssh://" }; static const char cmd_uploadpack[] = "git-upload-pack"; static const char cmd_receivepack[] = "git-receive-pack"; @@ -64,9 +63,9 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url) { char *repo; int len; + size_t i; - size_t i = 0; - for (i = 0; i < SSH_PREFIX_COUNT; ++i) { + for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) { const char *p = ssh_prefixes[i]; if (!git__prefixcmp(url, p)) { @@ -503,6 +502,7 @@ static int _git_ssh_setup_conn( char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL; const char *default_port="22"; int auth_methods, error = 0; + size_t i; ssh_stream *s; git_cred *cred = NULL; LIBSSH2_SESSION* session=NULL; @@ -518,8 +518,7 @@ static int _git_ssh_setup_conn( s->session = NULL; s->channel = NULL; - size_t i = 0; - for (i = 0; i < SSH_PREFIX_COUNT; ++i) { + for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) { const char *p = ssh_prefixes[i]; if (!git__prefixcmp(url, p)) { From 1cc7f544a005faf87f4a1d9f35bdaa7b4156c6b2 Mon Sep 17 00:00:00 2001 From: Chris Bargren Date: Mon, 28 Dec 2015 11:35:19 -0700 Subject: [PATCH 6/7] Adding test cases that actually test the functionality of the new transport ssh, ssh+git and git+ssh should all successfully build an SSH transport --- tests/transport/register.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/transport/register.c b/tests/transport/register.c index 385ef0a4c30..67a2efd9980 100644 --- a/tests/transport/register.c +++ b/tests/transport/register.c @@ -48,6 +48,9 @@ void test_transport_register__custom_transport_ssh(void) cl_git_fail_with(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"), -1); cl_git_fail_with(git_transport_new(&transport, NULL, "git@somehost:somepath"), -1); #else + cl_git_pass(git_transport_new(&transport, NULL, "ssh://somehost:somepath")); + cl_git_pass(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath")); + cl_git_pass(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath")); cl_git_pass(git_transport_new(&transport, NULL, "git@somehost:somepath")); transport->free(transport); #endif @@ -66,6 +69,9 @@ void test_transport_register__custom_transport_ssh(void) cl_git_fail_with(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"), -1); cl_git_fail_with(git_transport_new(&transport, NULL, "git@somehost:somepath"), -1); #else + cl_git_pass(git_transport_new(&transport, NULL, "ssh://somehost:somepath")); + cl_git_pass(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath")); + cl_git_pass(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath")); cl_git_pass(git_transport_new(&transport, NULL, "git@somehost:somepath")); transport->free(transport); #endif From 813d73f64d779257fd24cd70bbc281352c34812b Mon Sep 17 00:00:00 2001 From: Chris Bargren Date: Mon, 28 Dec 2015 11:37:39 -0700 Subject: [PATCH 7/7] Tabs --- src/transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transport.c b/src/transport.c index cf785bc8892..327052fa393 100644 --- a/src/transport.c +++ b/src/transport.c @@ -35,8 +35,8 @@ static transport_definition transports[] = { { "file://", git_transport_local, NULL }, #ifdef GIT_SSH { "ssh://", git_transport_smart, &ssh_subtransport_definition }, - { "ssh+git://", git_transport_smart, &ssh_subtransport_definition }, - { "git+ssh://", git_transport_smart, &ssh_subtransport_definition }, + { "ssh+git://", git_transport_smart, &ssh_subtransport_definition }, + { "git+ssh://", git_transport_smart, &ssh_subtransport_definition }, #endif { NULL, 0, 0 } };