캐싱(Windows 인터넷)

WinINet 함수에는 단순하면서도 유연한 기본 제공 캐싱 지원이 있습니다. 네트워크에서 검색된 모든 데이터는 하드 디스크에 캐시되고 후속 요청에 대해 검색됩니다. 애플리케이션은 각 요청에 대한 캐싱을 제어할 수 있습니다. 서버에서 http 요청의 경우 수신된 대부분의 헤더도 캐시됩니다. 캐시에서 http 요청이 충족되면 캐시된 헤더도 호출자에게 반환됩니다. 이렇게 하면 데이터가 캐시에서 오든 네트워크에서 오는지 여부에 관계없이 데이터를 원활하게 다운로드할 수 있습니다.

애플리케이션은 영구 URL 캐싱 함수를 사용할 때 원하는 결과를 얻으려면 버퍼를 올바르게 할당해야 합니다. 자세한 내용은 버퍼 사용을 참조하세요.

응답 처리 중 캐시 동작

WinINet 캐시는 RFC 2616에 설명된 HTTP 캐시 제어 지시문을 준수합니다. 캐시 제어 지시문 및 애플리케이션 집합 플래그는 캐시할 수 있는 내용을 결정합니다. 그러나 WinINet은 다음 기준에 따라 실제로 캐시되는 항목을 결정합니다.

  • WinINet은 HTTP 및 FTP 응답만 캐시합니다.
  • 잘 동작하는 응답만 캐시에 의해 저장되고 후속 요청에 대한 회신에 사용될 수 있습니다. 잘 작동하는 응답은 성공적으로 반환되는 응답으로 정의됩니다.
  • 기본적으로 WinINet은 서버의 캐시 제어 지시문 또는 애플리케이션 정의 플래그가 응답이 캐시되지 않을 수 있음을 구체적으로 나타내지 않는 한 성공적인 응답을 캐시합니다.
  • 일반적으로 위에 나열된 요구 사항이 충족되면 GET 동사에 대한 응답이 캐시됩니다. PUT 및 POST 동사에 대한 응답은 어떤 상황에서도 캐시되지 않습니다.
  • 캐시가 가득 찬 경우에도 항목이 캐시됩니다. 추가된 항목이 캐시를 크기 제한을 초과하면 캐시 청소부가 예약됩니다. 기본적으로 항목은 캐시에 10분 이상 유지되도록 보장되지 않습니다. 자세한 내용은 아래 캐시 청소기 섹션을 참조하세요.
  • Https는 기본적으로 캐시됩니다. 애플리케이션 정의 캐시 지시문으로 재정의할 수 없는 전역 설정에 의해 관리됩니다. 전역 설정을 재정의하려면 제어판에서 인터넷 옵션 애플릿을 선택하고 고급 탭으로 이동합니다. "보안" 섹션에서 "암호화된 페이지를 디스크에 저장하지 마세요" 상자를 선택합니다.

캐시 청소기

캐시 청소기에서는 캐시에서 항목을 주기적으로 정리합니다. 항목이 캐시에 추가되고 캐시가 가득 차면 항목이 캐시에 추가되고 캐시 청소부가 예약됩니다. 캐시 청소기에서 한 라운드의 청소를 완료하고 캐시가 캐시 제한에 도달하지 않으면 다른 항목이 캐시에 추가될 때 다른 라운드가 예약됩니다. 일반적으로 추가된 항목이 캐시의 크기 제한을 초과하면 청소기는 예약됩니다. 기본적으로 캐시 제어 지시문에 달리 지정하지 않는 한 캐시에서의 최소 사용 시간은 10분으로 설정됩니다. 캐시 청소기를 시작하면 가장 오래된 항목이 캐시에서 가장 먼저 삭제된다는 보장은 없습니다.

캐시는 동일한 사용자에 대해 컴퓨터의 모든 WinINet 애플리케이션에서 공유됩니다. Windows Vista 및 Windows Server 2008부터 캐시 크기는 디스크 크기 1/32로 설정되며 최소 크기는 8MB, 최대 크기는 50MB입니다.

