1 /*
2 * Copyright (c) 2023 Unionman Technology 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 #include <drogon/drogon.h>
17 #include <fstream>
18 #include "../untils/picosha2.h"
19 #include "download.h"
20 using namespace drogon;
getFile(const HttpRequestPtr & req,std::function<void (const HttpResponsePtr &)> && callback,const std::string & filename)21 void Download::getFile(
22 const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback, const std::string& filename)
23 {
24 std::string path(app().getUploadPath());
25 path.append("/");
26 path.append(filename);
27 HttpResponsePtr response = HttpResponse::newFileResponse(path, filename, CT_CUSTOM, "");
28 callback(response);
29 }
30
uploadFile(const HttpRequestPtr & req,std::function<void (const HttpResponsePtr &)> && callback)31 void Download::uploadFile(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback)
32 {
33 using namespace std;
34 MultiPartParser formData;
35 if (formData.parse(req) != 0 || formData.getFiles().size() != 1) {
36 HttpResponsePtr response = HttpResponse::newHttpResponse();
37 response->setBody("the file must only one");
38 response->setStatusCode(k403Forbidden);
39 callback(response);
40 }
41 const HttpFile& file = formData.getFiles()[0];
42 file.save();
43 Info info;
44 std::map<std::string, std::string> maps = formData.getParameters();
45 info.versionCode = maps["versionCode"];
46 info.versionName = maps["versionName"];
47 info.url = "http://"s + req->getLocalAddr().toIpPort() + "/api/download/"s + file.getFileName();
48 info.fileSize = file.fileLength();
49 info.verifyInfo = getFileSha256(app().getUploadPath() + "/"s + file.getFileName());
50 info.description = maps["content"];
51 addInfoJsonFile("./config/serverInfo.json", info);
52
53 HttpResponsePtr response = HttpResponse::newHttpResponse();
54 response->setBody("success!");
55 response->setStatusCode(k200OK);
56 callback(response);
57 }
58
readJsonFromFile(const std::string & path)59 Json::Value Download::readJsonFromFile(const std::string& path)
60 {
61 Json::Value json;
62 std::ifstream inputFile(path, std::ios::binary);
63 LOG_ERROR_IF(!inputFile.is_open()) << "open updatainfo.json error!";
64 Json::CharReaderBuilder readerBuilder;
65 std::string error;
66 LOG_ERROR_IF(!Json::parseFromStream(readerBuilder, inputFile, &json, &error)) << "fail parse JSON error:" << error;
67 inputFile.close();
68 return json;
69 }
70
saveJsonToFile(const std::string & path,const Json::Value json)71 void Download::saveJsonToFile(const std::string& path, const Json::Value json)
72 {
73 Json::StreamWriterBuilder writer;
74 writer["emitUTF8"] = true;
75 std::string jsonString = Json::writeString(writer, json);
76 std::ofstream file(path, std::ios::out);
77 LOG_ERROR_IF(!file.is_open()) << "open updatainfo.json error!";
78 file << jsonString;
79 file.close();
80 }
81
addInfoJsonFile(const std::string & path,const Info & info)82 bool Download::addInfoJsonFile(const std::string& path, const Info& info)
83 {
84 Json::Value json = readJsonFromFile(path);
85 Json::Value& checkResults = json["checkResults"];
86 Json::Value& descriptInfo = json["descriptInfo"];
87 Json::Value checkResultsItem, descriptInfoItem;
88 checkResultsItem["versionCode"] = info.versionCode;
89 checkResultsItem["packageType"] = 1;
90 checkResultsItem["descriptPackageId"] = "abcdefg123456789";
91 checkResultsItem["url"] = info.url;
92 checkResultsItem["versionName"] = info.versionName;
93 checkResultsItem["verifyInfo"] = info.verifyInfo;
94 checkResultsItem["size"] = info.fileSize;
95 checkResults.append(checkResultsItem);
96 descriptInfoItem["descriptionType"] = 0;
97 descriptInfoItem["content"] = info.description;
98 descriptInfo.append(descriptInfoItem);
99 saveJsonToFile(path, json);
100 return true;
101 }
102
getFileSha256(const std::string & path)103 std::string Download::getFileSha256(const std::string& path)
104 {
105 std::ifstream file(path, std::ios::binary);
106 LOG_ERROR_IF(!file.is_open()) << "open " << path << " error!";
107 std::vector<picosha2::byte_t> hash(picosha2::k_digest_size);
108 picosha2::hash256(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), hash.begin(), hash.end());
109 std::string value = picosha2::bytes_to_hex_string(hash.begin(), hash.end());
110 return value;
111 }
112