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:
Junio C Hamano 2009-03-26 00:27:59 -07:00
commit 6422c6af38
2 changed files with 190 additions and 141 deletions

View file

@ -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
View file

@ -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)