diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2022-01-04 07:05:20 -0500 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2022-01-13 21:34:21 +0000 |
commit | fda59a76ffccdbd411aa06e271be03a0d466ae3c (patch) | |
tree | 4dddaedc61de07aaabf5949cc956ab03133c05cb | |
parent | 515daeaf4d5918ae93b02a5478adee563b4dac5e (diff) | |
download | libgit2-fda59a76ffccdbd411aa06e271be03a0d466ae3c.tar.gz |
remote: honor `http.followRedirects` configuration option
-rw-r--r-- | src/remote.c | 79 | ||||
-rw-r--r-- | src/remote.h | 1 | ||||
-rw-r--r-- | src/transports/local.c | 4 | ||||
-rw-r--r-- | src/transports/smart.c | 4 |
4 files changed, 68 insertions, 20 deletions
diff --git a/src/remote.c b/src/remote.c index 2e818cd91..f1010415a 100644 --- a/src/remote.c +++ b/src/remote.c @@ -858,25 +858,70 @@ static int validate_custom_headers(const git_strarray *custom_headers) return 0; } +static int lookup_redirect_config( + git_remote_redirect_t *out, + git_repository *repo) +{ + git_config *config; + const char *value; + int bool_value, error = 0; + + if (!repo) { + *out = GIT_REMOTE_REDIRECT_INITIAL; + return 0; + } + + if ((error = git_repository_config_snapshot(&config, repo)) < 0) + goto done; + + if ((error = git_config_get_string(&value, config, "http.followRedirects")) < 0) { + if (error == GIT_ENOTFOUND) { + *out = GIT_REMOTE_REDIRECT_INITIAL; + error = 0; + } + + goto done; + } + + if (git_config_parse_bool(&bool_value, value) == 0) { + *out = bool_value ? GIT_REMOTE_REDIRECT_ALL : + GIT_REMOTE_REDIRECT_NONE; + } else if (strcasecmp(value, "initial") == 0) { + *out = GIT_REMOTE_REDIRECT_INITIAL; + } else { + git_error_set(GIT_ERROR_CONFIG, "invalid configuration setting '%s' for 'http.followRedirects'", value); + error = -1; + } + +done: + git_config_free(config); + return error; +} + int git_remote_connect_options_normalize( git_remote_connect_options *dst, + git_repository *repo, const git_remote_connect_options *src) { git_remote_connect_options_dispose(dst); + git_remote_connect_options_init(dst, GIT_REMOTE_CONNECT_OPTIONS_VERSION); - if (!src) { - git_remote_connect_options_init(dst, GIT_REMOTE_CONNECT_OPTIONS_VERSION); - return 0; - } + if (src) { + GIT_ERROR_CHECK_VERSION(src, GIT_REMOTE_CONNECT_OPTIONS_VERSION, "git_remote_connect_options"); + GIT_ERROR_CHECK_VERSION(&src->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); + GIT_ERROR_CHECK_VERSION(&src->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options"); - GIT_ERROR_CHECK_VERSION(src, GIT_REMOTE_CONNECT_OPTIONS_VERSION, "git_remote_connect_options"); - GIT_ERROR_CHECK_VERSION(&src->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); - GIT_ERROR_CHECK_VERSION(&src->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options"); + if (validate_custom_headers(&src->custom_headers) < 0 || + git_remote_connect_options_dup(dst, src) < 0) + return -1; + } - if (validate_custom_headers(&src->custom_headers)) - return -1; + if (dst->follow_redirects == 0) { + if (lookup_redirect_config(&dst->follow_redirects, repo) < 0) + return -1; + } - return git_remote_connect_options_dup(dst, src); + return 0; } int git_remote_connect_ext( @@ -1176,11 +1221,12 @@ static int ls_to_vector(git_vector *out, git_remote *remote) GIT_INLINE(int) connect_opts_from_fetch_opts( git_remote_connect_options *out, + git_remote *remote, const git_fetch_options *fetch_opts) { git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT; copy_opts(&tmp, fetch_opts); - return git_remote_connect_options_normalize(out, &tmp); + return git_remote_connect_options_normalize(out, remote->repo, &tmp); } static int connect_or_reset_options( @@ -1270,7 +1316,7 @@ int git_remote_download( return -1; } - if (connect_opts_from_fetch_opts(&connect_opts, opts) < 0) + if (connect_opts_from_fetch_opts(&connect_opts, remote, opts) < 0) return -1; if ((error = connect_or_reset_options(remote, GIT_DIRECTION_FETCH, &connect_opts)) < 0) @@ -1298,7 +1344,7 @@ int git_remote_fetch( return -1; } - if (connect_opts_from_fetch_opts(&connect_opts, opts) < 0) + if (connect_opts_from_fetch_opts(&connect_opts, remote, opts) < 0) return -1; if ((error = connect_or_reset_options(remote, GIT_DIRECTION_FETCH, &connect_opts)) < 0) @@ -2771,11 +2817,12 @@ done: GIT_INLINE(int) connect_opts_from_push_opts( git_remote_connect_options *out, + git_remote *remote, const git_push_options *push_opts) { git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT; copy_opts(&tmp, push_opts); - return git_remote_connect_options_normalize(out, &tmp); + return git_remote_connect_options_normalize(out, remote->repo, &tmp); } int git_remote_upload( @@ -2796,7 +2843,7 @@ int git_remote_upload( return -1; } - if ((error = connect_opts_from_push_opts(&connect_opts, opts)) < 0) + if ((error = connect_opts_from_push_opts(&connect_opts, remote, opts)) < 0) goto cleanup; if ((error = connect_or_reset_options(remote, GIT_DIRECTION_PUSH, &connect_opts)) < 0) @@ -2857,7 +2904,7 @@ int git_remote_push( return -1; } - if (connect_opts_from_push_opts(&connect_opts, opts) < 0) + if (connect_opts_from_push_opts(&connect_opts, remote, opts) < 0) return -1; if ((error = git_remote_upload(remote, refspecs, opts)) < 0) diff --git a/src/remote.h b/src/remote.h index 1655e1551..3cf0fd953 100644 --- a/src/remote.h +++ b/src/remote.h @@ -50,6 +50,7 @@ int git_remote_connect_options_dup( const git_remote_connect_options *src); int git_remote_connect_options_normalize( git_remote_connect_options *dst, + git_repository *repo, const git_remote_connect_options *src); void git_remote_connect_options_dispose(git_remote_connect_options *opts); diff --git a/src/transports/local.c b/src/transports/local.c index 6065d4020..86524edf1 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -209,7 +209,7 @@ static int local_connect( if (t->connected) return 0; - if (git_remote_connect_options_normalize(&t->connect_opts, connect_opts) < 0) + if (git_remote_connect_options_normalize(&t->connect_opts, t->owner->repo, connect_opts) < 0) return -1; free_heads(&t->refs); @@ -253,7 +253,7 @@ static int local_set_connect_opts( return -1; } - return git_remote_connect_options_normalize(&t->connect_opts, connect_opts); + return git_remote_connect_options_normalize(&t->connect_opts, t->owner->repo, connect_opts); } static int local_ls(const git_remote_head ***out, size_t *size, git_transport *transport) diff --git a/src/transports/smart.c b/src/transports/smart.c index 4267e8841..e76c18fc3 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -125,7 +125,7 @@ static int git_smart__connect( if (git_smart__reset_stream(t, true) < 0) return -1; - if (git_remote_connect_options_normalize(&t->connect_opts, connect_opts) < 0) + if (git_remote_connect_options_normalize(&t->connect_opts, t->owner->repo, connect_opts) < 0) return -1; t->url = git__strdup(url); @@ -223,7 +223,7 @@ static int git_smart__set_connect_opts( return -1; } - return git_remote_connect_options_normalize(&t->connect_opts, opts); + return git_remote_connect_options_normalize(&t->connect_opts, t->owner->repo, opts); } static int git_smart__ls(const git_remote_head ***out, size_t *size, git_transport *transport) |