{"action":"closed","issue":{"url":"https://api.github.com/repos/tornadoweb/tornado/issues/1484","labels_url":"https://api.github.com/repos/tornadoweb/tornado/issues/1484/labels{/name}","comments_url":"https://api.github.com/repos/tornadoweb/tornado/issues/1484/comments","events_url":"https://api.github.com/repos/tornadoweb/tornado/issues/1484/events","html_url":"https://github.com/tornadoweb/tornado/issues/1484","id":100809111,"number":1484,"title":"On OS X, pre-fork requests with python-requests cause HTTPS connections in workers to kill the worker","user":{"login":"jsocol","id":180459,"avatar_url":"https://avatars.githubusercontent.com/u/180459?v=3","gravatar_id":"","url":"https://api.github.com/users/jsocol","html_url":"https://github.com/jsocol","followers_url":"https://api.github.com/users/jsocol/followers","following_url":"https://api.github.com/users/jsocol/following{/other_user}","gists_url":"https://api.github.com/users/jsocol/gists{/gist_id}","starred_url":"https://api.github.com/users/jsocol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsocol/subscriptions","organizations_url":"https://api.github.com/users/jsocol/orgs","repos_url":"https://api.github.com/users/jsocol/repos","events_url":"https://api.github.com/users/jsocol/events{/privacy}","received_events_url":"https://api.github.com/users/jsocol/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-08-13T16:10:14Z","updated_at":"2015-08-13T16:24:53Z","closed_at":"2015-08-13T16:24:52Z","body":"This is a very specific set of circumstances, so I've included as minimal a reproduction as I can below. I recognize that it's probably too esoteric to bother fixing, but I figured it was worth writing down.\r\n\r\nOn OS X (at least on 10.10.4) if you\r\n1. Configure AsyncHTTPClient with the CurlAsyncHTTPClient\r\n2. Make a request using [requests](http://python-requests.org/) in the main process (HTTP or HTTPS)\r\n3. Then call `.bind(PORT)` `.start(n)` (for any n) and start the IOLoop\r\n4. Then use AsyncHTTPClient (with `@gen.coroutine` or `@web.asynchronous`) _or_ HTTPClient to make an HTTPS request in a handler\r\n5. The worker process dies\r\n\r\nI tried this on Tornado 4.0.2, 4.2.1, and master, using the most recent released requests (2.7.0) and pycurl (`'PycURL/7.19.5.1 libcurl/7.37.1 SecureTransport zlib/1.2.5'`), the curl version is:\r\n```\r\n$ curl --version\r\ncurl 7.37.1 (x86_64-apple-darwin14.0) libcurl/7.37.1 SecureTransport zlib/1.2.5\r\nProtocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp \r\nFeatures: AsynchDNS GSS-Negotiate IPv6 Largefile NTLM NTLM_WB SSL libz \r\n```\r\n\r\nSome things which prevent the issue from occurring:\r\n- I can't reproduce this on Ubuntu 14.04 with the `libcurl4-openssl-dev` or `libcurl4-gnutls-dev` libraries, so I think it might be related to SecureTransport somehow.\r\n- Using the default AsyncHTTPClient. \r\n- Moving the `requests.get()` call until after `.start(0)`.\r\n- Using `.listen()` instead of `bind/start`.\r\n- Making an HTTP request in the handler instead of HTTPS.\r\n\r\nHere's the output of the log:\r\n```\r\n2015-08-13 12:01:24,882 [INFO] 80378 [requests.packages.urllib3.connectionpool]: Starting new HTTP connection (1): jamessocol.com\r\n2015-08-13 12:01:25,355 [DEBUG] 80378 [requests.packages.urllib3.connectionpool]: \"GET / HTTP/1.1\" 200 None\r\n2015-08-13 12:01:25,363 [INFO] 80378 [tornado.general]: Starting 4 processes\r\n2015-08-13 12:01:32,542 [DEBUG] 80385 [tornado.curl_httpclient]: GET https://github.com/\r\n2015-08-13 12:01:32,544 [DEBUG] 80385 [tornado.curl_httpclient]: Hostname was NOT found in DNS cache\r\n2015-08-13 12:01:32,578 [DEBUG] 80385 [tornado.curl_httpclient]: Trying 192.30.252.130...\r\n2015-08-13 12:01:32,595 [DEBUG] 80385 [tornado.curl_httpclient]: Connected to github.com (192.30.252.130) port 443 (#0)\r\n2015-08-13 12:01:33,063 [WARNING] 80378 [tornado.general]: child 3 (pid 80385) killed by signal 11, restarting\r\n```\r\n\r\nAnd here's the full reproduction (the logging config is to get the PID and turn on the requests logging, otherwise you can ignore it)\r\n\r\n```python\r\nimport logging.config\r\n\r\nfrom tornado import web, httpclient, httpserver, ioloop\r\n\r\nimport requests\r\n\r\n\r\ndef configure_logging():\r\n    LOGGING = {\r\n        'version': 1,\r\n        'disable_existing_loggers': True,\r\n        'formatters': {\r\n            'standard': {\r\n                'format': ('%(asctime)s [%(levelname)s] %(process)d '\r\n                           '[%(name)s]: %(message)s'),\r\n            },\r\n        },\r\n        'handlers': {\r\n            'default': {\r\n                'class': 'logging.StreamHandler',\r\n                'formatter': 'standard',\r\n            },\r\n        },\r\n        'loggers': {\r\n            'tornado': {\r\n                'propagate': True,\r\n            },\r\n            'requests': {\r\n                'propagate': True,\r\n            },\r\n        },\r\n        'root': {\r\n            'handlers': ['default'],\r\n            'level': 'DEBUG',\r\n        },\r\n    }\r\n    logging.config.dictConfig(LOGGING)\r\n\r\n\r\nclass DemoHandler(web.RequestHandler):\r\n    def get(self):\r\n        client = httpclient.HTTPClient()\r\n        client.fetch('https://github.com/')\r\n        self.write('hi\\n')\r\n        self.finish()\r\n\r\n\r\nif __name__ == '__main__':\r\n    configure_logging()\r\n    httpclient.AsyncHTTPClient.configure(\r\n        'tornado.curl_httpclient.CurlAsyncHTTPClient')\r\n    app = web.Application([web.url(r'^/$', DemoHandler)])\r\n    http_server = httpserver.HTTPServer(app)\r\n    requests.get('http://jamessocol.com/')\r\n    http_server.bind(5001)\r\n    http_server.start(0)\r\n    ioloop.IOLoop.instance().start()\r\n```"}}