{"action":"created","issue":{"url":"https://api.github.com/repos/PyGithub/PyGithub/issues/403","repository_url":"https://api.github.com/repos/PyGithub/PyGithub","labels_url":"https://api.github.com/repos/PyGithub/PyGithub/issues/403/labels{/name}","comments_url":"https://api.github.com/repos/PyGithub/PyGithub/issues/403/comments","events_url":"https://api.github.com/repos/PyGithub/PyGithub/issues/403/events","html_url":"https://github.com/PyGithub/PyGithub/pull/403","id":157207378,"number":403,"title":"Follow redirects in the case of a 301 status code","user":{"login":"mat128","id":234168,"avatar_url":"https://avatars.githubusercontent.com/u/234168?v=3","gravatar_id":"","url":"https://api.github.com/users/mat128","html_url":"https://github.com/mat128","followers_url":"https://api.github.com/users/mat128/followers","following_url":"https://api.github.com/users/mat128/following{/other_user}","gists_url":"https://api.github.com/users/mat128/gists{/gist_id}","starred_url":"https://api.github.com/users/mat128/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mat128/subscriptions","organizations_url":"https://api.github.com/users/mat128/orgs","repos_url":"https://api.github.com/users/mat128/repos","events_url":"https://api.github.com/users/mat128/events{/privacy}","received_events_url":"https://api.github.com/users/mat128/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2016-05-27T13:31:37Z","updated_at":"2016-09-01T13:59:59Z","closed_at":"2016-06-28T16:59:06Z","pull_request":{"url":"https://api.github.com/repos/PyGithub/PyGithub/pulls/403","html_url":"https://github.com/PyGithub/PyGithub/pull/403","diff_url":"https://github.com/PyGithub/PyGithub/pull/403.diff","patch_url":"https://github.com/PyGithub/PyGithub/pull/403.patch"},"body":"PyGithub does not follow HTTP redirects. This issue is visible when a repository is moved on GitHub. GitHub returns a proper 301 with a new location for the resource, but httplib does not follow redirects on it's own.\r\n\r\nThis PR ensures it follow redirects when a 301 is returned and a location header is provided in the response.\r\n\r\nI was unable to add a test case for it as it does not seem possible to have multiple exchanges while using ReplayingConnection.\r\n\r\nHere is an example curl (test_redirect was renamed to test_redirect_new_name)\r\n```\r\n~$ curl -v https://api.github.com/repos/mat128/test_redirect\r\n* Adding handle: conn: 0x7fb7a9804000\r\n* Adding handle: send: 0\r\n* Adding handle: recv: 0\r\n* Curl_addHandleToPipeline: length: 1\r\n* - Conn 0 (0x7fb7a9804000) send_pipe: 1, recv_pipe: 0\r\n* About to connect() to api.github.com port 443 (#0)\r\n*   Trying 192.30.252.126...\r\n* Connected to api.github.com (192.30.252.126) port 443 (#0)\r\n* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256\r\n* Server certificate: *.github.com\r\n* Server certificate: DigiCert SHA2 High Assurance Server CA\r\n* Server certificate: DigiCert High Assurance EV Root CA\r\n> GET /repos/mat128/test_redirect HTTP/1.1\r\n> User-Agent: curl/7.30.0\r\n> Host: api.github.com\r\n> Accept: */*\r\n>\r\n< HTTP/1.1 301 Moved Permanently\r\n* Server GitHub.com is not blacklisted\r\n< Server: GitHub.com\r\n< Date: Fri, 27 May 2016 13:28:20 GMT\r\n< Content-Type: application/json; charset=utf-8\r\n< Content-Length: 168\r\n< Status: 301 Moved Permanently\r\n< X-RateLimit-Limit: 60\r\n< X-RateLimit-Remaining: 55\r\n< X-RateLimit-Reset: 1464359212\r\n< Location: https://api.github.com/repositories/59836255\r\n< X-GitHub-Media-Type: github.v3\r\n< Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval\r\n< Access-Control-Allow-Origin: *\r\n< Content-Security-Policy: default-src 'none'\r\n< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload\r\n< X-Content-Type-Options: nosniff\r\n< X-Frame-Options: deny\r\n< X-XSS-Protection: 1; mode=block\r\n< Vary: Accept-Encoding\r\n< X-Served-By: 2811da37fbdda4367181b328b22b2499\r\n< X-GitHub-Request-Id: 6CA39808:1C0C2:B6973CA:57484B74\r\n<\r\n{\r\n  \"message\": \"Moved Permanently\",\r\n  \"url\": \"https://api.github.com/repositories/59836255\",\r\n  \"documentation_url\": \"https://developer.github.com/v3/#http-redirects\"\r\n}\r\n* Connection #0 to host api.github.com left intact\r\n```\r\n\r\nUsing curl's --location parameter, it correctly follows the redirect:\r\n\r\n```\r\n~$ curl -v --location https://api.github.com/repos/mat128/test_redirect\r\n* Adding handle: conn: 0x7ffdc2804000\r\n* Adding handle: send: 0\r\n* Adding handle: recv: 0\r\n* Curl_addHandleToPipeline: length: 1\r\n* - Conn 0 (0x7ffdc2804000) send_pipe: 1, recv_pipe: 0\r\n* About to connect() to api.github.com port 443 (#0)\r\n*   Trying 192.30.252.125...\r\n* Connected to api.github.com (192.30.252.125) port 443 (#0)\r\n* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256\r\n* Server certificate: *.github.com\r\n* Server certificate: DigiCert SHA2 High Assurance Server CA\r\n* Server certificate: DigiCert High Assurance EV Root CA\r\n> GET /repos/mat128/test_redirect HTTP/1.1\r\n> User-Agent: curl/7.30.0\r\n> Host: api.github.com\r\n> Accept: */*\r\n>\r\n< HTTP/1.1 301 Moved Permanently\r\n* Server GitHub.com is not blacklisted\r\n< Server: GitHub.com\r\n< Date: Fri, 27 May 2016 13:29:26 GMT\r\n< Content-Type: application/json; charset=utf-8\r\n< Content-Length: 168\r\n< Status: 301 Moved Permanently\r\n< X-RateLimit-Limit: 60\r\n< X-RateLimit-Remaining: 54\r\n< X-RateLimit-Reset: 1464359212\r\n< Location: https://api.github.com/repositories/59836255\r\n< X-GitHub-Media-Type: github.v3\r\n< Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval\r\n< Access-Control-Allow-Origin: *\r\n< Content-Security-Policy: default-src 'none'\r\n< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload\r\n< X-Content-Type-Options: nosniff\r\n< X-Frame-Options: deny\r\n< X-XSS-Protection: 1; mode=block\r\n< Vary: Accept-Encoding\r\n< X-Served-By: bd82876e9bf04990f289ba22f246ee9b\r\n< X-GitHub-Request-Id: 6CA39808:12715:602129C:57484BB6\r\n<\r\n* Ignoring the response-body\r\n* Connection #0 to host api.github.com left intact\r\n* Issue another request to this URL: 'https://api.github.com/repositories/59836255'\r\n* Found bundle for host api.github.com: 0x7ffdc2415340\r\n* Re-using existing connection! (#0) with host api.github.com\r\n* Connected to api.github.com (192.30.252.125) port 443 (#0)\r\n* Adding handle: conn: 0x7ffdc2804000\r\n* Adding handle: send: 0\r\n* Adding handle: recv: 0\r\n* Curl_addHandleToPipeline: length: 1\r\n* - Conn 0 (0x7ffdc2804000) send_pipe: 1, recv_pipe: 0\r\n> GET /repositories/59836255 HTTP/1.1\r\n> User-Agent: curl/7.30.0\r\n> Host: api.github.com\r\n> Accept: */*\r\n>\r\n< HTTP/1.1 200 OK\r\n* Server GitHub.com is not blacklisted\r\n< Server: GitHub.com\r\n< Date: Fri, 27 May 2016 13:29:26 GMT\r\n< Content-Type: application/json; charset=utf-8\r\n< Content-Length: 5478\r\n< Status: 200 OK\r\n< X-RateLimit-Limit: 60\r\n< X-RateLimit-Remaining: 53\r\n< X-RateLimit-Reset: 1464359212\r\n< Cache-Control: public, max-age=60, s-maxage=60\r\n< Vary: Accept\r\n< ETag: \"b05d4f4a2ac7c32e1fed5e1ee2ef40ac\"\r\n< Last-Modified: Fri, 27 May 2016 13:27:48 GMT\r\n< X-GitHub-Media-Type: github.v3\r\n< Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval\r\n< Access-Control-Allow-Origin: *\r\n< Content-Security-Policy: default-src 'none'\r\n< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload\r\n< X-Content-Type-Options: nosniff\r\n< X-Frame-Options: deny\r\n< X-XSS-Protection: 1; mode=block\r\n< Vary: Accept-Encoding\r\n< X-Served-By: 2d7a5e35115884240089368322196939\r\n< X-GitHub-Request-Id: 6CA39808:12715:60212AE:57484BB6\r\n<\r\n{\r\n  \"id\": 59836255,\r\n  \"name\": \"test_redirect_new_name\",\r\n  \"full_name\": \"mat128/test_redirect_new_name\",\r\n  \"owner\": {\r\n    \"login\": \"mat128\",\r\n    \"id\": 234168,\r\n    \"avatar_url\": \"https://avatars.githubusercontent.com/u/234168?v=3\",\r\n    \"gravatar_id\": \"\",\r\n    \"url\": \"https://api.github.com/users/mat128\",\r\n    \"html_url\": \"https://github.com/mat128\",\r\n    \"followers_url\": \"https://api.github.com/users/mat128/followers\",\r\n    \"following_url\": \"https://api.github.com/users/mat128/following{/other_user}\",\r\n    \"gists_url\": \"https://api.github.com/users/mat128/gists{/gist_id}\",\r\n    \"starred_url\": \"https://api.github.com/users/mat128/starred{/owner}{/repo}\",\r\n    \"subscriptions_url\": \"https://api.github.com/users/mat128/subscriptions\",\r\n    \"organizations_url\": \"https://api.github.com/users/mat128/orgs\",\r\n    \"repos_url\": \"https://api.github.com/users/mat128/repos\",\r\n    \"events_url\": \"https://api.github.com/users/mat128/events{/privacy}\",\r\n    \"received_events_url\": \"https://api.github.com/users/mat128/received_events\",\r\n    \"type\": \"User\",\r\n    \"site_admin\": false\r\n  },\r\n  \"private\": false,\r\n  \"html_url\": \"https://github.com/mat128/test_redirect_new_name\",\r\n  \"description\": \"\",\r\n  \"fork\": false,\r\n  \"url\": \"https://api.github.com/repos/mat128/test_redirect_new_name\",\r\n  \"forks_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/forks\",\r\n  \"keys_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/keys{/key_id}\",\r\n  \"collaborators_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/collaborators{/collaborator}\",\r\n  \"teams_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/teams\",\r\n  \"hooks_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/hooks\",\r\n  \"issue_events_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/issues/events{/number}\",\r\n  \"events_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/events\",\r\n  \"assignees_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/assignees{/user}\",\r\n  \"branches_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/branches{/branch}\",\r\n  \"tags_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/tags\",\r\n  \"blobs_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/git/blobs{/sha}\",\r\n  \"git_tags_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/git/tags{/sha}\",\r\n  \"git_refs_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/git/refs{/sha}\",\r\n  \"trees_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/git/trees{/sha}\",\r\n  \"statuses_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/statuses/{sha}\",\r\n  \"languages_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/languages\",\r\n  \"stargazers_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/stargazers\",\r\n  \"contributors_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/contributors\",\r\n  \"subscribers_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/subscribers\",\r\n  \"subscription_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/subscription\",\r\n  \"commits_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/commits{/sha}\",\r\n  \"git_commits_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/git/commits{/sha}\",\r\n  \"comments_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/comments{/number}\",\r\n  \"issue_comment_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/issues/comments{/number}\",\r\n  \"contents_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/contents/{+path}\",\r\n  \"compare_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/compare/{base}...{head}\",\r\n  \"merges_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/merges\",\r\n  \"archive_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/{archive_format}{/ref}\",\r\n  \"downloads_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/downloads\",\r\n  \"issues_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/issues{/number}\",\r\n  \"pulls_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/pulls{/number}\",\r\n  \"milestones_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/milestones{/number}\",\r\n  \"notifications_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/notifications{?since,all,participating}\",\r\n  \"labels_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/labels{/name}\",\r\n  \"releases_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/releases{/id}\",\r\n  \"deployments_url\": \"https://api.github.com/repos/mat128/test_redirect_new_name/deployments\",\r\n  \"created_at\": \"2016-05-27T13:27:40Z\",\r\n  \"updated_at\": \"2016-05-27T13:27:48Z\",\r\n  \"pushed_at\": \"2016-05-27T13:27:41Z\",\r\n  \"git_url\": \"git://github.com/mat128/test_redirect_new_name.git\",\r\n  \"ssh_url\": \"git@github.com:mat128/test_redirect_new_name.git\",\r\n  \"clone_url\": \"https://github.com/mat128/test_redirect_new_name.git\",\r\n  \"svn_url\": \"https://github.com/mat128/test_redirect_new_name\",\r\n  \"homepage\": null,\r\n  \"size\": 0,\r\n  \"stargazers_count\": 0,\r\n  \"watchers_count\": 0,\r\n  \"language\": null,\r\n  \"has_issues\": true,\r\n  \"has_downloads\": true,\r\n  \"has_wiki\": true,\r\n  \"has_pages\": false,\r\n  \"forks_count\": 0,\r\n  \"mirror_url\": null,\r\n  \"open_issues_count\": 0,\r\n  \"forks\": 0,\r\n  \"open_issues\": 0,\r\n  \"watchers\": 0,\r\n  \"default_branch\": \"master\",\r\n  \"network_count\": 0,\r\n  \"subscribers_count\": 1\r\n}\r\n* Connection #0 to host api.github.com left intact\r\n```\r\n\r\nI have manually tested the code included in the PR with success."},"comment":{"url":"https://api.github.com/repos/PyGithub/PyGithub/issues/comments/244087577","html_url":"https://github.com/PyGithub/PyGithub/pull/403#issuecomment-244087577","issue_url":"https://api.github.com/repos/PyGithub/PyGithub/issues/403","id":244087577,"user":{"login":"f1nality","id":1628232,"avatar_url":"https://avatars.githubusercontent.com/u/1628232?v=3","gravatar_id":"","url":"https://api.github.com/users/f1nality","html_url":"https://github.com/f1nality","followers_url":"https://api.github.com/users/f1nality/followers","following_url":"https://api.github.com/users/f1nality/following{/other_user}","gists_url":"https://api.github.com/users/f1nality/gists{/gist_id}","starred_url":"https://api.github.com/users/f1nality/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/f1nality/subscriptions","organizations_url":"https://api.github.com/users/f1nality/orgs","repos_url":"https://api.github.com/users/f1nality/repos","events_url":"https://api.github.com/users/f1nality/events{/privacy}","received_events_url":"https://api.github.com/users/f1nality/received_events","type":"User","site_admin":false},"created_at":"2016-09-01T13:59:59Z","updated_at":"2016-09-01T13:59:59Z","body":"Strange.. I've tested with python 2 end 3:\r\n\r\n```python\r\nPython 2.7.10 (default, Oct 23 2015, 18:05:06) \r\n[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin\r\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\r\n>>> a = 302\r\n>>> a is 302\r\nFalse\r\n```\r\n\r\n```python\r\nPython 3.4.3 (v3.4.3:9b73f1c3e601, Feb 23 2015, 02:52:03) \r\n[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin\r\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\r\n>>> a = 302\r\n>>> a is 302\r\nFalse\r\n```\r\n\r\nShould I create PR?"}}
{"actor":{"display_login":"f1nality"}}