// Downloads the file at $url, and stores it at $filename. void filter_url_download_file (string url, string filename, string& error) { #ifdef CLIENT_PREPARED filter_url_simple_http_request (url, error, {}, filename, false); #else CURL *curl = curl_easy_init (); if (curl) { curl_easy_setopt (curl, CURLOPT_URL, url.c_str()); FILE* file = fopen (filename.c_str(), "w"); curl_easy_setopt (curl, CURLOPT_WRITEDATA, file); curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); // curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); filter_url_curl_set_timeout (curl); CURLcode res = curl_easy_perform (curl); if (res == CURLE_OK) { error.clear (); long http_code = 0; curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); if (http_code != 200) { error.append ("http code " + convert_to_string ((int)http_code)); } } else { error = curl_easy_strerror (res); } curl_easy_cleanup (curl); fclose (file); } #endif }
// Sends a http GET request to the $url. // It returns the response from the server. // It writes any error to $error. string filter_url_http_get (string url, string& error) { string response; #ifdef CLIENT_PREPARED response = filter_url_simple_http_request (url, error, {}, "", false); #else CURL *curl = curl_easy_init (); if (curl) { curl_easy_setopt (curl, CURLOPT_URL, url.c_str()); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, filter_url_curl_write_function); curl_easy_setopt (curl, CURLOPT_WRITEDATA, &response); curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); // curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); // Because a Bibledit client should work even over very bad networks, // pass some timeout options to curl so it properly deals with such networks. filter_url_curl_set_timeout (curl); CURLcode res = curl_easy_perform (curl); if (res == CURLE_OK) { error.clear (); long http_code = 0; curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); if (http_code != 200) { response.append ("http code " + convert_to_string ((int)http_code)); } } else { response.clear (); error = curl_easy_strerror (res); } curl_easy_cleanup (curl); } #endif return response; }
string email_receive_message (string& error) { #ifdef CLIENT_PREPARED error = "Not implemented with embedded http library"; return ""; #else CURL *curl; CURLcode res = CURLE_OK; struct cstring s; init_string (&s); curl = curl_easy_init (); curl_easy_setopt (curl, CURLOPT_USERNAME, Database_Config_General::getMailStorageUsername ().c_str()); curl_easy_setopt (curl, CURLOPT_PASSWORD, Database_Config_General::getMailStoragePassword ().c_str()); string message_url = url () + "/1"; curl_easy_setopt (curl, CURLOPT_URL, message_url.c_str()); curl_easy_setopt (curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, writefunc); curl_easy_setopt (curl, CURLOPT_WRITEDATA, &s); // Some servers need this validation. curl_easy_setopt (curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); filter_url_curl_set_timeout (curl); res = curl_easy_perform (curl); string body; if (res == CURLE_OK) { body = (char *) s.ptr; } else { error = curl_easy_strerror (res); } // Set the DELE command. curl_easy_setopt (curl, CURLOPT_CUSTOMREQUEST, "DELE"); // Do not perform a transfer as DELE returns no data. curl_easy_setopt (curl, CURLOPT_NOBODY, 1L); // Perform the custom request. res = curl_easy_perform(curl); if (s.ptr) free (s.ptr); curl_easy_cleanup (curl); return body; #endif }
// Returns how many emails are waiting in the mail storage host's POP3 email inbox. int email_receive_count (string& error, bool verbose) { #ifdef CLIENT_PREPARED error = "Not implemented with embedded http library"; if (verbose) {} return 0; #else CURL *curl; CURLcode res = CURLE_OK; struct cstring s; init_string (&s); curl = curl_easy_init (); curl_easy_setopt (curl, CURLOPT_USERNAME, Database_Config_General::getMailStorageUsername ().c_str()); curl_easy_setopt (curl, CURLOPT_PASSWORD, Database_Config_General::getMailStoragePassword ().c_str()); curl_easy_setopt (curl, CURLOPT_URL, url ().c_str()); curl_easy_setopt (curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, writefunc); curl_easy_setopt (curl, CURLOPT_WRITEDATA, &s); if (verbose) { curl_easy_setopt (curl, CURLOPT_DEBUGFUNCTION, filter_url_curl_debug_callback); curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); } // Some servers need this validation. curl_easy_setopt (curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); filter_url_curl_set_timeout (curl); res = curl_easy_perform (curl); int mailcount = 0; if (res == CURLE_OK) { string response = (char *) s.ptr; response = filter_string_trim (response); mailcount = filter_string_explode (response, '\n').size(); } else { error = curl_easy_strerror (res); } if (s.ptr) free (s.ptr); curl_easy_cleanup (curl); return mailcount; #endif }
// Sends a http POST request to $url. // burst: Set connection timing for burst mode, where the response comes after a relatively long silence. // It posts the $values. // It returns the response from the server. // It writes any error to $error. string filter_url_http_post (string url, map <string, string> values, string& error, bool burst) { string response; #ifdef CLIENT_PREPARED if (burst) {} response = filter_url_simple_http_request (url, error, values, "", false); #else // Get a curl handle. CURL *curl = curl_easy_init (); if (curl) { // First set the URL that is about to receive the POST. // This can be http or https. curl_easy_setopt (curl, CURLOPT_URL, url.c_str()); // Generate the post data. string postdata; for (auto & element : values) { if (!postdata.empty ()) postdata.append ("&"); postdata.append (element.first); postdata.append ("="); postdata.append (filter_url_urlencode (element.second)); } // Specify the POST data to curl, e.g.: "name=foo&project=bar" curl_easy_setopt (curl, CURLOPT_POSTFIELDS, postdata.c_str()); // Callback for the server response. curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, filter_url_curl_write_function); curl_easy_setopt (curl, CURLOPT_WRITEDATA, &response); // Further options. curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); // curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); // Timeouts for very bad networks, see the GET routine above for an explanation. filter_url_curl_set_timeout (curl, burst); // Perform the request. CURLcode res = curl_easy_perform (curl); // Result check. if (res == CURLE_OK) { error.clear (); long http_code = 0; curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); if (http_code != 200) { error.append ("Server response " + filter_url_http_response_code_text (http_code)); } } else { error = curl_easy_strerror (res); } // Always cleanup. curl_easy_cleanup (curl); } #endif return response; }
// Sends a http POST request to $url as from a <form> with enctype="multipart/form-data". // It posts the $values. // It uploads $filename. // It returns the response from the server. // It writes any error to $error. string filter_url_http_upload (string url, map <string, string> values, string filename, string& error) { string response; #ifdef CLIENT_PREPARED url.clear (); values.clear (); filename.clear (); error = "Not implemented in client configuration"; #else // Coded while looking at http://curl.haxx.se/libcurl/c/postit2.html. struct curl_httppost *formpost=NULL; struct curl_httppost *lastptr=NULL; // Fill in the text fields to submit. for (auto & element : values) { curl_formadd (&formpost, &lastptr, CURLFORM_COPYNAME, element.first.c_str (), CURLFORM_COPYCONTENTS, element.second.c_str(), CURLFORM_END); } // Fill in the file upload field to submit. curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "uploadedZipFile", CURLFORM_FILE, filename.c_str(), CURLFORM_END); // Get a curl handle. CURL *curl = curl_easy_init (); if (curl) { // First set the URL that is about to receive the POST. curl_easy_setopt (curl, CURLOPT_URL, url.c_str()); // Specify the POST data to curl. curl_easy_setopt (curl, CURLOPT_HTTPPOST, formpost); // Callback for the server response. curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, filter_url_curl_write_function); curl_easy_setopt (curl, CURLOPT_WRITEDATA, &response); // Further options. curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); // curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); // Timeouts for very bad networks, see the GET routine above for an explanation. filter_url_curl_set_timeout (curl, false); // Perform the request. CURLcode res = curl_easy_perform (curl); // Result check. if (res == CURLE_OK) { error.clear (); long http_code = 0; curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); if (http_code != 200) { error.append ("Server response " + filter_url_http_response_code_text (http_code)); } } else { error = curl_easy_strerror (res); } // Always cleanup cURL. curl_easy_cleanup (curl); // Then cleanup the formpost chain. curl_formfree (formpost); } #endif return response; }