Skip to content

Commit

Permalink
remote: add new callback to get remote URL from client in git_remote_…
Browse files Browse the repository at this point in the history
…connect
  • Loading branch information
jasonhaslam committed Sep 15, 2017
1 parent 78b4c3d commit 2c801b9
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 16 deletions.
10 changes: 10 additions & 0 deletions include/git2/remote.h
Expand Up @@ -367,6 +367,11 @@ typedef struct {
*/
typedef int (*git_push_negotiation)(const git_push_update **updates, size_t len, void *payload);

/**
* Callback to generate a custom URL.
*/
typedef int (*git_url_cb)(git_buf *out, git_remote *remote, git_direction direction, void *payload);

/**
* The callback settings structure
*
Expand Down Expand Up @@ -452,6 +457,11 @@ struct git_remote_callbacks {
*/
git_transport_cb transport;

/**
* Get the URL for this operation. Leave empty to auto-detect.
*/
git_url_cb url;

/**
* This will be passed to each of the callbacks in this struct
* as the last parameter.
Expand Down
44 changes: 28 additions & 16 deletions src/remote.c
Expand Up @@ -650,61 +650,73 @@ static int set_transport_custom_headers(git_transport *t, const git_strarray *cu
int git_remote_connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_proxy_options *proxy, const git_strarray *custom_headers)
{
git_transport *t;
const char *url;
git_buf url = GIT_BUF_INIT;
int flags = GIT_TRANSPORTFLAGS_NONE;
int error;
void *payload = NULL;
git_cred_acquire_cb credentials = NULL;
git_transport_cb transport = NULL;
git_url_cb url_cb = NULL;

assert(remote);

if (callbacks) {
GITERR_CHECK_VERSION(callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
credentials = callbacks->credentials;
transport = callbacks->transport;
url_cb = callbacks->url;
payload = callbacks->payload;
}

if (proxy)
GITERR_CHECK_VERSION(proxy, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options");

t = remote->transport;
/* Look up URL. */
if (url_cb && (error = url_cb(&url, remote, direction, payload) < 0))
goto cleanup;

if (git_buf_len(&url) == 0)
git_buf_sets(&url, git_remote__urlfordirection(remote, direction));

url = git_remote__urlfordirection(remote, direction);
if (url == NULL) {
if (git_buf_len(&url) == 0) {
giterr_set(GITERR_INVALID,
"Malformed remote '%s' - missing URL", remote->name);
return -1;
error = -1;
goto cleanup;
}

/* Look up transport. */
t = remote->transport;

/* If we don't have a transport object yet, and the caller specified a
* custom transport factory, use that */
if (!t && transport &&
(error = transport(&t, remote, payload)) < 0)
return error;
goto cleanup;

/* If we still don't have a transport, then use the global
* transport registrations which map URI schemes to transport factories */
if (!t && (error = git_transport_new(&t, remote, url)) < 0)
return error;
if (!t && (error = git_transport_new(&t, remote, git_buf_cstr(&url))) < 0)
goto cleanup;

if ((error = set_transport_custom_headers(t, custom_headers)) != 0)
goto on_error;
goto cleanup;

if ((error = set_transport_callbacks(t, callbacks)) < 0 ||
(error = t->connect(t, url, credentials, payload, proxy, direction, flags)) != 0)
goto on_error;
(error = t->connect(t, git_buf_cstr(&url), credentials, payload, proxy, direction, flags)) != 0)
goto cleanup;

remote->transport = t;

return 0;
cleanup:
if (error && t) {
t->free(t);

on_error:
t->free(t);
if (t == remote->transport)
remote->transport = NULL;
}

if (t == remote->transport)
remote->transport = NULL;
git_buf_free(&url);

return error;
}
Expand Down

0 comments on commit 2c801b9

Please sign in to comment.