플래그를 사용하여 캐싱 제어

캐싱 플래그를 사용하면 애플리케이션이 캐시를 사용하는 시기와 방법을 제어할 수 있습니다. 이러한 플래그는 인터넷의 정보 또는 리소스에 액세스하는 함수에서 dwFlags 매개 변수와 함께 단독으로 또는 함께 사용할 수 있습니다. 기본적으로 함수는 인터넷에서 다운로드한 모든 데이터를 저장합니다.

다음 플래그를 사용하여 캐싱을 제어할 수 있습니다.

의미
INTERNET_FLAG_CACHE_ASYNC 이 플래그는 아무런 영향을 주지 않습니다.
INTERNET_FLAG_CACHE_IF_NET_FAIL ERROR_INTERNET_CONNECTION_RESET 또는ERROR_INTERNET_CANNOT_CONNECT 오류로 인해 리소스에 대한 네트워크 요청이 실패하면 캐시에서 리소스를 반환합니다. 이 플래그는 HttpOpenRequest에서 사용됩니다.
INTERNET_FLAG_DONT_CACHE 로컬 또는 게이트웨이에서 데이터를 캐시하지 않습니다. 기본 설정 값과 동일 하며 INTERNET_FLAG_NO_CACHE_WRITE.
양식 제출임을 나타냅니다.
INTERNET_FLAG_FROM_CACHEINTERNET_FLAG_FORMS_SUBMIT 네트워크 요청을 수행하지 않습니다. 모든 엔터티는 캐시에서 반환됩니다. 요청된 항목이 캐시에 없으면 ERROR_FILE_NOT_FOUND 같은 적절한 오류가 반환됩니다. InternetOpen 함수만 이 플래그를 사용합니다.
INTERNET_FLAG_FWD_BACK 함수가 현재 인터넷 캐시에 있는 리소스의 복사본을 사용해야 했음을 나타냅니다. 만료 날짜 및 리소스에 대한 기타 정보는 확인되지 않습니다. 요청된 항목이 인터넷 캐시에 없으면 시스템에서 네트워크에서 리소스를 찾으려고 시도합니다. 이 값은 Microsoft Internet Explorer 5에서 도입되었으며 인터넷 Explorer 앞으로뒤로 단추 작업과 연결됩니다.
INTERNET_FLAG_HYPERLINK 만료 시간이 없고 리소스가 캐시에 저장되었을 때 마지막으로 수정한 시간이 반환되지 않은 경우 애플리케이션이 리소스를 다시 로드하도록 합니다.
INTERNET_FLAG_MAKE_PERSISTENT 더 이상 지원되지 않습니다.
INTERNET_FLAG_MUST_CACHE_REQUEST 파일을 캐시할 수 없는 경우 임시 파일을 만듭니다. 이는 기본 설정 값인 INTERNET_FLAG_NEED_FILE 동일합니다.
INTERNET_FLAG_NEED_FILE 파일을 캐시할 수 없는 경우 임시 파일을 만듭니다.
INTERNET_FLAG_NO_CACHE_WRITE 캐시에 인터넷에서 다운로드한 데이터를 저장하려는 함수의 시도를 거부합니다. 이 플래그는 애플리케이션에서 다운로드한 리소스를 로컬로 저장하지 않으려는 경우에 필요합니다.
INTERNET_FLAG_NO_UI 쿠키 대화 상자를 사용하지 않도록 설정합니다. 이 플래그는 HttpOpenRequestInternetOpenUrl (HTTP 요청만 해당)에서 사용할 수 있습니다.
INTERNET_FLAG_OFFLINE 애플리케이션이 네트워크에 요청을 보내지 못하도록 합니다. 모든 요청은 캐시에 저장된 리소스를 사용하여 확인됩니다. 리소스가 캐시에 없으면 ERROR_FILE_NOT_FOUND 같은 적절한 오류가 반환됩니다.
INTERNET_FLAG_PRAGMA_NOCACHE 프록시에 캐시된 복사본이 있는 경우에도 원본 서버에서 요청을 강제로 확인합니다. InternetOpenUrl 함수(HTTP 및 HTTPS 요청에만 해당) 및 HttpOpenRequest 함수는 이 플래그를 사용합니다.
INTERNET_FLAG_RELOAD 함수가 인터넷에서 직접 요청된 리소스를 검색하도록 합니다. 다운로드되는 정보는 캐시에 저장됩니다.
INTERNET_FLAG_RESYNCHRONIZE 애플리케이션이 인터넷에서 리소스의 조건부 다운로드를 수행하도록 합니다. 캐시에 저장된 버전이 현재인 경우 캐시에서 정보가 다운로드됩니다. 그렇지 않으면 서버에서 정보가 다시 로드됩니다.

 

