浏览代码

feat(api): gracefully deal with requests too large for pdns

Peter Thomassen 6 年之前
父节点
当前提交
a76ae0851b
共有 3 个文件被更改,包括 16 次插入6 次删除
  1. 4 0
      api/api/settings.py
  2. 9 6
      api/desecapi/exceptions.py
  3. 3 0
      api/desecapi/pdns.py

+ 4 - 0
api/api/settings.py

@@ -146,6 +146,10 @@ NSLORD_PDNS_API_TOKEN = os.environ['DESECSTACK_NSLORD_APIKEY']
 NSMASTER_PDNS_API = 'http://nsmaster:8081/api/v1/servers/localhost'
 NSMASTER_PDNS_API = 'http://nsmaster:8081/api/v1/servers/localhost'
 NSMASTER_PDNS_API_TOKEN = os.environ['DESECSTACK_NSMASTER_APIKEY']
 NSMASTER_PDNS_API_TOKEN = os.environ['DESECSTACK_NSMASTER_APIKEY']
 
 
+# pdns accepts request payloads of this size.
+# This will hopefully soon be configurable: https://github.com/PowerDNS/pdns/pull/7550
+PDNS_MAX_BODY_SIZE = 2 * 1024 * 1024
+
 # SEPA direct debit settings
 # SEPA direct debit settings
 SEPA = {
 SEPA = {
     'CREDITOR_ID': os.environ['DESECSTACK_API_SEPA_CREDITOR_ID'],
     'CREDITOR_ID': os.environ['DESECSTACK_API_SEPA_CREDITOR_ID'],

+ 9 - 6
api/desecapi/exceptions.py

@@ -4,9 +4,12 @@ import json
 
 
 class PdnsException(APIException):
 class PdnsException(APIException):
 
 
-    def __init__(self, response):
-        self.status_code = response.status_code
-        try:
-            self.detail = json.loads(response.text)['error']
-        except:
-            self.detail = response.text
+    def __init__(self, response=None, detail=None, status=None):
+        self.status_code = status or response.status_code
+        if detail:
+            self.detail = detail
+        else:
+            try:
+                self.detail = json.loads(response.text)['error']
+            except:
+                self.detail = response.text

+ 3 - 0
api/desecapi/pdns.py

@@ -45,6 +45,9 @@ def _pdns_delete_zone(domain):
 
 
 def _pdns_request(method, path, body=None, acceptable_range=range(200, 300)):
 def _pdns_request(method, path, body=None, acceptable_range=range(200, 300)):
     data = json.dumps(body) if body else None
     data = json.dumps(body) if body else None
+    if data is not None and len(data) > settings.PDNS_MAX_BODY_SIZE:
+        raise PdnsException(detail='Payload too large', status=413)
+
     r = requests.request(method, settings.NSLORD_PDNS_API + path, data=data, headers=headers_nslord)
     r = requests.request(method, settings.NSLORD_PDNS_API + path, data=data, headers=headers_nslord)
     if r.status_code not in acceptable_range:
     if r.status_code not in acceptable_range:
         raise PdnsException(r)
         raise PdnsException(r)