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 }
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; }
/** * 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; }
/** * 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; }