1 | // Aseprite |
2 | // Copyright (C) 2020 Igara Studio S.A. |
3 | // Copyright (C) 2001-2018 David Capello |
4 | // |
5 | // This program is distributed under the terms of |
6 | // the End-User License Agreement for Aseprite. |
7 | |
8 | #ifdef HAVE_CONFIG_H |
9 | #include "config.h" |
10 | #endif |
11 | |
12 | #include "updater/check_update.h" |
13 | |
14 | #include "base/convert_to.h" |
15 | #include "base/debug.h" |
16 | #include "net/http_headers.h" |
17 | #include "net/http_request.h" |
18 | #include "net/http_response.h" |
19 | #include "tinyxml.h" |
20 | #include "updater/user_agent.h" |
21 | #include "ver/info.h" |
22 | |
23 | #include <iostream> |
24 | #include <memory> |
25 | #include <sstream> |
26 | |
27 | namespace updater { |
28 | |
29 | CheckUpdateResponse::CheckUpdateResponse() |
30 | : m_type(Unknown) |
31 | , m_waitDays(0.0) |
32 | { |
33 | } |
34 | |
35 | CheckUpdateResponse::CheckUpdateResponse(const CheckUpdateResponse& other) |
36 | : m_type(other.m_type) |
37 | , m_version(other.m_version) |
38 | , m_url(other.m_url) |
39 | , m_waitDays(0.0) |
40 | { |
41 | } |
42 | |
43 | CheckUpdateResponse::CheckUpdateResponse(const std::string& responseBody) |
44 | : m_type(Unknown) |
45 | , m_waitDays(0.0) |
46 | { |
47 | TiXmlDocument doc; |
48 | doc.Parse(responseBody.c_str()); |
49 | |
50 | TiXmlHandle handle(&doc); |
51 | TiXmlElement* xmlUpdate = handle.FirstChild("update" ).ToElement(); |
52 | if (!xmlUpdate) { |
53 | // TODO show error? |
54 | return; |
55 | } |
56 | |
57 | const char* latest_attr = xmlUpdate->Attribute("latest" ); |
58 | const char* version_attr = xmlUpdate->Attribute("version" ); |
59 | const char* type_attr = xmlUpdate->Attribute("type" ); |
60 | const char* url_attr = xmlUpdate->Attribute("url" ); |
61 | const char* uuid_attr = xmlUpdate->Attribute("uuid" ); |
62 | const char* waitdays_attr = xmlUpdate->Attribute("waitdays" ); |
63 | |
64 | if (latest_attr && strcmp(latest_attr, "1" ) == 0) |
65 | m_type = NoUpdate; |
66 | |
67 | if (type_attr) { |
68 | if (strcmp(type_attr, "critical" ) == 0) |
69 | m_type = Critical; |
70 | else if (strcmp(type_attr, "major" ) == 0) |
71 | m_type = Major; |
72 | } |
73 | |
74 | if (version_attr) |
75 | m_version = version_attr; |
76 | |
77 | if (url_attr) |
78 | m_url = url_attr; |
79 | |
80 | if (uuid_attr) |
81 | m_uuid = uuid_attr; |
82 | |
83 | if (waitdays_attr) |
84 | m_waitDays = base::convert_to<double>(std::string(waitdays_attr)); |
85 | } |
86 | |
87 | class CheckUpdate::CheckUpdateImpl |
88 | { |
89 | public: |
90 | CheckUpdateImpl() { } |
91 | ~CheckUpdateImpl() { } |
92 | |
93 | void abort() |
94 | { |
95 | if (m_request) |
96 | m_request->abort(); |
97 | } |
98 | |
99 | bool checkNewVersion(const Uuid& uuid, const std::string& , CheckUpdateDelegate* delegate) |
100 | { |
101 | std::string url = get_app_update_url(); |
102 | if (!uuid.empty()) { |
103 | url += "&uuid=" ; |
104 | url += uuid; |
105 | } |
106 | if (!extraParams.empty()) { |
107 | url += "&" ; |
108 | url += extraParams; |
109 | } |
110 | |
111 | m_request.reset(new net::HttpRequest(url)); |
112 | net::HttpHeaders ; |
113 | headers.setHeader("User-Agent" , getUserAgent()); |
114 | m_request->setHeaders(headers); |
115 | |
116 | std::stringstream body; |
117 | net::HttpResponse response(&body); |
118 | if (m_request->send(response)) { |
119 | TRACE("Checking updates: %s (User-Agent: %s)\n" , url.c_str(), getUserAgent().c_str()); |
120 | TRACE("Response:\n--\n%s--\n" , body.str().c_str()); |
121 | |
122 | CheckUpdateResponse data(body.str()); |
123 | delegate->onResponse(data); |
124 | return true; |
125 | } |
126 | else |
127 | return false; |
128 | } |
129 | |
130 | private: |
131 | std::unique_ptr<net::HttpRequest> m_request; |
132 | }; |
133 | |
134 | CheckUpdate::CheckUpdate() |
135 | : m_impl(new CheckUpdateImpl) |
136 | { |
137 | } |
138 | |
139 | CheckUpdate::~CheckUpdate() |
140 | { |
141 | delete m_impl; |
142 | } |
143 | |
144 | void CheckUpdate::abort() |
145 | { |
146 | m_impl->abort(); |
147 | } |
148 | |
149 | bool CheckUpdate::checkNewVersion(const Uuid& uuid, const std::string& , CheckUpdateDelegate* delegate) |
150 | { |
151 | return m_impl->checkNewVersion(uuid, extraParams, delegate); |
152 | } |
153 | |
154 | } // namespace updater |
155 | |