Juan Lang : cryptnet: Set cache expiration time of objects that have an expiration time to the object 's expiration time, rather than relying on the HTTP Expires header.

Alexandre Julliard julliard at winehq.org
Wed Oct 8 08:32:40 CDT 2008


Module: wine
Branch: master
Commit: 6b8fb4ed9b1c2a885a6eac5ef7e4c5f9fd8d7ad5
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6b8fb4ed9b1c2a885a6eac5ef7e4c5f9fd8d7ad5

Author: Juan Lang <juan.lang at gmail.com>
Date:   Fri Oct  3 10:51:09 2008 -0700

cryptnet: Set cache expiration time of objects that have an expiration time to the object's expiration time, rather than relying on the HTTP Expires header.

---

 dlls/cryptnet/cryptnet_main.c |  133 +++++++++++++++++++++++++++++++++++++----
 1 files changed, 121 insertions(+), 12 deletions(-)

diff --git a/dlls/cryptnet/cryptnet_main.c b/dlls/cryptnet/cryptnet_main.c
index 3f44aeb..7a79371 100644
--- a/dlls/cryptnet/cryptnet_main.c
+++ b/dlls/cryptnet/cryptnet_main.c
@@ -400,7 +400,6 @@ static BOOL CRYPT_GetObjectFromFile(HANDLE hFile, PCRYPT_BLOB_ARRAY pObject)
     return ret;
 }
 
