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

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)