diff --git a/lbrynet/extras/daemon/Components.py b/lbrynet/extras/daemon/Components.py index 4bb8d427e..4a930b050 100644 --- a/lbrynet/extras/daemon/Components.py +++ b/lbrynet/extras/daemon/Components.py @@ -1,6 +1,5 @@ import os import asyncio -import aiohttp import logging import math import binascii @@ -54,11 +53,10 @@ async def gather_dict(tasks: dict): async def get_external_ip(): # used if upnp is disabled or non-functioning try: - async with aiohttp.ClientSession() as session: - async with session.get("https://api.lbry.io/ip") as resp: - response = await resp.json() - if response['success']: - return response['data']['ip'] + async with utils.aiohttp_request("get", "https://api.lbry.io/ip") as resp: + response = await resp.json() + if response['success']: + return response['data']['ip'] except Exception as e: pass @@ -149,7 +147,7 @@ class HeadersComponent(Component): async def fetch_headers_from_s3(self): local_header_size = self.local_header_file_size() resume_header = {"Range": f"bytes={local_header_size}-"} - async with aiohttp.request('get', HEADERS_URL, headers=resume_header) as response: + async with utils.aiohttp_request('get', HEADERS_URL, headers=resume_header) as response: if response.status == 406 or response.content_length < HEADER_SIZE: # our file is bigger log.warning("s3 is more out of date than we are") return diff --git a/lbrynet/extras/daemon/analytics.py b/lbrynet/extras/daemon/analytics.py index 3ac005b6a..db4115c29 100644 --- a/lbrynet/extras/daemon/analytics.py +++ b/lbrynet/extras/daemon/analytics.py @@ -81,7 +81,7 @@ class Manager: 'cookies': self.cookies } try: - async with aiohttp.request(**request_kwargs) as response: + async with utils.aiohttp_request(**request_kwargs) as response: self.cookies.update(response.cookies) except Exception as e: log.exception('Encountered an exception while POSTing to %s: ', self.url + endpoint, exc_info=e) diff --git a/lbrynet/extras/daemon/exchange_rate_manager.py b/lbrynet/extras/daemon/exchange_rate_manager.py index b304f265f..12f83c865 100644 --- a/lbrynet/extras/daemon/exchange_rate_manager.py +++ b/lbrynet/extras/daemon/exchange_rate_manager.py @@ -1,10 +1,10 @@ import asyncio -import aiohttp import time import logging import json from lbrynet.error import InvalidExchangeRateResponse, CurrencyConversionError +from lbrynet.utils import aiohttp_request log = logging.getLogger(__name__) @@ -52,8 +52,8 @@ class MarketFeed: def is_online(self): return self._online - async def _make_request(self): - async with aiohttp.request('get', self.url, params=self.params) as response: + async def _make_request(self) -> str: + async with aiohttp_request('get', self.url, params=self.params) as response: return (await response.read()).decode() def _handle_response(self, response): diff --git a/lbrynet/extras/daemon/loggly_handler.py b/lbrynet/extras/daemon/loggly_handler.py index 57456ce23..99fdff040 100644 --- a/lbrynet/extras/daemon/loggly_handler.py +++ b/lbrynet/extras/daemon/loggly_handler.py @@ -1,5 +1,4 @@ import asyncio -import aiohttp import json import logging.handlers import traceback @@ -51,7 +50,7 @@ class HTTPSLogglyHandler(logging.Handler): async def _emit(self, record): payload = self.format(record) - async with aiohttp.request('post', self.url, data=payload.encode(), cookies=self.cookies) as response: + async with utils.aiohttp_request('post', self.url, data=payload.encode(), cookies=self.cookies) as response: self.cookies.update(response.cookies) def emit(self, record): diff --git a/lbrynet/utils.py b/lbrynet/utils.py index ecb43fc71..86d917b25 100644 --- a/lbrynet/utils.py +++ b/lbrynet/utils.py @@ -7,9 +7,13 @@ import string import json import typing import asyncio +import ssl import logging import ipaddress import pkg_resources +import contextlib +import certifi +import aiohttp from lbrynet.schema.claim import ClaimDict from lbrynet.cryptoutils import get_lbry_hash_obj @@ -156,3 +160,16 @@ async def resolve_host(url: str, port: int, proto: str) -> str: proto=socket.IPPROTO_TCP if proto == 'tcp' else socket.IPPROTO_UDP, type=socket.SOCK_STREAM if proto == 'tcp' else socket.SOCK_DGRAM ))[0][4][0] + + +def get_ssl_context() -> ssl.SSLContext: + return ssl.create_default_context( + purpose=ssl.Purpose.CLIENT_AUTH, capath=certifi.where() + ) + + +@contextlib.asynccontextmanager +async def aiohttp_request(method, url, **kwargs) -> typing.AsyncContextManager[aiohttp.ClientResponse]: + async with aiohttp.ClientSession() as session: + async with session.request(method, url, ssl=get_ssl_context(), **kwargs) as response: + yield response diff --git a/setup.py b/setup.py index 5b193236e..27df21ce7 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,7 @@ setup( 'aiohttp==3.5.4', 'aioupnp', 'appdirs==1.4.3', + 'certifi>=2018.11.29', 'colorama==0.3.7', 'distro==1.4.0', 'base58==1.0.0',