| File: System\Net\Http\WinHttpCookieContainerAdapter.cs | Web Access |
| Project: src\runtime\src\libraries\System.Net.Http.WinHttpHandler\src\System.Net.Http.WinHttpHandler.csproj (System.Net.Http.WinHttpHandler) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using SafeWinHttpHandle = Interop.WinHttp.SafeWinHttpHandle; namespace System.Net.Http { internal static class WinHttpCookieContainerAdapter { private const string CookieHeaderNameWithColon = "Cookie" + ":"; public static void AddResponseCookiesToContainer(WinHttpRequestState state) { HttpRequestMessage? request = state.RequestMessage; SafeWinHttpHandle? requestHandle = state.RequestHandle; Debug.Assert(state.Handler != null); CookieContainer? cookieContainer = state.Handler.CookieContainer; Debug.Assert(state.Handler.CookieUsePolicy == CookieUsePolicy.UseSpecifiedCookieContainer); Debug.Assert(request != null); Debug.Assert(requestHandle != null); Debug.Assert(cookieContainer != null); Debug.Assert(request.RequestUri != null); // Get 'Set-Cookie' headers from response. char[]? buffer = null; uint index = 0; string? cookieHeader; while (WinHttpResponseParser.GetResponseHeader( requestHandle, Interop.WinHttp.WINHTTP_QUERY_SET_COOKIE, ref buffer, ref index, out cookieHeader)) { try { cookieContainer.SetCookies(request.RequestUri, cookieHeader); if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(cookieContainer, $"Added cookie: {cookieHeader}"); } catch (CookieException) { // We ignore malformed cookies in the response. if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(cookieContainer, $"Ignoring invalid cookie: {cookieHeader}"); } } } public static void ResetCookieRequestHeaders(WinHttpRequestState state, Uri redirectUri) { SafeWinHttpHandle? requestHandle = state.RequestHandle; Debug.Assert(state.Handler != null); Debug.Assert(state.Handler.CookieUsePolicy == CookieUsePolicy.UseSpecifiedCookieContainer); Debug.Assert(state.Handler.CookieContainer != null); Debug.Assert(requestHandle != null); // Clear cookies. if (!Interop.WinHttp.WinHttpAddRequestHeaders( requestHandle, CookieHeaderNameWithColon, (uint)CookieHeaderNameWithColon.Length, Interop.WinHttp.WINHTTP_ADDREQ_FLAG_REPLACE)) { int lastError = Marshal.GetLastWin32Error(); if (lastError != Interop.WinHttp.ERROR_WINHTTP_HEADER_NOT_FOUND) { throw WinHttpException.CreateExceptionUsingError(lastError, nameof(Interop.WinHttp.WinHttpAddRequestHeaders)); } } // Re-add cookies. The GetCookieHeader() method will return the correct set of // cookies based on the redirectUri. string? cookieHeader = GetCookieHeader(redirectUri, state.Handler.CookieContainer); if (!string.IsNullOrEmpty(cookieHeader)) { if (!Interop.WinHttp.WinHttpAddRequestHeaders( requestHandle, cookieHeader, (uint)cookieHeader.Length, Interop.WinHttp.WINHTTP_ADDREQ_FLAG_ADD)) { throw WinHttpException.CreateExceptionUsingLastError(nameof(Interop.WinHttp.WinHttpAddRequestHeaders)); } } } public static string? GetCookieHeader(Uri uri, CookieContainer cookies) { string? cookieHeader = null; Debug.Assert(cookies != null); string cookieValues = cookies.GetCookieHeader(uri); if (!string.IsNullOrEmpty(cookieValues)) { cookieHeader = CookieHeaderNameWithColon + " " + cookieValues; } return cookieHeader; } } }