Merge branch 'mg/http-auth'
* mg/http-auth: http-push.c: use a faux remote to pass to http_init Do not name "repo" struct "remote" in push_http.c http.c: CURLOPT_NETRC_OPTIONAL is not available in ancient versions of cURL http authentication via prompts http_init(): Fix config file parsing http.c: style cleanups Conflicts: http-push.c
This commit is contained in:
commit
6422c6af38
162
http-push.c
162
http-push.c
@ -97,7 +97,7 @@ struct repo
|
||||
struct remote_lock *locks;
|
||||
};
|
||||
|
||||
static struct repo *remote;
|
||||
static struct repo *repo;
|
||||
|
||||
enum transfer_state {
|
||||
NEED_FETCH,
|
||||
@ -324,7 +324,7 @@ static void start_fetch_loose(struct transfer_request *request)
|
||||
|
||||
git_SHA1_Init(&request->c);
|
||||
|
||||
url = get_remote_object_url(remote->url, hex, 0);
|
||||
url = get_remote_object_url(repo->url, hex, 0);
|
||||
request->url = xstrdup(url);
|
||||
|
||||
/* If a previous temp file is present, process what was already
|
||||
@ -389,7 +389,7 @@ static void start_fetch_loose(struct transfer_request *request)
|
||||
request->state = RUN_FETCH_LOOSE;
|
||||
if (!start_active_slot(slot)) {
|
||||
fprintf(stderr, "Unable to start GET request\n");
|
||||
remote->can_update_info_refs = 0;
|
||||
repo->can_update_info_refs = 0;
|
||||
release_request(request);
|
||||
}
|
||||
}
|
||||
@ -399,7 +399,7 @@ static void start_mkcol(struct transfer_request *request)
|
||||
char *hex = sha1_to_hex(request->obj->sha1);
|
||||
struct active_request_slot *slot;
|
||||
|
||||
request->url = get_remote_object_url(remote->url, hex, 1);
|
||||
request->url = get_remote_object_url(repo->url, hex, 1);
|
||||
|
||||
slot = get_active_slot();
|
||||
slot->callback_func = process_response;
|
||||
@ -434,10 +434,10 @@ static void start_fetch_packed(struct transfer_request *request)
|
||||
struct transfer_request *check_request = request_queue_head;
|
||||
struct active_request_slot *slot;
|
||||
|
||||
target = find_sha1_pack(request->obj->sha1, remote->packs);
|
||||
target = find_sha1_pack(request->obj->sha1, repo->packs);
|
||||
if (!target) {
|
||||
fprintf(stderr, "Unable to fetch %s, will not be able to update server info refs\n", sha1_to_hex(request->obj->sha1));
|
||||
remote->can_update_info_refs = 0;
|
||||
repo->can_update_info_refs = 0;
|
||||
release_request(request);
|
||||
return;
|
||||
}
|
||||
@ -450,9 +450,9 @@ static void start_fetch_packed(struct transfer_request *request)
|
||||
snprintf(request->tmpfile, sizeof(request->tmpfile),
|
||||
"%s.temp", filename);
|
||||
|
||||
url = xmalloc(strlen(remote->url) + 64);
|
||||
url = xmalloc(strlen(repo->url) + 64);
|
||||
sprintf(url, "%sobjects/pack/pack-%s.pack",
|
||||
remote->url, sha1_to_hex(target->sha1));
|
||||
repo->url, sha1_to_hex(target->sha1));
|
||||
|
||||
/* Make sure there isn't another open request for this pack */
|
||||
while (check_request) {
|
||||
@ -469,7 +469,7 @@ static void start_fetch_packed(struct transfer_request *request)
|
||||
if (!packfile) {
|
||||
fprintf(stderr, "Unable to open local file %s for pack",
|
||||
request->tmpfile);
|
||||
remote->can_update_info_refs = 0;
|
||||
repo->can_update_info_refs = 0;
|
||||
free(url);
|
||||
return;
|
||||
}
|
||||
@ -505,7 +505,7 @@ static void start_fetch_packed(struct transfer_request *request)
|
||||
request->state = RUN_FETCH_PACKED;
|
||||
if (!start_active_slot(slot)) {
|
||||
fprintf(stderr, "Unable to start GET request\n");
|
||||
remote->can_update_info_refs = 0;
|
||||
repo->can_update_info_refs = 0;
|
||||
release_request(request);
|
||||
}
|
||||
}
|
||||
@ -554,10 +554,10 @@ static void start_put(struct transfer_request *request)
|
||||
request->buffer.buf.len = stream.total_out;
|
||||
|
||||
strbuf_addstr(&buf, "Destination: ");
|
||||
append_remote_object_url(&buf, remote->url, hex, 0);
|
||||
append_remote_object_url(&buf, repo->url, hex, 0);
|
||||
request->dest = strbuf_detach(&buf, NULL);
|
||||
|
||||
append_remote_object_url(&buf, remote->url, hex, 0);
|
||||
append_remote_object_url(&buf, repo->url, hex, 0);
|
||||
strbuf_add(&buf, request->lock->tmpfile_suffix, 41);
|
||||
request->url = strbuf_detach(&buf, NULL);
|
||||
|
||||
@ -648,7 +648,7 @@ static int refresh_lock(struct remote_lock *lock)
|
||||
|
||||
static void check_locks(void)
|
||||
{
|
||||
struct remote_lock *lock = remote->locks;
|
||||
struct remote_lock *lock = repo->locks;
|
||||
time_t current_time = time(NULL);
|
||||
int time_remaining;
|
||||
|
||||
@ -788,7 +788,7 @@ static void finish_request(struct transfer_request *request)
|
||||
if (request->curl_result != CURLE_OK) {
|
||||
fprintf(stderr, "Unable to get pack file %s\n%s",
|
||||
request->url, curl_errorstr);
|
||||
remote->can_update_info_refs = 0;
|
||||
repo->can_update_info_refs = 0;
|
||||
} else {
|
||||
off_t pack_size = ftell(request->local_stream);
|
||||
|
||||
@ -798,7 +798,7 @@ static void finish_request(struct transfer_request *request)
|
||||
request->filename)) {
|
||||
target = (struct packed_git *)request->userData;
|
||||
target->pack_size = pack_size;
|
||||
lst = &remote->packs;
|
||||
lst = &repo->packs;
|
||||
while (*lst != target)
|
||||
lst = &((*lst)->next);
|
||||
*lst = (*lst)->next;
|
||||
@ -806,7 +806,7 @@ static void finish_request(struct transfer_request *request)
|
||||
if (!verify_pack(target))
|
||||
install_packed_git(target);
|
||||
else
|
||||
remote->can_update_info_refs = 0;
|
||||
repo->can_update_info_refs = 0;
|
||||
}
|
||||
}
|
||||
release_request(request);
|
||||
@ -889,7 +889,7 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)
|
||||
get_remote_object_list(obj->sha1[0]);
|
||||
if (obj->flags & (REMOTE | PUSHING))
|
||||
return 0;
|
||||
target = find_sha1_pack(obj->sha1, remote->packs);
|
||||
target = find_sha1_pack(obj->sha1, repo->packs);
|
||||
if (target) {
|
||||
obj->flags |= REMOTE;
|
||||
return 0;
|
||||
@ -930,8 +930,8 @@ static int fetch_index(unsigned char *sha1)
|
||||
struct slot_results results;
|
||||
|
||||
/* Don't use the index if the pack isn't there */
|
||||
url = xmalloc(strlen(remote->url) + 64);
|
||||
sprintf(url, "%sobjects/pack/pack-%s.pack", remote->url, hex);
|
||||
url = xmalloc(strlen(repo->url) + 64);
|
||||
sprintf(url, "%sobjects/pack/pack-%s.pack", repo->url, hex);
|
||||
slot = get_active_slot();
|
||||
slot->results = &results;
|
||||
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
|
||||
@ -956,7 +956,7 @@ static int fetch_index(unsigned char *sha1)
|
||||
if (push_verbosely)
|
||||
fprintf(stderr, "Getting index for pack %s\n", hex);
|
||||
|
||||
sprintf(url, "%sobjects/pack/pack-%s.idx", remote->url, hex);
|
||||
sprintf(url, "%sobjects/pack/pack-%s.idx", repo->url, hex);
|
||||
|
||||
filename = sha1_pack_index_name(sha1);
|
||||
snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
|
||||
@ -1018,8 +1018,8 @@ static int setup_index(unsigned char *sha1)
|
||||
return -1;
|
||||
|
||||
new_pack = parse_pack_index(sha1);
|
||||
new_pack->next = remote->packs;
|
||||
remote->packs = new_pack;
|
||||
new_pack->next = repo->packs;
|
||||
repo->packs = new_pack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1037,8 +1037,8 @@ static int fetch_indices(void)
|
||||
if (push_verbosely)
|
||||
fprintf(stderr, "Getting pack list\n");
|
||||
|
||||
url = xmalloc(strlen(remote->url) + 20);
|
||||
sprintf(url, "%sobjects/info/packs", remote->url);
|
||||
url = xmalloc(strlen(repo->url) + 20);
|
||||
sprintf(url, "%sobjects/info/packs", repo->url);
|
||||
|
||||
slot = get_active_slot();
|
||||
slot->results = &results;
|
||||
@ -1223,11 +1223,11 @@ static struct remote_lock *lock_remote(const char *path, long timeout)
|
||||
struct curl_slist *dav_headers = NULL;
|
||||
struct xml_ctx ctx;
|
||||
|
||||
url = xmalloc(strlen(remote->url) + strlen(path) + 1);
|
||||
sprintf(url, "%s%s", remote->url, path);
|
||||
url = xmalloc(strlen(repo->url) + strlen(path) + 1);
|
||||
sprintf(url, "%s%s", repo->url, path);
|
||||
|
||||
/* Make sure leading directories exist for the remote ref */
|
||||
ep = strchr(url + strlen(remote->url) + 1, '/');
|
||||
ep = strchr(url + strlen(repo->url) + 1, '/');
|
||||
while (ep) {
|
||||
char saved_character = ep[1];
|
||||
ep[1] = '\0';
|
||||
@ -1319,8 +1319,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)
|
||||
} else {
|
||||
lock->url = url;
|
||||
lock->start_time = time(NULL);
|
||||
lock->next = remote->locks;
|
||||
remote->locks = lock;
|
||||
lock->next = repo->locks;
|
||||
repo->locks = lock;
|
||||
}
|
||||
|
||||
return lock;
|
||||
@ -1330,7 +1330,7 @@ static int unlock_remote(struct remote_lock *lock)
|
||||
{
|
||||
struct active_request_slot *slot;
|
||||
struct slot_results results;
|
||||
struct remote_lock *prev = remote->locks;
|
||||
struct remote_lock *prev = repo->locks;
|
||||
struct curl_slist *dav_headers;
|
||||
int rc = 0;
|
||||
|
||||
@ -1356,8 +1356,8 @@ static int unlock_remote(struct remote_lock *lock)
|
||||
|
||||
curl_slist_free_all(dav_headers);
|
||||
|
||||
if (remote->locks == lock) {
|
||||
remote->locks = lock->next;
|
||||
if (repo->locks == lock) {
|
||||
repo->locks = lock->next;
|
||||
} else {
|
||||
while (prev && prev->next != lock)
|
||||
prev = prev->next;
|
||||
@ -1375,7 +1375,7 @@ static int unlock_remote(struct remote_lock *lock)
|
||||
|
||||
static void remove_locks(void)
|
||||
{
|
||||
struct remote_lock *lock = remote->locks;
|
||||
struct remote_lock *lock = repo->locks;
|
||||
|
||||
fprintf(stderr, "Removing remote locks...\n");
|
||||
while (lock) {
|
||||
@ -1457,7 +1457,7 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed)
|
||||
}
|
||||
}
|
||||
if (path) {
|
||||
path += remote->path_len;
|
||||
path += repo->path_len;
|
||||
ls->dentry_name = xstrdup(path);
|
||||
}
|
||||
} else if (!strcmp(ctx->name, DAV_PROPFIND_COLLECTION)) {
|
||||
@ -1480,7 +1480,7 @@ static void remote_ls(const char *path, int flags,
|
||||
void (*userFunc)(struct remote_ls_ctx *ls),
|
||||
void *userData)
|
||||
{
|
||||
char *url = xmalloc(strlen(remote->url) + strlen(path) + 1);
|
||||
char *url = xmalloc(strlen(repo->url) + strlen(path) + 1);
|
||||
struct active_request_slot *slot;
|
||||
struct slot_results results;
|
||||
struct strbuf in_buffer = STRBUF_INIT;
|
||||
@ -1496,7 +1496,7 @@ static void remote_ls(const char *path, int flags,
|
||||
ls.userData = userData;
|
||||
ls.userFunc = userFunc;
|
||||
|
||||
sprintf(url, "%s%s", remote->url, path);
|
||||
sprintf(url, "%s%s", repo->url, path);
|
||||
|
||||
strbuf_addf(&out_buffer.buf, PROPFIND_ALL_REQUEST);
|
||||
|
||||
@ -1574,7 +1574,7 @@ static int locking_available(void)
|
||||
struct xml_ctx ctx;
|
||||
int lock_flags = 0;
|
||||
|
||||
strbuf_addf(&out_buffer.buf, PROPFIND_SUPPORTEDLOCK_REQUEST, remote->url);
|
||||
strbuf_addf(&out_buffer.buf, PROPFIND_SUPPORTEDLOCK_REQUEST, repo->url);
|
||||
|
||||
dav_headers = curl_slist_append(dav_headers, "Depth: 0");
|
||||
dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
|
||||
@ -1586,7 +1586,7 @@ static int locking_available(void)
|
||||
curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
|
||||
curl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);
|
||||
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
|
||||
curl_easy_setopt(slot->curl, CURLOPT_URL, remote->url);
|
||||
curl_easy_setopt(slot->curl, CURLOPT_URL, repo->url);
|
||||
curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
|
||||
curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PROPFIND);
|
||||
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
|
||||
@ -1617,15 +1617,15 @@ static int locking_available(void)
|
||||
XML_ParserFree(parser);
|
||||
if (!lock_flags)
|
||||
error("no DAV locking support on %s",
|
||||
remote->url);
|
||||
repo->url);
|
||||
|
||||
} else {
|
||||
error("Cannot access URL %s, return code %d",
|
||||
remote->url, results.curl_result);
|
||||
repo->url, results.curl_result);
|
||||
lock_flags = 0;
|
||||
}
|
||||
} else {
|
||||
error("Unable to start PROPFIND request on %s", remote->url);
|
||||
error("Unable to start PROPFIND request on %s", repo->url);
|
||||
}
|
||||
|
||||
strbuf_release(&out_buffer.buf);
|
||||
@ -1801,10 +1801,10 @@ static void one_remote_ref(char *refname)
|
||||
|
||||
ref = alloc_ref(refname);
|
||||
|
||||
if (http_fetch_ref(remote->url, ref) != 0) {
|
||||
if (http_fetch_ref(repo->url, ref) != 0) {
|
||||
fprintf(stderr,
|
||||
"Unable to fetch ref %s from %s\n",
|
||||
refname, remote->url);
|
||||
refname, repo->url);
|
||||
free(ref);
|
||||
return;
|
||||
}
|
||||
@ -1813,7 +1813,7 @@ static void one_remote_ref(char *refname)
|
||||
* Fetch a copy of the object if it doesn't exist locally - it
|
||||
* may be required for updating server info later.
|
||||
*/
|
||||
if (remote->can_update_info_refs && !has_sha1_file(ref->old_sha1)) {
|
||||
if (repo->can_update_info_refs && !has_sha1_file(ref->old_sha1)) {
|
||||
obj = lookup_unknown_object(ref->old_sha1);
|
||||
if (obj) {
|
||||
fprintf(stderr, " fetch %s for %s\n",
|
||||
@ -1853,10 +1853,10 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)
|
||||
|
||||
ref = alloc_ref(ls->dentry_name);
|
||||
|
||||
if (http_fetch_ref(remote->url, ref) != 0) {
|
||||
if (http_fetch_ref(repo->url, ref) != 0) {
|
||||
fprintf(stderr,
|
||||
"Unable to fetch ref %s from %s\n",
|
||||
ls->dentry_name, remote->url);
|
||||
ls->dentry_name, repo->url);
|
||||
aborted = 1;
|
||||
free(ref);
|
||||
return;
|
||||
@ -1931,12 +1931,12 @@ static void update_remote_info_refs(struct remote_lock *lock)
|
||||
|
||||
static int remote_exists(const char *path)
|
||||
{
|
||||
char *url = xmalloc(strlen(remote->url) + strlen(path) + 1);
|
||||
char *url = xmalloc(strlen(repo->url) + strlen(path) + 1);
|
||||
struct active_request_slot *slot;
|
||||
struct slot_results results;
|
||||
int ret = -1;
|
||||
|
||||
sprintf(url, "%s%s", remote->url, path);
|
||||
sprintf(url, "%s%s", repo->url, path);
|
||||
|
||||
slot = get_active_slot();
|
||||
slot->results = &results;
|
||||
@ -1966,8 +1966,8 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1)
|
||||
struct active_request_slot *slot;
|
||||
struct slot_results results;
|
||||
|
||||
url = xmalloc(strlen(remote->url) + strlen(path) + 1);
|
||||
sprintf(url, "%s%s", remote->url, path);
|
||||
url = xmalloc(strlen(repo->url) + strlen(path) + 1);
|
||||
sprintf(url, "%s%s", repo->url, path);
|
||||
|
||||
slot = get_active_slot();
|
||||
slot->results = &results;
|
||||
@ -2082,7 +2082,7 @@ static int delete_remote_branch(char *pattern, int force)
|
||||
"of your current HEAD.\n"
|
||||
"If you are sure you want to delete it,"
|
||||
" run:\n\t'git http-push -D %s %s'",
|
||||
remote_ref->name, remote->url, pattern);
|
||||
remote_ref->name, repo->url, pattern);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2090,8 +2090,8 @@ static int delete_remote_branch(char *pattern, int force)
|
||||
fprintf(stderr, "Removing remote branch '%s'\n", remote_ref->name);
|
||||
if (dry_run)
|
||||
return 0;
|
||||
url = xmalloc(strlen(remote->url) + strlen(remote_ref->name) + 1);
|
||||
sprintf(url, "%s%s", remote->url, remote_ref->name);
|
||||
url = xmalloc(strlen(repo->url) + strlen(remote_ref->name) + 1);
|
||||
sprintf(url, "%s%s", repo->url, remote_ref->name);
|
||||
slot = get_active_slot();
|
||||
slot->results = &results;
|
||||
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
|
||||
@ -2128,13 +2128,14 @@ int main(int argc, char **argv)
|
||||
int i;
|
||||
int new_refs;
|
||||
struct ref *ref, *local_refs;
|
||||
struct remote *remote;
|
||||
char *rewritten_url = NULL;
|
||||
|
||||
git_extract_argv0_path(argv[0]);
|
||||
|
||||
setup_git_directory();
|
||||
|
||||
remote = xcalloc(sizeof(*remote), 1);
|
||||
repo = xcalloc(sizeof(*repo), 1);
|
||||
|
||||
argv++;
|
||||
for (i = 1; i < argc; i++, argv++) {
|
||||
@ -2167,14 +2168,14 @@ int main(int argc, char **argv)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!remote->url) {
|
||||
if (!repo->url) {
|
||||
char *path = strstr(arg, "//");
|
||||
remote->url = arg;
|
||||
remote->path_len = strlen(arg);
|
||||
repo->url = arg;
|
||||
repo->path_len = strlen(arg);
|
||||
if (path) {
|
||||
remote->path = strchr(path+2, '/');
|
||||
if (remote->path)
|
||||
remote->path_len = strlen(remote->path);
|
||||
repo->path = strchr(path+2, '/');
|
||||
if (repo->path)
|
||||
repo->path_len = strlen(repo->path);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -2187,7 +2188,7 @@ int main(int argc, char **argv)
|
||||
die("git-push is not available for http/https repository when not compiled with USE_CURL_MULTI");
|
||||
#endif
|
||||
|
||||
if (!remote->url)
|
||||
if (!repo->url)
|
||||
usage(http_push_usage);
|
||||
|
||||
if (delete_branch && nr_refspec != 1)
|
||||
@ -2195,17 +2196,24 @@ int main(int argc, char **argv)
|
||||
|
||||
memset(remote_dir_exists, -1, 256);
|
||||
|
||||
http_init(NULL);
|
||||
/*
|
||||
* Create a minimum remote by hand to give to http_init(),
|
||||
* primarily to allow it to look at the URL.
|
||||
*/
|
||||
remote = xcalloc(sizeof(*remote), 1);
|
||||
ALLOC_GROW(remote->url, remote->url_nr + 1, remote->url_alloc);
|
||||
remote->url[remote->url_nr++] = repo->url;
|
||||
http_init(remote);
|
||||
|
||||
no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");
|
||||
|
||||
if (remote->url && remote->url[strlen(remote->url)-1] != '/') {
|
||||
rewritten_url = xmalloc(strlen(remote->url)+2);
|
||||
strcpy(rewritten_url, remote->url);
|
||||
if (repo->url && repo->url[strlen(repo->url)-1] != '/') {
|
||||
rewritten_url = xmalloc(strlen(repo->url)+2);
|
||||
strcpy(rewritten_url, repo->url);
|
||||
strcat(rewritten_url, "/");
|
||||
remote->path = rewritten_url + (remote->path - remote->url);
|
||||
remote->path_len++;
|
||||
remote->url = rewritten_url;
|
||||
repo->path = rewritten_url + (repo->path - repo->url);
|
||||
repo->path_len++;
|
||||
repo->url = rewritten_url;
|
||||
}
|
||||
|
||||
/* Verify DAV compliance/lock support */
|
||||
@ -2217,20 +2225,20 @@ int main(int argc, char **argv)
|
||||
sigchain_push_common(remove_locks_on_signal);
|
||||
|
||||
/* Check whether the remote has server info files */
|
||||
remote->can_update_info_refs = 0;
|
||||
remote->has_info_refs = remote_exists("info/refs");
|
||||
remote->has_info_packs = remote_exists("objects/info/packs");
|
||||
if (remote->has_info_refs) {
|
||||
repo->can_update_info_refs = 0;
|
||||
repo->has_info_refs = remote_exists("info/refs");
|
||||
repo->has_info_packs = remote_exists("objects/info/packs");
|
||||
if (repo->has_info_refs) {
|
||||
info_ref_lock = lock_remote("info/refs", LOCK_TIME);
|
||||
if (info_ref_lock)
|
||||
remote->can_update_info_refs = 1;
|
||||
repo->can_update_info_refs = 1;
|
||||
else {
|
||||
error("cannot lock existing info/refs");
|
||||
rc = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (remote->has_info_packs)
|
||||
if (repo->has_info_packs)
|
||||
fetch_indices();
|
||||
|
||||
/* Get a list of all local and remote heads to validate refspecs */
|
||||
@ -2388,8 +2396,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* Update remote server info if appropriate */
|
||||
if (remote->has_info_refs && new_refs) {
|
||||
if (info_ref_lock && remote->can_update_info_refs) {
|
||||
if (repo->has_info_refs && new_refs) {
|
||||
if (info_ref_lock && repo->can_update_info_refs) {
|
||||
fprintf(stderr, "Updating remote server info\n");
|
||||
if (!dry_run)
|
||||
update_remote_info_refs(info_ref_lock);
|
||||
@ -2402,7 +2410,7 @@ int main(int argc, char **argv)
|
||||
free(rewritten_url);
|
||||
if (info_ref_lock)
|
||||
unlock_remote(info_ref_lock);
|
||||
free(remote);
|
||||
free(repo);
|
||||
|
||||
curl_slist_free_all(no_pragma_header);
|
||||
|
||||
|
169
http.c
169
http.c
@ -1,7 +1,7 @@
|
||||
#include "http.h"
|
||||
|
||||
int data_received;
|
||||
int active_requests = 0;
|
||||
int active_requests;
|
||||
|
||||
#ifdef USE_CURL_MULTI
|
||||
static int max_requests = -1;
|
||||
@ -13,22 +13,23 @@ static CURL *curl_default;
|
||||
char curl_errorstr[CURL_ERROR_SIZE];
|
||||
|
||||
static int curl_ssl_verify = -1;
|
||||
static const char *ssl_cert = NULL;
|
||||
static const char *ssl_cert;
|
||||
#if LIBCURL_VERSION_NUM >= 0x070902
|
||||
static const char *ssl_key = NULL;
|
||||
static const char *ssl_key;
|
||||
#endif
|
||||
#if LIBCURL_VERSION_NUM >= 0x070908
|
||||
static const char *ssl_capath = NULL;
|
||||
static const char *ssl_capath;
|
||||
#endif
|
||||
static const char *ssl_cainfo = NULL;
|
||||
static const char *ssl_cainfo;
|
||||
static long curl_low_speed_limit = -1;
|
||||
static long curl_low_speed_time = -1;
|
||||
static int curl_ftp_no_epsv = 0;
|
||||
static const char *curl_http_proxy = NULL;
|
||||
static int curl_ftp_no_epsv;
|
||||
static const char *curl_http_proxy;
|
||||
static char *user_name, *user_pass;
|
||||
|
||||
static struct curl_slist *pragma_header;
|
||||
|
||||
static struct active_request_slot *active_queue_head = NULL;
|
||||
static struct active_request_slot *active_queue_head;
|
||||
|
||||
size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb, void *buffer_)
|
||||
{
|
||||
@ -94,53 +95,33 @@ static void process_curl_messages(void)
|
||||
static int http_options(const char *var, const char *value, void *cb)
|
||||
{
|
||||
if (!strcmp("http.sslverify", var)) {
|
||||
if (curl_ssl_verify == -1) {
|
||||
curl_ssl_verify = git_config_bool(var, value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp("http.sslcert", var)) {
|
||||
if (ssl_cert == NULL)
|
||||
return git_config_string(&ssl_cert, var, value);
|
||||
curl_ssl_verify = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp("http.sslcert", var))
|
||||
return git_config_string(&ssl_cert, var, value);
|
||||
#if LIBCURL_VERSION_NUM >= 0x070902
|
||||
if (!strcmp("http.sslkey", var)) {
|
||||
if (ssl_key == NULL)
|
||||
return git_config_string(&ssl_key, var, value);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp("http.sslkey", var))
|
||||
return git_config_string(&ssl_key, var, value);
|
||||
#endif
|
||||
#if LIBCURL_VERSION_NUM >= 0x070908
|
||||
if (!strcmp("http.sslcapath", var)) {
|
||||
if (ssl_capath == NULL)
|
||||
return git_config_string(&ssl_capath, var, value);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp("http.sslcapath", var))
|
||||
return git_config_string(&ssl_capath, var, value);
|
||||
#endif
|
||||
if (!strcmp("http.sslcainfo", var)) {
|
||||
if (ssl_cainfo == NULL)
|
||||
return git_config_string(&ssl_cainfo, var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp("http.sslcainfo", var))
|
||||
return git_config_string(&ssl_cainfo, var, value);
|
||||
#ifdef USE_CURL_MULTI
|
||||
if (!strcmp("http.maxrequests", var)) {
|
||||
if (max_requests == -1)
|
||||
max_requests = git_config_int(var, value);
|
||||
max_requests = git_config_int(var, value);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!strcmp("http.lowspeedlimit", var)) {
|
||||
if (curl_low_speed_limit == -1)
|
||||
curl_low_speed_limit = (long)git_config_int(var, value);
|
||||
curl_low_speed_limit = (long)git_config_int(var, value);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp("http.lowspeedtime", var)) {
|
||||
if (curl_low_speed_time == -1)
|
||||
curl_low_speed_time = (long)git_config_int(var, value);
|
||||
curl_low_speed_time = (long)git_config_int(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -148,19 +129,28 @@ static int http_options(const char *var, const char *value, void *cb)
|
||||
curl_ftp_no_epsv = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp("http.proxy", var)) {
|
||||
if (curl_http_proxy == NULL)
|
||||
return git_config_string(&curl_http_proxy, var, value);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp("http.proxy", var))
|
||||
return git_config_string(&curl_http_proxy, var, value);
|
||||
|
||||
/* Fall back on the default ones */
|
||||
return git_default_config(var, value, cb);
|
||||
}
|
||||
|
||||
static CURL* get_curl_handle(void)
|
||||
static void init_curl_http_auth(CURL *result)
|
||||
{
|
||||
CURL* result = curl_easy_init();
|
||||
if (user_name) {
|
||||
struct strbuf up = STRBUF_INIT;
|
||||
if (!user_pass)
|
||||
user_pass = xstrdup(getpass("Password: "));
|
||||
strbuf_addf(&up, "%s:%s", user_name, user_pass);
|
||||
curl_easy_setopt(result, CURLOPT_USERPWD,
|
||||
strbuf_detach(&up, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
static CURL *get_curl_handle(void)
|
||||
{
|
||||
CURL *result = curl_easy_init();
|
||||
|
||||
if (!curl_ssl_verify) {
|
||||
curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
@ -176,6 +166,8 @@ static CURL* get_curl_handle(void)
|
||||
curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
|
||||
#endif
|
||||
|
||||
init_curl_http_auth(result);
|
||||
|
||||
if (ssl_cert != NULL)
|
||||
curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert);
|
||||
#if LIBCURL_VERSION_NUM >= 0x070902
|
||||
@ -213,11 +205,60 @@ static CURL* get_curl_handle(void)
|
||||
return result;
|
||||
}
|
||||
|
||||
static void http_auth_init(const char *url)
|
||||
{
|
||||
char *at, *colon, *cp, *slash;
|
||||
int len;
|
||||
|
||||
cp = strstr(url, "://");
|
||||
if (!cp)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Ok, the URL looks like "proto://something". Which one?
|
||||
* "proto://<user>:<pass>@<host>/...",
|
||||
* "proto://<user>@<host>/...", or just
|
||||
* "proto://<host>/..."?
|
||||
*/
|
||||
cp += 3;
|
||||
at = strchr(cp, '@');
|
||||
colon = strchr(cp, ':');
|
||||
slash = strchrnul(cp, '/');
|
||||
if (!at || slash <= at)
|
||||
return; /* No credentials */
|
||||
if (!colon || at <= colon) {
|
||||
/* Only username */
|
||||
len = at - cp;
|
||||
user_name = xmalloc(len + 1);
|
||||
memcpy(user_name, cp, len);
|
||||
user_name[len] = '\0';
|
||||
user_pass = NULL;
|
||||
} else {
|
||||
len = colon - cp;
|
||||
user_name = xmalloc(len + 1);
|
||||
memcpy(user_name, cp, len);
|
||||
user_name[len] = '\0';
|
||||
len = at - (colon + 1);
|
||||
user_pass = xmalloc(len + 1);
|
||||
memcpy(user_pass, colon + 1, len);
|
||||
user_pass[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static void set_from_env(const char **var, const char *envname)
|
||||
{
|
||||
const char *val = getenv(envname);
|
||||
if (val)
|
||||
*var = val;
|
||||
}
|
||||
|
||||
void http_init(struct remote *remote)
|
||||
{
|
||||
char *low_speed_limit;
|
||||
char *low_speed_time;
|
||||
|
||||
git_config(http_options, NULL);
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
if (remote && remote->http_proxy)
|
||||
@ -242,14 +283,14 @@ void http_init(struct remote *remote)
|
||||
if (getenv("GIT_SSL_NO_VERIFY"))
|
||||
curl_ssl_verify = 0;
|
||||
|
||||
ssl_cert = getenv("GIT_SSL_CERT");
|
||||
set_from_env(&ssl_cert, "GIT_SSL_CERT");
|
||||
#if LIBCURL_VERSION_NUM >= 0x070902
|
||||
ssl_key = getenv("GIT_SSL_KEY");
|
||||
set_from_env(&ssl_key, "GIT_SSL_KEY");
|
||||
#endif
|
||||
#if LIBCURL_VERSION_NUM >= 0x070908
|
||||
ssl_capath = getenv("GIT_SSL_CAPATH");
|
||||
set_from_env(&ssl_capath, "GIT_SSL_CAPATH");
|
||||
#endif
|
||||
ssl_cainfo = getenv("GIT_SSL_CAINFO");
|
||||
set_from_env(&ssl_cainfo, "GIT_SSL_CAINFO");
|
||||
|
||||
low_speed_limit = getenv("GIT_HTTP_LOW_SPEED_LIMIT");
|
||||
if (low_speed_limit != NULL)
|
||||
@ -258,8 +299,6 @@ void http_init(struct remote *remote)
|
||||
if (low_speed_time != NULL)
|
||||
curl_low_speed_time = strtol(low_speed_time, NULL, 10);
|
||||
|
||||
git_config(http_options, NULL);
|
||||
|
||||
if (curl_ssl_verify == -1)
|
||||
curl_ssl_verify = 1;
|
||||
|
||||
@ -271,6 +310,9 @@ void http_init(struct remote *remote)
|
||||
if (getenv("GIT_CURL_FTP_NO_EPSV"))
|
||||
curl_ftp_no_epsv = 1;
|
||||
|
||||
if (remote && remote->url && remote->url[0])
|
||||
http_auth_init(remote->url[0]);
|
||||
|
||||
#ifndef NO_CURL_EASY_DUPHANDLE
|
||||
curl_default = get_curl_handle();
|
||||
#endif
|
||||
@ -322,15 +364,14 @@ struct active_request_slot *get_active_slot(void)
|
||||
/* Wait for a slot to open up if the queue is full */
|
||||
while (active_requests >= max_requests) {
|
||||
curl_multi_perform(curlm, &num_transfers);
|
||||
if (num_transfers < active_requests) {
|
||||
if (num_transfers < active_requests)
|
||||
process_curl_messages();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while (slot != NULL && slot->in_use) {
|
||||
while (slot != NULL && slot->in_use)
|
||||
slot = slot->next;
|
||||
}
|
||||
|
||||
if (slot == NULL) {
|
||||
newslot = xmalloc(sizeof(*newslot));
|
||||
newslot->curl = NULL;
|
||||
@ -341,9 +382,8 @@ struct active_request_slot *get_active_slot(void)
|
||||
if (slot == NULL) {
|
||||
active_queue_head = newslot;
|
||||
} else {
|
||||
while (slot->next != NULL) {
|
||||
while (slot->next != NULL)
|
||||
slot = slot->next;
|
||||
}
|
||||
slot->next = newslot;
|
||||
}
|
||||
slot = newslot;
|
||||
@ -404,7 +444,7 @@ struct fill_chain {
|
||||
struct fill_chain *next;
|
||||
};
|
||||
|
||||
static struct fill_chain *fill_cfg = NULL;
|
||||
static struct fill_chain *fill_cfg;
|
||||
|
||||
void add_fill_function(void *data, int (*fill)(void *))
|
||||
{
|
||||
@ -535,9 +575,8 @@ static void finish_active_slot(struct active_request_slot *slot)
|
||||
}
|
||||
|
||||
/* Run callback if appropriate */
|
||||
if (slot->callback_func != NULL) {
|
||||
if (slot->callback_func != NULL)
|
||||
slot->callback_func(slot->callback_data);
|
||||
}
|
||||
}
|
||||
|
||||
void finish_all_active_slots(void)
|
||||
@ -567,8 +606,10 @@ static inline int needs_quote(int ch)
|
||||
|
||||
static inline int hex(int v)
|
||||
{
|
||||
if (v < 10) return '0' + v;
|
||||
else return 'A' + v - 10;
|
||||
if (v < 10)
|
||||
return '0' + v;
|
||||
else
|
||||
return 'A' + v - 10;
|
||||
}
|
||||
|
||||
static char *quote_ref_url(const char *base, const char *ref)
|
||||
|
Loading…
Reference in New Issue
Block a user