{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/comments/42186012","id":42186012,"diff_hunk":"@@ -1144,97 +820,57 @@ private void SaveServerCredentialsToCache(Uri uri, uint authScheme, ICredentials\n                 bool chunkedModeForSend = IsChunkedModeForSend(state.RequestMessage);\n \n                 AddRequestHeaders(\n-                    requestHandle,\n+                    state.RequestHandle,\n                     state.RequestMessage,\n                     _cookieUsePolicy == CookieUsePolicy.UseSpecifiedCookieContainer ? _cookieContainer : null);\n \n                 uint proxyAuthScheme = 0;\n                 uint serverAuthScheme = 0;\n-                bool retryRequest = false;\n-\n-                do\n+                state.RetryRequest = false;\n+\n+                // The only way to abort pending async operations in WinHTTP is to close the WinHTTP handle.\n+                // We will detect a cancellation request on the cancellation token by registering a callback.\n+                // If the callback is invoked, then we begin the abort process by disposing the handle. This\n+                // will have the side-affect of WinHTTP cancelling any pending I/O and accelerating its callbacks\n+                // on the handle and thus releasing the awaiting tasks in the loop below. This helps to provide\n+                // a more timely, cooperative, cancellation pattern.\n+                using (state.CancellationToken.Register(() => state.RequestHandle.Dispose()))\n                 {\n-                    state.CancellationToken.ThrowIfCancellationRequested();\n-\n-                    PreAuthenticateRequest(state, requestHandle, proxyAuthScheme);\n-\n-                    // Send a request.\n-                    if (!Interop.WinHttp.WinHttpSendRequest(\n-                        requestHandle,\n-                        null,\n-                        0,\n-                        IntPtr.Zero,\n-                        0,\n-                        0,\n-                        GCHandle.ToIntPtr(requestStateHandle)))\n+                    do\n                     {\n-                        WinHttpException.ThrowExceptionUsingLastError();\n-                    }\n+                        _authHelper.PreAuthenticateRequest(state, proxyAuthScheme);\n \n-                    // Send request body if present.\n-                    if (state.RequestMessage.Content != null)\n-                    {\n-                        using (var requestStream = new WinHttpRequestStream(requestHandle, chunkedModeForSend))\n-                        {\n-                            await state.RequestMessage.Content.CopyToAsync(\n-                                requestStream,\n-                                state.TransportContext).ConfigureAwait(false);\n-                            requestStream.EndUpload();\n-                        }\n-                    }\n-\n-                    state.CancellationToken.ThrowIfCancellationRequested();\n+                        await InternalSendRequestAsync(state).ConfigureAwait(false);\n \n-                    // End the request and wait for the response.\n-                    if (!Interop.WinHttp.WinHttpReceiveResponse(requestHandle, IntPtr.Zero))\n-                    {\n-                        int lastError = Marshal.GetLastWin32Error();\n-                        if (lastError == (int)Interop.WinHttp.ERROR_WINHTTP_RESEND_REQUEST)\n-                        {\n-                            retryRequest = true;\n-                        }\n-                        else if (lastError == (int)Interop.WinHttp.ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED)\n+                        if (state.RequestMessage.Content != null)\n                         {\n-                            // WinHttp will automatically drop any client SSL certificates that we\n-                            // have pre-set into the request handle.  For security reasons, we don't\n-                            // allow the certificate to be re-applied. But we need to tell WinHttp\n-                            // that we don't have any certificate.\n-                            SetNoClientCertificate(requestHandle);\n-                            retryRequest = true;\n+                            await InternalSendRequestBodyAsync(state, chunkedModeForSend).ConfigureAwait(false);\n                         }\n \n-                        else\n+                        bool receivedResponse = await InternalReceiveResponseHeadersAsync(state);","path":"src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs","position":616,"original_position":616,"commit_id":"e54947e29a6b534c2e99390c2fdd93d71961ee04","original_commit_id":"e54947e29a6b534c2e99390c2fdd93d71961ee04","user":{"login":"CIPop","id":8635911,"avatar_url":"https://avatars.githubusercontent.com/u/8635911?v=3","gravatar_id":"","url":"https://api.github.com/users/CIPop","html_url":"https://github.com/CIPop","followers_url":"https://api.github.com/users/CIPop/followers","following_url":"https://api.github.com/users/CIPop/following{/other_user}","gists_url":"https://api.github.com/users/CIPop/gists{/gist_id}","starred_url":"https://api.github.com/users/CIPop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CIPop/subscriptions","organizations_url":"https://api.github.com/users/CIPop/orgs","repos_url":"https://api.github.com/users/CIPop/repos","events_url":"https://api.github.com/users/CIPop/events{/privacy}","received_events_url":"https://api.github.com/users/CIPop/received_events","type":"User","site_admin":false},"body":"Missing `.ConfigureAwait(false)`.","created_at":"2015-10-15T21:55:54Z","updated_at":"2015-10-15T21:55:54Z","html_url":"https://github.com/dotnet/corefx/pull/3867#discussion_r42186012","pull_request_url":"https://api.github.com/repos/dotnet/corefx/pulls/3867","_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments/42186012"},"html":{"href":"https://github.com/dotnet/corefx/pull/3867#discussion_r42186012"},"pull_request":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3867"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/3867","id":47727582,"html_url":"https://github.com/dotnet/corefx/pull/3867","diff_url":"https://github.com/dotnet/corefx/pull/3867.diff","patch_url":"https://github.com/dotnet/corefx/pull/3867.patch","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/3867","number":3867,"state":"open","locked":false,"title":"WinHttpHandler uses async WinHTTP patterns","user":{"login":"davidsh","id":7684835,"avatar_url":"https://avatars.githubusercontent.com/u/7684835?v=3","gravatar_id":"","url":"https://api.github.com/users/davidsh","html_url":"https://github.com/davidsh","followers_url":"https://api.github.com/users/davidsh/followers","following_url":"https://api.github.com/users/davidsh/following{/other_user}","gists_url":"https://api.github.com/users/davidsh/gists{/gist_id}","starred_url":"https://api.github.com/users/davidsh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidsh/subscriptions","organizations_url":"https://api.github.com/users/davidsh/orgs","repos_url":"https://api.github.com/users/davidsh/repos","events_url":"https://api.github.com/users/davidsh/events{/privacy}","received_events_url":"https://api.github.com/users/davidsh/received_events","type":"User","site_admin":false},"body":"This is a large PR and addresses work item #3000. I apologize for not being able to structure it in a series of smaller commits.\r\n\r\nThe bulk of this PR is switching WinHttpHandler to use the async pattern of calling WinHTTP APIs. This involved a significant restructuring of the code. As part of that, I split up the large WinHttpHandler class into multiple, smaller, helper classes.\r\n\r\nWhile the intent of using async WinHTTP calls is better performance and cancel-ability, this PR has not been fully optimized yet. Due to the schedule of RC1 code complete next week, it's important that this PR get in and get mileage on it in the next few weeks.\r\n\r\nThere are several TODO items that will be done in later PR's. There is still work being tracked in #2165 for various follow-up items. For example, re-conciling the best SafeHandle pattern to use for WinHTTP between WebSockets.Client and WinHttpHandler.\r\n\r\nI'm currently using a simple Debug.WriteLine for verbose debug logging which can be turned on/off via environment variable. I plan to switch this to System.Net ETW trace loggers in the next commit and/or PR. But the logging has proved very useful in diagnosing issues.\r\n\r\nPlease provide feedback. Depending on the feedback, some of it will be marked as follow-up items for future PRs.","created_at":"2015-10-14T23:20:06Z","updated_at":"2015-10-15T21:55:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b6b6482a1179206e4ce574a88bb53ba5f3e93a8b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/corefx/pulls/3867/commits","review_comments_url":"https://api.github.com/repos/dotnet/corefx/pulls/3867/comments","review_comment_url":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/3867/comments","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/e54947e29a6b534c2e99390c2fdd93d71961ee04","head":{"label":"davidsh:winhttphandler_async","ref":"winhttphandler_async","sha":"e54947e29a6b534c2e99390c2fdd93d71961ee04","user":{"login":"davidsh","id":7684835,"avatar_url":"https://avatars.githubusercontent.com/u/7684835?v=3","gravatar_id":"","url":"https://api.github.com/users/davidsh","html_url":"https://github.com/davidsh","followers_url":"https://api.github.com/users/davidsh/followers","following_url":"https://api.github.com/users/davidsh/following{/other_user}","gists_url":"https://api.github.com/users/davidsh/gists{/gist_id}","starred_url":"https://api.github.com/users/davidsh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidsh/subscriptions","organizations_url":"https://api.github.com/users/davidsh/orgs","repos_url":"https://api.github.com/users/davidsh/repos","events_url":"https://api.github.com/users/davidsh/events{/privacy}","received_events_url":"https://api.github.com/users/davidsh/received_events","type":"User","site_admin":false},"repo":{"id":31976766,"name":"corefx","full_name":"davidsh/corefx","owner":{"login":"davidsh","id":7684835,"avatar_url":"https://avatars.githubusercontent.com/u/7684835?v=3","gravatar_id":"","url":"https://api.github.com/users/davidsh","html_url":"https://github.com/davidsh","followers_url":"https://api.github.com/users/davidsh/followers","following_url":"https://api.github.com/users/davidsh/following{/other_user}","gists_url":"https://api.github.com/users/davidsh/gists{/gist_id}","starred_url":"https://api.github.com/users/davidsh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidsh/subscriptions","organizations_url":"https://api.github.com/users/davidsh/orgs","repos_url":"https://api.github.com/users/davidsh/repos","events_url":"https://api.github.com/users/davidsh/events{/privacy}","received_events_url":"https://api.github.com/users/davidsh/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/davidsh/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":true,"url":"https://api.github.com/repos/davidsh/corefx","forks_url":"https://api.github.com/repos/davidsh/corefx/forks","keys_url":"https://api.github.com/repos/davidsh/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/davidsh/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/davidsh/corefx/teams","hooks_url":"https://api.github.com/repos/davidsh/corefx/hooks","issue_events_url":"https://api.github.com/repos/davidsh/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/davidsh/corefx/events","assignees_url":"https://api.github.com/repos/davidsh/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/davidsh/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/davidsh/corefx/tags","blobs_url":"https://api.github.com/repos/davidsh/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/davidsh/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/davidsh/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/davidsh/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/davidsh/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/davidsh/corefx/languages","stargazers_url":"https://api.github.com/repos/davidsh/corefx/stargazers","contributors_url":"https://api.github.com/repos/davidsh/corefx/contributors","subscribers_url":"https://api.github.com/repos/davidsh/corefx/subscribers","subscription_url":"https://api.github.com/repos/davidsh/corefx/subscription","commits_url":"https://api.github.com/repos/davidsh/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/davidsh/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/davidsh/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/davidsh/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/davidsh/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/davidsh/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/davidsh/corefx/merges","archive_url":"https://api.github.com/repos/davidsh/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/davidsh/corefx/downloads","issues_url":"https://api.github.com/repos/davidsh/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/davidsh/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/davidsh/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/davidsh/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/davidsh/corefx/labels{/name}","releases_url":"https://api.github.com/repos/davidsh/corefx/releases{/id}","created_at":"2015-03-10T19:16:38Z","updated_at":"2015-05-06T21:44:49Z","pushed_at":"2015-10-14T23:19:24Z","git_url":"git://github.com/davidsh/corefx.git","ssh_url":"git@github.com:davidsh/corefx.git","clone_url":"https://github.com/davidsh/corefx.git","svn_url":"https://github.com/davidsh/corefx","homepage":"","size":35465,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:master","ref":"master","sha":"772e42b5d6f3ed46cfb455a94b1ea6891d3271f4","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":26295345,"name":"corefx","full_name":"dotnet/corefx","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":false,"url":"https://api.github.com/repos/dotnet/corefx","forks_url":"https://api.github.com/repos/dotnet/corefx/forks","keys_url":"https://api.github.com/repos/dotnet/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/corefx/teams","hooks_url":"https://api.github.com/repos/dotnet/corefx/hooks","issue_events_url":"https://api.github.com/repos/dotnet/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/corefx/events","assignees_url":"https://api.github.com/repos/dotnet/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/corefx/tags","blobs_url":"https://api.github.com/repos/dotnet/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/corefx/languages","stargazers_url":"https://api.github.com/repos/dotnet/corefx/stargazers","contributors_url":"https://api.github.com/repos/dotnet/corefx/contributors","subscribers_url":"https://api.github.com/repos/dotnet/corefx/subscribers","subscription_url":"https://api.github.com/repos/dotnet/corefx/subscription","commits_url":"https://api.github.com/repos/dotnet/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/corefx/merges","archive_url":"https://api.github.com/repos/dotnet/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/corefx/downloads","issues_url":"https://api.github.com/repos/dotnet/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/corefx/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/corefx/releases{/id}","created_at":"2014-11-06T23:42:48Z","updated_at":"2015-10-15T20:08:09Z","pushed_at":"2015-10-15T21:00:31Z","git_url":"git://github.com/dotnet/corefx.git","ssh_url":"git@github.com:dotnet/corefx.git","clone_url":"https://github.com/dotnet/corefx.git","svn_url":"https://github.com/dotnet/corefx","homepage":"http://dotnet.github.io/core/","size":81475,"stargazers_count":8450,"watchers_count":8450,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1847,"mirror_url":null,"open_issues_count":636,"forks":1847,"open_issues":636,"watchers":8450,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3867"},"html":{"href":"https://github.com/dotnet/corefx/pull/3867"},"issue":{"href":"https://api.github.com/repos/dotnet/corefx/issues/3867"},"comments":{"href":"https://api.github.com/repos/dotnet/corefx/issues/3867/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3867/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3867/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/corefx/statuses/e54947e29a6b534c2e99390c2fdd93d71961ee04"}}}}