We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bot stops responding 
<!--
Thanks for reporting issues of python-telegram-bot!
To make it easier for us to help you please enter detailed information below.

Please note, we only support the latest version of python-telegram-bot and
master branch. Please make sure to upgrade & recreate the issue on the latest
version prior to opening an issue.
-->
### Steps to reproduce
1. Run the bot, type /start

2. Send your message, but don't end the conversation so it is waiting in some state

3. Wait for ~ 10 minutes

### Expected behaviour
Bot should answer when I get back and write something

### Actual behaviour
Bot does not answer instantly, but after certain period of time

### Configuration
Microsoft Azure Cloud
Ubuntu 16.04



**Version of Python, python-telegram-bot & dependencies:**

``python-telegram-bot 5.3.0``
``urllib3 1.19.1``
``certifi 2016.09.26``
``future 0.16.0``
``Python 2.7.12 (default, Jul 18 2016, 15:02:52)  [GCC 4.8.4]``


### Logs

> Profiler-0 (err): 2017-02-28 08:23 +00:00: /usr/local/lib/python2.7/dist-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
Profiler-0 (err):   "This module will be removed in 0.20.", DeprecationWarning)
Profiler-0 (err): 2017-02-28 08:51 +00:00: 2017-02-28 08:51:58,823 - urllib3.connectionpool - WARNING - Retrying (Retry(total=2, connect=None, read=None, redirect=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='api.telegram.org', port=443): Read timed out. (read timeout=<object object at 0x7fa6aa9590b0>)",)': /AAAAAAAAAAAAA:AAAAAAAAAAA/sendMessage


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `telegram/utils/request.py`
Content:
```
1 #!/usr/bin/env python
2 #
3 # A library that provides a Python interface to the Telegram Bot API
4 # Copyright (C) 2015-2017
5 # Leandro Toledo de Souza <devs@python-telegram-bot.org>
6 #
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Lesser Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU Lesser Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser Public License
18 # along with this program.  If not, see [http://www.gnu.org/licenses/].
19 """This module contains methods to make POST and GET requests"""
20 import os
21 import socket
22 import logging
23 import warnings
24 
25 try:
26     import ujson as json
27 except ImportError:
28     import json
29 
30 import certifi
31 try:
32     import telegram.vendor.ptb_urllib3.urllib3 as urllib3
33     import telegram.vendor.ptb_urllib3.urllib3.contrib.appengine as appengine
34     from telegram.vendor.ptb_urllib3.urllib3.connection import HTTPConnection
35     from telegram.vendor.ptb_urllib3.urllib3.util.timeout import Timeout
36 except ImportError:
37     warnings.warn("python-telegram-bot wasn't properly installed. Please refer to README.rst on "
38                   "how to properly install.")
39     raise
40 
41 from telegram import (InputFile, TelegramError)
42 from telegram.error import (Unauthorized, NetworkError, TimedOut, BadRequest, ChatMigrated,
43                             RetryAfter, InvalidToken)
44 
45 logging.getLogger('urllib3').setLevel(logging.WARNING)
46 
47 
48 class Request(object):
49     """
50     Helper class for python-telegram-bot which provides methods to perform POST & GET towards
51     telegram servers.
52 
53     Args:
54         con_pool_size (int): Number of connections to keep in the connection pool.
55         proxy_url (str): The URL to the proxy server. For example: `http://127.0.0.1:3128`.
56         urllib3_proxy_kwargs (dict): Arbitrary arguments passed as-is to `urllib3.ProxyManager`.
57             This value will be ignored if proxy_url is not set.
58         connect_timeout (int|float): The maximum amount of time (in seconds) to wait for a
59             connection attempt to a server to succeed. None will set an infinite timeout for
60             connection attempts. (default: 5.)
61         read_timeout (int|float): The maximum amount of time (in seconds) to wait between
62             consecutive read operations for a response from the server. None will set an infinite
63             timeout. This value is usually overridden by the various ``telegram.Bot`` methods.
64             (default: 5.)
65 
66     """
67 
68     def __init__(self,
69                  con_pool_size=1,
70                  proxy_url=None,
71                  urllib3_proxy_kwargs=None,
72                  connect_timeout=5.,
73                  read_timeout=5.):
74         if urllib3_proxy_kwargs is None:
75             urllib3_proxy_kwargs = dict()
76 
77         self._connect_timeout = connect_timeout
78 
79         kwargs = dict(
80             maxsize=con_pool_size,
81             cert_reqs='CERT_REQUIRED',
82             ca_certs=certifi.where(),
83             socket_options=HTTPConnection.default_socket_options + [
84                 (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
85             ],
86             timeout=urllib3.Timeout(
87                 connect=self._connect_timeout, read=read_timeout, total=None))
88 
89         # Set a proxy according to the following order:
90         # * proxy defined in proxy_url (+ urllib3_proxy_kwargs)
91         # * proxy set in `HTTPS_PROXY` env. var.
92         # * proxy set in `https_proxy` env. var.
93         # * None (if no proxy is configured)
94 
95         if not proxy_url:
96             proxy_url = os.environ.get('HTTPS_PROXY') or os.environ.get('https_proxy')
97 
98         if not proxy_url:
99             if appengine.is_appengine_sandbox():
100                 # Use URLFetch service if running in App Engine
101                 mgr = appengine.AppEngineManager()
102             else:
103                 mgr = urllib3.PoolManager(**kwargs)
104         else:
105             kwargs.update(urllib3_proxy_kwargs)
106             if proxy_url.startswith('socks'):
107                 try:
108                     from telegram.vendor.ptb_urllib3.urllib3.contrib.socks import SOCKSProxyManager
109                 except ImportError:
110                     raise RuntimeError('PySocks is missing')
111                 mgr = SOCKSProxyManager(proxy_url, **kwargs)
112             else:
113                 mgr = urllib3.proxy_from_url(proxy_url, **kwargs)
114                 if mgr.proxy.auth:
115                     # TODO: what about other auth types?
116                     auth_hdrs = urllib3.make_headers(proxy_basic_auth=mgr.proxy.auth)
117                     mgr.proxy_headers.update(auth_hdrs)
118 
119         self._con_pool = mgr
120 
121     def stop(self):
122         self._con_pool.clear()
123 
124     @staticmethod
125     def _parse(json_data):
126         """Try and parse the JSON returned from Telegram.
127 
128         Returns:
129             dict: A JSON parsed as Python dict with results - on error this dict will be empty.
130 
131         """
132         decoded_s = json_data.decode('utf-8')
133         try:
134             data = json.loads(decoded_s)
135         except ValueError:
136             raise TelegramError('Invalid server response')
137 
138         if not data.get('ok'):
139             description = data.get('description')
140             parameters = data.get('parameters')
141             if parameters:
142                 migrate_to_chat_id = parameters.get('migrate_to_chat_id')
143                 if migrate_to_chat_id:
144                     raise ChatMigrated(migrate_to_chat_id)
145                 retry_after = parameters.get('retry_after')
146                 if retry_after:
147                     raise RetryAfter(retry_after)
148             if description:
149                 return description
150 
151         return data['result']
152 
153     def _request_wrapper(self, *args, **kwargs):
154         """Wraps urllib3 request for handling known exceptions.
155 
156         Args:
157             args: unnamed arguments, passed to urllib3 request.
158             kwargs: keyword arguments, passed tp urllib3 request.
159 
160         Returns:
161             str: A non-parsed JSON text.
162 
163         Raises:
164             TelegramError
165 
166         """
167         # Make sure to hint Telegram servers that we reuse connections by sending
168         # "Connection: keep-alive" in the HTTP headers.
169         if 'headers' not in kwargs:
170             kwargs['headers'] = {}
171         kwargs['headers']['connection'] = 'keep-alive'
172 
173         try:
174             resp = self._con_pool.request(*args, **kwargs)
175         except urllib3.exceptions.TimeoutError:
176             raise TimedOut()
177         except urllib3.exceptions.HTTPError as error:
178             # HTTPError must come last as its the base urllib3 exception class
179             # TODO: do something smart here; for now just raise NetworkError
180             raise NetworkError('urllib3 HTTPError {0}'.format(error))
181 
182         if 200 <= resp.status <= 299:
183             # 200-299 range are HTTP success statuses
184             return resp.data
185 
186         try:
187             message = self._parse(resp.data)
188         except ValueError:
189             message = 'Unknown HTTPError'
190 
191         if resp.status in (401, 403):
192             raise Unauthorized(message)
193         elif resp.status == 400:
194             raise BadRequest(message)
195         elif resp.status == 404:
196             raise InvalidToken()
197         elif resp.status == 413:
198             raise NetworkError('File too large. Check telegram api limits '
199                                'https://core.telegram.org/bots/api#senddocument')
200 
201         elif resp.status == 502:
202             raise NetworkError('Bad Gateway')
203         else:
204             raise NetworkError('{0} ({1})'.format(message, resp.status))
205 
206     def get(self, url, timeout=None):
207         """Request an URL.
208 
209         Args:
210             url (str): The web location we want to retrieve.
211             timeout (Optional[int|float]): If this value is specified, use it as the read timeout
212                 from the server (instead of the one specified during creation of the connection
213                 pool).
214 
215         Returns:
216           A JSON object.
217 
218         """
219         urlopen_kwargs = {}
220 
221         if timeout is not None:
222             urlopen_kwargs['timeout'] = Timeout(read=timeout, connect=self._connect_timeout)
223 
224         result = self._request_wrapper('GET', url, **urlopen_kwargs)
225         return self._parse(result)
226 
227     def post(self, url, data, timeout=None):
228         """Request an URL.
229         Args:
230             url (str): The web location we want to retrieve.
231             data (dict[str, str|int]): A dict of key/value pairs. Note: On py2.7 value is unicode.
232             timeout (Optional[int|float]): If this value is specified, use it as the read timeout
233                 from the server (instead of the one specified during creation of the connection
234                 pool).
235 
236         Returns:
237           A JSON object.
238 
239         """
240         urlopen_kwargs = {}
241 
242         if timeout is not None:
243             urlopen_kwargs['timeout'] = Timeout(read=timeout, connect=self._connect_timeout)
244 
245         if InputFile.is_inputfile(data):
246             data = InputFile(data)
247             result = self._request_wrapper(
248                 'POST', url, body=data.to_form(), headers=data.headers, **urlopen_kwargs)
249         else:
250             data = json.dumps(data)
251             result = self._request_wrapper(
252                 'POST',
253                 url,
254                 body=data.encode(),
255                 headers={'Content-Type': 'application/json'},
256                 **urlopen_kwargs)
257 
258         return self._parse(result)
259 
260     def retrieve(self, url, timeout=None):
261         """Retrieve the contents of a file by its URL.
262 
263         Args:
264             url (str): The web location we want to retrieve.
265             timeout (Optional[int|float]): If this value is specified, use it as the read timeout
266                 from the server (instead of the one specified during creation of the connection
267                 pool).
268 
269         """
270         urlopen_kwargs = {}
271         if timeout is not None:
272             urlopen_kwargs['timeout'] = Timeout(read=timeout, connect=self._connect_timeout)
273 
274         return self._request_wrapper('GET', url, **urlopen_kwargs)
275 
276     def download(self, url, filename, timeout=None):
277         """Download a file by its URL.
278         Args:
279             url (str): The web location we want to retrieve.
280             timeout (Optional[int|float]): If this value is specified, use it as the read timeout
281                 from the server (instead of the one specified during creation of the connection
282                 pool).
283 
284           filename:
285             The filename within the path to download the file.
286 
287         """
288         buf = self.retrieve(url, timeout=timeout)
289         with open(filename, 'wb') as fobj:
290             fobj.write(buf)
291
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/telegram/utils/request.py b/telegram/utils/request.py
--- a/telegram/utils/request.py
+++ b/telegram/utils/request.py
@@ -19,6 +19,7 @@
 """This module contains methods to make POST and GET requests"""
 import os
 import socket
+import sys
 import logging
 import warnings
 
@@ -76,13 +77,20 @@
 
         self._connect_timeout = connect_timeout
 
+        sockopts = HTTPConnection.default_socket_options + [
+            (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)]
+
+        # TODO: Support other platforms like mac and windows.
+        if 'linux' in sys.platform:
+            sockopts.append((socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 120))
+            sockopts.append((socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 30))
+            sockopts.append((socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 8))
+
         kwargs = dict(
             maxsize=con_pool_size,
             cert_reqs='CERT_REQUIRED',
             ca_certs=certifi.where(),
-            socket_options=HTTPConnection.default_socket_options + [
-                (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
-            ],
+            socket_options=sockopts,
             timeout=urllib3.Timeout(
                 connect=self._connect_timeout, read=read_timeout, total=None))

{"golden_diff": "diff --git a/telegram/utils/request.py b/telegram/utils/request.py\n--- a/telegram/utils/request.py\n+++ b/telegram/utils/request.py\n@@ -19,6 +19,7 @@\n \"\"\"This module contains methods to make POST and GET requests\"\"\"\n import os\n import socket\n+import sys\n import logging\n import warnings\n \n@@ -76,13 +77,20 @@\n \n         self._connect_timeout = connect_timeout\n \n+        sockopts = HTTPConnection.default_socket_options + [\n+            (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)]\n+\n+        # TODO: Support other platforms like mac and windows.\n+        if 'linux' in sys.platform:\n+            sockopts.append((socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 120))\n+            sockopts.append((socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 30))\n+            sockopts.append((socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 8))\n+\n         kwargs = dict(\n             maxsize=con_pool_size,\n             cert_reqs='CERT_REQUIRED',\n             ca_certs=certifi.where(),\n-            socket_options=HTTPConnection.default_socket_options + [\n-                (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),\n-            ],\n+            socket_options=sockopts,\n             timeout=urllib3.Timeout(\n                 connect=self._connect_timeout, read=read_timeout, total=None))\n", "issue": "Bot stops responding \n<!--\r\nThanks for reporting issues of python-telegram-bot!\r\nTo make it easier for us to help you please enter detailed information below.\r\n\r\nPlease note, we only support the latest version of python-telegram-bot and\r\nmaster branch. Please make sure to upgrade & recreate the issue on the latest\r\nversion prior to opening an issue.\r\n-->\r\n### Steps to reproduce\r\n1. Run the bot, type /start\r\n\r\n2. Send your message, but don't end the conversation so it is waiting in some state\r\n\r\n3. Wait for ~ 10 minutes\r\n\r\n### Expected behaviour\r\nBot should answer when I get back and write something\r\n\r\n### Actual behaviour\r\nBot does not answer instantly, but after certain period of time\r\n\r\n### Configuration\r\nMicrosoft Azure Cloud\r\nUbuntu 16.04\r\n\r\n\r\n\r\n**Version of Python, python-telegram-bot & dependencies:**\r\n\r\n``python-telegram-bot 5.3.0``\r\n``urllib3 1.19.1``\r\n``certifi 2016.09.26``\r\n``future 0.16.0``\r\n``Python 2.7.12 (default, Jul 18 2016, 15:02:52)  [GCC 4.8.4]``\r\n\r\n\r\n### Logs\r\n\r\n> Profiler-0 (err): 2017-02-28 08:23 +00:00: /usr/local/lib/python2.7/dist-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.\r\nProfiler-0 (err):   \"This module will be removed in 0.20.\", DeprecationWarning)\r\nProfiler-0 (err): 2017-02-28 08:51 +00:00: 2017-02-28 08:51:58,823 - urllib3.connectionpool - WARNING - Retrying (Retry(total=2, connect=None, read=None, redirect=None)) after connection broken by 'ReadTimeoutError(\"HTTPSConnectionPool(host='api.telegram.org', port=443): Read timed out. (read timeout=<object object at 0x7fa6aa9590b0>)\",)': /AAAAAAAAAAAAA:AAAAAAAAAAA/sendMessage\r\n\n", "before_files": [{"content": "#!/usr/bin/env python\n#\n# A library that provides a Python interface to the Telegram Bot API\n# Copyright (C) 2015-2017\n# Leandro Toledo de Souza <devs@python-telegram-bot.org>\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser Public License for more details.\n#\n# You should have received a copy of the GNU Lesser Public License\n# along with this program.  If not, see [http://www.gnu.org/licenses/].\n\"\"\"This module contains methods to make POST and GET requests\"\"\"\nimport os\nimport socket\nimport logging\nimport warnings\n\ntry:\n    import ujson as json\nexcept ImportError:\n    import json\n\nimport certifi\ntry:\n    import telegram.vendor.ptb_urllib3.urllib3 as urllib3\n    import telegram.vendor.ptb_urllib3.urllib3.contrib.appengine as appengine\n    from telegram.vendor.ptb_urllib3.urllib3.connection import HTTPConnection\n    from telegram.vendor.ptb_urllib3.urllib3.util.timeout import Timeout\nexcept ImportError:\n    warnings.warn(\"python-telegram-bot wasn't properly installed. Please refer to README.rst on \"\n                  \"how to properly install.\")\n    raise\n\nfrom telegram import (InputFile, TelegramError)\nfrom telegram.error import (Unauthorized, NetworkError, TimedOut, BadRequest, ChatMigrated,\n                            RetryAfter, InvalidToken)\n\nlogging.getLogger('urllib3').setLevel(logging.WARNING)\n\n\nclass Request(object):\n    \"\"\"\n    Helper class for python-telegram-bot which provides methods to perform POST & GET towards\n    telegram servers.\n\n    Args:\n        con_pool_size (int): Number of connections to keep in the connection pool.\n        proxy_url (str): The URL to the proxy server. For example: `http://127.0.0.1:3128`.\n        urllib3_proxy_kwargs (dict): Arbitrary arguments passed as-is to `urllib3.ProxyManager`.\n            This value will be ignored if proxy_url is not set.\n        connect_timeout (int|float): The maximum amount of time (in seconds) to wait for a\n            connection attempt to a server to succeed. None will set an infinite timeout for\n            connection attempts. (default: 5.)\n        read_timeout (int|float): The maximum amount of time (in seconds) to wait between\n            consecutive read operations for a response from the server. None will set an infinite\n            timeout. This value is usually overridden by the various ``telegram.Bot`` methods.\n            (default: 5.)\n\n    \"\"\"\n\n    def __init__(self,\n                 con_pool_size=1,\n                 proxy_url=None,\n                 urllib3_proxy_kwargs=None,\n                 connect_timeout=5.,\n                 read_timeout=5.):\n        if urllib3_proxy_kwargs is None:\n            urllib3_proxy_kwargs = dict()\n\n        self._connect_timeout = connect_timeout\n\n        kwargs = dict(\n            maxsize=con_pool_size,\n            cert_reqs='CERT_REQUIRED',\n            ca_certs=certifi.where(),\n            socket_options=HTTPConnection.default_socket_options + [\n                (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),\n            ],\n            timeout=urllib3.Timeout(\n                connect=self._connect_timeout, read=read_timeout, total=None))\n\n        # Set a proxy according to the following order:\n        # * proxy defined in proxy_url (+ urllib3_proxy_kwargs)\n        # * proxy set in `HTTPS_PROXY` env. var.\n        # * proxy set in `https_proxy` env. var.\n        # * None (if no proxy is configured)\n\n        if not proxy_url:\n            proxy_url = os.environ.get('HTTPS_PROXY') or os.environ.get('https_proxy')\n\n        if not proxy_url:\n            if appengine.is_appengine_sandbox():\n                # Use URLFetch service if running in App Engine\n                mgr = appengine.AppEngineManager()\n            else:\n                mgr = urllib3.PoolManager(**kwargs)\n        else:\n            kwargs.update(urllib3_proxy_kwargs)\n            if proxy_url.startswith('socks'):\n                try:\n                    from telegram.vendor.ptb_urllib3.urllib3.contrib.socks import SOCKSProxyManager\n                except ImportError:\n                    raise RuntimeError('PySocks is missing')\n                mgr = SOCKSProxyManager(proxy_url, **kwargs)\n            else:\n                mgr = urllib3.proxy_from_url(proxy_url, **kwargs)\n                if mgr.proxy.auth:\n                    # TODO: what about other auth types?\n                    auth_hdrs = urllib3.make_headers(proxy_basic_auth=mgr.proxy.auth)\n                    mgr.proxy_headers.update(auth_hdrs)\n\n        self._con_pool = mgr\n\n    def stop(self):\n        self._con_pool.clear()\n\n    @staticmethod\n    def _parse(json_data):\n        \"\"\"Try and parse the JSON returned from Telegram.\n\n        Returns:\n            dict: A JSON parsed as Python dict with results - on error this dict will be empty.\n\n        \"\"\"\n        decoded_s = json_data.decode('utf-8')\n        try:\n            data = json.loads(decoded_s)\n        except ValueError:\n            raise TelegramError('Invalid server response')\n\n        if not data.get('ok'):\n            description = data.get('description')\n            parameters = data.get('parameters')\n            if parameters:\n                migrate_to_chat_id = parameters.get('migrate_to_chat_id')\n                if migrate_to_chat_id:\n                    raise ChatMigrated(migrate_to_chat_id)\n                retry_after = parameters.get('retry_after')\n                if retry_after:\n                    raise RetryAfter(retry_after)\n            if description:\n                return description\n\n        return data['result']\n\n    def _request_wrapper(self, *args, **kwargs):\n        \"\"\"Wraps urllib3 request for handling known exceptions.\n\n        Args:\n            args: unnamed arguments, passed to urllib3 request.\n            kwargs: keyword arguments, passed tp urllib3 request.\n\n        Returns:\n            str: A non-parsed JSON text.\n\n        Raises:\n            TelegramError\n\n        \"\"\"\n        # Make sure to hint Telegram servers that we reuse connections by sending\n        # \"Connection: keep-alive\" in the HTTP headers.\n        if 'headers' not in kwargs:\n            kwargs['headers'] = {}\n        kwargs['headers']['connection'] = 'keep-alive'\n\n        try:\n            resp = self._con_pool.request(*args, **kwargs)\n        except urllib3.exceptions.TimeoutError:\n            raise TimedOut()\n        except urllib3.exceptions.HTTPError as error:\n            # HTTPError must come last as its the base urllib3 exception class\n            # TODO: do something smart here; for now just raise NetworkError\n            raise NetworkError('urllib3 HTTPError {0}'.format(error))\n\n        if 200 <= resp.status <= 299:\n            # 200-299 range are HTTP success statuses\n            return resp.data\n\n        try:\n            message = self._parse(resp.data)\n        except ValueError:\n            message = 'Unknown HTTPError'\n\n        if resp.status in (401, 403):\n            raise Unauthorized(message)\n        elif resp.status == 400:\n            raise BadRequest(message)\n        elif resp.status == 404:\n            raise InvalidToken()\n        elif resp.status == 413:\n            raise NetworkError('File too large. Check telegram api limits '\n                               'https://core.telegram.org/bots/api#senddocument')\n\n        elif resp.status == 502:\n            raise NetworkError('Bad Gateway')\n        else:\n            raise NetworkError('{0} ({1})'.format(message, resp.status))\n\n    def get(self, url, timeout=None):\n        \"\"\"Request an URL.\n\n        Args:\n            url (str): The web location we want to retrieve.\n            timeout (Optional[int|float]): If this value is specified, use it as the read timeout\n                from the server (instead of the one specified during creation of the connection\n                pool).\n\n        Returns:\n          A JSON object.\n\n        \"\"\"\n        urlopen_kwargs = {}\n\n        if timeout is not None:\n            urlopen_kwargs['timeout'] = Timeout(read=timeout, connect=self._connect_timeout)\n\n        result = self._request_wrapper('GET', url, **urlopen_kwargs)\n        return self._parse(result)\n\n    def post(self, url, data, timeout=None):\n        \"\"\"Request an URL.\n        Args:\n            url (str): The web location we want to retrieve.\n            data (dict[str, str|int]): A dict of key/value pairs. Note: On py2.7 value is unicode.\n            timeout (Optional[int|float]): If this value is specified, use it as the read timeout\n                from the server (instead of the one specified during creation of the connection\n                pool).\n\n        Returns:\n          A JSON object.\n\n        \"\"\"\n        urlopen_kwargs = {}\n\n        if timeout is not None:\n            urlopen_kwargs['timeout'] = Timeout(read=timeout, connect=self._connect_timeout)\n\n        if InputFile.is_inputfile(data):\n            data = InputFile(data)\n            result = self._request_wrapper(\n                'POST', url, body=data.to_form(), headers=data.headers, **urlopen_kwargs)\n        else:\n            data = json.dumps(data)\n            result = self._request_wrapper(\n                'POST',\n                url,\n                body=data.encode(),\n                headers={'Content-Type': 'application/json'},\n                **urlopen_kwargs)\n\n        return self._parse(result)\n\n    def retrieve(self, url, timeout=None):\n        \"\"\"Retrieve the contents of a file by its URL.\n\n        Args:\n            url (str): The web location we want to retrieve.\n            timeout (Optional[int|float]): If this value is specified, use it as the read timeout\n                from the server (instead of the one specified during creation of the connection\n                pool).\n\n        \"\"\"\n        urlopen_kwargs = {}\n        if timeout is not None:\n            urlopen_kwargs['timeout'] = Timeout(read=timeout, connect=self._connect_timeout)\n\n        return self._request_wrapper('GET', url, **urlopen_kwargs)\n\n    def download(self, url, filename, timeout=None):\n        \"\"\"Download a file by its URL.\n        Args:\n            url (str): The web location we want to retrieve.\n            timeout (Optional[int|float]): If this value is specified, use it as the read timeout\n                from the server (instead of the one specified during creation of the connection\n                pool).\n\n          filename:\n            The filename within the path to download the file.\n\n        \"\"\"\n        buf = self.retrieve(url, timeout=timeout)\n        with open(filename, 'wb') as fobj:\n            fobj.write(buf)\n", "path": "telegram/utils/request.py"}], "after_files": [{"content": "#!/usr/bin/env python\n#\n# A library that provides a Python interface to the Telegram Bot API\n# Copyright (C) 2015-2017\n# Leandro Toledo de Souza <devs@python-telegram-bot.org>\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser Public License for more details.\n#\n# You should have received a copy of the GNU Lesser Public License\n# along with this program.  If not, see [http://www.gnu.org/licenses/].\n\"\"\"This module contains methods to make POST and GET requests\"\"\"\nimport os\nimport socket\nimport sys\nimport logging\nimport warnings\n\ntry:\n    import ujson as json\nexcept ImportError:\n    import json\n\nimport certifi\ntry:\n    import telegram.vendor.ptb_urllib3.urllib3 as urllib3\n    import telegram.vendor.ptb_urllib3.urllib3.contrib.appengine as appengine\n    from telegram.vendor.ptb_urllib3.urllib3.connection import HTTPConnection\n    from telegram.vendor.ptb_urllib3.urllib3.util.timeout import Timeout\nexcept ImportError:\n    warnings.warn(\"python-telegram-bot wasn't properly installed. Please refer to README.rst on \"\n                  \"how to properly install.\")\n    raise\n\nfrom telegram import (InputFile, TelegramError)\nfrom telegram.error import (Unauthorized, NetworkError, TimedOut, BadRequest, ChatMigrated,\n                            RetryAfter, InvalidToken)\n\nlogging.getLogger('urllib3').setLevel(logging.WARNING)\n\n\nclass Request(object):\n    \"\"\"\n    Helper class for python-telegram-bot which provides methods to perform POST & GET towards\n    telegram servers.\n\n    Args:\n        con_pool_size (int): Number of connections to keep in the connection pool.\n        proxy_url (str): The URL to the proxy server. For example: `http://127.0.0.1:3128`.\n        urllib3_proxy_kwargs (dict): Arbitrary arguments passed as-is to `urllib3.ProxyManager`.\n            This value will be ignored if proxy_url is not set.\n        connect_timeout (int|float): The maximum amount of time (in seconds) to wait for a\n            connection attempt to a server to succeed. None will set an infinite timeout for\n            connection attempts. (default: 5.)\n        read_timeout (int|float): The maximum amount of time (in seconds) to wait between\n            consecutive read operations for a response from the server. None will set an infinite\n            timeout. This value is usually overridden by the various ``telegram.Bot`` methods.\n            (default: 5.)\n\n    \"\"\"\n\n    def __init__(self,\n                 con_pool_size=1,\n                 proxy_url=None,\n                 urllib3_proxy_kwargs=None,\n                 connect_timeout=5.,\n                 read_timeout=5.):\n        if urllib3_proxy_kwargs is None:\n            urllib3_proxy_kwargs = dict()\n\n        self._connect_timeout = connect_timeout\n\n        sockopts = HTTPConnection.default_socket_options + [\n            (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)]\n\n        # TODO: Support other platforms like mac and windows.\n        if 'linux' in sys.platform:\n            sockopts.append((socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 120))\n            sockopts.append((socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 30))\n            sockopts.append((socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 8))\n\n        kwargs = dict(\n            maxsize=con_pool_size,\n            cert_reqs='CERT_REQUIRED',\n            ca_certs=certifi.where(),\n            socket_options=sockopts,\n            timeout=urllib3.Timeout(\n                connect=self._connect_timeout, read=read_timeout, total=None))\n\n        # Set a proxy according to the following order:\n        # * proxy defined in proxy_url (+ urllib3_proxy_kwargs)\n        # * proxy set in `HTTPS_PROXY` env. var.\n        # * proxy set in `https_proxy` env. var.\n        # * None (if no proxy is configured)\n\n        if not proxy_url:\n            proxy_url = os.environ.get('HTTPS_PROXY') or os.environ.get('https_proxy')\n\n        if not proxy_url:\n            if appengine.is_appengine_sandbox():\n                # Use URLFetch service if running in App Engine\n                mgr = appengine.AppEngineManager()\n            else:\n                mgr = urllib3.PoolManager(**kwargs)\n        else:\n            kwargs.update(urllib3_proxy_kwargs)\n            if proxy_url.startswith('socks'):\n                try:\n                    from telegram.vendor.ptb_urllib3.urllib3.contrib.socks import SOCKSProxyManager\n                except ImportError:\n                    raise RuntimeError('PySocks is missing')\n                mgr = SOCKSProxyManager(proxy_url, **kwargs)\n            else:\n                mgr = urllib3.proxy_from_url(proxy_url, **kwargs)\n                if mgr.proxy.auth:\n                    # TODO: what about other auth types?\n                    auth_hdrs = urllib3.make_headers(proxy_basic_auth=mgr.proxy.auth)\n                    mgr.proxy_headers.update(auth_hdrs)\n\n        self._con_pool = mgr\n\n    def stop(self):\n        self._con_pool.clear()\n\n    @staticmethod\n    def _parse(json_data):\n        \"\"\"Try and parse the JSON returned from Telegram.\n\n        Returns:\n            dict: A JSON parsed as Python dict with results - on error this dict will be empty.\n\n        \"\"\"\n        decoded_s = json_data.decode('utf-8')\n        try:\n            data = json.loads(decoded_s)\n        except ValueError:\n            raise TelegramError('Invalid server response')\n\n        if not data.get('ok'):\n            description = data.get('description')\n            parameters = data.get('parameters')\n            if parameters:\n                migrate_to_chat_id = parameters.get('migrate_to_chat_id')\n                if migrate_to_chat_id:\n                    raise ChatMigrated(migrate_to_chat_id)\n                retry_after = parameters.get('retry_after')\n                if retry_after:\n                    raise RetryAfter(retry_after)\n            if description:\n                return description\n\n        return data['result']\n\n    def _request_wrapper(self, *args, **kwargs):\n        \"\"\"Wraps urllib3 request for handling known exceptions.\n\n        Args:\n            args: unnamed arguments, passed to urllib3 request.\n            kwargs: keyword arguments, passed tp urllib3 request.\n\n        Returns:\n            str: A non-parsed JSON text.\n\n        Raises:\n            TelegramError\n\n        \"\"\"\n        # Make sure to hint Telegram servers that we reuse connections by sending\n        # \"Connection: keep-alive\" in the HTTP headers.\n        if 'headers' not in kwargs:\n            kwargs['headers'] = {}\n        kwargs['headers']['connection'] = 'keep-alive'\n\n        try:\n            resp = self._con_pool.request(*args, **kwargs)\n        except urllib3.exceptions.TimeoutError:\n            raise TimedOut()\n        except urllib3.exceptions.HTTPError as error:\n            # HTTPError must come last as its the base urllib3 exception class\n            # TODO: do something smart here; for now just raise NetworkError\n            raise NetworkError('urllib3 HTTPError {0}'.format(error))\n\n        if 200 <= resp.status <= 299:\n            # 200-299 range are HTTP success statuses\n            return resp.data\n\n        try:\n            message = self._parse(resp.data)\n        except ValueError:\n            message = 'Unknown HTTPError'\n\n        if resp.status in (401, 403):\n            raise Unauthorized(message)\n        elif resp.status == 400:\n            raise BadRequest(message)\n        elif resp.status == 404:\n            raise InvalidToken()\n        elif resp.status == 413:\n            raise NetworkError('File too large. Check telegram api limits '\n                               'https://core.telegram.org/bots/api#senddocument')\n\n        elif resp.status == 502:\n            raise NetworkError('Bad Gateway')\n        else:\n            raise NetworkError('{0} ({1})'.format(message, resp.status))\n\n    def get(self, url, timeout=None):\n        \"\"\"Request an URL.\n\n        Args:\n            url (str): The web location we want to retrieve.\n            timeout (Optional[int|float]): If this value is specified, use it as the read timeout\n                from the server (instead of the one specified during creation of the connection\n                pool).\n\n        Returns:\n          A JSON object.\n\n        \"\"\"\n        urlopen_kwargs = {}\n\n        if timeout is not None:\n            urlopen_kwargs['timeout'] = Timeout(read=timeout, connect=self._connect_timeout)\n\n        result = self._request_wrapper('GET', url, **urlopen_kwargs)\n        return self._parse(result)\n\n    def post(self, url, data, timeout=None):\n        \"\"\"Request an URL.\n        Args:\n            url (str): The web location we want to retrieve.\n            data (dict[str, str|int]): A dict of key/value pairs. Note: On py2.7 value is unicode.\n            timeout (Optional[int|float]): If this value is specified, use it as the read timeout\n                from the server (instead of the one specified during creation of the connection\n                pool).\n\n        Returns:\n          A JSON object.\n\n        \"\"\"\n        urlopen_kwargs = {}\n\n        if timeout is not None:\n            urlopen_kwargs['timeout'] = Timeout(read=timeout, connect=self._connect_timeout)\n\n        if InputFile.is_inputfile(data):\n            data = InputFile(data)\n            result = self._request_wrapper(\n                'POST', url, body=data.to_form(), headers=data.headers, **urlopen_kwargs)\n        else:\n            data = json.dumps(data)\n            result = self._request_wrapper(\n                'POST',\n                url,\n                body=data.encode(),\n                headers={'Content-Type': 'application/json'},\n                **urlopen_kwargs)\n\n        return self._parse(result)\n\n    def retrieve(self, url, timeout=None):\n        \"\"\"Retrieve the contents of a file by its URL.\n\n        Args:\n            url (str): The web location we want to retrieve.\n            timeout (Optional[int|float]): If this value is specified, use it as the read timeout\n                from the server (instead of the one specified during creation of the connection\n                pool).\n\n        \"\"\"\n        urlopen_kwargs = {}\n        if timeout is not None:\n            urlopen_kwargs['timeout'] = Timeout(read=timeout, connect=self._connect_timeout)\n\n        return self._request_wrapper('GET', url, **urlopen_kwargs)\n\n    def download(self, url, filename, timeout=None):\n        \"\"\"Download a file by its URL.\n        Args:\n            url (str): The web location we want to retrieve.\n            timeout (Optional[int|float]): If this value is specified, use it as the read timeout\n                from the server (instead of the one specified during creation of the connection\n                pool).\n\n          filename:\n            The filename within the path to download the file.\n\n        \"\"\"\n        buf = self.retrieve(url, timeout=timeout)\n        with open(filename, 'wb') as fobj:\n            fobj.write(buf)\n", "path": "telegram/utils/request.py"}]}