145 lines
4.3 KiB
Python
145 lines
4.3 KiB
Python
# standard import
|
||
import json
|
||
import os
|
||
import logging
|
||
import argparse
|
||
import sys
|
||
from http.server import (
|
||
HTTPServer,
|
||
BaseHTTPRequestHandler,
|
||
)
|
||
|
||
# external imports
|
||
import confini
|
||
from jsonrpc_std.parse import jsonrpc_from_str
|
||
from jsonrpc_std.interface import jsonrpc_response
|
||
|
||
# local imports
|
||
from eth_stat_syncer.store import RunStore
|
||
|
||
logging.basicConfig(level=logging.WARNING)
|
||
logg = logging.getLogger()
|
||
|
||
default_config_dir = os.environ.get('CONFINI_DIR', './config')
|
||
|
||
argparser = argparse.ArgumentParser()
|
||
argparser.add_argument('-c', '--config', dest='c', default=default_config_dir, type=str, help='rpc provider')
|
||
argparser.add_argument('--host', type=str, help='httpd host')
|
||
argparser.add_argument('--port', type=str, help='httpd port')
|
||
argparser.add_argument('--store-dir', dest='store_dir', type=str, help='syncerd data store base directory')
|
||
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
|
||
argparser.add_argument('-v', action='store_true', help='be verbose')
|
||
argparser.add_argument('-vv', action='store_true', help='be more verbose')
|
||
args = argparser.parse_args()
|
||
|
||
if args.vv:
|
||
logging.getLogger().setLevel(logging.DEBUG)
|
||
elif args.v:
|
||
logging.getLogger().setLevel(logging.INFO)
|
||
|
||
config = confini.Config(args.c, args.env_prefix)
|
||
config.process()
|
||
# override args
|
||
args_override = {
|
||
'HTTPD_HOST': getattr(args, 'host'),
|
||
'HTTPD_PORT': getattr(args, 'port'),
|
||
'STORE_BASE_DIR': getattr(args, 'store_dir'),
|
||
}
|
||
config.dict_override(args_override, 'cli flag')
|
||
logg.debug('loaded config: {}\n'.format(config))
|
||
|
||
class StatRequestHandler(BaseHTTPRequestHandler):
|
||
|
||
runstore = None
|
||
server_version = 'eth_stat_syncer/0.0.1'
|
||
|
||
|
||
def do_POST(self):
|
||
|
||
if self.headers.get('Content-Type') != 'application/json':
|
||
self.send_response(400, 'me read json only')
|
||
self.end_headers()
|
||
return
|
||
|
||
if 'application/json' not in self.headers.get('Accept').split(','):
|
||
self.send_response(400, 'me json only speak')
|
||
self.end_headers()
|
||
return
|
||
|
||
l = self.headers.get('Content-Length')
|
||
try:
|
||
l = int(l)
|
||
except ValueError:
|
||
self.send_response(400, 'content length must be integer')
|
||
self.end_headers()
|
||
return
|
||
if l > 4096:
|
||
self.send_response(400, 'too much information')
|
||
self.end_headers()
|
||
return
|
||
if l < 0:
|
||
self.send_response(400, 'you are too negative')
|
||
self.end_headers()
|
||
return
|
||
|
||
b = b''
|
||
c = 0
|
||
while c < l:
|
||
d = self.rfile.read(l-c)
|
||
if d == None:
|
||
break
|
||
b += d
|
||
c += len(d)
|
||
if c > 4096:
|
||
self.send_response(413, 'i should slap you around for lying about your size')
|
||
self.end_headers()
|
||
return
|
||
|
||
o = None
|
||
err = None
|
||
try:
|
||
o = jsonrpc_from_str(b.decode('utf-8'))
|
||
except JSONRPCException as e:
|
||
err = e
|
||
|
||
if err != None:
|
||
res = e
|
||
self.send_response(200, 'alas with jsonrpc error')
|
||
|
||
else:
|
||
r = self.runstore.get('high', 'minute')
|
||
r = int(r)
|
||
if r == 0:
|
||
r = 1
|
||
res = jsonrpc_response(o['id'], r)
|
||
logg.debug('returning {} for req {} {}'.format(r, o, self.requestline))
|
||
self.send_response(200, 'It\'s a gas')
|
||
|
||
b = json.dumps(res).encode('utf-8')
|
||
l = len(b)
|
||
self.send_header('Content-Length', str(l))
|
||
self.send_header('Cache-Control', 'no-cache')
|
||
self.send_header('Content-Type', 'application/json')
|
||
self.end_headers()
|
||
|
||
c = 0
|
||
while c < l:
|
||
n = self.wfile.write(b[c:])
|
||
c += n
|
||
|
||
|
||
def run(store, host=None, port=None):
|
||
if host == None:
|
||
host = ''
|
||
if port == None:
|
||
port = 8000
|
||
StatRequestHandler.runstore = store
|
||
server_address = (host, port)
|
||
httpd = HTTPServer(server_address, StatRequestHandler)
|
||
httpd.serve_forever()
|
||
|
||
|
||
if __name__ == '__main__':
|
||
store = RunStore(basedir=config.get('STORE_BASE_DIR'))
|
||
run(store, host=config.get('HTTPD_HOST'), port=config.get('HTTPD_PORT'))
|