영구 캐싱 함수

영구 캐싱 서비스가 필요한 클라이언트는 영구 캐싱 함수를 사용하여 낮은 대역폭 링크가 데이터에 대한 액세스를 제한하거나 액세스를 전혀 사용할 수 없는 경우와 같이 애플리케이션이 후속 사용을 위해 로컬 파일 시스템에 데이터를 저장할 수 있도록 합니다.

캐시 함수는 영구 캐싱 및 오프라인 검색을 제공합니다. INTERNET_FLAG_NO_CACHE_WRITE 플래그가 명시적으로 캐싱을 지정하지 않는 한 함수는 네트워크에서 다운로드한 모든 데이터를 캐시합니다. POST 데이터에 대한 응답은 캐시되지 않습니다.

영구 URL 캐시 함수 사용

다음 영구 URL 캐시 함수를 사용하면 애플리케이션이 캐시에 저장된 정보에 액세스하고 조작할 수 있습니다.

함수 설명
CommitUrlCacheEntryA 캐시 스토리지에서 지정된 파일의 데이터를 캐시하고 지정된 URL에 연결합니다.
CommitUrlCacheEntryW 캐시 스토리지에서 지정된 파일의 데이터를 캐시하고 지정된 URL에 연결합니다.
CreateUrlCacheEntry 요청된 캐시 스토리지를 할당하고 원본 이름에 해당하는 캐시 항목을 저장하기 위한 로컬 파일 이름을 만듭니다.
CreateUrlCacheGroup 캐시 그룹 ID를 생성합니다.
DeleteUrlCacheEntry 파일이 있는 경우 캐시에서 원본 이름과 연결된 파일을 제거합니다.
DeleteUrlCacheGroup GROUPID 및 캐시 인덱스 파일의 연결된 상태를 해제합니다.
FindCloseUrlCache 지정된 열거형 핸들을 닫습니다.
FindFirstUrlCacheEntry 캐시의 열거형을 시작합니다.
FindFirstUrlCacheEntryEx 캐시의 필터링된 열거형을 시작합니다.
FindNextUrlCacheEntry 캐시의 다음 항목을 검색합니다.
FindNextUrlCacheEntryEx 필터링된 캐시 열거형에서 다음 항목을 검색합니다.
GetUrlCacheEntryInfo 캐시 항목에 대한 정보를 검색합니다.
GetUrlCacheEntryInfoEx HttpSendRequest에서 오프라인 모드로 적용할 캐시된 리디렉션을 변환한 후 URL을 검색합니다.
ReadUrlCacheEntryStream RetrieveUrlCacheEntryStream을 사용하여 열린 스트림에서 캐시된 데이터를 읽습니다.
RetrieveUrlCacheEntryFile 파일 형식으로 캐시에서 캐시 항목을 검색합니다.
RetrieveUrlCacheEntryStream 캐시 데이터에 액세스하는 가장 효율적이고 구현 독립적인 방법을 제공합니다.
SetUrlCacheEntryGroup 캐시 그룹에서 항목을 추가하거나 제거합니다.
SetUrlCacheEntryInfo INTERNET_CACHE_ENTRY_INFO 구조체의 지정된 멤버를 설정합니다.
UnlockUrlCacheEntryFile RetrieveUrlCacheEntryFile에서 캐시에서 사용하기 위해 파일을 검색할 때 잠긴 캐시 항목의 잠금을 해제합니다.
UnlockUrlCacheEntryStream RetrieveUrlCacheEntryStream을 사용하여 검색된 스트림을 닫습니다.

 

