2424
2525#define OWNING_SUBTRANSPORT (s ) ((ssh_subtransport *)(s)->parent.subtransport)
2626
27- static const char * ssh_prefixes [] = { "ssh://" , "ssh+git://" , "git+ssh://" };
28-
2927static const char cmd_uploadpack [] = "git-upload-pack" ;
3028static const char cmd_receivepack [] = "git-receive-pack" ;
3129
@@ -35,7 +33,7 @@ typedef struct {
3533 LIBSSH2_SESSION * session ;
3634 LIBSSH2_CHANNEL * channel ;
3735 const char * cmd ;
38- char * url ;
36+ git_net_url url ;
3937 unsigned sent_command : 1 ;
4038} ssh_stream ;
4139
@@ -63,39 +61,23 @@ static void ssh_error(LIBSSH2_SESSION *session, const char *errmsg)
6361 *
6462 * For example: git-upload-pack '/libgit2/libgit2'
6563 */
66- static int gen_proto (git_str * request , const char * cmd , const char * url )
64+ static int gen_proto (git_str * request , const char * cmd , git_net_url * url )
6765{
6866 const char * repo ;
69- int len ;
70- size_t i ;
71-
72- for (i = 0 ; i < ARRAY_SIZE (ssh_prefixes ); ++ i ) {
73- const char * p = ssh_prefixes [i ];
7467
75- if (!git__prefixcmp (url , p )) {
76- url = url + strlen (p );
77- repo = strchr (url , '/' );
78- if (repo && repo [1 ] == '~' )
79- ++ repo ;
68+ repo = url -> path ;
8069
81- goto done ;
82- }
83- }
84- repo = strchr (url , ':' );
85- if (repo ) repo ++ ;
70+ if (repo && repo [0 ] == '/' && repo [1 ] == '~' )
71+ repo ++ ;
8672
87- done :
88- if (!repo ) {
73+ if (!repo || !repo [0 ]) {
8974 git_error_set (GIT_ERROR_NET , "malformed git protocol URL" );
9075 return -1 ;
9176 }
9277
93- len = strlen (cmd ) + 1 /* Space */ + 1 /* Quote */ + strlen (repo ) + 1 /* Quote */ + 1 ;
94-
95- git_str_grow (request , len );
9678 git_str_puts (request , cmd );
9779 git_str_puts (request , " '" );
98- git_str_decode_percent (request , repo , strlen ( repo ) );
80+ git_str_puts (request , repo );
9981 git_str_puts (request , "'" );
10082
10183 if (git_str_oom (request ))
@@ -109,7 +91,7 @@ static int send_command(ssh_stream *s)
10991 int error ;
11092 git_str request = GIT_STR_INIT ;
11193
112- error = gen_proto (& request , s -> cmd , s -> url );
94+ error = gen_proto (& request , s -> cmd , & s -> url );
11395 if (error < 0 )
11496 goto cleanup ;
11597
@@ -224,13 +206,12 @@ static void ssh_stream_free(git_smart_subtransport_stream *stream)
224206 s -> io = NULL ;
225207 }
226208
227- git__free ( s -> url );
209+ git_net_url_dispose ( & s -> url );
228210 git__free (s );
229211}
230212
231213static int ssh_stream_alloc (
232214 ssh_subtransport * t ,
233- const char * url ,
234215 const char * cmd ,
235216 git_smart_subtransport_stream * * stream )
236217{
@@ -248,12 +229,6 @@ static int ssh_stream_alloc(
248229
249230 s -> cmd = cmd ;
250231
251- s -> url = git__strdup (url );
252- if (!s -> url ) {
253- git__free (s );
254- return -1 ;
255- }
256-
257232 * stream = & s -> parent ;
258233 return 0 ;
259234}
@@ -487,9 +462,7 @@ static int _git_ssh_setup_conn(
487462 const char * cmd ,
488463 git_smart_subtransport_stream * * stream )
489464{
490- git_net_url urldata = GIT_NET_URL_INIT ;
491465 int auth_methods , error = 0 ;
492- size_t i ;
493466 ssh_stream * s ;
494467 git_credential * cred = NULL ;
495468 LIBSSH2_SESSION * session = NULL ;
@@ -498,28 +471,22 @@ static int _git_ssh_setup_conn(
498471 t -> current_stream = NULL ;
499472
500473 * stream = NULL ;
501- if (ssh_stream_alloc (t , url , cmd , stream ) < 0 )
474+ if (ssh_stream_alloc (t , cmd , stream ) < 0 )
502475 return -1 ;
503476
504477 s = (ssh_stream * )* stream ;
505478 s -> session = NULL ;
506479 s -> channel = NULL ;
507480
508- for (i = 0 ; i < ARRAY_SIZE (ssh_prefixes ); ++ i ) {
509- const char * p = ssh_prefixes [i ];
510-
511- if (!git__prefixcmp (url , p )) {
512- if ((error = git_net_url_parse (& urldata , url )) < 0 )
513- goto done ;
481+ if (git_net_str_is_url (url ))
482+ error = git_net_url_parse (& s -> url , url );
483+ else
484+ error = git_net_url_parse_scp (& s -> url , url );
514485
515- goto post_extract ;
516- }
517- }
518- if ((error = git_net_url_parse_scp (& urldata , url )) < 0 )
486+ if (error < 0 )
519487 goto done ;
520488
521- post_extract :
522- if ((error = git_socket_stream_new (& s -> io , urldata .host , urldata .port )) < 0 ||
489+ if ((error = git_socket_stream_new (& s -> io , s -> url .host , s -> url .port )) < 0 ||
523490 (error = git_stream_connect (s -> io )) < 0 )
524491 goto done ;
525492
@@ -603,7 +570,7 @@ static int _git_ssh_setup_conn(
603570 error = t -> owner -> connect_opts .callbacks .certificate_check (
604571 (git_cert * )cert_ptr ,
605572 0 ,
606- urldata .host ,
573+ s -> url .host ,
607574 t -> owner -> connect_opts .callbacks .payload );
608575
609576 if (error < 0 && error != GIT_PASSTHROUGH ) {
@@ -615,21 +582,21 @@ static int _git_ssh_setup_conn(
615582 }
616583
617584 /* we need the username to ask for auth methods */
618- if (!urldata .username ) {
585+ if (!s -> url .username ) {
619586 if ((error = request_creds (& cred , t , NULL , GIT_CREDENTIAL_USERNAME )) < 0 )
620587 goto done ;
621588
622- urldata .username = git__strdup (((git_credential_username * ) cred )-> username );
589+ s -> url .username = git__strdup (((git_credential_username * ) cred )-> username );
623590 cred -> free (cred );
624591 cred = NULL ;
625- if (!urldata .username )
592+ if (!s -> url .username )
626593 goto done ;
627- } else if (urldata .username && urldata .password ) {
628- if ((error = git_credential_userpass_plaintext_new (& cred , urldata .username , urldata .password )) < 0 )
594+ } else if (s -> url .username && s -> url .password ) {
595+ if ((error = git_credential_userpass_plaintext_new (& cred , s -> url .username , s -> url .password )) < 0 )
629596 goto done ;
630597 }
631598
632- if ((error = list_auth_methods (& auth_methods , session , urldata .username )) < 0 )
599+ if ((error = list_auth_methods (& auth_methods , session , s -> url .username )) < 0 )
633600 goto done ;
634601
635602 error = GIT_EAUTH ;
@@ -643,10 +610,10 @@ static int _git_ssh_setup_conn(
643610 cred = NULL ;
644611 }
645612
646- if ((error = request_creds (& cred , t , urldata .username , auth_methods )) < 0 )
613+ if ((error = request_creds (& cred , t , s -> url .username , auth_methods )) < 0 )
647614 goto done ;
648615
649- if (strcmp (urldata .username , git_credential_get_username (cred ))) {
616+ if (strcmp (s -> url .username , git_credential_get_username (cred ))) {
650617 git_error_set (GIT_ERROR_SSH , "username does not match previous request" );
651618 error = -1 ;
652619 goto done ;
@@ -656,7 +623,7 @@ static int _git_ssh_setup_conn(
656623
657624 if (error == GIT_EAUTH ) {
658625 /* refresh auth methods */
659- if ((error = list_auth_methods (& auth_methods , session , urldata .username )) < 0 )
626+ if ((error = list_auth_methods (& auth_methods , session , s -> url .username )) < 0 )
660627 goto done ;
661628 else
662629 error = GIT_EAUTH ;
@@ -691,8 +658,6 @@ static int _git_ssh_setup_conn(
691658 if (cred )
692659 cred -> free (cred );
693660
694- git_net_url_dispose (& urldata );
695-
696661 return error ;
697662}
698663
0 commit comments