Reload IV on each open, take hash into account.

Fixes #28111.
This commit is contained in:
John Preston 2024-07-02 10:27:26 +04:00
parent ab20f8eb31
commit ad7d1fddf0
2 changed files with 57 additions and 24 deletions

View file

@ -57,6 +57,7 @@ constexpr auto kGeoPointScale = 1;
constexpr auto kGeoPointZoomMin = 13; constexpr auto kGeoPointZoomMin = 13;
constexpr auto kMaxLoadParts = 5; constexpr auto kMaxLoadParts = 5;
constexpr auto kKeepLoadingParts = 8; constexpr auto kKeepLoadingParts = 8;
constexpr auto kAllowPageReloadAfter = 3 * crl::time(1000);
} // namespace } // namespace
@ -815,19 +816,19 @@ void Instance::show(
} }
break; break;
case Type::OpenPage: case Type::OpenPage:
case Type::OpenLink: case Type::OpenLink: {
if (!urlChecked) { if (!urlChecked) {
break; break;
} }
_fullRequested[_shownSession].emplace(event.url); const auto session = _shownSession;
_shownSession->api().request(MTPmessages_GetWebPage( const auto url = event.url;
MTP_string(event.url), auto &requested = _fullRequested[session][url];
MTP_int(0) requested.lastRequestedAt = crl::now();
session->api().request(MTPmessages_GetWebPage(
MTP_string(url),
MTP_int(requested.hash)
)).done([=](const MTPmessages_WebPage &result) { )).done([=](const MTPmessages_WebPage &result) {
_shownSession->data().processUsers(result.data().vusers()); const auto page = processReceivedPage(session, url, result);
_shownSession->data().processChats(result.data().vchats());
const auto page = _shownSession->data().processWebpage(
result.data().vwebpage());
if (page && page->iv) { if (page && page->iv) {
const auto parts = event.url.split('#'); const auto parts = event.url.split('#');
const auto hash = (parts.size() > 1) ? parts[1] : u""_q; const auto hash = (parts.size() > 1) ? parts[1] : u""_q;
@ -838,7 +839,7 @@ void Instance::show(
}).fail([=] { }).fail([=] {
UrlClickHandler::Open(event.url); UrlClickHandler::Open(event.url);
}).send(); }).send();
break; } break;
case Type::Report: case Type::Report:
if (const auto controller = _shownSession->tryResolveWindow()) { if (const auto controller = _shownSession->tryResolveWindow()) {
controller->window().activate(); controller->window().activate();
@ -954,15 +955,13 @@ void Instance::openWithIvPreferred(
}; };
_ivRequestSession = session; _ivRequestSession = session;
_ivRequestUri = uri; _ivRequestUri = uri;
_fullRequested[session].emplace(url); auto &requested = _fullRequested[session][url];
requested.lastRequestedAt = crl::now();
_ivRequestId = session->api().request(MTPmessages_GetWebPage( _ivRequestId = session->api().request(MTPmessages_GetWebPage(
MTP_string(url), MTP_string(url),
MTP_int(0) MTP_int(requested.hash)
)).done([=](const MTPmessages_WebPage &result) { )).done([=](const MTPmessages_WebPage &result) {
const auto &data = result.data(); finish(processReceivedPage(session, url, result));
session->data().processUsers(data.vusers());
session->data().processChats(data.vchats());
finish(session->data().processWebpage(data.vwebpage()));
}).fail([=] { }).fail([=] {
finish(nullptr); finish(nullptr);
}).send(); }).send();
@ -971,24 +970,47 @@ void Instance::openWithIvPreferred(
void Instance::requestFull( void Instance::requestFull(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const QString &id) { const QString &id) {
if (!_tracking.contains(session) if (!_tracking.contains(session)) {
|| !_fullRequested[session].emplace(id).second) {
return; return;
} }
auto &requested = _fullRequested[session][id];
const auto last = requested.lastRequestedAt;
const auto now = crl::now();
if (last && (now - last) < kAllowPageReloadAfter) {
return;
}
requested.lastRequestedAt = now;
session->api().request(MTPmessages_GetWebPage( session->api().request(MTPmessages_GetWebPage(
MTP_string(id), MTP_string(id),
MTP_int(0) MTP_int(requested.hash)
)).done([=](const MTPmessages_WebPage &result) { )).done([=](const MTPmessages_WebPage &result) {
session->data().processUsers(result.data().vusers()); const auto page = processReceivedPage(session, id, result);
session->data().processChats(result.data().vchats());
const auto page = session->data().processWebpage(
result.data().vwebpage());
if (page && page->iv && _shown && _shownSession == session) { if (page && page->iv && _shown && _shownSession == session) {
_shown->update(page->iv.get()); _shown->update(page->iv.get());
} }
}).send(); }).send();
} }
WebPageData *Instance::processReceivedPage(
not_null<Main::Session*> session,
const QString &url,
const MTPmessages_WebPage &result) {
const auto &data = result.data();
const auto owner = &session->data();
owner->processUsers(data.vusers());
owner->processChats(data.vchats());
auto &requested = _fullRequested[session][url];
const auto &mtp = data.vwebpage();
return mtp.match([&](const MTPDwebPageNotModified &data) {
return requested.page;
}, [&](const MTPDwebPage &data) {
requested.hash = data.vhash().v;
return owner->processWebpage(data).get();
}, [&](const auto &) {
return owner->processWebpage(mtp).get();
});
}
void Instance::processOpenChannel(const QString &context) { void Instance::processOpenChannel(const QString &context) {
if (!_shownSession) { if (!_shownSession) {
return; return;

View file

@ -61,12 +61,23 @@ public:
[[nodiscard]] rpl::lifetime &lifetime(); [[nodiscard]] rpl::lifetime &lifetime();
private: private:
struct FullResult {
crl::time lastRequestedAt = 0;
WebPageData *page = nullptr;
int32 hash = 0;
};
void processOpenChannel(const QString &context); void processOpenChannel(const QString &context);
void processJoinChannel(const QString &context); void processJoinChannel(const QString &context);
void requestFull(not_null<Main::Session*> session, const QString &id); void requestFull(not_null<Main::Session*> session, const QString &id);
void trackSession(not_null<Main::Session*> session); void trackSession(not_null<Main::Session*> session);
WebPageData *processReceivedPage(
not_null<Main::Session*> session,
const QString &url,
const MTPmessages_WebPage &result);
const not_null<Delegate*> _delegate; const not_null<Delegate*> _delegate;
std::unique_ptr<Shown> _shown; std::unique_ptr<Shown> _shown;
@ -77,7 +88,7 @@ private:
base::flat_set<not_null<ChannelData*>>> _joining; base::flat_set<not_null<ChannelData*>>> _joining;
base::flat_map< base::flat_map<
not_null<Main::Session*>, not_null<Main::Session*>,
base::flat_set<QString>> _fullRequested; base::flat_map<QString, FullResult>> _fullRequested;
base::flat_map< base::flat_map<
not_null<Main::Session*>, not_null<Main::Session*>,