캐시 열거

FindFirstUrlCacheEntryFindNextUrlCacheEntry 함수는 캐시에 저장된 정보를 열거합니다. FindFirstUrlCacheEntry 는 검색 패턴, 버퍼 및 버퍼 크기를 사용하여 핸들을 만들고 첫 번째 캐시 항목을 반환하여 열거형을 시작합니다. FindNextUrlCacheEntryFindFirstUrlCacheEntry, 버퍼 및 버퍼 크기로 만든 핸들을 사용하여 다음 캐시 항목을 반환합니다.

두 함수 모두 버퍼에 INTERNET_CACHE_ENTRY_INFO 구조를 저장합니다. 이 구조체의 크기는 각 항목에 따라 다릅니다. 두 함수에 전달된 버퍼 크기가 충분하지 않으면 함수가 실패하고 GetLastError 가 ERROR_INSUFFICIENT_BUFFER 반환합니다. 버퍼 크기 변수에는 해당 캐시 항목을 검색하는 데 필요한 버퍼 크기가 포함됩니다. 버퍼 크기 변수로 표시된 크기의 버퍼를 할당해야 하며 새 버퍼를 사용하여 함수를 다시 호출해야 합니다.

INTERNET_CACHE_ENTRY_INFO 구조체에는 구조 크기, 캐시된 정보의 URL, 로컬 파일 이름, 캐시 입력 유형, 사용 횟수, 적중률, 크기, 마지막 수정 시간, 만료, 마지막 액세스, 마지막 동기화 시간, 헤더 정보, 헤더 정보 크기 및 파일 이름 확장명을 포함합니다.

FindFirstUrlCacheEntry 함수는 검색 패턴, INTERNET_CACHE_ENTRY_INFO 구조를 저장하는 버퍼 및 버퍼 크기를 사용합니다. 현재 모든 캐시 항목을 반환하는 기본 검색 패턴만 구현됩니다.

캐시가 열거되면 애플리케이션은 FindCloseUrlCache 를 호출하여 캐시 열거형 핸들을 닫아야 합니다.

다음 예제에서는 목록 상자에 각 캐시 항목의 URL을 IDC_CacheList 표시합니다. 초기 버전의 WinINet API가 캐시를 제대로 열거하지 않으므로 MAX_CACHE_ENTRY_INFO_SIZE 사용하여 버퍼를 처음 할당합니다. 이후 버전에서는 캐시를 제대로 열거하며 캐시 크기 제한은 없습니다. 인터넷 Explorer 4.0의 WinINet API 버전이 있는 컴퓨터에서 실행되는 모든 애플리케이션은 필요한 크기의 버퍼를 할당해야 합니다. 자세한 내용은 버퍼 사용을 참조하세요.

int WINAPI EnumerateCacheOld(HWND hX)
{
    DWORD dwEntrySize;
    LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry;
    DWORD MAX_CACHE_ENTRY_INFO_SIZE = 4096;
    HANDLE hCacheDir;
    int nCount=0;

    SendDlgItemMessage(hX,IDC_CacheList,LB_RESETCONTENT,0,0);
    
    SetCursor(LoadCursor(NULL,IDC_WAIT));

    dwEntrySize = MAX_CACHE_ENTRY_INFO_SIZE;
    lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize];
    lpCacheEntry->dwStructSize = dwEntrySize;

