forked from 21dotco/ping21
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ping21-server.py
101 lines (82 loc) · 2.65 KB
/
ping21-server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import logging
import psutil
import subprocess
import os
import yaml
import ipaddress
from flask import Flask
from flask import request
from two1.wallet.two1_wallet import Wallet
from two1.bitserv.flask import Payment
from ping21 import ping21, getHostname
app = Flask(__name__)
# setup wallet
wallet = Wallet()
payment = Payment(app, wallet)
# flag for allowing private ip pinging
ALLOW_PRIVATE = False
# hide logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
@app.route('/manifest')
def manifest():
"""Provide the app manifest to the 21 crawler.
"""
with open('./manifest.yaml', 'r') as f:
manifest = yaml.load(f)
return json.dumps(manifest)
@app.route('/')
@payment.required(5)
def ping():
""" Runs ping on the provided url
Returns: HTTPResponse 200 with a json containing the ping info.
HTTP Response 400 if no uri is specified or the uri is malformed/cannot be pingd.
"""
try:
uri = request.args['uri']
except KeyError:
return 'HTTP Status 400: URI query parameter is missing from your request.', 400
try:
if ipaddress.ip_address(getHostname(uri)).is_private and not ALLOW_PRIVATE:
return 'HTTP Status 403: Private IP scanning is forbidden', 403
except ValueError:
pass
try:
data = ping21(uri)
response = json.dumps(data, indent=4, sort_keys=True)
return response
except ValueError as e:
return 'HTTP Status 400: {}'.format(e.args[0]), 400
if __name__ == '__main__':
import click
@click.command()
@click.option("-d", "--daemon", default=False, is_flag=True,
help="Run in daemon mode.")
@click.option("-p", "--private", default=False, is_flag=True,
help="Allow ping21 to ping private ips.")
def run(daemon, private):
if private:
global ALLOW_PRIVATE
ALLOW_PRIVATE = private
if daemon:
pid_file = './ping21.pid'
if os.path.isfile(pid_file):
pid = int(open(pid_file).read())
os.remove(pid_file)
try:
p = psutil.Process(pid)
p.terminate()
except:
pass
try:
p = subprocess.Popen(['python3', 'ping21-server.py'])
open(pid_file, 'w').write(str(p.pid))
except subprocess.CalledProcessError:
raise ValueError("error starting ping21-server.py daemon")
else:
print("Server running...")
app.run(host='::', port=6002)
run()