• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifdef IPPOVERUSB_ENABLE
17 #include "print_http_server_manager.h"
18 #include "print_http_request_process.h"
19 #include "print_usb_manager.h"
20 #include "print_log.h"
21 #include "nlohmann/json.hpp"
22 #include "cJSON.h"
23 
24 namespace OHOS::Print {
25 using namespace std;
26 using namespace OHOS;
27 using namespace httplib;
28 
29 using json = nlohmann::json;
30 
PrintHttpServerManager()31 PrintHttpServerManager::PrintHttpServerManager()
32 {}
33 
~PrintHttpServerManager()34 PrintHttpServerManager::~PrintHttpServerManager()
35 {
36 }
37 
AllocatePort(std::shared_ptr<httplib::Server> svr,int32_t & port)38 bool PrintHttpServerManager::AllocatePort(std::shared_ptr<httplib::Server> svr, int32_t &port)
39 {
40     for (int allocPort = HTTP_MIN_PORT; allocPort <= HTTP_MAX_PORT; allocPort++) {
41         bool isPortUse = false;
42         for (const auto& pair : printHttpPortMap) {
43             if (pair.second == allocPort) {
44                 isPortUse = true;
45                 break;
46             }
47         }
48         if (isPortUse) {
49             PRINT_HILOGD("port : %{public}d is using", allocPort);
50             continue;
51         }
52         if (svr != nullptr && svr->bind_to_port(LOCAL_HOST, allocPort)) {
53             PRINT_HILOGD("bind to port : %{public}d success", allocPort);
54             port = allocPort;
55             return true;
56         }
57     }
58     return false;
59 }
60 
StartServer(std::shared_ptr<httplib::Server> svr,std::shared_ptr<PrintHttpRequestProcess> process)61 void PrintHttpServerManager::StartServer(std::shared_ptr<httplib::Server> svr,
62     std::shared_ptr<PrintHttpRequestProcess> process)
63 {
64     PRINT_HILOGD("startServer");
65     if (svr == nullptr) {
66         PRINT_HILOGE("svr is null");
67         return;
68     }
69     svr->set_payload_max_length(HTTP_SERVER_MAX_LENGTH);
70     PRINT_HILOGD("post /");
71     svr->Post("^/.*", [process](const httplib::Request &req, httplib::Response &res,
72                               const httplib::ContentReader &content_reader) {
73         PRINT_HILOGD("listen path: %{public}s", req.path.c_str());
74         if (process != nullptr) {
75             process->ProcessRequest(req, res, content_reader);
76         }
77     });
78 
79     PRINT_HILOGD("after post");
80     svr->listen_after_bind();
81     PRINT_HILOGD("after listen");
82 }
83 
CreateServer(std::string printerName,int32_t & port)84 bool PrintHttpServerManager::CreateServer(std::string printerName, int32_t &port)
85 {
86     PRINT_HILOGD("PrintHttpServerManager init printerName: %{public}s, port: %{public}d", printerName.c_str(), port);
87     if (printHttpServerMap.find(printerName) != printHttpServerMap.end()) {
88         PRINT_HILOGI("printerName: %{public}s has server", printerName.c_str());
89         if (printHttpPortMap.find(printerName) != printHttpPortMap.end()) {
90             port = printHttpPortMap[printerName];
91             return true;
92         }
93         PRINT_HILOGE("printerName: %{public}s has server, but do not has port", printerName.c_str());
94         return false;
95     }
96 
97     std::shared_ptr<httplib::Server> newServer = std::make_shared<httplib::Server>();
98     int32_t allocPort = HTTP_MIN_PORT;
99     if (!AllocatePort(newServer, allocPort)) {
100         PRINT_HILOGE("AllocatePort fail, return!");
101         return false;
102     }
103     port = allocPort;
104     printHttpServerMap[printerName] = newServer;
105     printHttpPortMap[printerName] = port;
106     std::shared_ptr<PrintHttpRequestProcess> newProcess = std::make_shared<PrintHttpRequestProcess>();
107     printHttpProcessMap[printerName] = newProcess;
108     newProcess->SetDeviceName(printerName);
109 
110     std::thread tServer = std::thread([this, printerName] {
111         this->StartServer(this->printHttpServerMap[printerName], this->printHttpProcessMap[printerName]);
112     });
113     tServer.detach();
114     return true;
115 }
116 
StopServer(std::string printerName)117 void PrintHttpServerManager::StopServer(std::string printerName)
118 {
119     PRINT_HILOGD("stopServer printerName: %{public}s", printerName.c_str());
120     if (printHttpServerMap.find(printerName) != printHttpServerMap.end()) {
121         if (printHttpServerMap[printerName]->is_running()) {
122             printHttpServerMap[printerName]->stop();
123             printHttpServerMap.erase(printerName);
124         }
125     }
126     if (printHttpPortMap.find(printerName) != printHttpPortMap.end()) {
127         printHttpPortMap.erase(printerName);
128     }
129     if (printHttpProcessMap.find(printerName) != printHttpProcessMap.end()) {
130         printHttpProcessMap[printerName]->Stop();
131         printHttpProcessMap.erase(printerName);
132     }
133 }
134 
DealUsbDevDetach(const std::string & devStr)135 void PrintHttpServerManager::DealUsbDevDetach(const std::string &devStr)
136 {
137     PRINT_HILOGD("devStr: %{public}s", devStr.c_str());
138     cJSON *devJson = cJSON_Parse(devStr.c_str());
139     if (!devJson) {
140         PRINT_HILOGE("Create devJson error");
141     }
142     cJSON *jsonTemp = cJSON_GetObjectItem(devJson, "name");
143     if (jsonTemp == nullptr || jsonTemp->valuestring  == NULL) {
144         PRINT_HILOGE("The devJson does not have a necessary attribute.");
145         cJSON_Delete(devJson);
146         return;
147     }
148     string name = jsonTemp->valuestring;
149     string printerName = DelayedSingleton<PrintUsbManager>::GetInstance()->GetPrinterName(name);
150     PRINT_HILOGD("DealUsbDevDetach name: %{public}s, printerName: %{public}s", name.c_str(), printerName.c_str());
151     if (printerName.empty()) {
152         cJSON_Delete(devJson);
153         return;
154     }
155     StopServer(printerName);
156     cJSON_Delete(devJson);
157 }
158 }
159 #endif // IPPOVERUSB_ENABLE