84 lines
No EOL
2.3 KiB
Python
84 lines
No EOL
2.3 KiB
Python
import socket as _socket
|
|
import urllib.request
|
|
import http.client
|
|
|
|
from typing import Optional, Dict
|
|
from urllib.request import Request
|
|
|
|
|
|
ZERO_64 = b'\x00' * 64
|
|
HANDSHAKE_LEN = 64
|
|
SKIP_LEN = 8
|
|
PREKEY_LEN = 32
|
|
KEY_LEN = 32
|
|
IV_LEN = 16
|
|
PROTO_TAG_POS = 56
|
|
DC_IDX_POS = 60
|
|
|
|
PROTO_TAG_ABRIDGED = b'\xef\xef\xef\xef'
|
|
PROTO_TAG_INTERMEDIATE = b'\xee\xee\xee\xee'
|
|
PROTO_TAG_SECURE = b'\xdd\xdd\xdd\xdd'
|
|
|
|
PROTO_ABRIDGED_INT = 0xEFEFEFEF
|
|
PROTO_INTERMEDIATE_INT = 0xEEEEEEEE
|
|
PROTO_PADDED_INTERMEDIATE_INT = 0xDDDDDDDD
|
|
|
|
RESERVED_FIRST_BYTES = {0xEF}
|
|
RESERVED_STARTS = {b'\x48\x45\x41\x44', b'\x50\x4F\x53\x54',
|
|
b'\x47\x45\x54\x20', b'\xee\xee\xee\xee',
|
|
b'\xdd\xdd\xdd\xdd', b'\x16\x03\x01\x02'}
|
|
RESERVED_CONTINUE = b'\x00\x00\x00\x00'
|
|
|
|
_GITHUB_IPS: Dict[str, str] = {
|
|
"release-assets.githubusercontent.com": "185.199.109.133",
|
|
"raw.githubusercontent.com": "185.199.109.133",
|
|
}
|
|
|
|
|
|
def human_bytes(n: int) -> str:
|
|
for unit in ('B', 'KB', 'MB', 'GB'):
|
|
if abs(n) < 1024:
|
|
return f"{n:.1f}{unit}"
|
|
n /= 1024 # type: ignore
|
|
return f"{n:.1f}TB"
|
|
|
|
|
|
def get_link_host(host: str) -> Optional[str]:
|
|
if host == '0.0.0.0':
|
|
try:
|
|
with _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM) as _s:
|
|
_s.connect(('8.8.8.8', 80))
|
|
link_host = _s.getsockname()[0]
|
|
except OSError:
|
|
link_host = '127.0.0.1'
|
|
return link_host
|
|
else:
|
|
return host
|
|
|
|
|
|
class _PinnedHTTPSHandler(urllib.request.HTTPSHandler):
|
|
def https_open(self, req: Request):
|
|
host = req.host.split(":")[0]
|
|
ip = _GITHUB_IPS.get(host)
|
|
if not ip:
|
|
return super().https_open(req)
|
|
pinned = ip
|
|
|
|
class _Conn(http.client.HTTPSConnection):
|
|
def connect(self):
|
|
self.sock = _socket.create_connection(
|
|
(pinned, self.port or 443),
|
|
self.timeout,
|
|
self.source_address,
|
|
)
|
|
if self._tunnel_host:
|
|
self._tunnel()
|
|
self.sock = self._context.wrap_socket(
|
|
self.sock, server_hostname=self._tunnel_host or self.host
|
|
)
|
|
|
|
return self.do_open(_Conn, req)
|
|
|
|
|
|
def build_github_opener() -> urllib.request.OpenerDirector:
|
|
return urllib.request.build_opener(_PinnedHTTPSHandler()) |