-/* FIXME: should make wininet cache all downloads instead */
 static BOOL CRYPT_GetObjectFromCache(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject,
  PCRYPT_RETRIEVE_AUX_INFO pAuxInfo)
 {
@@ -605,30 +604,73 @@ static BOOL CRYPT_DownloadObject(DWORD dwRetrievalFlags, HINTERNET hHttp,
     return ret;
 }
 
+/* Finds the object specified by pszURL in the cache.  If it's not found,
+ * creates a new cache entry for the object and writes the object to it.
+ * Sets the expiration time of the cache entry to expires.
+ */
 static void CRYPT_CacheURL(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject,
  DWORD dwRetrievalFlags, FILETIME expires)
 {
     WCHAR cacheFileName[MAX_PATH];
+    DWORD size = 0;
+    BOOL ret, create = FALSE;
 
-    /* FIXME: let wininet directly cache instead */
-    if (CreateUrlCacheEntryW(pszURL, pObject->rgBlob[0].cbData, NULL,
-     cacheFileName, 0))
+    GetUrlCacheEntryInfoW(pszURL, NULL, &size);
+    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
     {
-        HANDLE hCacheFile = CreateFileW(cacheFileName, GENERIC_WRITE, 0, NULL,
-         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+        INTERNET_CACHE_ENTRY_INFOW *info = CryptMemAlloc(size);
 
-        if (hCacheFile != INVALID_HANDLE_VALUE)
+        if (info)
         {
-            DWORD bytesWritten, entryType;
-            FILETIME ft = { 0 };
+            FILETIME ft;
+
+            ret = GetUrlCacheEntryInfoW(pszURL, info, &size);
+            if (ret)
+                lstrcpyW(cacheFileName, info->lpszLocalFileName);
+            /* Check if the existing cache entry is up to date.  If it isn't,
+             * overwite it with the new value.
+             */
+            GetSystemTimeAsFileTime(&ft);
+            if (CompareFileTime(&info->ExpireTime, &ft) < 0)
+                create = TRUE;
+            CryptMemFree(info);
+        }
+        else
+            ret = FALSE;
+    }
+    else
+    {
+        ret = CreateUrlCacheEntryW(pszURL, pObject->rgBlob[0].cbData, NULL,
+         cacheFileName, 0);
+        create = TRUE;
+    }
+    if (ret)
+    {
+        DWORD entryType;
+        FILETIME ft = { 0 };
+
+        if (create)
+        {
+            HANDLE hCacheFile = CreateFileW(cacheFileName, GENERIC_WRITE, 0,
+             NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+            if (hCacheFile != INVALID_HANDLE_VALUE)
+            {
+                DWORD bytesWritten;
 
+                WriteFile(hCacheFile, pObject->rgBlob[0].pbData,
+                 pObject->rgBlob[0].cbData, &bytesWritten, NULL);
+                CloseHandle(hCacheFile);
+            }
+            else
+                ret = FALSE;
+        }
+        if (ret)
+        {
             if (!(dwRetrievalFlags & CRYPT_STICKY_CACHE_RETRIEVAL))
                 entryType = NORMAL_CACHE_ENTRY;
             else
                 entryType = STICKY_CACHE_ENTRY;
-            WriteFile(hCacheFile, pObject->rgBlob[0].pbData,
-             pObject->rgBlob[0].cbData, &bytesWritten, NULL);
-            CloseHandle(hCacheFile);
             CommitUrlCacheEntryW(pszURL, cacheFileName, expires, ft, entryType,
              NULL, 0, NULL, NULL);
         }
@@ -1280,6 +1322,63 @@ static BOOL CRYPT_GetCreateFunction(LPCSTR pszObjectOid,
     return ret;
 }
 
+typedef BOOL (*get_object_expiration_func)(void *pvContext,
+ FILETIME *expiration);
+
+static BOOL CRYPT_GetExpirationFromCert(void *pvObject, FILETIME *expiration)
+{
+    PCCERT_CONTEXT cert = (PCCERT_CONTEXT)pvObject;
+
+    *expiration = cert->pCertInfo->NotAfter;
+    return TRUE;
+}
+
+static BOOL CRYPT_GetExpirationFromCRL(void *pvObject, FILETIME *expiration)
+{
+    PCCRL_CONTEXT cert = (PCCRL_CONTEXT)pvObject;
+
+    *expiration = cert->pCrlInfo->NextUpdate;
+    return TRUE;
+}
+
+static BOOL CRYPT_GetExpirationFromCTL(void *pvObject, FILETIME *expiration)
+{
+    PCCTL_CONTEXT cert = (PCCTL_CONTEXT)pvObject;
+
+    *expiration = cert->pCtlInfo->NextUpdate;
+    return TRUE;
+}
+
+static BOOL CRYPT_GetExpirationFunction(LPCSTR pszObjectOid,
+ get_object_expiration_func *getExpiration)
+{
+    BOOL ret;
+
+    if (!HIWORD(pszObjectOid))
+    {
+        switch (LOWORD(pszObjectOid))
+        {
+        case LOWORD(CONTEXT_OID_CERTIFICATE):
+            *getExpiration = CRYPT_GetExpirationFromCert;
+            ret = TRUE;
+            break;
+        case LOWORD(CONTEXT_OID_CRL):
+            *getExpiration = CRYPT_GetExpirationFromCRL;
+            ret = TRUE;
+            break;
+        case LOWORD(CONTEXT_OID_CTL):
+            *getExpiration = CRYPT_GetExpirationFromCTL;
+            ret = TRUE;
+            break;
+        default:
+            ret = FALSE;
+        }
+    }
+    else
+        ret = FALSE;
+    return ret;
+}
+
 /***********************************************************************
  *    CryptRetrieveObjectByUrlW (CRYPTNET.@)
  */
@@ -1316,7 +1415,17 @@ BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid,
          pAuxInfo);
         if (ret)
         {
+            get_object_expiration_func getExpiration;
+
             ret = create(pszObjectOid, dwRetrievalFlags, &object, ppvObject);
+            if (ret && !(dwRetrievalFlags & CRYPT_DONT_CACHE_RESULT) &&
+             CRYPT_GetExpirationFunction(pszObjectOid, &getExpiration))
+            {
+                FILETIME expires;
+
+                if (getExpiration(*ppvObject, &expires))
+                    CRYPT_CacheURL(pszURL, &object, dwRetrievalFlags, expires);
+            }
             freeObject(pszObjectOid, &object, freeContext);
         }
     }




More information about the wine-cvs mailing list