@@ -636,14 +636,15 @@ static int write_chunk(git_stream *io, const char *buffer, size_t len)
636636 return 0 ;
637637}
638638
639- static int apply_proxy_config_to_stream (http_subtransport * t )
639+ static int apply_proxy_config_to_stream (
640+ git_stream * stream , git_proxy_options * proxy_opts )
640641{
641642 /* Only set the proxy configuration on the curl stream. */
642- if (!git_stream_supports_proxy (t -> server . stream ) ||
643- t -> proxy_opts . type == GIT_PROXY_NONE )
643+ if (!git_stream_supports_proxy (stream ) ||
644+ proxy_opts -> type == GIT_PROXY_NONE )
644645 return 0 ;
645646
646- return git_stream_set_proxy (t -> server . stream , & t -> proxy_opts );
647+ return git_stream_set_proxy (stream , proxy_opts );
647648}
648649
649650static int load_proxy_config (http_subtransport * t )
@@ -683,9 +684,41 @@ static int load_proxy_config(http_subtransport *t)
683684 return gitno_connection_data_from_url (& t -> proxy .url , t -> proxy_opts .url , NULL );
684685}
685686
687+ static int check_certificate (
688+ git_stream * stream ,
689+ gitno_connection_data * url ,
690+ int is_valid ,
691+ git_transport_certificate_check_cb cert_cb ,
692+ void * cert_cb_payload )
693+ {
694+ git_cert * cert ;
695+ int error ;
696+
697+ if ((error = git_stream_certificate (& cert , stream )) < 0 )
698+ return error ;
699+
700+ giterr_clear ();
701+ error = cert_cb (cert , is_valid , url -> host , cert_cb_payload );
702+
703+ if (error == GIT_PASSTHROUGH )
704+ error = is_valid ? 0 : GIT_ECERTIFICATE ;
705+
706+ if (error ) {
707+ if (!giterr_last ())
708+ giterr_set (GITERR_NET , "user cancelled certificate check" );
709+
710+ return error ;
711+ }
712+
713+ return 0 ;
714+ }
715+
686716static int http_connect (http_subtransport * t )
687717{
688- gitno_connection_data * connection_url ;
718+ gitno_connection_data * url ;
719+ git_stream * stream = NULL ;
720+ git_transport_certificate_check_cb cert_cb ;
721+ void * cb_payload ;
689722 int error ;
690723
691724 if (t -> connected &&
@@ -700,58 +733,56 @@ static int http_connect(http_subtransport *t)
700733 t -> connected = 0 ;
701734 }
702735
703- connection_url = (t -> proxy_opts .type == GIT_PROXY_SPECIFIED ) ?
704- & t -> proxy .url : & t -> server .url ;
736+ if (t -> proxy_opts .type == GIT_PROXY_SPECIFIED ) {
737+ url = & t -> proxy .url ;
738+ cert_cb = t -> proxy_opts .certificate_check ;
739+ cb_payload = t -> proxy_opts .payload ;
740+ } else {
741+ url = & t -> server .url ;
742+ cert_cb = t -> owner -> certificate_check_cb ;
743+ cb_payload = t -> owner -> message_cb_payload ;
744+ }
705745
706746#ifdef GIT_CURL
707- error = git_curl_stream_new (& t -> server . stream ,
747+ error = git_curl_stream_new (& stream ,
708748 t -> server .url .host , t -> server .url .port );
709749#else
710- if (connection_url -> use_ssl )
711- error = git_tls_stream_new (& t -> server .stream ,
712- connection_url -> host , connection_url -> port );
750+ if (url -> use_ssl )
751+ error = git_tls_stream_new (& stream , url -> host , url -> port );
713752 else
714- error = git_socket_stream_new (& t -> server .stream ,
715- connection_url -> host , connection_url -> port );
753+ error = git_socket_stream_new (& stream , url -> host , url -> port );
716754#endif
717755
718756 if (error < 0 )
719- return error ;
720-
721- GITERR_CHECK_VERSION (t -> server .stream , GIT_STREAM_VERSION , "git_stream" );
757+ goto on_error ;
722758
723- if ((error = apply_proxy_config_to_stream (t )) < 0 )
724- return error ;
759+ GITERR_CHECK_VERSION (stream , GIT_STREAM_VERSION , "git_stream" );
725760
726- error = git_stream_connect (t -> server .stream );
761+ if ((error = apply_proxy_config_to_stream (stream , & t -> proxy_opts )) < 0 )
762+ goto on_error ;
727763
728- if ((!error || error == GIT_ECERTIFICATE ) && t -> owner -> certificate_check_cb != NULL &&
729- git_stream_is_encrypted (t -> server .stream )) {
730- git_cert * cert ;
731- int is_valid = (error == GIT_OK );
764+ error = git_stream_connect (stream );
732765
733- if (( error = git_stream_certificate ( & cert , t -> server . stream )) < 0 )
734- return error ;
766+ if (error && error != GIT_ECERTIFICATE )
767+ goto on_error ;
735768
736- giterr_clear ();
737- error = t -> owner -> certificate_check_cb ( cert , is_valid , t -> server . url . host , t -> owner -> message_cb_payload );
769+ if ( git_stream_is_encrypted ( stream ) && cert_cb != NULL )
770+ error = check_certificate ( stream , url , ! error , cert_cb , cb_payload );
738771
739- if (error == GIT_PASSTHROUGH )
740- error = is_valid ? 0 : GIT_ECERTIFICATE ;
772+ if (error )
773+ goto on_error ;
741774
742- if ( error < 0 ) {
743- if (! giterr_last ())
744- giterr_set ( GITERR_NET , "user cancelled certificate check" ) ;
775+ t -> server . stream = stream ;
776+ t -> connected = 1 ;
777+ return 0 ;
745778
746- return error ;
747- }
779+ on_error :
780+ if (stream ) {
781+ git_stream_close (stream );
782+ git_stream_free (stream );
748783 }
749784
750- if (error < 0 )
751- return error ;
752-
753- t -> connected = 1 ;
754- return 0 ;
785+ return error ;
755786}
756787
757788static int http_stream_read (
0 commit comments