| 83 | } |
| 84 | |
| 85 | auto HttpMetaCache::resolveEntry(QString base, QString resource_path, QString expected_etag) -> MetaEntryPtr |
| 86 | { |
| 87 | resource_path = FS::RemoveInvalidPathChars(resource_path); |
| 88 | auto entry = getEntry(base, resource_path); |
| 89 | // it's not present? generate a default stale entry |
| 90 | if (!entry) { |
| 91 | return staleEntry(base, resource_path); |
| 92 | } |
| 93 | |
| 94 | auto& selected_base = m_entries[base]; |
| 95 | QString real_path = FS::PathCombine(selected_base.base_path, resource_path); |
| 96 | QFileInfo finfo(real_path); |
| 97 | |
| 98 | // is the file really there? if not -> stale |
| 99 | if (!finfo.isFile() || !finfo.isReadable()) { |
| 100 | // if the file doesn't exist, we disown the entry |
| 101 | selected_base.entry_list.remove(resource_path); |
| 102 | return staleEntry(base, resource_path); |
| 103 | } |
| 104 | |
| 105 | if (!expected_etag.isEmpty() && expected_etag != entry->m_etag) { |
| 106 | // if the etag doesn't match expected, we disown the entry |
| 107 | selected_base.entry_list.remove(resource_path); |
| 108 | return staleEntry(base, resource_path); |
| 109 | } |
| 110 | |
| 111 | // if the file changed, check md5sum |
| 112 | qint64 file_last_changed = finfo.lastModified().toUTC().toMSecsSinceEpoch(); |
| 113 | if (file_last_changed != entry->m_local_changed_timestamp) { |
| 114 | QFile input(real_path); |
| 115 | input.open(QIODevice::ReadOnly); |
| 116 | QString md5sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Md5).toHex().constData(); |
| 117 | if (entry->m_md5sum != md5sum) { |
| 118 | selected_base.entry_list.remove(resource_path); |
| 119 | return staleEntry(base, resource_path); |
| 120 | } |
| 121 | |
| 122 | // md5sums matched... keep entry and save the new state to file |
| 123 | entry->m_local_changed_timestamp = file_last_changed; |
| 124 | SaveEventually(); |
| 125 | } |
| 126 | |
| 127 | // Get rid of old entries, to prevent cache problems |
| 128 | auto current_time = QDateTime::currentSecsSinceEpoch(); |
| 129 | if (entry->isExpired(current_time - (file_last_changed / 1000))) { |
| 130 | qCWarning(taskNetLogC) << "[HttpMetaCache]" |
| 131 | << "Removing cache entry because of old age!"; |
| 132 | selected_base.entry_list.remove(resource_path); |
| 133 | return staleEntry(base, resource_path); |
| 134 | } |
| 135 | |
| 136 | // entry passed all the checks we cared about. |
| 137 | entry->m_basePath = getBasePath(base); |
| 138 | return entry; |
| 139 | } |
| 140 | |
| 141 | auto HttpMetaCache::updateEntry(MetaEntryPtr stale_entry) -> bool |
| 142 | { |
no test coverage detected