funga-eth

Ethereum implementation of the funga keystore and signer
Info | Log | Files | Refs | README | LICENSE

http.py (2298B)


      1 # standard imports
      2 import logging
      3 
      4 # external imports
      5 from http.server import (
      6         HTTPServer,
      7         BaseHTTPRequestHandler,
      8     )
      9 
     10 # local imports
     11 from .handle import SignRequestHandler
     12 from funga.error import SignerError
     13 
     14 logg = logging.getLogger(__name__)
     15 
     16 
     17 def start_server_http(spec):
     18     httpd = HTTPServer(spec, HTTPSignRequestHandler)
     19     logg.debug('starting http server {}'.format(spec))
     20     httpd.serve_forever()
     21 
     22 
     23 class HTTPSignRequestHandler(SignRequestHandler, BaseHTTPRequestHandler):
     24 
     25     def do_POST(self):
     26         if self.headers.get('Content-Type') != 'application/json':
     27             self.send_response(400, 'me read json only')
     28             self.end_headers()
     29             return
     30 
     31         try:
     32             if 'application/json' not in self.headers.get('Accept').split(','):
     33                 self.send_response(400, 'me json only speak')
     34                 self.end_headers()
     35                 return
     36         except AttributeError:
     37             pass
     38 
     39         l = self.headers.get('Content-Length')
     40         try:
     41             l = int(l)
     42         except ValueError:
     43             self.send_response(400, 'content length must be integer')
     44             self.end_headers()
     45             return
     46         if l > 4096:
     47             self.send_response(400, 'too much information')
     48             self.end_headers()
     49             return
     50         if l < 0:
     51             self.send_response(400, 'you are too negative')
     52             self.end_headers()
     53             return
     54 
     55         b = b''
     56         c = 0
     57         while c < l:
     58             d = self.rfile.read(l-c)
     59             if d == None:
     60                 break
     61             b += d
     62             c += len(d)
     63             if c > 4096:
     64                 self.send_response(413, 'i should slap you around for lying about your size')
     65                 self.end_headers()
     66                 return
     67 
     68         try:
     69             r = self.handle_jsonrpc(d)
     70         except SignerError as e:
     71             r = e.to_jsonrpc()
     72 
     73         l = len(r)
     74         self.send_response(200, 'You are the Keymaster')
     75         self.send_header('Content-Length', str(l))
     76         self.send_header('Cache-Control', 'no-cache')
     77         self.send_header('Content-Type', 'application/json')
     78         self.end_headers()
     79 
     80         c = 0
     81         while c < l:
     82             n = self.wfile.write(r[c:])
     83             c += n
     84 
     85