Repository: mesos Updated Branches: refs/heads/master d4f6fde17 -> b9982ba8d
Added a function to get the "Content-Length" field from HTTP header. Review: https://reviews.apache.org/r/30606 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/b9982ba8 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/b9982ba8 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/b9982ba8 Branch: refs/heads/master Commit: b9982ba8dfd98f48831da496d45a3fd0b4251c3e Parents: d4f6fde Author: Bernd Mathiske <[email protected]> Authored: Thu May 21 19:41:04 2015 -0700 Committer: Benjamin Hindman <[email protected]> Committed: Thu May 21 19:48:50 2015 -0700 ---------------------------------------------------------------------- .../3rdparty/stout/include/stout/net.hpp | 69 +++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/b9982ba8/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp index 0c09b34..a538fb1 100644 --- a/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp +++ b/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp @@ -84,11 +84,79 @@ inline struct sockaddr_storage createSockaddrStorage(const IP& ip, int port) } +// Initializes libraries that net:: functions depend on, in a +// thread-safe way. This does not have to be called explicitly by +// the user of any functions in question. They will call this +// themselves by need. +inline void initialize() +{ + // We use a static struct variable to initialize in a thread-safe + // way, at least with respect to calls within net::*, since there + // is no way to guarantee that another library is not concurrently + // initializing CURL. Thread safety is provided by the fact that + // the value 'curl' should get constructed (i.e., the CURL + // constructor invoked) in a thread safe way (as of GCC 4.3 and + // required for C++11). + struct CURL + { + CURL() + { + // This is the only one function in libcurl that is not deemed + // thread-safe. (And it must be called at least once before any + // other libcurl function is used.) + curl_global_init(CURL_GLOBAL_ALL); + } + }; + + static CURL curl; +} + + +// Downloads the header of the specified HTTP URL with a HEAD request +// and queries its "content-length" field. (Note that according to the +// HTTP specification there is no guarantee that this field contains +// any useful value.) +inline Try<Bytes> contentLength(const std::string& url) +{ + initialize(); + + CURL* curl = curl_easy_init(); + if (curl == NULL) { + curl_easy_cleanup(curl); + return Error("Failed to initialize libcurl"); + } + + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true); + curl_easy_setopt(curl, CURLOPT_HEADER, 1); + curl_easy_setopt(curl, CURLOPT_NOBODY, 1); + + CURLcode curlErrorCode = curl_easy_perform(curl); + if (curlErrorCode != 0) { + curl_easy_cleanup(curl); + return Error(curl_easy_strerror(curlErrorCode)); + } + + double result; + curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &result); + + curl_easy_cleanup(curl); + + if (result < 0) { + return Error("No URL content-length available"); + } + + return Bytes(uint64_t(result)); +} + + // Returns the HTTP response code resulting from attempting to // download the specified HTTP or FTP URL into a file at the specified // path. inline Try<int> download(const std::string& url, const std::string& path) { + initialize(); + Try<int> fd = os::open( path, O_CREAT | O_WRONLY | O_CLOEXEC, @@ -98,7 +166,6 @@ inline Try<int> download(const std::string& url, const std::string& path) return Error(fd.error()); } - curl_global_init(CURL_GLOBAL_ALL); CURL* curl = curl_easy_init(); if (curl == NULL) {
