def post(self): """ Unserialise the data and accept the following calls: PING CHAT APPEND LEAVING FIND_NODE FIND_VALUE APPEND signifies the requesting host has data for the given hash. """ parser = restful.reqparse.RequestParser() parser.add_argument("data", type=str, help="The RPC body.", default=None) args = parser.parse_args() if not args.data: return {}, 400 response = [] data = json.loads(args.data) if not validate_signature(data): log("Received message from %s with an invalid signature." % request.remote_addr) return "Invalid message signature.", 400 if not 'node' in data: log("%s didn't provide useable information about themselves." % request.remote_addr, "warning") return {}, 400 # Validate the node field for internet hosts if not any([request.remote_addr.startswith(subnet) for subnet in local_subnets]): stated_addr = data['node'].split()[1] if stated_addr != request.remote_addr: log("Request made from %s stated it originated from %s" % (request.remote_addr, stated_addr), "warning") return "sicillian shrug", 418 # Execute the corresponding RPC handler for field in data.keys(): if field.startswith('rpc_'): rpc_name = 'handle_%s' % field.replace('rpc_', '') # data[rpc_name] = data[field] # del data[field] rpc_method = getattr(app.routes.protocol, rpc_name, None) if not rpc_method: log("%s tried to call unknown procedure %s." % (request.remote_addr, rpc_name), "warning") return {}, 400 response = rpc_method(data) break return response
def store(responses): """ A closure for a dictionary of responses from ALPHA nodes containing peer information for neighbours close to a target key. These responses don't contain their own 'peers' field at the moment. """ # print pprint.pformat(responses) nodes = [] for id, response in responses.items(): valid_signature = utils.validate_signature(response) log("Received %s signature from %s." % \ ("valid" if valid_signature else "invalid", long(id.encode('hex'), 16))) if valid_signature: for data in response['nodes']: if not [data['node'][1],data['node'][2]] in [[n.ip, n.port] for n in nodes]: nodes.append(Node(*data['node'], pubkey=data['pubkey'])) log("Telling %s we have %s." % (nodes, url)) # Change self.storage_method when ready. threads = [gevent.spawn(self.storage_method, node, hexlify(hashed_url), content_hash) for node in nodes] gevent.joinall(threads) threads = [thread.value for thread in threads] log("%s: %s" % (self.storage_method.func_name, threads))