@@ -232,12 +232,18 @@ try_init_from_cache(Request *req)
232232 HINTERNET hUrl ;
233233 SYSTEMTIME modifiedTimeSys ;
234234 FILETIME modifiedTimeFile ;
235+ DWORD contentLength ;
235236 bool success ;
237+ bool deleteCache ;
236238
237239 success = false;
240+ deleteCache = false;
238241 hUrl = NULL ;
239242 lenlen = sizeof (INTERNET_CACHE_ENTRY_INFOA ) + MAX_URL_LENGTH + MAX_PATH ;
240243 cacheData = malloc (lenlen );
244+
245+ logmsg ("Checking cache for %s\n" , req -> url );
246+
241247retry :
242248 if (!RetrieveUrlCacheEntryFileA (req -> url , cacheData , & lenlen , 0 )) {
243249 err = GetLastError ();
@@ -251,30 +257,55 @@ try_init_from_cache(Request *req)
251257 goto cleanup ;
252258 }
253259
254- /* If we have internet, check the last modified time of the resource. If it's newer than what we have cached, bail. */
255260 hUrl = InternetOpenUrlA (hInternet , req -> url , NULL , 0 ,
256261 INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE , (DWORD_PTR )NULL );
257- lenlen = sizeof (modifiedTimeSys );
258- if (hUrl != NULL
259- && HttpQueryInfoA (hUrl , HTTP_QUERY_FLAG_SYSTEMTIME | HTTP_QUERY_LAST_MODIFIED , & modifiedTimeSys , & lenlen , 0 )
260- && SystemTimeToFileTime (& modifiedTimeSys , & modifiedTimeFile )
261- && CompareFileTime (& modifiedTimeFile , & cacheData -> LastModifiedTime ) == 1 ) {
262- goto cleanup ;
262+
263+ /* If we have internet, check the validity of the cached file. */
264+ if (hUrl != NULL ) {
265+ /* If the remote file is newer than what we have cached, bail. */
266+ lenlen = sizeof (modifiedTimeSys );
267+ if (HttpQueryInfoA (hUrl , HTTP_QUERY_FLAG_SYSTEMTIME | HTTP_QUERY_LAST_MODIFIED , & modifiedTimeSys , & lenlen , 0 )
268+ && SystemTimeToFileTime (& modifiedTimeSys , & modifiedTimeFile )
269+ && CompareFileTime (& modifiedTimeFile , & cacheData -> LastModifiedTime ) == 1 ) {
270+ goto cleanup ;
271+ }
263272 }
264273
265274 hFile = CreateFileA (cacheData -> lpszLocalFileName , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
266275 if (hFile == INVALID_HANDLE_VALUE ) {
267276 goto cleanup ;
268277 }
269278
279+ /* Compare actual file size on disk against Content-Length to catch truncation. */
280+ if (hUrl != NULL ) {
281+ DWORD fileSize = GetFileSize (hFile , NULL );
282+ lenlen = sizeof (contentLength );
283+ if (fileSize != INVALID_FILE_SIZE
284+ && HttpQueryInfoA (hUrl , HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_CONTENT_LENGTH , & contentLength , & lenlen , 0 )
285+ && fileSize != contentLength ) {
286+ logmsg ("Cache file size mismatch for %s: on disk %d, expected %d\n" ,
287+ req -> url , fileSize , contentLength );
288+ CloseHandle (hFile );
289+ deleteCache = true;
290+ goto cleanup ;
291+ }
292+ }
293+
270294 req -> handles .hFile = hFile ;
271295 req -> source = REQ_SRC_CACHE ;
272296 req -> sizeHint = cacheData -> dwSizeLow ;
273297 success = true;
274298
299+ logmsg ("Initialized from cache: %s\n" , req -> url );
300+ logmsg (" Cache file: %s\n" , cacheData -> lpszLocalFileName );
301+
275302cleanup :
276303 if (!success ) {
277304 UnlockUrlCacheEntryFileA (req -> url , 0 );
305+ if (deleteCache ) {
306+ DeleteUrlCacheEntryA (req -> url );
307+ logmsg ("Deleted cache entry for %s\n" , req -> url );
308+ }
278309 }
279310 if (hUrl != NULL ) {
280311 InternetCloseHandle (hUrl );
0 commit comments