public static void AddResponseCookiesToContainer(WinHttpRequestState state) { HttpRequestMessage request = state.RequestMessage; SafeWinHttpHandle requestHandle = state.RequestHandle; CookieContainer cookieContainer = state.Handler.CookieContainer; Debug.Assert(state.Handler.CookieUsePolicy == CookieUsePolicy.UseSpecifiedCookieContainer); Debug.Assert(cookieContainer != null); // Get 'Set-Cookie' headers from response. char[] buffer = null; uint index = 0; string cookieHeader; WinHttpTraceHelper.Trace("WINHTTP_QUERY_SET_COOKIE"); while (WinHttpResponseParser.GetResponseHeader( requestHandle, Interop.WinHttp.WINHTTP_QUERY_SET_COOKIE, ref buffer, ref index, out cookieHeader)) { WinHttpTraceHelper.Trace(cookieHeader); try { cookieContainer.SetCookies(request.RequestUri, cookieHeader); WinHttpTraceHelper.Trace(cookieHeader); } catch (CookieException) { // We ignore malformed cookies in the response. WinHttpTraceHelper.Trace("Ignoring invalid cookie: {0}", cookieHeader); } } }
public void CheckResponseForAuthentication( WinHttpRequestState state, ref uint proxyAuthScheme, ref uint serverAuthScheme) { uint supportedSchemes = 0; uint firstSchemeIgnored = 0; uint authTarget = 0; Uri uri = state.RequestMessage.RequestUri; state.RetryRequest = false; // Check the status code and retry the request applying credentials if needed. var statusCode = (HttpStatusCode)WinHttpResponseParser.GetResponseHeaderNumberInfo( state.RequestHandle, Interop.WinHttp.WINHTTP_QUERY_STATUS_CODE); switch (statusCode) { case HttpStatusCode.Unauthorized: if (state.ServerCredentials == null || state.LastStatusCode == HttpStatusCode.Unauthorized) { // Either we don't have server credentials or we already tried // to set the credentials and it failed before. // So we will let the 401 be the final status code returned. break; } state.LastStatusCode = statusCode; // Determine authorization scheme to use. We ignore the firstScheme // parameter which is included in the supportedSchemes flags already. // We pass the schemes to ChooseAuthScheme which will pick the scheme // based on most secure scheme to least secure scheme ordering. if (!Interop.WinHttp.WinHttpQueryAuthSchemes( state.RequestHandle, out supportedSchemes, out firstSchemeIgnored, out authTarget)) { // WinHTTP returns an error for schemes it doesn't handle. // So, we need to ignore the error and just let it stay at 401. break; } // WinHTTP returns the proper authTarget based on the status code (401, 407). // But we can validate with assert. Debug.Assert(authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_SERVER); serverAuthScheme = ChooseAuthScheme(supportedSchemes); if (serverAuthScheme != 0) { if (SetWinHttpCredential( state.RequestHandle, state.ServerCredentials, uri, serverAuthScheme, authTarget)) { state.RetryRequest = true; } } break; case HttpStatusCode.ProxyAuthenticationRequired: if (state.LastStatusCode == HttpStatusCode.ProxyAuthenticationRequired) { // We tried already to set the credentials. break; } state.LastStatusCode = statusCode; // If we don't have any proxy credentials to try, then we end up with 407. ICredentials proxyCreds = state.Proxy == null ? state.DefaultProxyCredentials : state.Proxy.Credentials; if (proxyCreds == null) { break; } // Determine authorization scheme to use. We ignore the firstScheme // parameter which is included in the supportedSchemes flags already. // We pass the schemes to ChooseAuthScheme which will pick the scheme // based on most secure scheme to least secure scheme ordering. if (!Interop.WinHttp.WinHttpQueryAuthSchemes( state.RequestHandle, out supportedSchemes, out firstSchemeIgnored, out authTarget)) { // WinHTTP returns an error for schemes it doesn't handle. // So, we need to ignore the error and just let it stay at 401. break; } // WinHTTP returns the proper authTarget based on the status code (401, 407). // But we can validate with assert. Debug.Assert(authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_PROXY); proxyAuthScheme = ChooseAuthScheme(supportedSchemes); state.RetryRequest = true; break; default: if (state.PreAuthenticate && serverAuthScheme != 0) { SaveServerCredentialsToCache(uri, serverAuthScheme, state.ServerCredentials); } break; } }