# openhttps **Repository Path**: northqd2018/openhttps ## Basic Information - **Project Name**: openhttps - **Description**: OpenHttps是一款Actor模式、组件设计的高性能、高并发的超轻量、超迷你的跨全平台Https框架。 使用OpenServer开源库开发,小巧迷你,支持IPv6,让C++开发Https如此简单,易如反掌。 由于时间关系,暂时没有实现状态机设计,不过使用OpenFSM库可以轻松实现状态机设计。 - **Primary Language**: C++ - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2023-04-26 - **Last Updated**: 2023-04-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OpenHttps OpenHttps is a high performance, high concurrency, ultra lightweight, ultra mini cross-platform Https framework designed with Actor model and component design. Developed with OpenServer open source library, it is small and mini, supporting IPv6, making C++ development of Https so simple and easy. Due to time constraints, state machine design has not been implemented yet, but state machine design can be easily implemented with OpenFSM library. OpenHttps is also very easy to implement Websocket, but it is not implemented for the time being due to time constraints. As a C++ Http framework, it needs to meet several points: 1. High performance, high concurrency and cross-platform; 2. Actor model, component design and state machine design; 3. Any assembly, to achieve various ultra-difficult network communication. Since C++ backend development is not suitable for coroutine, coroutine is not considered. **OpenLinyou is committed to the development of C++ cross-platform high-concurrency and high-performance server framework, with full platform design, supporting Windows, Linux, Mac, Android and iOS platforms. It can make full use of the advantages and tools of each platform to develop and write code on VS or XCode, and achieve one code running on all platforms.** OpenLinyou:https://www.openlinyou.com OpenHttps:https://github.com/openlinyou/openhttps https://gitee.com/linyouhappy/openhttps ## Cross-platform support Linux and Android use epoll, iOS and Mac use kqueue, Windows use IOCP(wepoll).other systems use select. ## Compilation and execution Please install the cmake tool. With cmake you can build a VS or XCode project and compile and run it on VS or XCode. Source code:https://github.com/openlinyou/openserver https://gitee.com/linyouhappy/openserver HTTPS requires support from OpenSSL. If the local does not have the OpenSSL library, it needs to be installed first. If not, close the USE_OPEN_SSL macro definition. ``` #Clone the project git clone https://github.com/openlinyou/openserver cd ./openserver #Create a build project directory mkdir build cd build cmake .. # If it's win32, openserver.sln will appear in this directory. Click it to start VS for coding and debugging. make ./helloworld ``` ## Technical features OpenServer's technical features: 1. Cross-platform design, this server framework can run on Android and iOS. 2. Linux and Android use epoll, Windows use IOCP (wepoll), iOS and Mac use kqueue, other systems use select. 3. Support IPv6, mini and small, adopt Actor mode and component design, assemble business through components. 4. The Actor mode and component design can easily realize high concurrency and distributed. The business and service can also be customized through configuration files. 5. One thread one actor, one actor is composed of multiple components. Develop server in a way of playing building blocks. ## Design a scientific internet access tool using Https Disclaimer: This example is only to demonstrate the functionality of OpenHttps. Any consequences arising from the use of scientific internet access are borne by the user. OpenHttps is just an application of OpenServer technology. Refer to OpenServer for specific usage. OpenHttps only implements three components, OpenComHttpServer, OpenComHttpAgent, and OpenComHttpClient. OpenComHttpServer is responsible for listening to the socket and cooperating with OpenComHttpAgent, while OpenComHttpAgent handles specific client communication, and they together form a web server. OpenComHttpClient is just an http client component. Next is to assemble their respective servers. OpenHttpServer is responsible for listening to client connections, and then distributing them to OpenComHttpAgent, which does not require much business and only needs one. OpenHttpAgent1 is responsible for specific client connections, and needs to handle a large number of client connections. Multiple servers need to be created to achieve multi-core processing. OpenHttpClient is responsible for http client requests and can be used to implement web server stress testing. OpenHttps is designed with the actor model, and can be started by simply sending messages to them. This example shows the principle of scientific internet access. Take accessing https://www.bing.com for example. Assuming the server is running on the local computer 127.0.0.1, similar to the turtle server. On the browser side, enter http://127.0.0.1/xx. Use the browser plug-in to add the client field to the http header, client:https://www.bing.com. The browser will request the server at 127.0.0.1. OpenHttpServer will listen to the browser's request connection, and then distribute it to OpenComHttpAgent. OpenHttpAgent parses the http packet and finds the http request header containing the client, and then removes it, and changes the url request to the domain name specified by the client. Then the modified packet is forwarded to OpenHttpClient. OpenHttpClient then uses the modified http packet to request https://www.bing.com. The obtained data is immediately forwarded to OpenHttpAgent. OpenHttpAgent immediately sends the received data to the browser. Of course, it is not feasible to achieve scientific internet access in actual use. Because scientific internet access is very unstable, packet loss, network connection timeout, and other issues may lead to request recognition. A UDP scheme needs to be adopted, and the http protocol is naturally suitable for UDP communication. ```C++ #include #include #include #include "openserver.h" #include "opencomhttpclient.h" #include "opencomhttpserver.h" using namespace open; class HttpApp :public OpenApp { int balance_; OpenServer* server_; std::vector accepts_; std::vector clients_; static HttpApp OpenApp_; public: static inline HttpApp& Instance() { return OpenApp_; } virtual void start() { OpenApp::start(); OpenTimer::Run(); OpenServer::RegisterCom("OpenComHttpServer"); OpenServer::RegisterCom("OpenComHttpAgent"); OpenServer::RegisterCom("OpenComHttpClient"); accepts_ = { OpenServer::StartServer("OpenHttpAgent1", { "OpenComHttpAgent" }), OpenServer::StartServer("OpenHttpAgent2", { "OpenComHttpAgent" }), OpenServer::StartServer("OpenHttpAgent3", { "OpenComHttpAgent" }), OpenServer::StartServer("OpenHttpAgent4", { "OpenComHttpAgent" }) }; server_ = OpenServer::StartServer("OpenHttpServer", { "OpenComHttpServer" }); assert(server_); balance_ = 0; clients_ = { OpenServer::StartServer("OpenHttpClient1", { "OpenComHttpClient" }), OpenServer::StartServer("OpenHttpClient2", { "OpenComHttpClient" }), OpenServer::StartServer("OpenHttpClient3", { "OpenComHttpClient" }), OpenServer::StartServer("OpenHttpClient4", { "OpenComHttpClient" }) }; } bool httpServer(std::shared_ptr& protoMsg) { for (size_t i = 0; i < accepts_.size(); i++) protoMsg->vectAccepts_.push_back(accepts_[i]->pid()); for (size_t i = 0; i < clients_.size(); i++) protoMsg->vectClients_.push_back(clients_[i]->pid()); auto proto = std::shared_ptr(new OpenMsgProto); proto->msg_ = protoMsg; bool ret = OpenThread::Send(server_->pid(), proto); assert(ret); return ret; } bool httpClient(std::shared_ptr& protoMsg, bool isAll) { if (clients_.empty()) { assert(false); return false; } //isAll auto proto = std::shared_ptr(new OpenMsgProto); proto->msg_ = protoMsg; bool ret = false; if (isAll) { for (size_t i = 0; i < clients_.size(); i++) { ret = OpenThread::Send(clients_[i]->pid(), proto); assert(ret); } } else { if (balance_ >= clients_.size()) balance_ = 0; OpenServer* client = clients_[balance_++]; ret = OpenThread::Send(client->pid(), proto); assert(ret); } return ret; } bool httpClient(std::shared_ptr& request) { if (clients_.empty()) { assert(false); return false; } auto protoMsg = std::shared_ptr(new OpenHttpClientSyncMsg); protoMsg->request_ = request; if (balance_ >= clients_.size()) { balance_ = 0; } OpenServer* client = clients_[balance_++]; auto proto = std::shared_ptr(new OpenMsgProto); proto->msg_ = protoMsg; bool ret = OpenThread::Send(client->pid(), proto); assert(ret); protoMsg->openSync_.await(); return ret; } }; HttpApp HttpApp::OpenApp_; void OnOpenHttpHandle(OpenHttpRequest& req, OpenHttpResponse& resp) { #ifdef USE_OPEN_SSL //80 redirect to 443 if (req.listenPort_ == 80) { resp.code_ = 302; resp["location"] = "https://" + req.host_ + ":" + std::to_string(req.port_) + "/" + req.url_; return; } #endif resp.response(".html", "

