static Error_Type image_load(const char *file, const char *key, const char *shmfile, Slave_Msg_Image_Load *params, Slave_Msg_Image_Loaded *result, const char *loader) { Evas_Img_Load_Params ilp; Evas_Loader_Module_Api *api; int err; Error_Type ret = CSERVE2_NONE; char *map = _cserve2_shm_map(shmfile, params->shm.mmap_size, params->shm.mmap_offset); if (map == MAP_FAILED) return CSERVE2_RESOURCE_ALLOCATION_FAILED; memset(&ilp, 0, sizeof(ilp)); api = loader_module_find(loader); if (!api) { ret = CSERVE2_GENERIC; goto done; } ilp.w = params->w; ilp.h = params->h; ilp.alpha = params->alpha; #define SETOPT(v) ilp.opts.v = params->opts.v SETOPT(w); SETOPT(h); SETOPT(rx); SETOPT(ry); SETOPT(rw); SETOPT(rh); SETOPT(scale_down_by); SETOPT(dpi); SETOPT(orientation); #undef SETOPT ilp.buffer = map + params->shm.image_offset; if (!api->data_load(&ilp, file, key, &err)) ret = err; result->alpha_sparse = ilp.alpha_sparse; done: _cserve2_shm_unmap(map, params->shm.mmap_size); return ret; }
static Error_Type image_open(const char *file, const char *key, Image_Load_Opts *opts, Slave_Msg_Image_Opened *result, const char **use_loader) { Evas_Img_Load_Params ilp; Evas_Loader_Module_Api *api; const char *loader = NULL, *end; unsigned int i; int len; int err; memset(&ilp, 0, sizeof(ilp)); if (opts) { #define SETOPT(v) ilp.opts.v = opts->v SETOPT(w); SETOPT(h); SETOPT(rx); SETOPT(ry); SETOPT(rw); SETOPT(rh); SETOPT(scale_down_by); SETOPT(dpi); SETOPT(orientation); #undef SETOPT ilp.has_opts = EINA_TRUE; } if (!*use_loader) goto try_extension; loader = *use_loader; api = loader_module_find(loader); if (!api) goto try_extension; if (api->head_load(&ilp, file, key, &err)) goto done; try_extension: len = strlen(file); end = file + len; for (i = 0; i < (sizeof (map_loaders) / sizeof(struct ext_loader_s)); i++) { int len2 = strlen(map_loaders[i].extension); if (len2 > len) continue; if (!strcasecmp(end - len2, map_loaders[i].extension)) { loader = map_loaders[i].loader; break; } } if (!loader) goto try_all_known; api = loader_module_find(loader); if (!api) goto try_all_known; if (api->head_load(&ilp, file, key, &err)) goto done; try_all_known: for (i = 0; i < (sizeof(loaders_name) / sizeof(loaders_name[0])); i++) { loader = loaders_name[i]; api = loader_module_find(loader); if (!api) continue; if (api->head_load(&ilp, file, key, &err)) goto done; } /* find every module available and try them, even if we don't know they * exist. That will be our generic loader */ return err; done: *use_loader = loader; result->w = ilp.w; result->h = ilp.h; if ((result->rotated = ilp.rotated)) { result->degree = ilp.degree; } if ((result->animated = ilp.animated)) { result->frame_count = ilp.frame_count; result->loop_count = ilp.loop_count; result->loop_hint = ilp.loop_hint; } result->scale = ilp.scale; result->alpha = ilp.alpha; return CSERVE2_NONE; }
/** * Set options specific for a fetch. * * \param f The fetch to set options on. * \return A curl result code. */ static CURLcode fetch_curl_set_options(struct curl_fetch_info *f) { CURLcode code; const char *auth; #undef SETOPT #define SETOPT(option, value) { \ code = curl_easy_setopt(f->curl_handle, option, value); \ if (code != CURLE_OK) \ return code; \ } SETOPT(CURLOPT_URL, nsurl_access(f->url)); SETOPT(CURLOPT_PRIVATE, f); SETOPT(CURLOPT_WRITEDATA, f); SETOPT(CURLOPT_WRITEHEADER, f); SETOPT(CURLOPT_PROGRESSDATA, f); SETOPT(CURLOPT_REFERER, fetch_get_referer_to_send(f->fetch_handle)); SETOPT(CURLOPT_HTTPHEADER, f->headers); if (f->post_urlenc) { SETOPT(CURLOPT_HTTPPOST, NULL); SETOPT(CURLOPT_HTTPGET, 0L); SETOPT(CURLOPT_POSTFIELDS, f->post_urlenc); } else if (f->post_multipart) { SETOPT(CURLOPT_POSTFIELDS, NULL); SETOPT(CURLOPT_HTTPGET, 0L); SETOPT(CURLOPT_HTTPPOST, f->post_multipart); } else { SETOPT(CURLOPT_POSTFIELDS, NULL); SETOPT(CURLOPT_HTTPPOST, NULL); SETOPT(CURLOPT_HTTPGET, 1L); } f->cookie_string = urldb_get_cookie(f->url, true); if (f->cookie_string) { SETOPT(CURLOPT_COOKIE, f->cookie_string); } else { SETOPT(CURLOPT_COOKIE, NULL); } if ((auth = urldb_get_auth_details(f->url, NULL)) != NULL) { SETOPT(CURLOPT_HTTPAUTH, CURLAUTH_ANY); SETOPT(CURLOPT_USERPWD, auth); } else { SETOPT(CURLOPT_USERPWD, NULL); } /* set up proxy options */ if (nsoption_bool(http_proxy) && (nsoption_charp(http_proxy_host) != NULL) && (strncmp(nsurl_access(f->url), "file:", 5) != 0)) { SETOPT(CURLOPT_PROXY, nsoption_charp(http_proxy_host)); SETOPT(CURLOPT_PROXYPORT, (long) nsoption_int(http_proxy_port)); #if LIBCURL_VERSION_NUM >= 0x071304 /* Added in 7.19.4 */ /* setup the omission list */ SETOPT(CURLOPT_NOPROXY, nsoption_charp(http_proxy_noproxy)); #endif if (nsoption_int(http_proxy_auth) != OPTION_HTTP_PROXY_AUTH_NONE) { SETOPT(CURLOPT_PROXYAUTH, nsoption_int(http_proxy_auth) == OPTION_HTTP_PROXY_AUTH_BASIC ? (long) CURLAUTH_BASIC : (long) CURLAUTH_NTLM); snprintf(fetch_proxy_userpwd, sizeof fetch_proxy_userpwd, "%s:%s", nsoption_charp(http_proxy_auth_user), nsoption_charp(http_proxy_auth_pass)); SETOPT(CURLOPT_PROXYUSERPWD, fetch_proxy_userpwd); } } else { SETOPT(CURLOPT_PROXY, NULL); } /* Disable SSL session ID caching, as some servers can't cope. */ SETOPT(CURLOPT_SSL_SESSIONID_CACHE, 0); if (urldb_get_cert_permissions(f->url)) { /* Disable certificate verification */ SETOPT(CURLOPT_SSL_VERIFYPEER, 0L); SETOPT(CURLOPT_SSL_VERIFYHOST, 0L); if (curl_with_openssl) { SETOPT(CURLOPT_SSL_CTX_FUNCTION, NULL); SETOPT(CURLOPT_SSL_CTX_DATA, NULL); } } else { /* do verification */ SETOPT(CURLOPT_SSL_VERIFYPEER, 1L); SETOPT(CURLOPT_SSL_VERIFYHOST, 2L); if (curl_with_openssl) { SETOPT(CURLOPT_SSL_CTX_FUNCTION, fetch_curl_sslctxfun); SETOPT(CURLOPT_SSL_CTX_DATA, f); } } return CURLE_OK; }
static ham_status_t _perform_request(ham_env_t *env, CURL *handle, proto_wrapper_t *request, proto_wrapper_t **reply) { CURLcode cc; long response=0; char header[128]; curl_buffer_t rbuf={0}; curl_buffer_t wbuf={0}; struct curl_slist *slist=0; wbuf.alloc=env_get_allocator(env); *reply=0; if (!proto_pack(request, wbuf.alloc, &rbuf.packed_data, &rbuf.packed_size)) return (HAM_INTERNAL_ERROR); sprintf(header, "Content-Length: %u", rbuf.packed_size); slist=curl_slist_append(slist, header); slist=curl_slist_append(slist, "Transfer-Encoding:"); slist=curl_slist_append(slist, "Expect:"); #ifdef HAM_DEBUG SETOPT(handle, CURLOPT_VERBOSE, 1); #endif SETOPT(handle, CURLOPT_URL, env_get_filename(env)); SETOPT(handle, CURLOPT_READFUNCTION, __readfunc); SETOPT(handle, CURLOPT_READDATA, &rbuf); SETOPT(handle, CURLOPT_UPLOAD, 1); SETOPT(handle, CURLOPT_PUT, 1); SETOPT(handle, CURLOPT_WRITEFUNCTION, __writefunc); SETOPT(handle, CURLOPT_WRITEDATA, &wbuf); SETOPT(handle, CURLOPT_HTTPHEADER, slist); cc=curl_easy_perform(handle); if (rbuf.packed_data) allocator_free(env_get_allocator(env), rbuf.packed_data); curl_slist_free_all(slist); if (cc) { ham_trace(("network transmission failed: %s", curl_easy_strerror(cc))); return (HAM_NETWORK_ERROR); } cc=curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &response); if (cc) { ham_trace(("network transmission failed: %s", curl_easy_strerror(cc))); return (HAM_NETWORK_ERROR); } if (response!=200) { ham_trace(("server returned error %u", response)); return (HAM_NETWORK_ERROR); } *reply=wbuf.wrapper; return (0); }
/* exported function documented in content/fetchers/curl.h */ nserror fetch_curl_register(void) { CURLcode code; curl_version_info_data *data; int i; lwc_string *scheme; const struct fetcher_operation_table fetcher_ops = { .initialise = fetch_curl_initialise, .acceptable = fetch_curl_can_fetch, .setup = fetch_curl_setup, .start = fetch_curl_start, .abort = fetch_curl_abort, .free = fetch_curl_free, .poll = fetch_curl_poll, .fdset = fetch_curl_fdset, .finalise = fetch_curl_finalise }; LOG("curl_version %s", curl_version()); code = curl_global_init(CURL_GLOBAL_ALL); if (code != CURLE_OK) { LOG("curl_global_init failed."); return NSERROR_INIT_FAILED; } fetch_curl_multi = curl_multi_init(); if (!fetch_curl_multi) { LOG("curl_multi_init failed."); return NSERROR_INIT_FAILED; } #if LIBCURL_VERSION_NUM >= 0x071e00 /* built against 7.30.0 or later: configure caching */ { CURLMcode mcode; int maxconnects = nsoption_int(max_fetchers) + nsoption_int(max_cached_fetch_handles); #undef SETOPT #define SETOPT(option, value) \ mcode = curl_multi_setopt(fetch_curl_multi, option, value); \ if (mcode != CURLM_OK) \ goto curl_multi_setopt_failed; SETOPT(CURLMOPT_MAXCONNECTS, maxconnects); SETOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, maxconnects); SETOPT(CURLMOPT_MAX_HOST_CONNECTIONS, nsoption_int(max_fetchers_per_host)); } #endif /* Create a curl easy handle with the options that are common to all * fetches. */ fetch_blank_curl = curl_easy_init(); if (!fetch_blank_curl) { LOG("curl_easy_init failed"); return NSERROR_INIT_FAILED; } #undef SETOPT #define SETOPT(option, value) \ code = curl_easy_setopt(fetch_blank_curl, option, value); \ if (code != CURLE_OK) \ goto curl_easy_setopt_failed; if (verbose_log) { SETOPT(CURLOPT_VERBOSE, 1); } else { SETOPT(CURLOPT_VERBOSE, 0); } SETOPT(CURLOPT_ERRORBUFFER, fetch_error_buffer); if (nsoption_bool(suppress_curl_debug)) { SETOPT(CURLOPT_DEBUGFUNCTION, fetch_curl_ignore_debug); } SETOPT(CURLOPT_WRITEFUNCTION, fetch_curl_data); SETOPT(CURLOPT_HEADERFUNCTION, fetch_curl_header); SETOPT(CURLOPT_PROGRESSFUNCTION, fetch_curl_progress); SETOPT(CURLOPT_NOPROGRESS, 0); SETOPT(CURLOPT_USERAGENT, user_agent_string()); SETOPT(CURLOPT_ENCODING, "gzip"); SETOPT(CURLOPT_LOW_SPEED_LIMIT, 1L); SETOPT(CURLOPT_LOW_SPEED_TIME, 180L); SETOPT(CURLOPT_NOSIGNAL, 1L); SETOPT(CURLOPT_CONNECTTIMEOUT, nsoption_uint(curl_fetch_timeout)); if (nsoption_charp(ca_bundle) && strcmp(nsoption_charp(ca_bundle), "")) { LOG("ca_bundle: '%s'", nsoption_charp(ca_bundle)); SETOPT(CURLOPT_CAINFO, nsoption_charp(ca_bundle)); } if (nsoption_charp(ca_path) && strcmp(nsoption_charp(ca_path), "")) { LOG("ca_path: '%s'", nsoption_charp(ca_path)); SETOPT(CURLOPT_CAPATH, nsoption_charp(ca_path)); } /* Detect whether the SSL CTX function API works */ curl_with_openssl = true; code = curl_easy_setopt(fetch_blank_curl, CURLOPT_SSL_CTX_FUNCTION, NULL); if (code != CURLE_OK) { curl_with_openssl = false; } LOG("cURL %slinked against openssl", curl_with_openssl ? "" : "not "); /* cURL initialised okay, register the fetchers */ data = curl_version_info(CURLVERSION_NOW); for (i = 0; data->protocols[i]; i++) { if (strcmp(data->protocols[i], "http") == 0) { scheme = lwc_string_ref(corestring_lwc_http); } else if (strcmp(data->protocols[i], "https") == 0) { scheme = lwc_string_ref(corestring_lwc_https); } else { /* Ignore non-http(s) protocols */ continue; } if (fetcher_add(scheme, &fetcher_ops) != NSERROR_OK) { LOG("Unable to register cURL fetcher for %s", data->protocols[i]); } } return NSERROR_OK; curl_easy_setopt_failed: LOG("curl_easy_setopt failed."); return NSERROR_INIT_FAILED; #if LIBCURL_VERSION_NUM >= 0x071e00 curl_multi_setopt_failed: LOG("curl_multi_setopt failed."); return NSERROR_INIT_FAILED; #endif }