| #include <Poco/Net/HTTPServer.h> |
| #include <Poco/Net/HTTPRequestHandler.h> |
| #include <Poco/Net/HTTPRequestHandlerFactory.h> |
| #include <Poco/Net/HTTPServerRequest.h> |
| #include <Poco/Net/HTTPServerResponse.h> |
| #include <Poco/Net/ServerSocket.h> |
| #include <Poco/Util/ServerApplication.h> |
| #include <Poco/StreamCopier.h> |
| #include <Poco/Util/IniFileConfiguration.h> |
| #include <Poco/URI.h> |
| #include <Poco/StringTokenizer.h> |
| #include <Poco/JSON/Parser.h> |
| #include <Poco/JSON/Object.h> |
| #include <Poco/Dynamic/Var.h> |
| #include <Poco/Net/MailMessage.h> |
| #include <Poco/Net/StringPartSource.h> |
| #include <Poco/Net/SMTPClientSession.h> |
| #include <Poco/Net/SecureSMTPClientSession.h> |
| #include <Poco/Exception.h> |
| #include <iostream> |
| |
| using namespace Poco; |
| using namespace Poco::Net; |
| using namespace Poco::Util; |
| using namespace Poco::JSON; |
| |
| static std::string mailuser,mailpasswd; |
| |
| class HelloRequestHandler: public HTTPRequestHandler |
| { |
| void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) |
| { |
| Application& app = Application::instance(); |
| try{ |
| std::istream& is = request.stream(); |
| std::string body; |
| StreamCopier::copyToString(is,body); |
| |
| Poco::Net::HTTPResponse::HTTPStatus status = Poco::Net::HTTPResponse::HTTP_NOT_FOUND; |
| Poco::URI uri(request.getURI()); |
| if(uri.getPath() != "/release"){ |
| throw status; |
| } |
| std::string query = uri.getQuery(); |
| if(query.find("NotifyParty") != 0){ |
| throw status; |
| } |
| Poco::StringTokenizer tok(query.substr(sizeof("NotifyParty")),";",1); |
| std::vector<std::string> notifyParty(tok.begin(),tok.end()); |
| |
| Poco::Net::MailMessage message; |
| Poco::JSON::Parser jsonparser; |
| Poco::Dynamic::Var result = jsonparser.parse(body); |
| Object::Ptr rootObj = result.extract<Object::Ptr>(); |
| Object::Ptr releaseObj = rootObj->getObject("release"); |
| Object::Ptr repositoryObj = rootObj->getObject("repository"); |
| Object::Ptr authorObj = releaseObj->getObject("author"); |
| |
| std::string mailSubject = "版本发布:" + repositoryObj->getValue<std::string>("name") |
| + " " + releaseObj->getValue<std::string>("name"); |
| message.setSubject(mailSubject); |
| |
| std::string mailDatetime = releaseObj->getValue<std::string>("created_at"); |
| Poco::DateTime dt; int tzd; |
| Poco::DateTimeParser::parse(Poco::DateTimeFormat::ISO8601_FORMAT, mailDatetime, dt, tzd); |
| message.setDate(dt.timestamp() - Poco::Timespan(tzd,0)); |
| mailDatetime = Poco::DateTimeFormatter::format(dt.timestamp(),"%Y年%m月%d日 %H:%M:%S"); |
| |
| |
| std::string mailbody; |
| mailbody.append("\n项 目:").append(repositoryObj->getValue<std::string>("name")); |
| mailbody.append("\n描 述:").append(repositoryObj->getValue<std::string>("description")); |
| mailbody.append("\n版本标题:").append(releaseObj->getValue<std::string>("name")); |
| mailbody.append("\n版本标签:").append(releaseObj->getValue<std::string>("tag_name")); |
| mailbody.append("\n版本描述:").append(releaseObj->getValue<std::string>("body")); |
| mailbody.append("\n发布时间:").append(mailDatetime); |
| mailbody.append("\n发布作者:").append(authorObj->getValue<std::string>("full_name")); |
| mailbody.append("\n访问地址:").append(repositoryObj->getValue<std::string>("html_url")); |
| |
| message.setContentType("text/html;charset=utf-8"); |
| message.addContent(new Poco::Net::StringPartSource(mailbody)); |
| |
| |
| message.setSender(mailuser); |
| for(auto& r: notifyParty) { |
| message.addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, r)); |
| } |
| |
| |
| |
| |
| Poco::Net::SecureSMTPClientSession smtpSession("smtp.exmail.qq.com"); |
| |
| smtpSession.open(); |
| |
| |
| smtpSession.login(); |
| smtpSession.startTLS(); |
| smtpSession.login(Poco::Net::SMTPClientSession::LoginMethod::AUTH_LOGIN, mailuser, mailpasswd); |
| |
| |
| smtpSession.sendMessage(message); |
| |
| smtpSession.close(); |
| } |
| catch (Poco::Exception& e) { |
| app.logger().error("Poco Exception(%s)\n", e.displayText()); |
| } |
| catch (std::exception& e) { |
| app.logger().error("std Exception(%s)\n", e.what()); |
| } |
| catch(Poco::Net::HTTPResponse::HTTPStatus s){ |
| response.setStatusAndReason(s); |
| response.send(); |
| return; |
| } |
| response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_OK); |
| response.send(); |
| } |
| }; |
| |
| class HelloRequestHandlerFactory: public HTTPRequestHandlerFactory |
| { |
| HTTPRequestHandler* createRequestHandler(const HTTPServerRequest&) |
| { |
| return new HelloRequestHandler; |
| } |
| }; |
| |
| class WebServerApp: public ServerApplication |
| { |
| void initialize(Application& self) |
| { |
| loadConfiguration(); |
| ServerApplication::initialize(self); |
| } |
| |
| int main(const std::vector<std::string>&) |
| { |
| try{ |
| |
| AutoPtr<IniFileConfiguration> pConf(new IniFileConfiguration("./custom/conf/app.ini")); |
| mailuser = pConf->getString("mailer.USER"); |
| mailpasswd = pConf->getString("mailer.PASSWD"); |
| logger().information("Email User is %s",mailuser); |
| logger().information("Email Password is %s",mailpasswd); |
| |
| UInt16 port = static_cast<UInt16>(config().getUInt("port", 3001)); |
| |
| HTTPServer srv(new HelloRequestHandlerFactory, port); |
| srv.start(); |
| logger().information("HTTP Server started on port %hu.", port); |
| waitForTerminationRequest(); |
| logger().information("Stopping HTTP Server..."); |
| srv.stop(); |
| |
| return Application::EXIT_OK; |
| } |
| catch (Poco::Exception& e) { |
| logger().error("Poco Exception(%s)\n", e.displayText()); |
| } |
| catch (std::exception& e) { |
| logger().error("std Exception(%s)\n", e.what()); |
| } |
| catch (...) { |
| logger().error("Unknown Exception"); |
| } |
| return Application::EXIT_OK; |
| } |
| }; |
| |
| POCO_SERVER_MAIN(WebServerApp) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理