From 594a009eaddc109e708efdeb396482db573c589c Mon Sep 17 00:00:00 2001 From: maxiaoyao Date: Thu, 26 Sep 2024 14:25:36 +0800 Subject: [PATCH] 1.add curlpp::Multi::poll/wait 2.add option:TimeoutMs 3.add example26,which use wait and TimeoutMs --- examples/README | 12 ++-- examples/example26.cpp | 115 +++++++++++++++++++++++++++++++++++++ include/curlpp/Multi.hpp | 26 +++++---- include/curlpp/Options.hpp | 43 +++++++------- src/curlpp/Multi.cpp | 39 +++++++++---- 5 files changed, 184 insertions(+), 51 deletions(-) create mode 100644 examples/example26.cpp diff --git a/examples/README b/examples/README index f3e8ade2..e381e657 100644 --- a/examples/README +++ b/examples/README @@ -1,6 +1,6 @@ configure.in is a good example to add curlpp to your project -Note that example 22 is contains the easiest and shorter examples of cURLpp +Note that example 22 is contains the easiest and shorter examples of cURLpp usage. Example 00: Minimal example for fetching a site. @@ -13,14 +13,14 @@ usage. Example 07: Cookie interface example via getInfo. Demonstrates usage of Infos::CookieList which example04 did not. Example 08: verbose callback example, with exception safe handling. - Example 09: verbose callback example, with exception safe handling, + Example 09: verbose callback example, with exception safe handling, but without raiseException function. Example 10: Binded function functor for WriteFunction example. Example 11: Plain write function example. Example 12: HTTP POST example. Example 13: Simple Multi interface example. Example 14: Multi interface example with info function example. - Example 15: Simple example for demonstrating the NoValueOptionTrait. + Example 15: Simple example for demonstrating the NoValueOptionTrait. (SslEngineDefault) Example 16: HTTP POST example with HTTP Authentification. Example 17: Binded method functor for WriteFunction example. @@ -29,10 +29,8 @@ usage. Example 20: std::ostream usage. Example 21: upload example with std::istream. Example 22: Real easy and quick examples. - Example 23: Setting request options using iterators to custom container + Example 23: Setting request options using iterators to custom container of curlpp options. Example 24: Binded method functor for DebugFunction example. Example 25: Send e-mail over SMTP. - - - + Example 26: Multi interface using multi poll/wait diff --git a/examples/example26.cpp b/examples/example26.cpp new file mode 100644 index 00000000..bcf460ff --- /dev/null +++ b/examples/example26.cpp @@ -0,0 +1,115 @@ +/* +* Copyright (c) <2002-2005> +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files +* (curlpp), to deal in the Software without restriction, +* including without limitation the rights to use, copy, modify, merge, +* publish, distribute, sublicense, and/or sell copies of the Software, +* and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/** + * \file + * Multi demo using poll/wait + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +#pragma comment(lib, "Ws2_32.lib") +#endif // WIN32 + +int main(int argc, char *argv[]) { + const char *url1 = "http://www.baidu.com"; + const char *url2 = "https://cn.bing.com"; + + try { + curlpp::initialize(); + + curlpp::Easy request1; + curlpp::Easy request2; + + request1.setOpt(new curlpp::options::Url(url1)); + std::ostringstream os1; + curlpp::options::WriteStream ws1(&os1); + request1.setOpt(ws1); + + std::list headers1; + headers1.push_back("content-type:text/html; charset=utf-8"); + request1.setOpt(new curlpp::Options::HttpHeader(headers1)); + request1.setOpt(new curlpp::options::TimeoutMs(1000)); + + + request2.setOpt(new curlpp::options::Url(url2)); + std::ostringstream os2; + curlpp::options::WriteStream ws2(&os2); + request2.setOpt(ws2); + request2.setOpt(new curlpp::options::TimeoutMs(1000)); + + curlpp::Multi requests; + requests.add(&request1); + requests.add(&request2); + + /* we start some action by calling perform right away */ + int nbLeft = 0; + while (!requests.perform(&nbLeft)) { + }; + + while (nbLeft) { + // block until activity is detected on at least one of the handles or timeout_ms has passed + requests.wait(100); + while (!requests.perform(&nbLeft)) { + }; + } + + std::cout << "NB lefts: " << nbLeft << std::endl; + + /* See how the transfers went */ + /* + Multi::info returns a list of: + std::pair< curlpp::Easy, curlpp::Multi::Info > + */ + const curlpp::Multi::Msgs msgs = requests.info(); + for (auto pos = msgs.begin(); pos != msgs.end(); pos++) { + if (pos->second.msg == CURLMSG_DONE) { + /* Find out which handle this message is about */ + if (pos->first == &request1) { + std::cout << "First request completed with status " << pos->second.code << ",data:" << os1.str() << std::endl; + } else if (pos->first == &request2) { + std::cout << "Second request completed with status " << pos->second.code << ",data:" << os2.str() << std::endl; + } + } + } + + curlpp::terminate(); + + } catch (curlpp::LogicError &e) { + std::cout << e.what() << std::endl; + } catch (curlpp::RuntimeError &e) { + std::cout << e.what() << std::endl; + } + + return EXIT_SUCCESS; +} diff --git a/include/curlpp/Multi.hpp b/include/curlpp/Multi.hpp index c29102ee..a4c9981f 100644 --- a/include/curlpp/Multi.hpp +++ b/include/curlpp/Multi.hpp @@ -1,22 +1,22 @@ /* * Copyright (c) <2002-2009> - * + * * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (curlpp), to deal in the Software without restriction, + * a copy of this software and associated documentation files + * (curlpp), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, + * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ @@ -42,7 +42,7 @@ namespace curlpp public: - struct Info + struct Info { CURLcode code; CURLMSG msg; @@ -61,10 +61,14 @@ namespace curlpp fd_set * write_fd_set, fd_set * exc_fd_set, int * max_fd); + void wait(int timeout_ms, struct curl_waitfd extra_fds[] = nullptr, unsigned int extra_nfds = 0, int * numfds = nullptr); +#if LIBCURL_VERSION_NUM >= 0x074200 + void poll(int timeout_ms, struct curl_waitfd extra_fds[] = nullptr, unsigned int extra_nfds = 0, int * numfds = nullptr); +#endif typedef std::list > Msgs; - + Msgs info(); private: diff --git a/include/curlpp/Options.hpp b/include/curlpp/Options.hpp index 40b64ed2..9d9b84e9 100644 --- a/include/curlpp/Options.hpp +++ b/include/curlpp/Options.hpp @@ -1,22 +1,22 @@ /* * Copyright (c) <2002-2009> - * + * * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (curlpp), to deal in the Software without restriction, + * a copy of this software and associated documentation files + * (curlpp), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, + * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ @@ -27,15 +27,15 @@ #include "Option.hpp" -#include +#include #ifdef CURLPP_ALLOW_NOT_AVAILABLE #define DEF_IF_ALLOW_AVAILABLE (type,option,name) typedef curlpp::NotAvailableOptionTrait name; #endif -// #begin define OPTION(version,type,option,name) -// #if LIBCURL_VERSION_NUM >= version +// #begin define OPTION(version,type,option,name) +// #if LIBCURL_VERSION_NUM >= version // typedef curlpp::OptionTrait name; // #else // DEF_IF_ALLOW_AVAILABLE(type,option,name) @@ -81,7 +81,7 @@ namespace options /** - * Callback options. + * Callback options. */ typedef curlpp::OptionTrait @@ -92,10 +92,10 @@ namespace options /** - * Using this option will reset CURLOPT_WRITEFUNCTION to - * default callback. In fact, use only this option if you only - * want libcURL to use the FILE * given in argument instead - * of stdout. + * Using this option will reset CURLOPT_WRITEFUNCTION to + * default callback. In fact, use only this option if you only + * want libcURL to use the FILE * given in argument instead + * of stdout. */ #if LIBCURL_VERSION_NUM >= 0x070907 @@ -133,10 +133,10 @@ namespace options /** - * Using this option will reset CURLOPT_READFUNCTION to - * default callback. In fact, use only this option if you only - * want libcURL to use the FILE * given in argument instead - * of stdout. + * Using this option will reset CURLOPT_READFUNCTION to + * default callback. In fact, use only this option if you only + * want libcURL to use the FILE * given in argument instead + * of stdout. */ #if LIBCURL_VERSION_NUM >= 0x070907 @@ -305,6 +305,7 @@ namespace options */ typedef curlpp::OptionTrait Timeout; + typedef curlpp::OptionTrait TimeoutMs; typedef curlpp::OptionTrait LowSpeedLimit; typedef curlpp::OptionTrait LowSpeedTime; typedef curlpp::OptionTrait MaxConnects; diff --git a/src/curlpp/Multi.cpp b/src/curlpp/Multi.cpp index 58b05aad..bb9f0a8e 100644 --- a/src/curlpp/Multi.cpp +++ b/src/curlpp/Multi.cpp @@ -1,22 +1,22 @@ /* * Copyright (c) <2002-2009> - * + * * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (curlpp), to deal in the Software without restriction, + * a copy of this software and associated documentation files + * (curlpp), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, + * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ @@ -36,7 +36,7 @@ curlpp::Multi::Multi() curlpp::Multi::~Multi() { // remove all the remaining easy handles - while (!mHandles.empty()) + while (!mHandles.empty()) { std::map::iterator handle = mHandles.begin(); curl_multi_remove_handle(mMultiHandle, handle->second->getHandle()); @@ -96,11 +96,27 @@ curlpp::Multi::fdset(fd_set * read, fd_set * write, fd_set * exc, int * max) } } +void curlpp::Multi::wait(int timeout_ms, struct curl_waitfd extra_fds[], unsigned int extra_nfds, int * numfds) { + CURLMcode code = curl_multi_wait(mMultiHandle, extra_fds, extra_nfds, timeout_ms, numfds); + if (code != CURLM_OK) { + throw curlpp::RuntimeError(curl_multi_strerror(code)); + } +} + +#if LIBCURL_VERSION_NUM >= 0x074200 +void curlpp::Multi::poll(int timeout_ms, struct curl_waitfd extra_fds[], unsigned int extra_nfds, int * numfds) { + CURLMcode code = curl_multi_poll(mMultiHandle, extra_fds, extra_nfds, timeout_ms, numfds); + if (code != CURLM_OK) { + throw curlpp::RuntimeError(curl_multi_strerror(code)); + } +} +#endif + curlpp::Multi::Msgs curlpp::Multi::info() { CURLMsg * msg; /* for picking up messages with the transfer status */ - + int msgsInQueue; Msgs result; while ((msg = curl_multi_info_read(mMultiHandle, &msgsInQueue)) != NULL) { @@ -112,4 +128,3 @@ curlpp::Multi::info() return result; } -