again:

    hCacheDir = FindFirstUrlCacheEntry(NULL,
                                       lpCacheEntry,
                                       &dwEntrySize);
    if (!hCacheDir)                                             
    {
        delete[]lpCacheEntry;
        switch(GetLastError())
        {
            case ERROR_NO_MORE_ITEMS: 
                TCHAR tempout[80];
                _stprintf_s(tempout, 
                            80,   
                            TEXT("The number of cache entries = %d \n"),
                            nCount);
                MessageBox(hX,tempout,TEXT("Cache Enumeration"),MB_OK);
                FindCloseUrlCache(hCacheDir);
                SetCursor(LoadCursor(NULL,IDC_ARROW));
                return TRUE;
                break;
            case ERROR_INSUFFICIENT_BUFFER:
                lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) 
                                new char[dwEntrySize];
                lpCacheEntry->dwStructSize = dwEntrySize;
                goto again;
                break;
            default:
                ErrorOut( hX,GetLastError(),
                          TEXT("FindNextUrlCacheEntry Init"));
                FindCloseUrlCache(hCacheDir);
                SetCursor(LoadCursor(NULL,IDC_ARROW));
                return FALSE;
        }
    }

    SendDlgItemMessage(hX,IDC_CacheList,LB_ADDSTRING,
                       0,(LPARAM)(lpCacheEntry->lpszSourceUrlName));
    nCount++;
    delete (lpCacheEntry);

    do 
    {
        dwEntrySize = MAX_CACHE_ENTRY_INFO_SIZE;
        lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize];
        lpCacheEntry->dwStructSize = dwEntrySize;

retry:
        if (!FindNextUrlCacheEntry(hCacheDir,
                                   lpCacheEntry, 
                                   &dwEntrySize))
        {
            delete[]lpCacheEntry;
            switch(GetLastError())
            {
                case ERROR_NO_MORE_ITEMS: 
                    TCHAR tempout[80];
                    _stprintf_s(tempout,
                                80,
                                TEXT("The number of cache entries = %d \n"),nCount);
                    MessageBox(hX,
                               tempout,
                               TEXT("Cache Enumeration"),MB_OK);
                    FindCloseUrlCache(hCacheDir);
                    return TRUE;
                    break;
                case ERROR_INSUFFICIENT_BUFFER:
                    lpCacheEntry = 
                             (LPINTERNET_CACHE_ENTRY_INFO) 
                              new char[dwEntrySize];
                    lpCacheEntry->dwStructSize = dwEntrySize;
                    goto retry;
                    break;
                default:
                    ErrorOut(hX,
                             GetLastError(),
                             TEXT("FindNextUrlCacheEntry Init"));
                    FindCloseUrlCache(hCacheDir);
                    return FALSE;
            }
        }

        SendDlgItemMessage(hX,
                           IDC_CacheList,LB_ADDSTRING,
                           0,
                          (LPARAM)(lpCacheEntry->lpszSourceUrlName));
        nCount++;
        delete[] lpCacheEntry;        
    }  while (TRUE);

    SetCursor(LoadCursor(NULL,IDC_ARROW));
    return TRUE;        
}

캐시 항목 정보 검색

GetUrlCacheEntryInfo 함수를 사용하면 지정된 URL에 대한 INTERNET_CACHE_ENTRY_INFO 구조를 검색할 수 있습니다. 이 구조체에는 구조체 크기, 캐시된 정보의 URL, 로컬 파일 이름, 캐시 입력 유형, 사용 횟수, 적중률, 크기, 마지막으로 수정한 시간, 만료, 마지막 액세스, 마지막 동기화 시간, 헤더 정보, 헤더 정보 크기 및 파일 이름 확장명 등이 포함됩니다.

GetUrlCacheEntryInfo 는 URL, INTERNET_CACHE_ENTRY_INFO 구조에 대한 버퍼 및 버퍼 크기를 허용합니다. URL이 발견되면 정보가 버퍼에 복사됩니다. 그렇지 않으면 함수가 실패하고 GetLastError가 ERROR_FILE_NOT_FOUND 반환합니다. 버퍼 크기가 캐시 항목 정보를 저장하기에 충분하지 않으면 함수가 실패하고 GetLastError가 ERROR_INSUFFICIENT_BUFFER 반환합니다. 정보를 검색하는 데 필요한 크기는 버퍼 크기 변수에 저장됩니다.