HelloWorld

" "

Welcome to OpenLinyou

"); } int main() { HttpApp::Instance().start(); printf("start HttpServer\n"); auto msg = std::shared_ptr(new OpenHttpServerMsg); msg->ip_ = "0.0.0.0"; #ifdef USE_OPEN_SSL msg->port_ = 443; msg->port1_ = 80; msg->isHttps_ = 1; msg->keyFile_ = "www.xx.com.key"; msg->certFile_ = "www.xx.com.crt"; #else msg->port_ = 80; msg->port1_ = 0; msg->isHttps_ = 0; #endif msg->handle_ = &OnOpenHttpHandle; HttpApp::Instance().httpServer(msg); //httpclient OpenThread::Sleep(500); auto request = std::shared_ptr(new OpenHttpRequest); request->method_ = "GET"; #ifdef USE_OPEN_SSL request->url_ = "https://www.xx.com/"; (*request)["client"] = "https://www.bing.com/"; #else request->url_ = "http://127.0.0.1/"; (*request)["client"] = "http://www.bing.com/"; #endif HttpApp::Instance().httpClient(request); auto& response = request->response_; std::string head; response.getHead(head); printf("[http client]code:%d, header:%s\n", response.code_, head.data()); std::string body; response.getBody(body); printf("[http client]body:%s\n", body.data()); HttpApp::Instance().wait(); return getchar(); } ```