/// <summary> /// Получить содержимое /// </summary> /// <param name="hRequest"> /// Указатель на HTTPS-запрос /// </param> /// <param name="result"> /// Результат HTTPS-запроса /// </param> private static void GetContent(IntPtr hRequest, HttpResult result) { using (var stream = new MemoryStream()) { const uint chunkSize = 1024U; using (var buffer = InteropUtil.Alloc(chunkSize)) { while (true) { var bytesRead = 0U; if (!WinInet.InternetReadFile(hRequest, buffer.Address, chunkSize, ref bytesRead)) { ThrowWinInetLastException("InternetReadFile"); } for (var i = 0; i < bytesRead; i++) { stream.WriteByte(Marshal.ReadByte(buffer.Address + i)); } if (bytesRead <= 0) { break; } } } result.Content = stream.ToArray(); } }
/// <summary> /// Получить тип содержимого /// </summary> /// <param name="hRequest"> /// Указатель на HTTPS-запрос /// </param> /// <param name="result"> /// Результат HTTPS-запроса /// </param> private static void GetContentType(IntPtr hRequest, HttpResult result) { var statusSize = 256U; using (var buffer = InteropUtil.Alloc(statusSize)) { if (!WinInet.HttpQueryInfoW( hRequest, WinInet.HTTP_QUERY_CONTENT_TYPE, buffer.Address, ref statusSize, IntPtr.Zero)) { ThrowWinInetLastException("HttpQueryInfoW(HTTP_QUERY_CONTENT_TYPE)"); } result.ContentType = Marshal.PtrToStringUni(buffer.Address); } }
/// <summary> /// Получить код статуса HTTP /// </summary> /// <param name="hRequest"> /// Указатель на HTTPS-запрос /// </param> /// <param name="result"> /// Результат HTTPS-запроса /// </param> private static void GetStatusCode(IntPtr hRequest, HttpResult result) { uint statusSize = sizeof(uint); using (var buffer = InteropUtil.Alloc(statusSize)) { if (!WinInet.HttpQueryInfoW( hRequest, WinInet.HTTP_QUERY_FLAG_NUMBER | WinInet.HTTP_QUERY_STATUS_CODE, buffer.Address, ref statusSize, IntPtr.Zero)) { ThrowWinInetLastException("HttpQueryInfoW(HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE)"); } result.Code = (HttpStatusCode)Marshal.ReadInt32(buffer.Address); } }
/// <summary> /// Конструктор /// </summary> /// <param name="uri"> /// Адрес конечной точки /// </param> /// <param name="certificate"> /// Клиентский сертифика /// </param> public WinInetHttpsClient(Uri uri, X509Certificate2 certificate) { this.uri = uri; #region Инициализация Crypt32 if (certificate != null) { // Поиск сертификата var hStore = Crypt32.CertOpenSystemStoreW(0, "My"); var hash = certificate.GetCertHash(); Crypt32.CRYPTOAPI_BLOB cryptBlob; cryptBlob.cbData = hash.Length; using (var hashHandle = InteropUtil.Pin(hash)) { cryptBlob.pbData = hashHandle.Address; using (var blobHandle = InteropUtil.Pin(cryptBlob)) { pCertContext = Crypt32.CertFindCertificateInStore( hStore, Crypt32.X509_ASN_ENCODING | Crypt32.PKCS_7_ASN_ENCODING, 0, Crypt32.CERT_FIND_SHA1_HASH, blobHandle.Address, IntPtr.Zero); if (pCertContext == IntPtr.Zero) { ThrowWinInetLastException("CertFindCertificateInStore"); } } } Crypt32.CertCloseStore(hStore, 0); hasClientCertificate = true; } else { hasClientCertificate = false; } #endregion #region Инициализация WinInet // Инициализация WinInet hInternet = WinInet.InternetOpenW( "WSL_Proxy", WinInet.INTERNET_OPEN_TYPE_DIRECT, null, null, 0); if (hInternet == IntPtr.Zero) { ThrowWinInetLastException("InternetOpen"); } hConnect = WinInet.InternetConnectW(hInternet, uri.Host, (short)uri.Port, null, null, WinInet.INTERNET_SERVICE_HTTP, 0, IntPtr.Zero); if (hConnect == IntPtr.Zero) { ThrowWinInetLastException("InternetConnect"); } #endregion }