GetUrlCacheEntryInfo 는 URL 구문 분석을 수행하지 않으므로 리소스가 캐시되더라도 앵커(#)가 포함된 URL을 캐시에 찾을 수 없습니다. 예를 들어 URL "https://example.com/example.htm#sample" 가 전달되고 ERROR_FILE_NOT_FOUND 함수는 "https://example.com/example.htm" 는 캐시에 있습니다.

다음 예제에서는 지정된 URL에 대한 캐시 항목 정보를 검색합니다. 그런 다음 함수는 IDC_CacheDump 편집 상자에 헤더 정보를 표시합니다.

int WINAPI GetCacheEntryInfo(HWND hX,LPTSTR lpszUrl)
{
    DWORD dwEntrySize=0;
    LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry;

    SetCursor(LoadCursor(NULL,IDC_WAIT));
    if (!GetUrlCacheEntryInfo(lpszUrl,NULL,&dwEntrySize))
    {
        if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
        {
            ErrorOut(hX,GetLastError(),TEXT("GetUrlCacheEntryInfo"));
            SetCursor(LoadCursor(NULL,IDC_ARROW));
            return FALSE;
        }
        else
            lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) 
                            new char[dwEntrySize];
    }
    else
        return FALSE; // should not be successful w/ NULL buffer
                      // and 0 size

    if (!GetUrlCacheEntryInfo(lpszUrl,lpCacheEntry,&dwEntrySize))
    {
        ErrorOut(hX,GetLastError(),TEXT("GetUrlCacheEntryInfo"));
        SetCursor(LoadCursor(NULL,IDC_ARROW));
        return FALSE;
    }
    else
    {
        if ((lpCacheEntry->dwHeaderInfoSize)!=0)
        {
            LPSTR(lpCacheEntry->lpHeaderInfo)
                                [lpCacheEntry->dwHeaderInfoSize]=TEXT('\0');
            SetDlgItemText(hX,IDC_Headers,
                           lpCacheEntry->lpHeaderInfo);
        }
        else
        {
            SetDlgItemText(hX,IDC_Headers,TEXT("None"));
        }

        SetCursor(LoadCursor(NULL,IDC_ARROW));
        return TRUE;
    }
        
}

캐시 항목 만들기

애플리케이션은 CreateUrlCacheEntryCommitUrlCacheEntry 함수를 사용하여 캐시 항목을 만듭니다.

CreateUrlCacheEntry 는 URL, 예상 파일 크기 및 파일 이름 확장명을 허용합니다. 그런 다음 함수는 URL 및 파일 이름 확장명 에 해당하는 캐시 항목을 저장하기 위한 로컬 파일 이름을 만듭니다.

로컬 파일 이름을 사용하여 로컬 파일에 데이터를 씁니다. 데이터가 로컬 파일에 기록된 후 애플리케이션은 CommitUrlCacheEntry를 호출해야 합니다.

CommitUrlCacheEntry 는 URL, 로컬 파일 이름, 만료, 마지막 수정 시간, 캐시 입력 유형, 헤더 정보, 헤더 정보 크기 및 파일 이름 확장명을 허용합니다. 그런 다음, 함수는 캐시 스토리지에 지정된 파일의 데이터를 캐시하고 지정된 URL에 연결합니다.

다음 예제에서는 IDC_LocalFile 텍스트 상자에 저장된 CreateUrlCacheEntry에 대한 이전 호출로 만든 로컬 파일 이름을 사용하여 IDC_CacheDump 텍스트 상자의 텍스트를 캐시 항목에 저장합니다. fopen, fprintffclose를 사용하여 파일에 데이터를 쓴 후에는 CommitUrlCacheEntry를 사용하여 항목이 커밋됩니다.

