Skip to content

Instantly share code, notes, and snippets.

@cdy51223
Forked from lilydjwg/gh-check
Created March 17, 2022 08:32
Show Gist options
  • Select an option

  • Save cdy51223/2ba6705e6e30e710649b5082ce8dbc8b to your computer and use it in GitHub Desktop.

Select an option

Save cdy51223/2ba6705e6e30e710649b5082ce8dbc8b to your computer and use it in GitHub Desktop.

Revisions

  1. @lilydjwg lilydjwg revised this gist Dec 3, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions gh-check
    Original file line number Diff line number Diff line change
    @@ -105,7 +105,7 @@ async def main(proto):
    producer_fu = asyncio.ensure_future(producer(q, proto))
    printer_fu = asyncio.ensure_future(printer(ret_q))

    await asyncio.wait(futures)
    await asyncio.gather(*futures)
    printer_fu.cancel()
    await producer_fu
    await printer_fu
    @@ -125,7 +125,7 @@ async def update_hosts():
    finder_fu = asyncio.ensure_future(
    fastest_finder(ret_q))

    await asyncio.wait(futures)
    await asyncio.gather(*futures)
    finder_fu.cancel()
    await producer_fu
    ip = await finder_fu
  2. @lilydjwg lilydjwg revised this gist Sep 27, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions gh-check
    Original file line number Diff line number Diff line change
    @@ -168,8 +168,8 @@ async def get_items(proto):
    ('140.82.114.4', 'Ashburn'),
    ('140.82.118.3', 'Armsterdam'),
    ('140.82.118.4', 'Armsterdam'),
    ('140.82.121.3', 'Frankfort'),
    ('140.82.121.4', 'Frankfort'),
    ('140.82.121.3', 'Frankfurt'),
    ('140.82.121.4', 'Frankfurt'),
    ('13.237.44.5', 'Sydney'),
    ('52.64.108.95', 'Sydney'),
    ('13.236.229.21', 'Sydney'),
  3. @lilydjwg lilydjwg revised this gist Sep 27, 2020. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion gh-check
    Original file line number Diff line number Diff line change
    @@ -156,16 +156,20 @@ async def get_items(proto):
    ('13.229.188.59', 'Singapore'),
    ('13.250.177.223', 'Singapore'),
    ('52.74.223.119', 'Singapore'),
    ('192.30.255.113', 'Seattle'),
    ('192.30.255.112', 'Seattle'),
    ('192.30.255.113', 'Seattle'),
    ('140.82.112.3', 'Seattle'),
    ('140.82.112.4', 'Seattle'),
    ('192.30.253.112', 'Ashburn'),
    ('192.30.253.113', 'Ashburn'),
    ('140.82.113.3', 'Ashburn'),
    ('140.82.113.4', 'Ashburn'),
    ('140.82.114.3', 'Ashburn'),
    ('140.82.114.4', 'Ashburn'),
    ('140.82.118.3', 'Armsterdam'),
    ('140.82.118.4', 'Armsterdam'),
    ('140.82.121.3', 'Frankfort'),
    ('140.82.121.4', 'Frankfort'),
    ('13.237.44.5', 'Sydney'),
    ('52.64.108.95', 'Sydney'),
    ('13.236.229.21', 'Sydney'),
  4. @lilydjwg lilydjwg revised this gist Jul 24, 2020. 1 changed file with 29 additions and 34 deletions.
    63 changes: 29 additions & 34 deletions gh-check
    Original file line number Diff line number Diff line change
    @@ -131,7 +131,7 @@ async def update_hosts():
    ip = await finder_fu

    if ip is not None:
    cmd = ['sed', '-i', rf'/^[0-9.]\+[[:space:]]\+github\.com\>/s/[^[:space:]]\+/{ip}/', '/etc/hosts']
    cmd = ['sed', '-Ei', rf'/^[0-9.]+[[:space:]]+(gist\.)?github\.com\>/s/[^[:space:]]+/{ip}/', '/etc/hosts']
    subprocess.check_call(cmd)

    async def resolve(domain):
    @@ -145,41 +145,36 @@ async def resolve(domain):
    return domain, ips

    async def get_items(proto):
    domains = [
    "sea-region.github.com",
    "iad-region.github.com",
    "sin-region.github.com",
    "ams-region.github.com",
    "fra-region.github.com",
    ]
    print('Resolving domains...', flush=True, end='')
    futures = [resolve(domain) for domain in domains]
    futures, _ = await asyncio.wait(futures)
    results = [fu.result() for fu in futures]

    items = []
    for domain, ips in results:
    for ip in ips:
    items.append((domain, ip))
    print('done.')

    items += [
    ('Sydney', '13.237.44.5'),
    ('Sydney', '52.64.108.95'),
    ('Sydney', '13.236.229.21'),
    ('Sao Paulo', '18.231.5.6'),
    ('Sao Paulo', '18.228.52.138'),
    ('Sao Paulo', '18.228.67.229'),
    ('Seoul', '15.164.81.167'),
    ('Seoul', '52.78.231.108'),
    ('Tokyo', '52.192.72.89'),
    ('Tokyo', '13.114.40.48'),
    ('Tokyo', '52.69.186.44'),
    ('Bombay', '13.234.210.38'),
    ('Bombay', '13.234.176.102'),
    items = [
    ('13.234.210.38', 'Bombay'),
    ('13.234.176.102', 'Bombay'),
    ('52.192.72.89', 'Tokyo'),
    ('13.114.40.48', 'Tokyo'),
    ('52.69.186.44', 'Tokyo'),
    ('15.164.81.167', 'Seoul'),
    ('52.78.231.108', 'Seoul'),
    ('13.229.188.59', 'Singapore'),
    ('13.250.177.223', 'Singapore'),
    ('52.74.223.119', 'Singapore'),
    ('192.30.255.113', 'Seattle'),
    ('192.30.255.112', 'Seattle'),
    ('140.82.112.3', 'Seattle'),
    ('140.82.112.4', 'Seattle'),
    ('140.82.113.3', 'Ashburn'),
    ('140.82.113.4', 'Ashburn'),
    ('140.82.114.3', 'Ashburn'),
    ('140.82.114.4', 'Ashburn'),
    ('140.82.118.3', 'Armsterdam'),
    ('140.82.118.4', 'Armsterdam'),
    ('13.237.44.5', 'Sydney'),
    ('52.64.108.95', 'Sydney'),
    ('13.236.229.21', 'Sydney'),
    ('18.231.5.6', 'Sao Paulo'),
    ('18.228.52.138', 'Sao Paulo'),
    ('18.228.67.229', 'Sao Paulo'),
    ]

    return [(x[0], x[1], y) for x in items for y in proto]
    return [(x[1], x[0], y) for x in items for y in proto]

    if __name__ == '__main__':
    import logging
  5. @lilydjwg lilydjwg revised this gist May 15, 2020. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions gh-check
    Original file line number Diff line number Diff line change
    @@ -146,10 +146,11 @@ async def resolve(domain):

    async def get_items(proto):
    domains = [
    "ams-region.github.com",
    "sea-region.github.com",
    "iad-region.github.com",
    "sin-region.github.com",
    "ams-region.github.com",
    "fra-region.github.com",
    ]
    print('Resolving domains...', flush=True, end='')
    futures = [resolve(domain) for domain in domains]
    @@ -171,7 +172,7 @@ async def get_items(proto):
    ('Sao Paulo', '18.228.67.229'),
    ('Seoul', '15.164.81.167'),
    ('Seoul', '52.78.231.108'),
    ('Seattle', '52.192.72.89'),
    ('Tokyo', '52.192.72.89'),
    ('Tokyo', '13.114.40.48'),
    ('Tokyo', '52.69.186.44'),
    ('Bombay', '13.234.210.38'),
    @@ -203,4 +204,4 @@ if __name__ == '__main__':
    try:
    loop.run_until_complete(main_fu)
    except KeyboardInterrupt:
    pass
    pass
  6. @lilydjwg lilydjwg revised this gist Apr 16, 2020. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions gh-check
    Original file line number Diff line number Diff line change
    @@ -130,8 +130,9 @@ async def update_hosts():
    await producer_fu
    ip = await finder_fu

    cmd = ['sed', '-i', rf'/^[0-9.]\+[[:space:]]\+github\.com\>/s/[^[:space:]]\+/{ip}/', '/etc/hosts']
    subprocess.check_call(cmd)
    if ip is not None:
    cmd = ['sed', '-i', rf'/^[0-9.]\+[[:space:]]\+github\.com\>/s/[^[:space:]]\+/{ip}/', '/etc/hosts']
    subprocess.check_call(cmd)

    async def resolve(domain):
    loop = asyncio.get_event_loop()
  7. @lilydjwg lilydjwg revised this gist Apr 16, 2020. 1 changed file with 13 additions and 2 deletions.
    15 changes: 13 additions & 2 deletions gh-check
    Original file line number Diff line number Diff line change
    @@ -162,8 +162,19 @@ async def get_items(proto):
    print('done.')

    items += [
    ('(Tokyo)', '52.69.186.44'),
    ('(Sydney)', '52.64.108.95'),
    ('Sydney', '13.237.44.5'),
    ('Sydney', '52.64.108.95'),
    ('Sydney', '13.236.229.21'),
    ('Sao Paulo', '18.231.5.6'),
    ('Sao Paulo', '18.228.52.138'),
    ('Sao Paulo', '18.228.67.229'),
    ('Seoul', '15.164.81.167'),
    ('Seoul', '52.78.231.108'),
    ('Seattle', '52.192.72.89'),
    ('Tokyo', '13.114.40.48'),
    ('Tokyo', '52.69.186.44'),
    ('Bombay', '13.234.210.38'),
    ('Bombay', '13.234.176.102'),
    ]

    return [(x[0], x[1], y) for x in items for y in proto]
  8. @lilydjwg lilydjwg revised this gist Apr 2, 2020. 1 changed file with 64 additions and 13 deletions.
    77 changes: 64 additions & 13 deletions gh-check
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    import asyncio
    import time
    import socket
    import sys
    import argparse

    import aiohttp

    @@ -38,14 +38,17 @@ async def test_domain_ssh(domain, ip):
    async def test_domain_http(domain, ip):
    url = 'https://github.com/'
    st = time.time()
    async with aiohttp.ClientSession(connector=MyConnector(ip)) as s:
    async with aiohttp.ClientSession(
    connector = MyConnector(ip),
    timeout = aiohttp.ClientTimeout(total=10),
    ) as s:
    r = await s.get(url)
    _ = await r.text()

    return time.time() - st

    async def producer(q):
    items = await get_items()
    async def producer(q, proto):
    items = await get_items(proto)
    for item in items:
    await q.put(item)

    @@ -65,6 +68,21 @@ async def printer(q):
    (domain, ip, proto), t = item
    print(f'{domain:21} {ip:15} {proto:4} {t:6.2f}')

    async def fastest_finder(q):
    fastest_ip, latency = None, 1000

    while True:
    try:
    item = await q.get()
    except asyncio.CancelledError:
    return fastest_ip

    if not isinstance(item[1], Exception):
    (_, ip, _), t = item
    if t < latency:
    latency = t
    fastest_ip = ip

    async def worker(q, ret_q):
    while True:
    item = await q.get()
    @@ -79,19 +97,42 @@ async def worker(q, ret_q):
    else:
    await ret_q.put((item, t))

    async def main():
    async def main(proto):
    q = asyncio.Queue()
    ret_q = asyncio.Queue()

    futures = [worker(q, ret_q) for _ in range(40)]
    producer_fu = asyncio.ensure_future(producer(q))
    producer_fu = asyncio.ensure_future(producer(q, proto))
    printer_fu = asyncio.ensure_future(printer(ret_q))

    await asyncio.wait(futures)
    printer_fu.cancel()
    await producer_fu
    await printer_fu

    async def update_hosts():
    import os, sys, subprocess

    if os.geteuid() != 0:
    sys.exit('not root?')

    q = asyncio.Queue()
    ret_q = asyncio.Queue()

    futures = [worker(q, ret_q) for _ in range(40)]
    producer_fu = asyncio.ensure_future(
    producer(q, ['http']))
    finder_fu = asyncio.ensure_future(
    fastest_finder(ret_q))

    await asyncio.wait(futures)
    finder_fu.cancel()
    await producer_fu
    ip = await finder_fu

    cmd = ['sed', '-i', rf'/^[0-9.]\+[[:space:]]\+github\.com\>/s/[^[:space:]]\+/{ip}/', '/etc/hosts']
    subprocess.check_call(cmd)

    async def resolve(domain):
    loop = asyncio.get_event_loop()
    addrinfo = await loop.getaddrinfo(
    @@ -102,7 +143,7 @@ async def resolve(domain):
    ips = [x[-1][0] for x in addrinfo]
    return domain, ips

    async def get_items():
    async def get_items(proto):
    domains = [
    "ams-region.github.com",
    "sea-region.github.com",
    @@ -125,19 +166,29 @@ async def get_items():
    ('(Sydney)', '52.64.108.95'),
    ]

    if len(sys.argv) == 2:
    proto = sys.argv[1]
    proto = [proto]
    else:
    proto = ['http', 'ssh']
    return [(x[0], x[1], y) for x in items for y in proto]

    if __name__ == '__main__':
    import logging
    logging.getLogger().addHandler(logging.NullHandler())

    parser = argparse.ArgumentParser(
    description='GitHub IP 访问速度测试')
    parser.add_argument('proto', nargs='*',
    default=['http', 'ssh'],
    help='测试指定协议')
    parser.add_argument('--hosts',
    action='store_true',
    help='更新 /etc/hosts')
    args = parser.parse_args()

    if args.hosts:
    main_fu = update_hosts()
    else:
    main_fu = main(args.proto)

    loop = asyncio.get_event_loop()
    try:
    loop.run_until_complete(main())
    loop.run_until_complete(main_fu)
    except KeyboardInterrupt:
    pass
  9. @lilydjwg lilydjwg created this gist Aug 16, 2019.
    143 changes: 143 additions & 0 deletions gh-check
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,143 @@
    #!/usr/bin/python3

    import asyncio
    import time
    import socket
    import sys

    import aiohttp

    class MyConnector(aiohttp.TCPConnector):
    def __init__(self, ip):
    self.__ip = ip
    super().__init__()

    async def _resolve_host(
    self, host: str, port: int,
    traces: None = None,
    ):
    return [{
    'hostname': host, 'host': self.__ip, 'port': port,
    'family': self._family, 'proto': 0, 'flags': 0,
    }]

    async def test_domain(domain, ip, proto):
    if proto == 'http':
    return await test_domain_http(domain, ip)
    elif proto == 'ssh':
    return await test_domain_ssh(domain, ip)
    else:
    raise ValueError('unknown proto', proto)

    async def test_domain_ssh(domain, ip):
    st = time.time()
    r, _w = await asyncio.open_connection(ip, 22)
    await r.read(1)
    return time.time() - st

    async def test_domain_http(domain, ip):
    url = 'https://github.com/'
    st = time.time()
    async with aiohttp.ClientSession(connector=MyConnector(ip)) as s:
    r = await s.get(url)
    _ = await r.text()

    return time.time() - st

    async def producer(q):
    items = await get_items()
    for item in items:
    await q.put(item)

    await q.put(None)

    async def printer(q):
    while True:
    try:
    item = await q.get()
    except asyncio.CancelledError:
    break

    if isinstance(item[1], Exception):
    (domain, ip, proto), e = item
    print(f'{domain:21} {ip:15} {proto:4} {e!r}')
    else:
    (domain, ip, proto), t = item
    print(f'{domain:21} {ip:15} {proto:4} {t:6.2f}')

    async def worker(q, ret_q):
    while True:
    item = await q.get()
    if item is None:
    await q.put(None)
    break

    try:
    t = await test_domain(*item)
    except Exception as e:
    await ret_q.put((item, e))
    else:
    await ret_q.put((item, t))

    async def main():
    q = asyncio.Queue()
    ret_q = asyncio.Queue()

    futures = [worker(q, ret_q) for _ in range(40)]
    producer_fu = asyncio.ensure_future(producer(q))
    printer_fu = asyncio.ensure_future(printer(ret_q))

    await asyncio.wait(futures)
    printer_fu.cancel()
    await producer_fu
    await printer_fu

    async def resolve(domain):
    loop = asyncio.get_event_loop()
    addrinfo = await loop.getaddrinfo(
    domain, None,
    family=socket.AF_INET,
    proto=socket.IPPROTO_TCP,
    )
    ips = [x[-1][0] for x in addrinfo]
    return domain, ips

    async def get_items():
    domains = [
    "ams-region.github.com",
    "sea-region.github.com",
    "iad-region.github.com",
    "sin-region.github.com",
    ]
    print('Resolving domains...', flush=True, end='')
    futures = [resolve(domain) for domain in domains]
    futures, _ = await asyncio.wait(futures)
    results = [fu.result() for fu in futures]

    items = []
    for domain, ips in results:
    for ip in ips:
    items.append((domain, ip))
    print('done.')

    items += [
    ('(Tokyo)', '52.69.186.44'),
    ('(Sydney)', '52.64.108.95'),
    ]

    if len(sys.argv) == 2:
    proto = sys.argv[1]
    proto = [proto]
    else:
    proto = ['http', 'ssh']
    return [(x[0], x[1], y) for x in items for y in proto]

    if __name__ == '__main__':
    import logging
    logging.getLogger().addHandler(logging.NullHandler())

    loop = asyncio.get_event_loop()
    try:
    loop.run_until_complete(main())
    except KeyboardInterrupt:
    pass