Пример #1
0
void http_init(struct remote *remote, const char *url, int proactive_auth)
{
	char *low_speed_limit;
	char *low_speed_time;
	char *normalized_url;
	struct urlmatch_config config = { STRING_LIST_INIT_DUP };

	config.section = "http";
	config.key = NULL;
	config.collect_fn = http_options;
	config.cascade_fn = git_default_config;
	config.cb = NULL;

	http_is_verbose = 0;
	normalized_url = url_normalize(url, &config.url);

	git_config(urlmatch_config_entry, &config);
	free(normalized_url);

	curl_global_init(CURL_GLOBAL_ALL);

	http_proactive_auth = proactive_auth;

	if (remote && remote->http_proxy)
		curl_http_proxy = xstrdup(remote->http_proxy);

	pragma_header = curl_slist_append(pragma_header, "Pragma: no-cache");
	no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");

#ifdef USE_CURL_MULTI
	{
		char *http_max_requests = getenv("GIT_HTTP_MAX_REQUESTS");
		if (http_max_requests != NULL)
			max_requests = atoi(http_max_requests);
	}

	curlm = curl_multi_init();
	if (curlm == NULL) {
		fprintf(stderr, "Error creating curl multi handle.\n");
		exit(1);
	}
#endif

	if (getenv("GIT_SSL_NO_VERIFY"))
		curl_ssl_verify = 0;

	set_from_env(&ssl_cert, "GIT_SSL_CERT");
#if LIBCURL_VERSION_NUM >= 0x070903
	set_from_env(&ssl_key, "GIT_SSL_KEY");
#endif
#if LIBCURL_VERSION_NUM >= 0x070908
	set_from_env(&ssl_capath, "GIT_SSL_CAPATH");
#endif
	set_from_env(&ssl_cainfo, "GIT_SSL_CAINFO");

	set_from_env(&user_agent, "GIT_HTTP_USER_AGENT");

	low_speed_limit = getenv("GIT_HTTP_LOW_SPEED_LIMIT");
	if (low_speed_limit != NULL)
		curl_low_speed_limit = strtol(low_speed_limit, NULL, 10);
	low_speed_time = getenv("GIT_HTTP_LOW_SPEED_TIME");
	if (low_speed_time != NULL)
		curl_low_speed_time = strtol(low_speed_time, NULL, 10);

	if (curl_ssl_verify == -1)
		curl_ssl_verify = 1;

	curl_session_count = 0;
#ifdef USE_CURL_MULTI
	if (max_requests < 1)
		max_requests = DEFAULT_MAX_REQUESTS;
#endif

	if (getenv("GIT_CURL_FTP_NO_EPSV"))
		curl_ftp_no_epsv = 1;

	if (url) {
		credential_from_url(&http_auth, url);
		if (!ssl_cert_password_required &&
		    getenv("GIT_SSL_CERT_PASSWORD_PROTECTED") &&
		    !prefixcmp(url, "https://"))
			ssl_cert_password_required = 1;
	}

#ifndef NO_CURL_EASY_DUPHANDLE
	curl_default = get_curl_handle();
#endif
}
Пример #2
0
int urlmatch_config_entry(const char *var, const char *value, void *cb)
{
	struct string_list_item *item;
	struct urlmatch_config *collect = cb;
	struct urlmatch_item *matched;
	struct url_info *url = &collect->url;
	const char *key, *dot;
	struct strbuf synthkey = STRBUF_INIT;
	size_t matched_len = 0;
	int user_matched = 0;
	int retval;

	key = skip_prefix(var, collect->section);
	if (!key || *(key++) != '.') {
		if (collect->cascade_fn)
			return collect->cascade_fn(var, value, cb);
		return 0; /* not interested */
	}
	dot = strrchr(key, '.');
	if (dot) {
		char *config_url, *norm_url;
		struct url_info norm_info;

		config_url = xmemdupz(key, dot - key);
		norm_url = url_normalize(config_url, &norm_info);
		free(config_url);
		if (!norm_url)
			return 0;
		matched_len = match_urls(url, &norm_info, &user_matched);
		free(norm_url);
		if (!matched_len)
			return 0;
		key = dot + 1;
	}

	if (collect->key && strcmp(key, collect->key))
		return 0;

	item = string_list_insert(&collect->vars, key);
	if (!item->util) {
		matched = xcalloc(1, sizeof(*matched));
		item->util = matched;
	} else {
		matched = item->util;
		/*
		 * Is our match shorter?  Is our match the same
		 * length, and without user while the current
		 * candidate is with user?  Then we cannot use it.
		 */
		if (matched_len < matched->matched_len ||
		    ((matched_len == matched->matched_len) &&
		     (!user_matched && matched->user_matched)))
			return 0;
		/* Otherwise, replace it with this one. */
	}

	matched->matched_len = matched_len;
	matched->user_matched = user_matched;
	strbuf_addstr(&synthkey, collect->section);
	strbuf_addch(&synthkey, '.');
	strbuf_addstr(&synthkey, key);
	retval = collect->collect_fn(synthkey.buf, value, collect->cb);

	strbuf_release(&synthkey);
	return retval;
}
Пример #3
0
/**
 * Add new URL to cache, possibly pushing off an older one if cache is full.
 *
 * @return TRUE if the URL was added, FALSE otherwise.
 */