int WINAPI CommitEntry(HWND hX)
{
    LPTSTR lpszUrl, lpszExt, lpszFileName;
    LPTSTR lpszData,lpszSize;
    DWORD dwSize;
    DWORD dwEntryType=0;
    FILE *lpfCacheEntry;
    LPFILETIME lpdtmExpire, lpdtmLastModified;
    LPSYSTEMTIME lpdtmSysTime;
    errno_t err;

    if( SendDlgItemMessage(hX,IDC_RBNormal,BM_GETCHECK,0,0) )
    {
        dwEntryType = dwEntryType + NORMAL_CACHE_ENTRY;
    }
    else if( SendDlgItemMessage(hX,IDC_RBSticky, BM_GETCHECK,0,0) )
    {
        dwEntryType = dwEntryType + STICKY_CACHE_ENTRY;
    }
    else if(SendDlgItemMessage( hX,IDC_RBSparse, BM_GETCHECK,0,0) )
    {
        dwEntryType = dwEntryType + SPARSE_CACHE_ENTRY;
    }
 

    if( SendDlgItemMessage(hX,IDC_RBCookie, BM_GETCHECK,0,0))
    {
            dwEntryType = dwEntryType + COOKIE_CACHE_ENTRY;
    }
    else if( SendDlgItemMessage(hX,IDC_RBUrl, BM_GETCHECK,0,0) )
    {
        dwEntryType = dwEntryType + URLHISTORY_CACHE_ENTRY;
    }


    if( SendDlgItemMessage(hX,IDC_RBNone, BM_GETCHECK,0,0) )
    {
        dwEntryType=0;
    }
        
    lpdtmSysTime = new SYSTEMTIME;
    lpdtmExpire = new FILETIME;
    lpdtmLastModified = new FILETIME;

    GetLocalTime(lpdtmSysTime);
    SystemTimeToFileTime(lpdtmSysTime,lpdtmExpire);
    SystemTimeToFileTime(lpdtmSysTime,lpdtmLastModified);
    delete(lpdtmSysTime);

    lpszUrl = new TCHAR[MAX_PATH];
    lpszFileName = new TCHAR[MAX_PATH];
    lpszExt = new TCHAR[5];
    lpszSize = new TCHAR[10];

    GetDlgItemText(hX,IDC_SourceURL,lpszUrl,MAX_PATH);
    GetDlgItemText(hX,IDC_LocalFile,lpszFileName,MAX_PATH);
    GetDlgItemText(hX,IDC_FileExt,lpszExt,5);

    GetDlgItemText(hX,IDC_SizeLow,lpszSize,10);
    dwSize = (DWORD)_ttol(lpszSize);
    delete(lpszSize);

    if (dwSize==0)
    {
        if((MessageBox(hX,
                       TEXT("Incorrect File Size.\nUsing 8000 characters, Okay?\n"),
                       TEXT("Commit Entry"),MB_YESNO))
                        ==IDYES)
        {
            dwSize = 8000;
        }
        else
        {
            return FALSE;
        }
    }

    lpszData = new TCHAR[dwSize];
    GetDlgItemText(hX,IDC_CacheDump,lpszData,dwSize);
        
     err = _tfopen_s(&lpfCacheEntry,lpszFileName,_T("w"));
     if (err)
        return FALSE;
    fprintf(lpfCacheEntry,"%s",lpszData);
    fclose(lpfCacheEntry);
    delete(lpszData);

    if ( !CommitUrlCacheEntry( lpszUrl, 
                               lpszFileName, 
                               *lpdtmExpire,
                               *lpdtmLastModified, 
                               dwEntryType,
                               NULL,
                               0,
                               lpszExt,
                               0) )
    {
        ErrorOut(hX,GetLastError(),TEXT("Commit Cache Entry"));
        delete(lpszUrl);
        delete(lpszFileName);
        delete(lpszExt);
        delete(lpdtmExpire);
        delete(lpdtmLastModified);
        return FALSE;
    }
    else
    {
        delete(lpszUrl);
        delete(lpszFileName);
        delete(lpszExt);
        delete(lpdtmExpire);
        delete(lpdtmLastModified);
        return TRUE;
    }
}

캐시 항목 삭제

DeleteUrlCacheEntry 함수는 URL을 사용하고 연결된 캐시 파일을 제거합니다. 캐시 파일이 없으면 함수가 실패하고 GetLastError가 ERROR_FILE_NOT_FOUND 반환합니다. 캐시 파일이 현재 잠겨 있거나 사용 중인 경우 함수가 실패하고 GetLastError 가 ERROR_ACCESS_DENIED 반환합니다. 잠금 해제 시 파일이 삭제됩니다.

