def POST_zonefile(self, path_info):
        """
        Publish a zonefile which has *already* been announced.
        Return 200 and {'status': True, 'servers': [...]} on success
        Return 400 on invalid request, such as invalid JSON, JSON that doesn't match the schema, etc.
        Return 502 on failure to replicate the zone file
        """
        request_schema = {
            'type': 'object',
            'properties': {
                'zonefile': {
                    'type': 'string',
                    'maxLength': RPC_MAX_ZONEFILE_LEN
                },
                'zonefile_b64': {
                    'type': 'string',
                    'pattern': OP_BASE64_EMPTY_PATTERN,
                    'maxLength': (RPC_MAX_ZONEFILE_LEN * 4) / 3 + 1,
                }
            }
        }
        blockstackd_url = get_blockstackd_url()
        zonefile_json = self._read_json(schema=request_schema)
        if zonefile_json is None:
            return self._reply_json({'error': 'Invalid request'}, status_code=400)

        elif 'error' in zonefile_json:
            log.error("Failed to parse JSON")
            return self._reply_json({'error': 'Invalid request'}, status_code=400)
        
        zonefile_str = zonefile_json.get('zonefile', False)
        zonefile_hash = None 

        if zonefile_str:
            # base64-encode 
            zonefile_hash = storage.get_zonefile_data_hash(zonefile_str)
            zonefile_str = base64.b64encode(zonefile_str)

        else:
            # already given as b64-encoded?
            zonefile_str = zonefile_json.get('zonefile_b64', False)
            if not zonefile_str:
                # neither given
                return self._reply_json({'error': 'Invalid request'}, status_code=400)

            zonefile_hash = storage.get_zonefile_data_hash(base64.b64decode(zonefile_json['zonefile_b64']))

        zonefiles_b64 = [zonefile_str]
        resp = blockstackd_client.put_zonefiles(blockstackd_url, zonefiles_b64)
        if json_is_error(resp):
            log.error("Failed to put {}: {}".format(zonefile_hash, resp['error']))
            return self._reply_json({'error': resp['error']}, status_code=resp.get('http_status', 502))

        if len(resp['saved']) != 1:
            log.error("Did not save {}, saved is {}".format(zonefile_hash, resp['saved']))
            return self._reply_json({'error': 'Blockstack node did not save the zone file'}, status_code=400)

        return self._reply_json({'status': True, 'servers': [blockstackd_url]}, status_code=200)
def POST_zonefile ( self , path_info ) : request_schema = { 'type' : 'object' , 'properties' : { 'zonefile' : { 'type' : 'string' , 'maxLength' : RPC_MAX_ZONEFILE_LEN } , 'zonefile_b64' : { 'type' : 'string' , 'pattern' : OP_BASE64_EMPTY_PATTERN , 'maxLength' : ( RPC_MAX_ZONEFILE_LEN * 4 ) / 3 + 1 , } } } blockstackd_url = get_blockstackd_url ( ) zonefile_json = self . _read_json ( schema = request_schema ) if zonefile_json is None : return self . _reply_json ( { 'error' : 'Invalid request' } , status_code = 400 ) elif 'error' in zonefile_json : log . error ( "Failed to parse JSON" ) return self . _reply_json ( { 'error' : 'Invalid request' } , status_code = 400 ) zonefile_str = zonefile_json . get ( 'zonefile' , False ) zonefile_hash = None if zonefile_str : zonefile_hash = storage . get_zonefile_data_hash ( zonefile_str ) zonefile_str = base64 . b64encode ( zonefile_str ) else : zonefile_str = zonefile_json . get ( 'zonefile_b64' , False ) if not zonefile_str : return self . _reply_json ( { 'error' : 'Invalid request' } , status_code = 400 ) zonefile_hash = storage . get_zonefile_data_hash ( base64 . b64decode ( zonefile_json [ 'zonefile_b64' ] ) ) zonefiles_b64 = [ zonefile_str ] resp = blockstackd_client . put_zonefiles ( blockstackd_url , zonefiles_b64 ) if json_is_error ( resp ) : log . error ( "Failed to put {}: {}" . format ( zonefile_hash , resp [ 'error' ] ) ) return self . _reply_json ( { 'error' : resp [ 'error' ] } , status_code = resp . get ( 'http_status' , 502 ) ) if len ( resp [ 'saved' ] ) != 1 : log . error ( "Did not save {}, saved is {}" . format ( zonefile_hash , resp [ 'saved' ] ) ) return self . _reply_json ( { 'error' : 'Blockstack node did not save the zone file' } , status_code = 400 ) return self . _reply_json ( { 'status' : True , 'servers' : [ blockstackd_url ] } , status_code = 200 )
Publish a zonefile which has *already* been announced.
        Return 200 and {'status': True, 'servers': [...]} on success
        Return 400 on invalid request, such as invalid JSON, JSON that doesn't match the schema, etc.
        Return 502 on failure to replicate the zone file