static bool
gwc_add(const char *new_url)
{
    const char *url_atom;
    const char *old_url;
    char *url, *ret;

    url = h_strdup(new_url); /* url_normalize() can modify the URL */

    ret = url_normalize(url, URL_POLICY_GWC_RULES);
    if (!ret) {
        g_warning("%s(): ignoring bad web cache URL \"%s\"",
                  G_STRFUNC, new_url);
        HFREE_NULL(url);
        return FALSE;
    }
    if (ret != url) {
        HFREE_NULL(url);
        url = ret;
    }

    /*
     * Don't add duplicates to the cache.
     */

    if (
        hset_contains(gwc_known_url, url) ||
        hset_contains(gwc_failed_url, url)
    ) {
        HFREE_NULL(url);
        return FALSE;
    }

    /*
     * OK, record new entry at the `gwc_url_slot'.
     */

    if (++gwc_url_slot >= MAX_GWC_URLS)
        gwc_url_slot = 0;

    g_assert(url != NULL);
    url_atom = atom_str_get(url);
    HFREE_NULL(url);

    /*
     * Expire any entry present at the slot we're about to write into.
     */

    old_url = gwc_url[gwc_url_slot].url;

    if (old_url != NULL) {
        g_assert(hset_contains(gwc_known_url, old_url));
        hset_remove(gwc_known_url, old_url);
        atom_str_free_null(&old_url);
        gwc_url[gwc_url_slot].url = NULL;
    }

    hset_insert(gwc_known_url, url_atom);

    gwc_url[gwc_url_slot].url = url_atom;
    gwc_url[gwc_url_slot].stamp = 0;
    gwc_file_dirty = TRUE;

    if (GNET_PROPERTY(bootstrap_debug)) {
        g_debug("%s(): loaded GWC URL %s", G_STRFUNC, url_atom);
    }

    return TRUE;
}
Пример #4
0
/**
 * retrieve 1 url reference to 1 favicon
 * \param html xml node of html element
 * \return pointer to url; NULL for no icon; caller owns returned pointer
 */
char *favicon_get_icon_ref(struct content *c, xmlNode *html)
{
	xmlNode *node = html;
	char *rel, *href, *url, *url2 = NULL;
	url_func_result res;

	while (node) {
		if (node->children != NULL) {  /* children */
			node = node->children;
		} else if (node->next != NULL) {  /* siblings */
			node = node->next;
		} else {  /* ancestor siblings */
			while (node != NULL && node->next == NULL)
				node = node->parent;

			if (node == NULL)
				break;

			node = node->next;
		}

		assert(node != NULL);

		if (node->type != XML_ELEMENT_NODE)
			continue;

		if (strcmp((const char *) node->name, "link") == 0) {
			/* rel=<space separated list, including 'icon'> */
			if ((rel = (char *) xmlGetProp(node,
					(const xmlChar *) "rel")) == NULL)
				continue;

			if (strcasestr(rel, "icon") == 0) {
				xmlFree(rel);
				continue;
			}

			if (strcasecmp(rel, "apple-touch-icon") == 0) {
				xmlFree(rel);
				continue;
			}

			xmlFree(rel);

			if ((href = (char *) xmlGetProp(node,
					(const xmlChar *) "href")) == NULL)
				continue;

			res = url_join(href, c->data.html.base_url, &url);

			xmlFree(href);

			if (res != URL_FUNC_OK)
				continue;

			if (url2 != NULL) {
				free(url2);
				url2 = NULL;
			}

			res = url_normalize(url, &url2);

			free(url);

			if (res != URL_FUNC_OK) {
				url2 = NULL;

				if (res == URL_FUNC_NOMEM)
					return NULL;

				continue;
			}

		}
	}

	if (url2 == NULL) {
		char *scheme;

		/* There was no icon link defined in the HTML source data.
		 * If the HTML document's base URL uses either the HTTP or 
		 * HTTPS schemes, then try using "<scheme>://host/favicon.ico"
		 */
		if (url_scheme(c->data.html.base_url, &scheme) != URL_FUNC_OK)
			return NULL;

		if (strcasecmp(scheme, "http") != 0 && 
				strcasecmp(scheme, "https") != 0) {
			free(scheme);
			return NULL;
		}

		free(scheme);

		if (url_join("/favicon.ico", c->data.html.base_url, &url2)
				!= URL_FUNC_OK)
			return NULL;
	}

	return url2;
}