summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2022-01-04 07:05:20 -0500
committerEdward Thomson <ethomson@edwardthomson.com>2022-01-13 21:34:21 +0000
commitfda59a76ffccdbd411aa06e271be03a0d466ae3c (patch)
tree4dddaedc61de07aaabf5949cc956ab03133c05cb
parent515daeaf4d5918ae93b02a5478adee563b4dac5e (diff)
downloadlibgit2-fda59a76ffccdbd411aa06e271be03a0d466ae3c.tar.gz
remote: honor `http.followRedirects` configuration option
-rw-r--r--src/remote.c79
-rw-r--r--src/remote.h1
-rw-r--r--src/transports/local.c4
-rw-r--r--src/transports/smart.c4
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)