캐시 항목 파일 검색

리소스의 파일 이름이 필요한 애플리케이션의 경우 RetrieveUrlCacheEntryFileUnlockUrlCacheEntryFile 함수를 사용합니다. 파일 이름이 필요하지 않은 애플리케이션은 RetrieveUrlCacheEntryStream, ReadUrlCacheEntryStream 및 UnlockUrlCacheEntryStream 함수를 사용하여 캐시의 정보를 검색해야 합니다.

RetrieveUrlCacheEntryStream 은 URL 구문 분석을 수행하지 않으므로 리소스가 캐시되더라도 앵커(#)가 포함된 URL을 캐시에 찾을 수 없습니다. 예를 들어 URL "https://example.com/example.htm#sample" 가 전달되고 ERROR_FILE_NOT_FOUND 함수는 "https://example.com/example.htm" 는 캐시에 있습니다.

RetrieveUrlCacheEntryFile 은 URL, INTERNET_CACHE_ENTRY_INFO 구조를 저장하는 버퍼 및 버퍼 크기를 허용합니다. 함수가 검색되고 호출자에 대해 잠깁니다.

파일의 정보를 사용한 후 애플리케이션은 UnlockUrlCacheEntryFile 을 호출하여 파일의 잠금을 해제해야 합니다.

캐시 그룹

캐시 그룹을 만들려면 캐시 그룹에 대한 GROUPID를 생성하려면 CreateUrlCacheGroup 함수를 호출해야 합니다. SetUrlCacheEntryGroup 함수에 캐시 항목의 URL 및 INTERNET_CACHE_GROUP_ADD 플래그를 제공하여 항목을 캐시 그룹에 추가할 수 있습니다. 그룹에서 캐시 항목을 제거하려면 캐시 항목의 URL과 INTERNET_CACHE_GROUP_REMOVE 플래그를 SetUrlCacheEntryGroup에 전달합니다.

FindFirstUrlCacheEntryExFindNextUrlCacheEntryEx 함수를 사용하여 지정된 캐시 그룹의 항목을 열거할 수 있습니다. 열거가 완료되면 함수는 FindCloseUrlCache를 호출해야 합니다.

가변 크기 정보를 사용하여 구조체 처리

캐시에는 저장된 각 URL에 대한 가변 크기 정보가 포함될 수 있습니다. 이는 INTERNET_CACHE_ENTRY_INFO 구조에 반영됩니다. 캐시 함수는 이 구조를 반환할 때 항상 INTERNET_CACHE_ENTRY_INFO 크기와 모든 변수 크기 정보인 버퍼를 만듭니다. 포인터 멤버가 NULL이 아닌 경우 구조체 바로 뒤의 메모리 영역을 가리킵니다. 함수에서 반환된 버퍼를 다른 버퍼로 복사하는 동안 다음 예제와 같이 포인터 멤버가 새 버퍼의 적절한 위치를 가리키도록 고정되어야 합니다.

lpDstCEInfo->lpszSourceUrlName = 
    (LPINTERNET_CACHE_ENTRY_INFO) ((LPBYTE) lpSrcCEInfo + 
       ((DWORD)(lpOldCEInfo->lpszSourceUrlName) - (DWORD)lpOldCEInfo));

함수에서 검색한 캐시 항목 정보를 포함하기에는 너무 작은 버퍼를 지정하면 일부 캐시 함수가 ERROR_INSUFFICIENT_BUFFER 오류 메시지와 함께 실패합니다. 이 경우 함수는 버퍼의 필요한 크기도 반환합니다. 그런 다음 적절한 크기의 버퍼를 할당하고 함수를 다시 호출할 수 있습니다.

참고

WinINet은 서버 구현을 지원하지 않습니다. 또한 서비스에서 사용하면 안 됩니다. 서버 구현 또는 서비스의 경우 WinHTTP(Microsoft Windows HTTP 서비스)를 사용합니다.