@@ -849,112 +849,91 @@ int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote
849849 return remote -> transport -> ls (out , size , remote -> transport );
850850}
851851
852- int git_remote__get_http_proxy_bypass ( git_net_url * url , git_buf * no_proxy_env , bool * bypass )
852+ static int lookup_config ( char * * out , git_config * cfg , const char * name )
853853{
854- int error = 0 ;
855- char * p_start = no_proxy_env -> ptr ;
856- size_t p_length = 0 ;
857- char c ;
858- git_buf hostport = GIT_BUF_INIT ;
854+ git_config_entry * ce = NULL ;
855+ int error ;
859856
860- error = git_buf_printf (& hostport , "%s:%s" , url -> host , url -> port );
861- if (error < 0 )
857+ if ((error = git_config__lookup_entry (& ce , cfg , name , false)) < 0 )
862858 return error ;
863859
864- * bypass = false;
865-
866- do {
867- c = * (p_start + p_length );
868- if ((c == ',' ) || (c == 0 )) {
869- if ((p_length == 1 ) && (* p_start == '*' )) {
870- // wildcard match (*)
871- goto found ;
872- } else if ((p_length == strlen (url -> host )) && !memcmp (p_start , url -> host , p_length )) {
873- // exact host match
874- goto found ;
875- } else if ((p_length == strlen (hostport .ptr )) && !memcmp (p_start , hostport .ptr , p_length )) {
876- // exact host:port match
877- goto found ;
878- } else {
879- if ((p_length >= 2 ) && (* p_start == '*' ) && (* (p_start + 1 ) == '.' )) {
880- // *.foo == .foo
881- p_start ++ ;
882- p_length -- ;
883- }
884- if ((* p_start == '.' ) && (strlen (url -> host ) > p_length ) && !memcmp (p_start , url -> host + strlen (url -> host ) - p_length , p_length )) {
885- // host suffix match (.example.org)
886- goto found ;
887- } else if ((* p_start == '.' ) && (strlen (hostport .ptr ) > p_length ) && !memcmp (p_start , hostport .ptr + strlen (hostport .ptr ) - p_length , p_length )) {
888- // host:port suffix match (.example.org:443)
889- goto found ;
890- }
891- }
892- p_start += p_length + 1 ;
893- p_length = 0 ;
894- } else {
895- p_length ++ ;
896- }
897- } while (c != 0 );
860+ if (ce && ce -> value ) {
861+ * out = git__strdup (ce -> value );
862+ GIT_ERROR_CHECK_ALLOC (* out );
863+ } else {
864+ error = GIT_ENOTFOUND ;
865+ }
866+
867+ git_config_entry_free (ce );
868+ return error ;
869+ }
898870
899- goto end ;
871+ static void url_config_trim (git_net_url * url )
872+ {
873+ size_t len = strlen (url -> path );
900874
901- found :
902- * bypass = true;
875+ if (url -> path [len - 1 ] == '/' ) {
876+ len -- ;
877+ } else {
878+ while (len && url -> path [len - 1 ] != '/' )
879+ len -- ;
880+ }
903881
904- end :
905- git_buf_dispose (& hostport );
906- return 0 ;
882+ url -> path [len ] = '\0' ;
907883}
908884
909- int git_remote__get_http_proxy ( git_remote * remote , bool use_ssl , git_net_url * url , char * * proxy_url )
885+ static int http_proxy_config ( char * * out , git_remote * remote , git_net_url * url )
910886{
911887 git_config * cfg ;
912- git_config_entry * ce = NULL ;
913- git_buf proxy_env = GIT_BUF_INIT ;
914- git_buf no_proxy_env = GIT_BUF_INIT ;
915- bool bypass = false;
888+ git_buf buf = GIT_BUF_INIT ;
889+ git_net_url lookup_url = GIT_NET_URL_INIT ;
916890 int error ;
917891
918- GIT_ASSERT_ARG (remote );
892+ if ((error = git_net_url_dup (& lookup_url , url )) < 0 ||
893+ (error = git_repository_config__weakptr (& cfg , remote -> repo )) < 0 )
894+ goto done ;
919895
920- if (!proxy_url || !remote -> repo )
921- return -1 ;
896+ /* remote.<name>.proxy config setting */
897+ if (remote -> name && remote -> name [0 ]) {
898+ git_buf_clear (& buf );
922899
923- * proxy_url = NULL ;
900+ if ((error = git_buf_printf (& buf , "remote.%s.proxy" , remote -> name )) < 0 ||
901+ (error = lookup_config (out , cfg , buf .ptr )) != GIT_ENOTFOUND )
902+ goto done ;
903+ }
924904
925- if (( error = git_repository_config__weakptr ( & cfg , remote -> repo )) < 0 )
926- return error ;
905+ while (true) {
906+ git_buf_clear ( & buf ) ;
927907
928- /* Go through the possible sources for proxy configuration, from most specific
929- * to least specific. */
908+ if ((error = git_buf_puts (& buf , "http." )) < 0 ||
909+ (error = git_net_url_fmt (& buf , & lookup_url )) < 0 ||
910+ (error = git_buf_puts (& buf , ".proxy" )) < 0 ||
911+ (error = lookup_config (out , cfg , buf .ptr )) != GIT_ENOTFOUND )
912+ goto done ;
930913
931- /* remote.<name>.proxy config setting */
932- if (remote -> name && remote -> name [0 ]) {
933- git_buf buf = GIT_BUF_INIT ;
914+ if (! lookup_url .path [0 ])
915+ break ;
934916
935- if (( error = git_buf_printf ( & buf , "remote.%s.proxy" , remote -> name )) < 0 )
936- return error ;
917+ url_config_trim ( & lookup_url );
918+ }
937919
938- error = git_config__lookup_entry (& ce , cfg , git_buf_cstr (& buf ), false);
939- git_buf_dispose (& buf );
920+ git_buf_clear (& buf );
940921
941- if (error < 0 )
942- return error ;
922+ error = lookup_config (out , cfg , "http.proxy" );
943923
944- if ( ce && ce -> value ) {
945- * proxy_url = git__strdup ( ce -> value );
946- goto found ;
947- }
948- }
924+ done :
925+ git_buf_dispose ( & buf );
926+ git_net_url_dispose ( & lookup_url ) ;
927+ return error ;
928+ }
949929
950- /* http.proxy config setting */
951- if ((error = git_config__lookup_entry (& ce , cfg , "http.proxy" , false)) < 0 )
952- return error ;
930+ static int http_proxy_env (char * * out , git_remote * remote , git_net_url * url )
931+ {
932+ git_buf proxy_env = GIT_BUF_INIT , no_proxy_env = GIT_BUF_INIT ;
933+ bool use_ssl = (strcmp (url -> scheme , "https" ) == 0 );
934+ int error ;
953935
954- if (ce && ce -> value ) {
955- * proxy_url = git__strdup (ce -> value );
956- goto found ;
957- }
936+ GIT_UNUSED (remote );
958937
959938 /* http_proxy / https_proxy environment variables */
960939 error = git__getenv (& proxy_env , use_ssl ? "https_proxy" : "http_proxy" );
@@ -963,46 +942,51 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, git_net_url *ur
963942 if (error == GIT_ENOTFOUND )
964943 error = git__getenv (& proxy_env , use_ssl ? "HTTPS_PROXY" : "HTTP_PROXY" );
965944
966- if (error < 0 ) {
967- if (error == GIT_ENOTFOUND ) {
968- git_error_clear ();
969- error = 0 ;
970- }
971-
972- return error ;
973- }
945+ if (error )
946+ goto done ;
974947
975948 /* no_proxy/NO_PROXY environment variables */
976949 error = git__getenv (& no_proxy_env , "no_proxy" );
950+
977951 if (error == GIT_ENOTFOUND )
978952 error = git__getenv (& no_proxy_env , "NO_PROXY" );
979953
980- if (error == GIT_ENOTFOUND ) {
981- git_error_clear ();
982- error = 0 ;
983- } else if (error < 0 ) {
984- goto cleanup ;
985- } else {
986- error = git_remote__get_http_proxy_bypass (url , & no_proxy_env , & bypass );
987- }
988-
989- if (bypass ) {
990- git_buf_dispose (& proxy_env );
991- goto cleanup ;
992- } else {
993- * proxy_url = git_buf_detach (& proxy_env );
994- }
954+ if (error && error != GIT_ENOTFOUND )
955+ goto done ;
995956
996- found :
997- GIT_ERROR_CHECK_ALLOC (* proxy_url );
957+ if (!git_net_url_matches_pattern_list (url , no_proxy_env .ptr ))
958+ * out = git_buf_detach (& proxy_env );
959+ else
960+ error = GIT_ENOTFOUND ;
998961
999- cleanup :
962+ done :
963+ git_buf_dispose (& proxy_env );
1000964 git_buf_dispose (& no_proxy_env );
1001- git_config_entry_free (ce );
1002-
1003965 return error ;
1004966}
1005967
968+ int git_remote__http_proxy (char * * out , git_remote * remote , git_net_url * url )
969+ {
970+ int error ;
971+
972+ GIT_ASSERT_ARG (out );
973+ GIT_ASSERT_ARG (remote );
974+ GIT_ASSERT_ARG (remote -> repo );
975+
976+ * out = NULL ;
977+
978+ /*
979+ * Go through the possible sources for proxy configuration,
980+ * Examine the various git config options first, then
981+ * consult environment variables.
982+ */
983+ if ((error = http_proxy_config (out , remote , url )) != GIT_ENOTFOUND ||
984+ (error = http_proxy_env (out , remote , url )) != GIT_ENOTFOUND )
985+ return error ;
986+
987+ return 0 ;
988+ }
989+
1006990/* DWIM `refspecs` based on `refs` and append the output to `out` */
1007991static int dwim_refspecs (git_vector * out , git_vector * refspecs , git_vector * refs )
1008992{
0 commit comments