void PageCache::ReadClosure::complete() { std::unique_lock<std::mutex> lock(p_cache->p_mutex); PageInfo *info = p_cache->p_presentPages.at(p_pageNumber); char *buffer = info->p_buffer; lock.unlock(); // NOTE: unlock before entering callbacks p_callback(buffer); delete this; }
static const char *url_execute(const char *p_url, MCUrlExecuteCallback p_callback, void *p_state) { const char *t_error; t_error = NULL; bool t_is_http, t_is_https; t_is_http = strncmp(p_url, "http", 4) == 0; t_is_https = strncmp(p_url, "https", 5) == 0; curl_slist *t_headers; t_headers = NULL; if (t_error == NULL && MChttpheaders != NULL && t_is_http) { if (!url_build_header_list(MChttpheaders, t_headers)) t_error = "couldn't build header list"; } CURL *t_url_handle; t_url_handle = NULL; if (t_error == NULL) { t_url_handle = curl_easy_init(); if (t_url_handle == NULL) t_error = "couldn't create handle"; } if (t_error == NULL) { if (curl_easy_setopt(t_url_handle, CURLOPT_URL, p_url) != CURLE_OK) t_error = "couldn't set url"; } if (t_error == NULL) { if (curl_easy_setopt(t_url_handle, CURLOPT_WRITEFUNCTION, url_write_callback) != CURLE_OK) t_error = "couldn't set callback"; } if (t_error == NULL && t_headers != NULL) { if (curl_easy_setopt(t_url_handle, CURLOPT_HTTPHEADER, t_headers) != CURLE_OK) t_error = "couldn't set headers"; } if (t_error == NULL && t_is_https) { if (curl_easy_setopt(t_url_handle, CURLOPT_SSL_VERIFYPEER, 1) != CURLE_OK || curl_easy_setopt(t_url_handle, CURLOPT_SSL_VERIFYHOST, 2) != CURLE_OK || (MCsslcertificates != NULL && curl_easy_setopt(t_url_handle, CURLOPT_CAINFO, MCsslcertificates) != CURLE_OK)) t_error = "couldn't configure ssl"; } if (t_error == NULL) { #if LIBCURL_VERSION_MINOR >= 19 if (curl_easy_setopt(t_url_handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS) != CURLE_OK || curl_easy_setopt(t_url_handle, CURLOPT_FOLLOWLOCATION, 1) != CURLE_OK) t_error = "couldn't configure follow"; #endif } // MM-2011-07-07: Added support for specifying which network interface to use. if (t_error == NULL) { if (MCdefaultnetworkinterface != NULL) if (curl_easy_setopt(t_url_handle, CURLOPT_INTERFACE, MCdefaultnetworkinterface) != CURLE_OK) t_error = "couldn't set network interface"; } if (t_error == NULL && p_callback != NULL) t_error = p_callback(p_state, t_url_handle); if (t_error == NULL) { char t_error_buffer[CURL_ERROR_SIZE]; curl_easy_setopt(t_url_handle, CURLOPT_ERRORBUFFER, t_error_buffer); MCurlresult -> clear(); MCresult -> clear(); if (curl_easy_perform(t_url_handle) == CURLE_OK) { if (t_is_http) { long t_code; if (curl_easy_getinfo(t_url_handle, CURLINFO_RESPONSE_CODE, &t_code) == CURLE_OK) { if (t_code != 200) { static char t_error_str[64]; sprintf(t_error_str, "error %ld", t_code); MCresult -> copysvalue(t_error_str); } } else t_error = "couldn't fetch response code"; } } else { static char t_error_str[CURL_ERROR_SIZE + 64]; sprintf(t_error_str, "error %s", t_error_buffer); MCresult -> copysvalue(t_error_str); } } if (t_error == NULL && t_is_http) { } if (t_url_handle != NULL) curl_easy_cleanup(t_url_handle); if (t_headers != NULL) curl_slist_free_all(t_headers); return t_error; }