Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b7809b8

Browse files
author
Edward Thomson
committed
Merge pull request libgit2#3555 from cbargren/ssh-git-protocols
Support for ssh+git and git+ssh protocols
2 parents 534ca88 + 813d73f commit b7809b8

File tree

4 files changed

+49
-19
lines changed

4 files changed

+49
-19
lines changed

deps/http-parser/http_parser.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ do { \
9999
FOR##_mark = NULL; \
100100
} \
101101
} while (0)
102-
102+
103103
/* Run the data callback FOR and consume the current byte */
104104
#define CALLBACK_DATA(FOR) \
105105
CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)
@@ -444,14 +444,17 @@ parse_url_char(enum state s, const char ch)
444444
return s_req_path;
445445
}
446446

447+
/* The schema must start with an alpha character. After that, it may
448+
* consist of digits, '+', '-' or '.', followed by a ':'.
449+
*/
447450
if (IS_ALPHA(ch)) {
448451
return s_req_schema;
449452
}
450453

451454
break;
452455

453456
case s_req_schema:
454-
if (IS_ALPHA(ch)) {
457+
if (IS_ALPHANUM(ch) || ch == '+' || ch == '-' || ch == '.') {
455458
return s;
456459
}
457460

src/transport.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ static transport_definition transports[] = {
3535
{ "file://", git_transport_local, NULL },
3636
#ifdef GIT_SSH
3737
{ "ssh://", git_transport_smart, &ssh_subtransport_definition },
38+
{ "ssh+git://", git_transport_smart, &ssh_subtransport_definition },
39+
{ "git+ssh://", git_transport_smart, &ssh_subtransport_definition },
3840
#endif
3941
{ NULL, 0, 0 }
4042
};

src/transports/ssh.c

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121

2222
#define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport)
2323

24-
static const char prefix_ssh[] = "ssh://";
24+
static const char *ssh_prefixes[] = { "ssh://", "ssh+git://", "git+ssh://" };
25+
2526
static const char cmd_uploadpack[] = "git-upload-pack";
2627
static const char cmd_receivepack[] = "git-receive-pack";
2728

@@ -63,17 +64,24 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url)
6364
{
6465
char *repo;
6566
int len;
67+
size_t i;
6668

67-
if (!git__prefixcmp(url, prefix_ssh)) {
68-
url = url + strlen(prefix_ssh);
69-
repo = strchr(url, '/');
70-
if (repo && repo[1] == '~')
71-
++repo;
72-
} else {
73-
repo = strchr(url, ':');
74-
if (repo) repo++;
69+
for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) {
70+
const char *p = ssh_prefixes[i];
71+
72+
if (!git__prefixcmp(url, p)) {
73+
url = url + strlen(p);
74+
repo = strchr(url, '/');
75+
if (repo && repo[1] == '~')
76+
++repo;
77+
78+
goto done;
79+
}
7580
}
81+
repo = strchr(url, ':');
82+
if (repo) repo++;
7683

84+
done:
7785
if (!repo) {
7886
giterr_set(GITERR_NET, "Malformed git protocol URL");
7987
return -1;
@@ -500,6 +508,7 @@ static int _git_ssh_setup_conn(
500508
char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
501509
const char *default_port="22";
502510
int auth_methods, error = 0;
511+
size_t i;
503512
ssh_stream *s;
504513
git_cred *cred = NULL;
505514
LIBSSH2_SESSION* session=NULL;
@@ -515,16 +524,22 @@ static int _git_ssh_setup_conn(
515524
s->session = NULL;
516525
s->channel = NULL;
517526

518-
if (!git__prefixcmp(url, prefix_ssh)) {
519-
if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0)
520-
goto done;
521-
} else {
522-
if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0)
523-
goto done;
524-
port = git__strdup(default_port);
525-
GITERR_CHECK_ALLOC(port);
527+
for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) {
528+
const char *p = ssh_prefixes[i];
529+
530+
if (!git__prefixcmp(url, p)) {
531+
if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0)
532+
goto done;
533+
534+
goto post_extract;
535+
}
526536
}
537+
if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0)
538+
goto done;
539+
port = git__strdup(default_port);
540+
GITERR_CHECK_ALLOC(port);
527541

542+
post_extract:
528543
if ((error = git_socket_stream_new(&s->io, host, port)) < 0 ||
529544
(error = git_stream_connect(s->io)) < 0)
530545
goto done;

tests/transport/register.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,13 @@ void test_transport_register__custom_transport_ssh(void)
4444

4545
#ifndef GIT_SSH
4646
cl_git_fail_with(git_transport_new(&transport, NULL, "ssh://somehost:somepath"), -1);
47+
cl_git_fail_with(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath"), -1);
48+
cl_git_fail_with(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"), -1);
4749
cl_git_fail_with(git_transport_new(&transport, NULL, "git@somehost:somepath"), -1);
4850
#else
51+
cl_git_pass(git_transport_new(&transport, NULL, "ssh://somehost:somepath"));
52+
cl_git_pass(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath"));
53+
cl_git_pass(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"));
4954
cl_git_pass(git_transport_new(&transport, NULL, "git@somehost:somepath"));
5055
transport->free(transport);
5156
#endif
@@ -60,8 +65,13 @@ void test_transport_register__custom_transport_ssh(void)
6065

6166
#ifndef GIT_SSH
6267
cl_git_fail_with(git_transport_new(&transport, NULL, "ssh://somehost:somepath"), -1);
68+
cl_git_fail_with(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath"), -1);
69+
cl_git_fail_with(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"), -1);
6370
cl_git_fail_with(git_transport_new(&transport, NULL, "git@somehost:somepath"), -1);
6471
#else
72+
cl_git_pass(git_transport_new(&transport, NULL, "ssh://somehost:somepath"));
73+
cl_git_pass(git_transport_new(&transport, NULL, "ssh+git://somehost:somepath"));
74+
cl_git_pass(git_transport_new(&transport, NULL, "git+ssh://somehost:somepath"));
6575
cl_git_pass(git_transport_new(&transport, NULL, "git@somehost:somepath"));
6676
transport->free(transport);
6777
#endif

0 commit comments

Comments
 (0)