{"action":"created","comment":{"url":"https://api.github.com/repos/getlantern/lantern/pulls/comments/35027405","id":35027405,"diff_hunk":"@@ -93,35 +101,50 @@ func (client *Client) targetQOS(req *http.Request) int {\n // pipeData pipes data between the client and proxy connections.  It's also\n // responsible for responding to the initial CONNECT request with a 200 OK.\n func pipeData(clientConn net.Conn, connOut net.Conn, req *http.Request) {\n-\n-\tvar wg sync.WaitGroup\n-\twg.Add(1)\n-\t// Start piping from client to proxy\n-\tgo func() {\n-\t\tio.Copy(connOut, clientConn)\n-\t\t// Force closing if EOF at the request half or error encountered.\n-\t\t// A bit arbitrary, but it's rather rare now to use half closing\n-\t\t// as a way to notify server. Most application closes both connections\n-\t\t// after completed send / receive so that won't cause problem.\n-\t\twg.Wait()\n-\t\tclientConn.Close()\n-\t\tconnOut.Close()\n-\t}()\n-\n \t// Respond OK\n \terr := respondOK(clientConn, req)\n-\twg.Done()\n \tif err != nil {\n \t\tlog.Errorf(\"Unable to respond OK: %s\", err)\n \t\treturn\n \t}\n \n+\t// Make sure of closing connections only once\n+\tvar closeOnce sync.Once\n+\n+\t// Force closing if EOF at the request half or error encountered.\n+\t// A bit arbitrary, but it's rather rare now to use half closing\n+\t// as a way to notify server. Most application closes both connections\n+\t// after completed send / receive so that won't cause problem.\n+\tcloseConns := func() {\n+\t\tif err := clientConn.Close(); err != nil {\n+\t\t\tlog.Debugf(\"Error closing the out connection: %s\", err)\n+\t\t}\n+\t\tif err := connOut.Close(); err != nil {\n+\t\t\tlog.Debugf(\"Error closing the client connection: %s\", err)\n+\t\t}\n+\t}\n+\n+\t// Start piping from client to proxy\n+\tgo func() {\n+\t\tif _, err := io.Copy(connOut, clientConn); err != nil {\n+\t\t\tlog.Debugf(\"Error piping data from client to proxy: %s\", err)\n+\t\t}\n+\t\tcloseOnce.Do(closeConns)\n+\t}()\n+\n \t// Then start coyping from proxy to client\n-\tio.Copy(clientConn, connOut)\n+\tif _, err := io.Copy(clientConn, connOut); err != nil {\n+\t\tlog.Debugf(\"Error piping data from proxy to client: %s\", err)\n+\t}\n+\tcloseOnce.Do(closeConns)","path":"src/github.com/getlantern/flashlight/client/handler.go","position":82,"original_position":82,"commit_id":"33ccee90058ce6b0465214cef46374a6d4ab60c7","original_commit_id":"33ccee90058ce6b0465214cef46374a6d4ab60c7","user":{"login":"uaalto","id":12701448,"avatar_url":"https://avatars.githubusercontent.com/u/12701448?v=3","gravatar_id":"","url":"https://api.github.com/users/uaalto","html_url":"https://github.com/uaalto","followers_url":"https://api.github.com/users/uaalto/followers","following_url":"https://api.github.com/users/uaalto/following{/other_user}","gists_url":"https://api.github.com/users/uaalto/gists{/gist_id}","starred_url":"https://api.github.com/users/uaalto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uaalto/subscriptions","organizations_url":"https://api.github.com/users/uaalto/orgs","repos_url":"https://api.github.com/users/uaalto/repos","events_url":"https://api.github.com/users/uaalto/events{/privacy}","received_events_url":"https://api.github.com/users/uaalto/received_events","type":"User","site_admin":false},"body":"That's perfectly possible. I'm touching many things in order to figure out the issue #2721, but I'll revisit this before making a case. I _believe_ I have a real clue of what's going on with that issue.","created_at":"2015-07-20T18:31:19Z","updated_at":"2015-07-20T18:31:19Z","html_url":"https://github.com/getlantern/lantern/pull/2769#discussion_r35027405","pull_request_url":"https://api.github.com/repos/getlantern/lantern/pulls/2769","_links":{"self":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/comments/35027405"},"html":{"href":"https://github.com/getlantern/lantern/pull/2769#discussion_r35027405"},"pull_request":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/2769"}}},"pull_request":{"url":"https://api.github.com/repos/getlantern/lantern/pulls/2769","id":40307163,"html_url":"https://github.com/getlantern/lantern/pull/2769","diff_url":"https://github.com/getlantern/lantern/pull/2769.diff","patch_url":"https://github.com/getlantern/lantern/pull/2769.patch","issue_url":"https://api.github.com/repos/getlantern/lantern/issues/2769","number":2769,"state":"open","locked":false,"title":"Issue 2429","user":{"login":"uaalto","id":12701448,"avatar_url":"https://avatars.githubusercontent.com/u/12701448?v=3","gravatar_id":"","url":"https://api.github.com/users/uaalto","html_url":"https://github.com/uaalto","followers_url":"https://api.github.com/users/uaalto/followers","following_url":"https://api.github.com/users/uaalto/following{/other_user}","gists_url":"https://api.github.com/users/uaalto/gists{/gist_id}","starred_url":"https://api.github.com/users/uaalto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uaalto/subscriptions","organizations_url":"https://api.github.com/users/uaalto/orgs","repos_url":"https://api.github.com/users/uaalto/repos","events_url":"https://api.github.com/users/uaalto/events{/privacy}","received_events_url":"https://api.github.com/users/uaalto/received_events","type":"User","site_admin":false},"body":"[This issue](https://github.com/getlantern/lantern/issues/2429) was identified as part of the ongoing investigation of issue [2721](https://github.com/getlantern/lantern/issues/2721).\r\n\r\nThe most important thing to review and discuss here, in my opinion, concerns the new handling of the bidirectional piping client<->proxy, which now will make sure that a) starts after the succesful OK response and b) closes both directions just once, if any pipe exits. At the moment the closing is done only by the client->proxy direction, which causes the function to unblock with ongoing piping in the other direction.\r\n\r\nIt also handles all errors in flashlight/client package.","created_at":"2015-07-19T12:00:47Z","updated_at":"2015-07-20T18:31:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7ae0ad8bdc1089bc58f40137a65c8770a879ced0","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/getlantern/lantern/pulls/2769/commits","review_comments_url":"https://api.github.com/repos/getlantern/lantern/pulls/2769/comments","review_comment_url":"https://api.github.com/repos/getlantern/lantern/pulls/comments{/number}","comments_url":"https://api.github.com/repos/getlantern/lantern/issues/2769/comments","statuses_url":"https://api.github.com/repos/getlantern/lantern/statuses/33ccee90058ce6b0465214cef46374a6d4ab60c7","head":{"label":"getlantern:issue-2429","ref":"issue-2429","sha":"33ccee90058ce6b0465214cef46374a6d4ab60c7","user":{"login":"getlantern","id":624178,"avatar_url":"https://avatars.githubusercontent.com/u/624178?v=3","gravatar_id":"","url":"https://api.github.com/users/getlantern","html_url":"https://github.com/getlantern","followers_url":"https://api.github.com/users/getlantern/followers","following_url":"https://api.github.com/users/getlantern/following{/other_user}","gists_url":"https://api.github.com/users/getlantern/gists{/gist_id}","starred_url":"https://api.github.com/users/getlantern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getlantern/subscriptions","organizations_url":"https://api.github.com/users/getlantern/orgs","repos_url":"https://api.github.com/users/getlantern/repos","events_url":"https://api.github.com/users/getlantern/events{/privacy}","received_events_url":"https://api.github.com/users/getlantern/received_events","type":"Organization","site_admin":false},"repo":{"id":1380117,"name":"lantern","full_name":"getlantern/lantern","owner":{"login":"getlantern","id":624178,"avatar_url":"https://avatars.githubusercontent.com/u/624178?v=3","gravatar_id":"","url":"https://api.github.com/users/getlantern","html_url":"https://github.com/getlantern","followers_url":"https://api.github.com/users/getlantern/followers","following_url":"https://api.github.com/users/getlantern/following{/other_user}","gists_url":"https://api.github.com/users/getlantern/gists{/gist_id}","starred_url":"https://api.github.com/users/getlantern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getlantern/subscriptions","organizations_url":"https://api.github.com/users/getlantern/orgs","repos_url":"https://api.github.com/users/getlantern/repos","events_url":"https://api.github.com/users/getlantern/events{/privacy}","received_events_url":"https://api.github.com/users/getlantern/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/getlantern/lantern","description":"Open Internet for Everyone. Lantern is a free desktop application that delivers fast, reliable and secure access to the open Internet.","fork":false,"url":"https://api.github.com/repos/getlantern/lantern","forks_url":"https://api.github.com/repos/getlantern/lantern/forks","keys_url":"https://api.github.com/repos/getlantern/lantern/keys{/key_id}","collaborators_url":"https://api.github.com/repos/getlantern/lantern/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/getlantern/lantern/teams","hooks_url":"https://api.github.com/repos/getlantern/lantern/hooks","issue_events_url":"https://api.github.com/repos/getlantern/lantern/issues/events{/number}","events_url":"https://api.github.com/repos/getlantern/lantern/events","assignees_url":"https://api.github.com/repos/getlantern/lantern/assignees{/user}","branches_url":"https://api.github.com/repos/getlantern/lantern/branches{/branch}","tags_url":"https://api.github.com/repos/getlantern/lantern/tags","blobs_url":"https://api.github.com/repos/getlantern/lantern/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/getlantern/lantern/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/getlantern/lantern/git/refs{/sha}","trees_url":"https://api.github.com/repos/getlantern/lantern/git/trees{/sha}","statuses_url":"https://api.github.com/repos/getlantern/lantern/statuses/{sha}","languages_url":"https://api.github.com/repos/getlantern/lantern/languages","stargazers_url":"https://api.github.com/repos/getlantern/lantern/stargazers","contributors_url":"https://api.github.com/repos/getlantern/lantern/contributors","subscribers_url":"https://api.github.com/repos/getlantern/lantern/subscribers","subscription_url":"https://api.github.com/repos/getlantern/lantern/subscription","commits_url":"https://api.github.com/repos/getlantern/lantern/commits{/sha}","git_commits_url":"https://api.github.com/repos/getlantern/lantern/git/commits{/sha}","comments_url":"https://api.github.com/repos/getlantern/lantern/comments{/number}","issue_comment_url":"https://api.github.com/repos/getlantern/lantern/issues/comments{/number}","contents_url":"https://api.github.com/repos/getlantern/lantern/contents/{+path}","compare_url":"https://api.github.com/repos/getlantern/lantern/compare/{base}...{head}","merges_url":"https://api.github.com/repos/getlantern/lantern/merges","archive_url":"https://api.github.com/repos/getlantern/lantern/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/getlantern/lantern/downloads","issues_url":"https://api.github.com/repos/getlantern/lantern/issues{/number}","pulls_url":"https://api.github.com/repos/getlantern/lantern/pulls{/number}","milestones_url":"https://api.github.com/repos/getlantern/lantern/milestones{/number}","notifications_url":"https://api.github.com/repos/getlantern/lantern/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/getlantern/lantern/labels{/name}","releases_url":"https://api.github.com/repos/getlantern/lantern/releases{/id}","created_at":"2011-02-17T22:12:29Z","updated_at":"2015-07-20T17:16:59Z","pushed_at":"2015-07-20T17:52:57Z","git_url":"git://github.com/getlantern/lantern.git","ssh_url":"git@github.com:getlantern/lantern.git","clone_url":"https://github.com/getlantern/lantern.git","svn_url":"https://github.com/getlantern/lantern","homepage":"https://getlantern.org","size":906151,"stargazers_count":1372,"watchers_count":1372,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":288,"mirror_url":null,"open_issues_count":401,"forks":288,"open_issues":401,"watchers":1372,"default_branch":"valencia"}},"base":{"label":"getlantern:valencia","ref":"valencia","sha":"6c7a5d61df12c46ebc3025fbe092951b2d1df96a","user":{"login":"getlantern","id":624178,"avatar_url":"https://avatars.githubusercontent.com/u/624178?v=3","gravatar_id":"","url":"https://api.github.com/users/getlantern","html_url":"https://github.com/getlantern","followers_url":"https://api.github.com/users/getlantern/followers","following_url":"https://api.github.com/users/getlantern/following{/other_user}","gists_url":"https://api.github.com/users/getlantern/gists{/gist_id}","starred_url":"https://api.github.com/users/getlantern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getlantern/subscriptions","organizations_url":"https://api.github.com/users/getlantern/orgs","repos_url":"https://api.github.com/users/getlantern/repos","events_url":"https://api.github.com/users/getlantern/events{/privacy}","received_events_url":"https://api.github.com/users/getlantern/received_events","type":"Organization","site_admin":false},"repo":{"id":1380117,"name":"lantern","full_name":"getlantern/lantern","owner":{"login":"getlantern","id":624178,"avatar_url":"https://avatars.githubusercontent.com/u/624178?v=3","gravatar_id":"","url":"https://api.github.com/users/getlantern","html_url":"https://github.com/getlantern","followers_url":"https://api.github.com/users/getlantern/followers","following_url":"https://api.github.com/users/getlantern/following{/other_user}","gists_url":"https://api.github.com/users/getlantern/gists{/gist_id}","starred_url":"https://api.github.com/users/getlantern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getlantern/subscriptions","organizations_url":"https://api.github.com/users/getlantern/orgs","repos_url":"https://api.github.com/users/getlantern/repos","events_url":"https://api.github.com/users/getlantern/events{/privacy}","received_events_url":"https://api.github.com/users/getlantern/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/getlantern/lantern","description":"Open Internet for Everyone. Lantern is a free desktop application that delivers fast, reliable and secure access to the open Internet.","fork":false,"url":"https://api.github.com/repos/getlantern/lantern","forks_url":"https://api.github.com/repos/getlantern/lantern/forks","keys_url":"https://api.github.com/repos/getlantern/lantern/keys{/key_id}","collaborators_url":"https://api.github.com/repos/getlantern/lantern/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/getlantern/lantern/teams","hooks_url":"https://api.github.com/repos/getlantern/lantern/hooks","issue_events_url":"https://api.github.com/repos/getlantern/lantern/issues/events{/number}","events_url":"https://api.github.com/repos/getlantern/lantern/events","assignees_url":"https://api.github.com/repos/getlantern/lantern/assignees{/user}","branches_url":"https://api.github.com/repos/getlantern/lantern/branches{/branch}","tags_url":"https://api.github.com/repos/getlantern/lantern/tags","blobs_url":"https://api.github.com/repos/getlantern/lantern/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/getlantern/lantern/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/getlantern/lantern/git/refs{/sha}","trees_url":"https://api.github.com/repos/getlantern/lantern/git/trees{/sha}","statuses_url":"https://api.github.com/repos/getlantern/lantern/statuses/{sha}","languages_url":"https://api.github.com/repos/getlantern/lantern/languages","stargazers_url":"https://api.github.com/repos/getlantern/lantern/stargazers","contributors_url":"https://api.github.com/repos/getlantern/lantern/contributors","subscribers_url":"https://api.github.com/repos/getlantern/lantern/subscribers","subscription_url":"https://api.github.com/repos/getlantern/lantern/subscription","commits_url":"https://api.github.com/repos/getlantern/lantern/commits{/sha}","git_commits_url":"https://api.github.com/repos/getlantern/lantern/git/commits{/sha}","comments_url":"https://api.github.com/repos/getlantern/lantern/comments{/number}","issue_comment_url":"https://api.github.com/repos/getlantern/lantern/issues/comments{/number}","contents_url":"https://api.github.com/repos/getlantern/lantern/contents/{+path}","compare_url":"https://api.github.com/repos/getlantern/lantern/compare/{base}...{head}","merges_url":"https://api.github.com/repos/getlantern/lantern/merges","archive_url":"https://api.github.com/repos/getlantern/lantern/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/getlantern/lantern/downloads","issues_url":"https://api.github.com/repos/getlantern/lantern/issues{/number}","pulls_url":"https://api.github.com/repos/getlantern/lantern/pulls{/number}","milestones_url":"https://api.github.com/repos/getlantern/lantern/milestones{/number}","notifications_url":"https://api.github.com/repos/getlantern/lantern/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/getlantern/lantern/labels{/name}","releases_url":"https://api.github.com/repos/getlantern/lantern/releases{/id}","created_at":"2011-02-17T22:12:29Z","updated_at":"2015-07-20T17:16:59Z","pushed_at":"2015-07-20T17:52:57Z","git_url":"git://github.com/getlantern/lantern.git","ssh_url":"git@github.com:getlantern/lantern.git","clone_url":"https://github.com/getlantern/lantern.git","svn_url":"https://github.com/getlantern/lantern","homepage":"https://getlantern.org","size":906151,"stargazers_count":1372,"watchers_count":1372,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":288,"mirror_url":null,"open_issues_count":401,"forks":288,"open_issues":401,"watchers":1372,"default_branch":"valencia"}},"_links":{"self":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/2769"},"html":{"href":"https://github.com/getlantern/lantern/pull/2769"},"issue":{"href":"https://api.github.com/repos/getlantern/lantern/issues/2769"},"comments":{"href":"https://api.github.com/repos/getlantern/lantern/issues/2769/comments"},"review_comments":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/2769/comments"},"review_comment":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/2769/commits"},"statuses":{"href":"https://api.github.com/repos/getlantern/lantern/statuses/33ccee90058ce6b0465214cef46374a6d4ab60c7"}}}}