WinHTTP의 URL(Uniform Resource Locators)

URL은 인터넷에 있는 리소스의 위치 및 액세스 방법을 간결하게 표현한 것입니다. 각 URL은 스키마(HTTP, HTTPS, FTP 또는 Gopher)와 스키마별 문자열로 구성됩니다. 이 문자열에는 디렉터리 경로, 검색 문자열 또는 리소스 이름의 조합이 포함될 수도 있습니다. WinHTTP(Microsoft Windows HTTP 서비스) 함수는 URL을 만들고, 결합하고, 분해하고, 정식화하는 기능을 제공합니다. 자세한 내용은 RFC 1738, Uniform Resource LocatorsRFC 2396, URI(Uniform Resource Identifiers): 일반 구문을 참조하세요.

정식화된 URL이란?

URL의 지정된 구문과 의미 체계는 변형 및 오류를 위한 공간을 남깁니다. 정식화는 실제 URL을 올바른 표준 "정식" 형식으로 정규화하는 프로세스입니다.

여기에는 일부 문자를 "이스케이프 시퀀스"로 코딩하는 작업이 포함됩니다. 영숫자 US-ASCII 문자는 인코딩할 필요가 없습니다(숫자 0-9, 대문자 A-Z 및 소문자 a-z). 컨트롤 문자, 공백 문자, 백분율 기호, "안전하지 않은 문자"( , <, >", #, {, }, |, \, ^, ~, [, ], ' ) 및 코드 포인트가 127을 초과하는 모든 문자를 포함하여 대부분의 다른 문자를 이스케이프해야 합니다.

WinHTTP 함수를 사용하여 URL 처리

WinHTTP는 URL을 처리하기 위한 두 가지 함수를 제공합니다. WinHttpCrackUrl 은 URL을 구성 요소 부분으로 구분하고 WinHttpCreateUrl 은 구성 요소에서 URL을 만듭니다.

URL 분리

WinHttpCrackUrl 함수는 URL을 구성 요소 부분으로 구분하고 함수에 전달되는 URL_COMPONENTS 구조체로 표시된 구성 요소를 반환합니다.

URL_COMPONENTS 구조를 구성하는 구성 요소는 체계 번호, 호스트 이름, 포트 번호, 사용자 이름, 암호, URL 경로 및 검색 매개 변수와 같은 추가 정보입니다. 스키마 및 포트 번호를 제외한 각 구성 요소에는 정보를 포함하는 문자열 멤버와 문자열 멤버의 길이를 보유하는 멤버가 있습니다. 스키마 및 포트 번호에는 해당 값을 저장하는 멤버만 있습니다. 스키마와 포트 번호는 WinHttpCrackUrl에 대한 모든 성공적인 호출에서 반환됩니다.

URL_COMPONENTS 구조에서 특정 구성 요소의 값을 검색하려면 해당 구성 요소의 문자열 길이를 저장하는 멤버를 0이 아닌 값으로 설정해야 합니다. 문자열 멤버는 버퍼 또는 NULL에 대한 포인터일 수 있습니다.

포인터 멤버에 버퍼에 대한 포인터가 포함된 경우 문자열 길이 멤버는 해당 버퍼의 크기를 포함해야 합니다. WinHttpCrackUrl 함수는 구성 요소 정보를 버퍼의 문자열로 반환하고 문자열 길이 멤버에 문자열 길이를 저장합니다.

포인터 멤버가 NULL로 설정된 경우 문자열 길이 멤버를 0이 아닌 값으로 설정할 수 있습니다. WinHttpCrackUrl 함수는 구성 요소 정보를 포함하는 URL 문자열의 첫 번째 문자에 대한 포인터를 저장하고 문자열 길이를 구성 요소와 관련된 URL 문자열의 나머지 부분에 있는 문자 수로 설정합니다.

0이 아닌 길이 멤버가 URL 문자열의 적절한 시작점을 가리키는 NULL 로 설정된 모든 포인터 멤버입니다. 길이 멤버에 저장된 길이를 사용하여 개별 구성 요소 정보의 끝을 확인해야 합니다.

URL_COMPONENTS 구조체의 초기화를 제대로 완료하려면 dwStructSize 멤버를 URL_COMPONENTS 구조체의 크기로 설정해야 합니다.

URL 만들기

WinHttpCreateUrl 함수는 앞에서 설명한 URL_COMPONENTS 구조체의 정보를 사용하여 URL을 만듭니다.

필요한 각 구성 요소에 대해 포인터 멤버는 정보를 보유하는 버퍼에 대한 포인터를 포함해야 합니다. 포인터 멤버에 0으로 끝나는 문자열에 대한 포인터가 포함된 경우 길이 멤버를 0으로 설정해야 합니다. 포인터 멤버에 0으로 종료되지 않은 문자열에 대한 포인터가 포함된 경우 길이 멤버를 문자열 길이로 설정해야 합니다. 필요하지 않은 구성 요소의 포인터 멤버를 NULL로 설정해야 합니다.

예제 코드

다음 샘플 코드에서는 WinHttpCrackUrlWinHttpCreateUrl 을 사용하여 기존 URL을 디스어셈블하고, 해당 구성 요소 중 하나를 수정하고, 새 URL로 다시 조립하는 방법을 보여 줍니다.

  URL_COMPONENTS urlComp;
  LPCWSTR pwszUrl1 = 
    L"https://search.msn.com/results.asp?RS=CHECKED&FORM=MSNH&v=1&q=wininet";
  DWORD dwUrlLen = 0;

  // Initialize the URL_COMPONENTS structure.
  ZeroMemory(&urlComp, sizeof(urlComp));
  urlComp.dwStructSize = sizeof(urlComp);

  // Set required component lengths to non-zero so that they are cracked.
  urlComp.dwSchemeLength    = (DWORD)-1;
  urlComp.dwHostNameLength  = (DWORD)-1;
  urlComp.dwUrlPathLength   = (DWORD)-1;
  urlComp.dwExtraInfoLength = (DWORD)-1;

  // Crack the URL.
  if( !WinHttpCrackUrl( pwszUrl1, (DWORD)wcslen(pwszUrl1), 0, &urlComp ) )
      printf( "Error %u in WinHttpCrackUrl.\n", GetLastError( ) );
  else
  {
    // Change the search information.  New info is the same length.
    urlComp.lpszExtraInfo = L"?RS=CHECKED&FORM=MSNH&v=1&q=winhttp";

    // Obtain the size of the new URL and allocate memory.
    WinHttpCreateUrl( &urlComp, 0, NULL, &dwUrlLen );
    LPWSTR pwszUrl2 = new WCHAR[dwUrlLen];

    // Create a new URL.
    if( !WinHttpCreateUrl( &urlComp, 0, pwszUrl2, &dwUrlLen ) )
      printf( "Error %u in WinHttpCreateUrl.\n", GetLastError( ) );
    else
    {
      // Show both URLs.
      printf( "Old URL:  %S\nNew URL:  %S\n", pwszUrl1, pwszUrl2 );
    }

    // Free allocated memory.
    delete [] pwszUrl2;
  }