/* * Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved. * * This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit). * * Use of this source code is governed by MIT-like license that can be found in the * LICENSE file in the root of the source tree. All contributing project authors * may be found in the AUTHORS file in the root of the source tree. */ #include "HttpRequester.h" #include "Util/onceToken.h" #include "Util/NoticeCenter.h" #include using namespace std; using namespace toolkit; namespace mediakit { void HttpRequester::onResponseHeader(const string &status, const HttpHeader &headers) { _res_body.clear(); } void HttpRequester::onResponseBody(const char *buf, size_t size) { _res_body.append(buf, size); } void HttpRequester::onResponseCompleted(const SockException &ex) { if (ex && _retry++ < _max_retry) { std::weak_ptr weak_self = std::static_pointer_cast(shared_from_this()); getPoller()->doDelayTask(_retry_delay, [weak_self](){ if (auto self = weak_self.lock()) { InfoL << "resend request " << self->getUrl() << " with retry " << self->getRetry(); self->sendRequest(self->getUrl()); } return 0; }); return ; } const_cast(response()).setContent(std::move(_res_body)); if (_on_result) { _on_result(ex, response()); _on_result = nullptr; } } void HttpRequester::setRetry(size_t count, size_t delay) { InfoL << "setRetry max=" << count << ", delay=" << delay; _max_retry = count; _retry_delay = delay; } void HttpRequester::startRequester(const string &url, const HttpRequesterResult &on_result, float timeout_sec) { _on_result = on_result; _retry = 0; setCompleteTimeout(timeout_sec * 1000); sendRequest(url); } void HttpRequester::clear() { HttpClientImp::clear(); _res_body.clear(); _on_result = nullptr; } void HttpRequester::setOnResult(const HttpRequesterResult &onResult) { _on_result = onResult; } //////////////////////////////////////////////////////////////////////// #if !defined(DISABLE_REPORT) static constexpr auto s_report_url = "http://report.zlmediakit.com:8888/index/api/report"; extern const char kServerName[]; static std::string httpBody() { HttpArgs args; auto &os = args["os"]; #if defined(_WIN32) os = "windows"; #elif defined(__ANDROID__) os = "android"; #elif defined(__linux__) os = "linux"; #elif defined(OS_IPHONE) os = "ios"; #elif defined(__MACH__) os = "macos"; #else os = "unknow"; #endif #if (defined(_WIN32) && !defined(WIN32)) #define WIN32 _WIN32 #elif (defined(WIN32) && !defined(_WIN32)) #define _WIN32 WIN32 #endif #if (defined(_WIN32) && !defined(_MSC_VER) && !defined(_WIN64)) #ifndef __i386__ #define __i386__ #endif #elif defined(_MSC_VER) #if (defined(_M_IX86) && !defined(__i386__)) #define __i386__ #endif #endif #ifndef __i386__ #if (defined(__386__) || defined(__I386__) || _M_IX86) #define __i386__ #endif #endif #if (defined(__i386__) && !defined(__I386__)) #define __I386__ #endif #if (defined(__x86_64__) && !defined(__x86_64)) #define __x86_64 #endif #if (defined(__x86_64) && !defined(__x86_64__)) #define __x86_64__ #endif #if (defined(_M_AMD64)) && (!defined(__amd64__)) #define __amd64__ #endif #if (defined(__amd64) && !defined(__amd64__)) #define __amd64__ #endif #if (defined(__amd64__) && !defined(__amd64)) #define __amd64 #endif #if (defined(_M_ARM64) && !defined(__arm64__)) #define __arm64__ #endif #if (defined(_M_X64) && !defined(__x86_64__)) #define __x86_64__ #endif #if (defined(_M_ARM) && !defined(__arm__)) #define __arm__ #endif #if (defined(__i386__) || defined(__amd64__)) && (!defined(__x86__)) #if !(defined(_MSC_VER) && defined(__amd64__)) #define __x86__ // MSVC doesn't support inline assembly in x64 #endif #endif auto &arch = args["arch"]; #if defined(__x86_64__) || defined(__amd64__) arch = "x86_64"; #elif defined(__x86__) || defined(__X86__) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) arch = "x86"; #elif defined(__arm64__) || defined(__aarch64__) arch = "arm64"; #elif defined(__arm__) arch = "arm"; #elif defined(__loognarch__) arch = "loognarch"; #elif defined(__riscv) || defined(__riscv__) arch = "riscv"; #elif defined(__mipsl__) || defined(__mips__) arch = "mipsl"; #else arch = "unknow"; #endif auto &compiler = args["compiler"]; #if defined(__clang__) compiler = "clang"; #elif defined(_MSC_VER) compiler = "msvc"; #elif defined(__MINGW32__) compiler = "mingw"; #elif defined(__CYGWIN__) compiler = "cygwin"; #elif defined(__GNUC__) compiler = "gcc"; #elif defined(__ICC__) compiler = "icc"; #else compiler = "unknow"; #endif args["cplusplus"] = __cplusplus; args["build_date"] = __DATE__; args["version"] = kServerName; args["exe_name"] = exeName(); args["start_time"] = getTimeStr("%Y-%m-%d %H:%M:%S"); #if NDEBUG args["release"] = 1; #else args["release"] = 0; #endif #if ENABLE_RTPPROXY args["rtp_proxy"] = 1; #else args["rtp_proxy"] = 0; #endif #if ENABLE_HLS args["hls"] = 1; #else args["hls"] = 0; #endif #if ENABLE_WEBRTC args["webrtc"] = 1; #else args["webrtc"] = 0; #endif #if ENABLE_SCTP args["sctp"] = 1; #else args["sctp"] = 0; #endif #if ENABLE_SRT args["srt"] = 1; #else args["srt"] = 0; #endif #if ENABLE_MP4 args["mp4"] = 1; #else args["mp4"] = 0; #endif #if ENABLE_OPENSSL args["openssl"] = 1; #else args["openssl"] = 0; #endif #if ENABLE_FFMPEG args["ffmpeg"] = 1; #else args["ffmpeg"] = 0; #endif args["rand_str"] = makeRandStr(32); for (auto &pr : mINI::Instance()) { // 只获取转协议相关配置 [AUTO-TRANSLATED:4e1e5840] // Only get the configuration related to protocol conversion if (pr.first.find("protocol.") == 0) { args[pr.first] = pr.second; } } return args.make(); } static void sendReport() { static HttpRequester::Ptr requester = std::make_shared(); // 获取一次静态信息,定时上报主要方便统计在线实例个数 [AUTO-TRANSLATED:1612d609] // Get static information once, and report it regularly to facilitate statistics of the number of online instances static auto body = httpBody(); requester->setMethod("POST"); requester->setBody(body); // http超时时间设置为30秒 [AUTO-TRANSLATED:466f9b71] // Set the http timeout to 30 seconds requester->startRequester(s_report_url, nullptr, 30); } static toolkit::onceToken s_token([]() { NoticeCenter::Instance().addListener(nullptr, "kBroadcastEventPollerPoolStarted", [](EventPollerPoolOnStartedArgs) { // 第一次汇报在程序启动后5分钟 [AUTO-TRANSLATED:02e6c508] // The first report is 5 minutes after the program starts pool.getPoller()->doDelayTask(5 * 60 * 1000, []() { sendReport(); // 后续每一个小时汇报一次 [AUTO-TRANSLATED:0322b8aa] // Report every hour afterwards return 60 * 60 * 1000; }); }); }); #endif } // namespace mediakit