diff --git a/poppy/model/helpers/origin.py b/poppy/model/helpers/origin.py index 8909a6ec..3ac60e7a 100644 --- a/poppy/model/helpers/origin.py +++ b/poppy/model/helpers/origin.py @@ -20,11 +20,14 @@ from poppy.model.helpers import rule class Origin(common.DictSerializableModel): """Origin.""" - def __init__(self, origin, port=80, ssl=False, rules=[]): + def __init__(self, origin, hostheadertype='domain', hostheadervalue='-', + port=80, ssl=False, rules=[]): self._origin = origin self._port = port self._ssl = ssl self._rules = rules + self._hostheadertype = hostheadertype + self._hostheadervalue = hostheadervalue @property def origin(self): @@ -76,6 +79,26 @@ class Origin(common.DictSerializableModel): # TODO(tonytan4ever) this field should by typed too self._rules = value + @property + def hostheadertype(self): + """hostheadertype.""" + return self._hostheadertype + + @hostheadertype.setter + def hostheadertype(self, value): + """hostheadertype setter.""" + self._hostheadertype = value + + @property + def hostheadervalue(self): + """hostheadervalue.""" + return self._hostheadervalue + + @hostheadervalue.setter + def hostheadervalue(self, value): + """hostheadervalue setter.""" + self._hostheadervalue = value + @classmethod def init_from_dict(cls, dict_obj): """Construct a model instance from a dictionary. @@ -90,6 +113,10 @@ class Origin(common.DictSerializableModel): o.origin = dict_obj.get("origin", "unnamed") o.port = dict_obj.get("port", 80) o.ssl = dict_obj.get("ssl", False) + o.hostheadertype = dict_obj.get("hostheadertype", "domain") + o.hostheadervalue = dict_obj.get("hostheadervalue", None) + if o.hostheadertype == 'origin': + o.hostheadervalue = o.origin rules_dict_list = dict_obj.get("rules", []) o.rules = [] for rule_dict in rules_dict_list: @@ -98,7 +125,6 @@ class Origin(common.DictSerializableModel): new_rule.from_dict(rule_dict) o.rules.append(new_rule) return o - return o def to_dict(self): result = common.DictSerializableModel.to_dict(self) diff --git a/poppy/provider/akamai/services.py b/poppy/provider/akamai/services.py index 85c1dd24..ebe125cc 100644 --- a/poppy/provider/akamai/services.py +++ b/poppy/provider/akamai/services.py @@ -478,6 +478,15 @@ class ServiceController(base.ServiceBase): } } + if origin.hostheadertype == 'custom': + origin_behavior_dict['params']['hostHeaderType'] = 'fixed' + origin_behavior_dict['params']['hostHeaderValue'] = \ + origin.hostheadervalue + elif origin.hostheadertype == 'origin': + origin_behavior_dict['params']['hostHeaderType'] = 'origin' + origin_behavior_dict['params']['hostHeaderValue'] = \ + origin.hostheadervalue + wildcards = [] # this is the global 'url-wildcard' rule diff --git a/poppy/storage/cassandra/services.py b/poppy/storage/cassandra/services.py index f44bb851..e1c56c03 100644 --- a/poppy/storage/cassandra/services.py +++ b/poppy/storage/cassandra/services.py @@ -595,6 +595,8 @@ class ServicesController(base.ServicesController): origins = [ origin.Origin( o['origin'], + o.get('hostheadertype', 'domain'), + o.get('hostheadervalue', None), o.get('port', 80), o.get('ssl', False), [ rule.Rule( diff --git a/poppy/transport/pecan/models/request/origin.py b/poppy/transport/pecan/models/request/origin.py index 1b6af9ab..a1f2bfe3 100644 --- a/poppy/transport/pecan/models/request/origin.py +++ b/poppy/transport/pecan/models/request/origin.py @@ -20,10 +20,14 @@ from poppy.transport.pecan.models.request import rule def load_from_json(json_data): origin_name = json_data.get("origin") origin_name = origin_name.rstrip("/") + hostheadertype = json_data.get("hostheadertype", "domain") + hostheadervalue = json_data.get("hostheadervalue", None) port = json_data.get("port", 80) ssl = json_data.get("ssl", False) rules = json_data.get("rules", []) rules = [rule.load_from_json(r) for r in rules] - result = origin.Origin(origin_name, port, ssl) + result = origin.Origin(origin=origin_name, hostheadertype=hostheadertype, + hostheadervalue=hostheadervalue, port=port, + ssl=ssl) result.rules = rules return result diff --git a/poppy/transport/pecan/models/response/origin.py b/poppy/transport/pecan/models/response/origin.py index 8f83ef98..c6d6bae9 100644 --- a/poppy/transport/pecan/models/response/origin.py +++ b/poppy/transport/pecan/models/response/origin.py @@ -31,3 +31,6 @@ class Model(collections.OrderedDict): self['port'] = origin.port self['ssl'] = origin.ssl self['rules'] = [rule.Model(r) for r in origin.rules] + self['hostheadertype'] = origin.hostheadertype + if origin.hostheadervalue is not None: + self['hostheadervalue'] = origin.hostheadervalue diff --git a/poppy/transport/validators/schemas/service.py b/poppy/transport/validators/schemas/service.py index 76339239..ded574be 100644 --- a/poppy/transport/validators/schemas/service.py +++ b/poppy/transport/validators/schemas/service.py @@ -20,7 +20,6 @@ from poppy.transport.validators import schema_base class ServiceSchema(schema_base.SchemaBase): - '''JSON Schmema validation for /service.''' schema = { @@ -61,7 +60,7 @@ class ServiceSchema(schema_base.SchemaBase): 'required': True, 'type': 'string', 'enum': [ - 'http'] + 'http'] }, # When protocol is http # certificate must be null @@ -83,13 +82,13 @@ class ServiceSchema(schema_base.SchemaBase): 'required': True, 'type': 'string', 'enum': [ - 'https'] + 'https'] }, 'certificate': { 'required': True, 'type': 'string', 'enum': [ - 'shared'] + 'shared'] }, }, "additionalProperties": False @@ -106,14 +105,14 @@ class ServiceSchema(schema_base.SchemaBase): 'required': True, 'type': 'string', 'enum': [ - 'https'] + 'https'] }, 'certificate': { 'required': True, 'type': 'string', 'enum': [ - 'san', - 'custom'] + 'san', + 'custom'] }, }, "additionalProperties": False @@ -127,50 +126,116 @@ class ServiceSchema(schema_base.SchemaBase): # the first origin does not have to # have rules field, it will be defaulted # to global url matching - 'items': [{ - 'type': 'object', - 'properties': { - 'origin': { - 'type': 'string', - 'pattern': re.compile( - '^(([^:/?#]+):)?' - '(//([^/?#]*))?' - '([^?#]*)(\?([^#]*))?' - '(#(.*))?$', - re.UNICODE - ), - 'required': True, - 'minLength': 3, - 'maxLength': 253}, - 'port': { - 'type': 'integer', - 'enum': [ - 80, - 443]}, - 'ssl': { - 'type': 'boolean'}, - 'rules': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'name': { - 'type': 'string', - 'required': True, - 'minLength': 1, - 'maxLength': 256 - }, - 'request_url': { - 'type': 'string', - 'required': True, - 'minLength': 1, - 'maxLength': 1024 + 'items': { + 'type': [{ + 'type': 'object', + 'properties': { + 'origin': { + 'type': 'string', + 'pattern': re.compile( + '^(([^:/?#]+):)?' + '(//([^/?#]*))?' + '([^?#]*)(\?([^#]*))?' + '(#(.*))?$', + re.UNICODE + ), + 'required': True, + 'minLength': 3, + 'maxLength': 253}, + 'port': { + 'type': 'integer', + 'enum': [ + 80, + 443]}, + 'ssl': { + 'type': 'boolean'}, + 'rules': { + 'type': 'array', + 'items': { + 'type': 'object', + 'properties': { + 'name': { + 'type': 'string', + 'required': True, + 'minLength': 1, + 'maxLength': 256 + }, + 'request_url': { + 'type': 'string', + 'required': True, + 'minLength': 1, + 'maxLength': 1024 + } } } + }, + 'hostheadertype': { + 'type': 'string', + 'enum': ['domain', 'origin'], + 'required': False, + }, + } + }, { + 'type': 'object', + 'properties': { + 'origin': { + 'type': 'string', + 'pattern': re.compile( + '^(([^:/?#]+):)?' + '(//([^/?#]*))?' + '([^?#]*)(\?([^#]*))?' + '(#(.*))?$', + re.UNICODE + ), + 'required': True, + 'minLength': 3, + 'maxLength': 253}, + 'port': { + 'type': 'integer', + 'enum': [ + 80, + 443]}, + 'ssl': { + 'type': 'boolean'}, + 'rules': { + 'type': 'array', + 'items': { + 'type': 'object', + 'properties': { + 'name': { + 'type': 'string', + 'required': True, + 'minLength': 1, + 'maxLength': 256 + }, + 'request_url': { + 'type': 'string', + 'required': True, + 'minLength': 1, + 'maxLength': 1024 + } + } + } + }, + 'hostheadertype': { + 'type': 'string', + 'enum': ['custom'], + 'required': False, + }, + 'hostheadervalue': { + 'type': 'string', + 'pattern': re.compile( + '^(([^:/?#]+):)?' + '(//([^/?#]*))?' + '([^?#]*)(\?([^#]*))?' + '(#(.*))?$', + re.UNICODE + ), + 'required': True, } } } - }], + ]}, 'required': True, 'minItems': 1, 'maxItems': 10, @@ -220,6 +285,71 @@ class ServiceSchema(schema_base.SchemaBase): 'required': True, 'minItems': 1, }, + 'hostheadertype': { + 'type': 'string', + 'enum': ['domain', 'origin'], + 'required': False, + } + }, + 'type': 'object', + 'properties': { + 'origin': { + 'type': 'string', + 'pattern': re.compile( + '^(([^:/?#]+):)?' + '(//([^/?#]*))?' + '([^?#]*)(\?([^#]*))?' + '(#(.*))?$', + re.UNICODE + ), + 'required': True, + 'minLength': 3, + 'maxLength': 253}, + 'port': { + 'type': 'integer', + 'enum': [ + 80, + 443]}, + 'ssl': { + 'type': 'boolean'}, + 'rules': { + 'type': 'array', + 'items': { + 'type': 'object', + 'properties': { + 'name': { + 'type': 'string', + 'required': True, + 'minLength': 1, + 'maxLength': 256, + }, + 'request_url': { + 'type': 'string', + 'required': True, + 'minLength': 1, + 'maxLength': 1024, + } + } + }, + 'required': True, + 'minItems': 1, + }, + 'hostheadertype': { + 'type': 'string', + 'enum': ['custom'], + 'required': False, + }, + 'hostheadervalue': { + 'type': 'string', + 'pattern': re.compile( + '^(([^:/?#]+):)?' + '(//([^/?#]*))?' + '([^?#]*)(\?([^#]*))?' + '(#(.*))?$', + re.UNICODE + ), + 'required': True, + } } } }, diff --git a/requirements/common.txt b/requirements/common.txt index 6c15a773..1ec11ba1 100644 --- a/requirements/common.txt +++ b/requirements/common.txt @@ -1,4 +1,4 @@ -pbr +pbr==0.11.0 Babel>=1.3 netaddr>=0.7.6 diff --git a/tests/api/services/data_create_service.json b/tests/api/services/data_create_service.json index 713f7c1b..1d59111f 100644 --- a/tests/api/services/data_create_service.json +++ b/tests/api/services/data_create_service.json @@ -11,8 +11,9 @@ { "name" : "default", "request_url" : "/*" - } - ] + }], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" }], "caching_list": [ { @@ -58,11 +59,12 @@ "port": 80, "ssl": false, "rules": [ - { - "name" : "default", - "request_url" : "/*" - } - ] + { + "name": "default", + "request_url": "/*" + }], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" }], "caching_list": [] }, @@ -78,7 +80,9 @@ "name": "default rule", "request_url": "/*" } - ] + ], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" }, { "origin": "mywebsite2.com", @@ -89,7 +93,9 @@ "name": "images rules", "request_url": "/images/*" } - ] + ], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "caching_list": [{"name": "default", @@ -109,7 +115,9 @@ "name": "default rule", "request_url": "/*" } - ] + ], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" }, { "origin": "mywebsite2.com", @@ -120,7 +128,9 @@ "name": "images rules", "request_url": "/images/test.jpg" } - ] + ], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "caching_list": [{"name": "default", @@ -137,11 +147,12 @@ "port": 80, "ssl": false, "rules": [ - { - "name" : "default", - "request_url" : "/*" - } - ] + { + "name": "default", + "request_url": "/*" + }], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" }], "caching_list": [ { @@ -192,7 +203,9 @@ "name" : "default", "request_url" : "/*" } - ] + ], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" }], "caching_list": [ { @@ -242,8 +255,111 @@ "name" : "default", "request_url" : "/*" } + ], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" + }], + "caching_list": [] + }, + "origin_hostheadertype": { + "name": "origin_hostheadertype", + "domain_list": [{"domain": "my-website.com", "protocol": "http"}], + "origin_list": [{"origin": "mywebsite1.com", + "port": 80, + "ssl": false, + "hostheadertype": "origin", + "rules": [ + { + "name" : "default", + "request_url" : "/*" + } ] }], "caching_list": [] + }, + "custom_hostheadertype": { + "name": "custom_hostheadertype", + "domain_list": [{"domain": "my-website.com", "protocol": "http"}], + "origin_list": [{"origin": "mywebsite1.com", + "port": 80, + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "customweb.com", + "rules": [ + { + "name" : "default", + "request_url" : "/*" + } + ] + }], + "caching_list": [] + }, + "domain_hostheadertype": { + "name": "domain_hostheadertype", + "domain_list": [{"domain": "my-website.com", "protocol": "http"}], + "origin_list": [{"origin": "mywebsite1.com", + "port": 80, + "ssl": false, + "rules": [ + { + "name" : "default", + "request_url" : "/*" + } + ] + }], + "caching_list": [] + }, + "origin_hostheadertype_other_hostheadervalue": { + "name": "origin_hostheadertype_other_hostheadervalue", + "domain_list": [{"domain": "my-website.com", "protocol": "http"}], + "origin_list": [{"origin": "mywebsite1.com", + "port": 80, + "ssl": false, + "rules": [ + { + "name" : "default", + "request_url" : "/*" + } + ], + "hostheadertype": "origin", + "hostheadervalue": "www.somewebsite.com" + }], + "caching_list": [] + }, + "multiple_hostheadertypes": { + "name": "multiple_hostheadertypes", + "domain_list": [{"domain": "my-website.com", "protocol": "http"}], + "origin_list": [{"origin": "mywebsite1.com", + "port": 80, + "ssl": false, + "rules": [ + { + "name" : "default", + "request_url" : "/*" + } + ]}, + {"origin": "www.mywebsite23.com", + "port": 80, + "ssl": false, + "rules": [ + { + "name" : "images", + "request_url" : "/images/testpic.jpg" + }], + "hostheadertype": "origin" + }, + {"origin": "www.mywebsite34.com", + "port": 80, + "ssl": false, + "rules": [ + { + "name" : "videos", + "request_url" : "/videos/testvideo.mp4" + }], + "hostheadertype": "custom", + "hostheadervalue": "www.mycustomweb.com" + }], + "caching_list": [] } + } diff --git a/tests/api/services/data_create_service_negative.json b/tests/api/services/data_create_service_negative.json index 8af17026..61edce69 100644 --- a/tests/api/services/data_create_service_negative.json +++ b/tests/api/services/data_create_service_negative.json @@ -713,5 +713,62 @@ "rules": [{"name" : "index", "request_url" : "/index.htm"}]}], "restrictions_list": [] + }, + "invalid_hostheadertype":{ + "service_name": "invalid_hostheadertype", + "domain_list": [{"domain": "mywebsite.com"}], + "origin_list": [{"origin": "mywebsite1.com", + "port": 443, + "ssl": false, + "hostheadertype": "org"}], + "caching_list": [], + "restrictions_list": [] + }, + "missing_hostheadervalue":{ + "service_name": "missing_hostheadervalue", + "domain_list": [{"domain": "mywebsite.com"}], + "origin_list": [{"origin": "mywebsite1.com", + "port": 443, + "ssl": false, + "hostheadertype": "custom"}], + "caching_list": [], + "restrictions_list": [] + }, + "nonASCII_hostheadertype": { + "service_name": "nonASCII_hostheadertype", + "domain_list": [ + { + "domain": "mywebsite.com" + } + ], + "origin_list": [ + { + "origin": "mywebsite1.com", + "port": 443, + "ssl": false, + "hostheadertype": ": איבערזעצן" + } + ], + "caching_list": [], + "restrictions_list": [] + }, + "nonASCII_hostheadervalue": { + "service_name": "nonASCII_hostheadervalue", + "domain_list": [ + { + "domain": "mywebsite.com" + } + ], + "origin_list": [ + { + "origin": "mywebsite1.com", + "port": 443, + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": ": איבערזעצן" + } + ], + "caching_list": [], + "restrictions_list": [] } } diff --git a/tests/api/services/data_create_service_ssl_domain.json b/tests/api/services/data_create_service_ssl_domain.json index d1a571f7..6157ddb7 100644 --- a/tests/api/services/data_create_service_ssl_domain.json +++ b/tests/api/services/data_create_service_ssl_domain.json @@ -8,7 +8,9 @@ "origin_list": [{"origin": "mywebsite1.com", "port": 443, "ssl": true, - "rules": [{ "name" : "default", "request_url" : "/*"}] + "rules": [{ "name" : "default", "request_url" : "/*"}], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" }], "caching_list": [{"name": "default", "ttl": 3600}, {"name": "home", @@ -29,7 +31,9 @@ "certificate": "san"}], "origin_list": [{"origin": "mywebsite1.com", "port": 443, - "ssl": true}], + "ssl": true, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com"}], "caching_list": [{"name": "default", "ttl": 3600}, {"name": "home", "ttl": 1200, @@ -48,7 +52,9 @@ "certificate": "custom"}], "origin_list": [{"origin": "mywebsite1.com", "port": 443, - "ssl": true}], + "ssl": true, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com"}], "caching_list": [{"name": "default", "ttl": 3600}, {"name": "home", "ttl": 1200, @@ -68,7 +74,9 @@ ], "origin_list": [{"origin": "mywebsite1.com", "port": 443, - "ssl": true}], + "ssl": true, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com"}], "caching_list": [{"name": "default", "ttl": 3600}, {"name": "home", "ttl": 1200, diff --git a/tests/api/services/data_create_service_xss.json b/tests/api/services/data_create_service_xss.json index eee2f7f0..7475d6ce 100644 --- a/tests/api/services/data_create_service_xss.json +++ b/tests/api/services/data_create_service_xss.json @@ -31,7 +31,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -78,7 +80,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -125,7 +129,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -172,7 +178,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -219,7 +227,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -266,7 +276,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -313,7 +325,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -360,7 +374,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -407,7 +423,9 @@ { "origin": "%3Cscript%3Ealert%281%29%3C/script%3E", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -454,7 +472,9 @@ { "origin": "mywebsite1.com", "port": "%3Cscript%3Ealert%281%29%3C/script%3E", - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -501,7 +521,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -548,7 +570,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -595,7 +619,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -642,7 +668,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -689,7 +717,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": "%3Cscript%3Ealert%281%29%3C/script%3E" + "ssl": "%3Cscript%3Ealert%281%29%3C/script%3E", + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -736,7 +766,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -783,7 +815,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -830,7 +864,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -877,7 +913,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -924,7 +962,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -971,7 +1011,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1018,7 +1060,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1065,7 +1109,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1112,7 +1158,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1159,7 +1207,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1206,7 +1256,9 @@ { "origin": "%22", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1253,7 +1305,9 @@ { "origin": "mywebsite1.com", "port": "%22", - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1300,7 +1354,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1347,7 +1403,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1394,7 +1452,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1441,7 +1501,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1488,7 +1550,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": "%22" + "ssl": "%22", + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1535,7 +1599,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1582,7 +1648,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1629,7 +1697,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1676,7 +1746,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1723,7 +1795,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1770,7 +1844,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1817,7 +1893,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1864,7 +1942,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1911,7 +1991,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -1958,7 +2040,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2005,7 +2089,9 @@ { "origin": "", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2052,7 +2138,9 @@ { "origin": "mywebsite1.com", "port": "", - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2099,7 +2187,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2146,7 +2236,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2193,7 +2285,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2240,7 +2334,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2287,7 +2383,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": "" + "ssl": "", + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2334,7 +2432,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2381,7 +2481,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2428,7 +2530,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2475,7 +2579,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2522,7 +2628,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2569,7 +2677,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2616,7 +2726,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2663,7 +2775,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2710,7 +2824,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2757,7 +2873,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2804,7 +2922,9 @@ { "origin": "<", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2851,7 +2971,9 @@ { "origin": "mywebsite1.com", "port": "<", - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2898,7 +3020,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2945,7 +3069,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -2992,7 +3118,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3039,7 +3167,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3086,7 +3216,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": "<" + "ssl": "<", + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3133,7 +3265,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3180,7 +3314,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3227,7 +3363,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3274,7 +3412,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3321,7 +3461,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3368,7 +3510,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3415,7 +3559,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3462,7 +3608,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3509,7 +3657,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3556,7 +3706,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3603,7 +3755,9 @@ { "origin": ">", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3650,7 +3804,9 @@ { "origin": "mywebsite1.com", "port": ">", - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3697,7 +3853,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3744,7 +3902,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3791,7 +3951,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3838,7 +4000,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3885,7 +4049,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": ">" + "ssl": ">", + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3932,7 +4098,9 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ], "restrictions_list": [ @@ -3979,7 +4147,107 @@ { "origin": "mywebsite1.com", "port": 443, - "ssl": false + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" + } + ], + "restrictions_list": [ + { + "name": "test", + "rules": [ + { + "name": "only me", + "referrer": "www.mywebsite.com" + } + ] + } + ] + }, + "xss_escaped_jscript_into_hostheadertype": { + "caching_list": [ + { + "name": "default", + "ttl": 3600 + }, + { + "name": "home", + "rules": [ + { + "name": "index", + "request_url": "/index.htm" + } + ], + "ttl": 1200 + } + ], + "domain_list": [ + { + "domain": "www.domain1234.com", + "protocol": "http" + }, + { + "domain": "blog.mywebsite.com", + "protocol": "http" + } + ], + "name": "my_service_name", + "origin_list": [ + { + "origin": "mywebsite1.com", + "port": 443, + "ssl": false, + "hostheadertype": "%3Cscript%3Ealert%281%29%3C/script%3E", + "hostheadervalue": "www.customweb.com" + } + ], + "restrictions_list": [ + { + "name": "test", + "rules": [ + { + "name": "only me", + "referrer": "www.mywebsite.com" + } + ] + } + ] + }, + "xss_escaped_jscript_into_hostheadervalue": { + "caching_list": [ + { + "name": "default", + "ttl": 3600 + }, + { + "name": "home", + "rules": [ + { + "name": "index", + "request_url": "/index.htm" + } + ], + "ttl": 1200 + } + ], + "domain_list": [ + { + "domain": "www.domain1234.com", + "protocol": "http" + }, + { + "domain": "blog.mywebsite.com", + "protocol": "http" + } + ], + "name": "my_service_name", + "origin_list": [ + { + "origin": "mywebsite1.com", + "port": 443, + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "%3Cscript%3Ealert%281%29%3C/script%3E" } ], "restrictions_list": [ diff --git a/tests/api/services/data_default_service_values.json b/tests/api/services/data_default_service_values.json index 9341d279..a48c1872 100644 --- a/tests/api/services/data_default_service_values.json +++ b/tests/api/services/data_default_service_values.json @@ -34,7 +34,9 @@ "name" : "default", "request_url" : "/*" } - ] + ], + "hostheadertype": "domain", + "hostheadervalue": null } ] } @@ -80,7 +82,9 @@ "name" : "default", "request_url" : "/*" } - ] + ], + "hostheadertype": "domain", + "hostheadervalue": null } ], "caching_list": [ @@ -144,6 +148,20 @@ "origin": "mywebsite1.com", "port": 80, "ssl": false, + "rules": [ + { + "name" : "default", + "request_url" : "/*" + } + ], + "hostheadertype": "domain", + "hostheadervalue": null + } + ], + "caching_list": [ + { + "name": "default", + "ttl": 3600, "rules": [ { "name" : "default", @@ -152,6 +170,246 @@ ] } ], + "restrictions": [ + { + "name": "test", + "rules": [ + { + "name": "only me", + "referrer": "www.mywebsite.com", + "request_url": "/*" + } + ] + } + ] + } + }, + "default_hostheadertype": { + "submit_value": { + "name": "my_service_name", + "domain_list": [ + { + "domain": "mywebsite.com", + "protocol": "http" + } + ], + "origin_list": [ + { + "origin": "mywebsite1.com", + "port": 80, + "ssl": false + } + ], + "caching_list": [ + { + "name": "default", + "ttl": 3600 + } + ], + "restrictions": [ + { + "name": "test", + "rules": [ + { + "name": "only me", + "referrer": "www.mywebsite.com" + } + ] + } + ] + }, + "expected_value": { + "name": "my_service_name", + "domain_list": [ + { + "domain": "mywebsite.com", + "protocol": "http" + } + ], + "origin_list": [ + { + "origin": "mywebsite1.com", + "port": 80, + "ssl": false, + "rules": [ + { + "name" : "default", + "request_url" : "/*" + } + ], + "hostheadertype": "domain", + "hostheadervalue": null + } + ], + "caching_list": [ + { + "name": "default", + "ttl": 3600, + "rules": [ + { + "name" : "default", + "request_url" : "/*" + } + ] + } + ], + "restrictions": [ + { + "name": "test", + "rules": [ + { + "name": "only me", + "referrer": "www.mywebsite.com", + "request_url": "/*" + } + ] + } + ] + } + }, + "origin_hostheadertype": { + "submit_value": { + "name": "my_service_name", + "domain_list": [ + { + "domain": "mywebsite.com", + "protocol": "http" + } + ], + "origin_list": [ + { + "origin": "mywebsite1.com", + "port": 80, + "ssl": false, + "hostheadertype": "origin" + } + ], + "caching_list": [ + { + "name": "default", + "ttl": 3600 + } + ], + "restrictions": [ + { + "name": "test", + "rules": [ + { + "name": "only me", + "referrer": "www.mywebsite.com" + } + ] + } + ] + }, + "expected_value": { + "name": "my_service_name", + "domain_list": [ + { + "domain": "mywebsite.com", + "protocol": "http" + } + ], + "origin_list": [ + { + "origin": "mywebsite1.com", + "port": 80, + "ssl": false, + "rules": [ + { + "name" : "default", + "request_url" : "/*" + } + ], + "hostheadertype": "origin", + "hostheadervalue": "mywebsite1.com" + } + ], + "caching_list": [ + { + "name": "default", + "ttl": 3600, + "rules": [ + { + "name" : "default", + "request_url" : "/*" + } + ] + } + ], + "restrictions": [ + { + "name": "test", + "rules": [ + { + "name": "only me", + "referrer": "www.mywebsite.com", + "request_url": "/*" + } + ] + } + ] + } + }, + "custom_hostheadertype": { + "submit_value": { + "name": "my_service_name", + "domain_list": [ + { + "domain": "mywebsite.com", + "protocol": "http" + } + ], + "origin_list": [ + { + "origin": "mywebsite1.com", + "port": 80, + "ssl": false, + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" + } + ], + "caching_list": [ + { + "name": "default", + "ttl": 3600 + } + ], + "restrictions": [ + { + "name": "test", + "rules": [ + { + "name": "only me", + "referrer": "www.mywebsite.com" + } + ] + } + ] + }, + "expected_value": { + "name": "my_service_name", + "domain_list": [ + { + "domain": "mywebsite.com", + "protocol": "http" + } + ], + "origin_list": [ + { + "origin": "mywebsite1.com", + "port": 80, + "ssl": false, + "rules": [ + { + "name" : "default", + "request_url" : "/*" + } + ], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" + } + ], "caching_list": [ { "name": "default", diff --git a/tests/api/services/data_patch_service.json b/tests/api/services/data_patch_service.json index 1a822253..5e0ae723 100644 --- a/tests/api/services/data_patch_service.json +++ b/tests/api/services/data_patch_service.json @@ -46,7 +46,7 @@ "replace_origin": [ {"op": "replace", "path": "/origins/0", - "value": {"origin": "1.2.3.4", "port": 80, "rules": [{"name": "default", "request_url": "/replacement"}], "ssl": false}} + "value": {"origin": "1.2.3.4", "port": 80, "rules": [{"name": "default", "request_url": "/replacement"}], "ssl": false, "hostheadertype": "custom", "hostheadervalue": "www.customweb.com"}} ], "add_origin": [ {"op": "add", @@ -113,11 +113,25 @@ {"op": "remove", "path": "/origins/0"} ], + "add_origin_with_origin_hostheadertype": [ + {"op": "add", + "path": "/origins/1", + "value": {"origin": "1.2.3.4", "port": 80, "ssl": false, + "rules": [{"name" : "origin", "request_url" : "/origin.htm"}], "hostheadertype": "origin"} + } + ], + "add_origin_with_custom_hostheadertype": [ + {"op": "add", + "path": "/origins/1", + "value": {"origin": "1.2.3.4", "port": 80, "ssl": false, + "rules": [{"name" : "origin", "request_url" : "/origin.htm"}], "hostheadertype": "custom", "hostheadervalue": "www.mycustom.com"} + } + ], "add_caching": [ {"op": "add", "path": "/caching/-", "value": {"name": "cache_name", "ttl": 111, - "rules": [{"name" : "index","request_url" : "/cats.jpg"}]}} + "rules": [{"name" : "index","request_url" : "/cats.jpg"}] }} ], "add_caching_with_minimum_length_name": [ {"op": "add", @@ -225,7 +239,7 @@ {"op": "replace", "path": "/origins/0", "value": {"origin": "1.1.1.1", "port": 443, "ssl": true, - "rules": [{"name" : "origin", "request_url" : "/origin2.htm"}]}} + "rules": [{"name" : "origin", "request_url" : "/origin2.htm"}], "hostheadertype": "custom", "hostheadervalue": "www.customweb.com"}} ], "empty_list": [] } diff --git a/tests/api/services/test_services.py b/tests/api/services/test_services.py index 1971884a..9202c6bc 100644 --- a/tests/api/services/test_services.py +++ b/tests/api/services/test_services.py @@ -20,6 +20,7 @@ import urlparse import uuid import ddt +import jsonpatch from nose.plugins import attrib from tests.api import base @@ -83,6 +84,11 @@ class TestCreateService(providers.TestProviderBase): for item in origin_list: if 'rules' not in item: item[u'rules'] = [] + if 'hostheadertype' not in item: + item[u'hostheadertype'] = 'domain' + item[u'hostheadervalue'] = None + elif item['hostheadertype'] == 'origin': + item[u'hostheadervalue'] = item['origin'] self.assertEqual(body['origins'], origin_list) # TODO(malini): uncomment below after caching list is implemented. @@ -163,7 +169,9 @@ class TestListServices(base.TestBase): prefix='api-test-domain') + '.com'}] self.origin_list = [{"origin": self.generate_random_string( - prefix='api-test-origin') + '.com', "port": 80, "ssl": False}] + prefix='api-test-origin') + '.com', "port": 80, "ssl": False, + "hostheadertype": "custom", "hostheadervalue": + "www.customweb.com"}] self.caching_list = [{"name": "default", "ttl": 3600}, {"name": "home", "ttl": 1200, @@ -292,7 +300,9 @@ class TestServiceActions(base.TestBase): u"rules": [{ u"name": u"default", u"request_url": u"/*" - }] + }], + u"hostheadertype": "custom", + u"hostheadervalue": "www.customweb.com" } ] @@ -423,6 +433,476 @@ class TestServiceActions(base.TestBase): super(TestServiceActions, self).tearDown() +@ddt.ddt +class TestServicePatch(base.TestBase): + + """Tests for PATCH Services.""" + + def setUp(self): + super(TestServicePatch, self).setUp() + self.service_name = self.generate_random_string(prefix='api-test') + self.flavor_id = self.test_flavor + self.log_delivery = {"enabled": False} + + domain = self.generate_random_string(prefix='api-test-domain') + '.com' + self.domain_list = [ + { + "domain": domain, + "protocol": "http" + } + ] + + origin = self.generate_random_string(prefix='api-test-origin') + '.com' + self.origin_list = [ + { + "origin": origin, + "port": 80, + "ssl": False, + "rules": [ + { + "name": "default", + "request_url": "/*" + } + ], + "hostheadertype": "domain", + "hostheadervalue": None + } + ] + + self.caching_list = [ + { + "name": "default", + "ttl": 3600, + "rules": [ + { + "name": "default", + "request_url": "/*" + } + ] + }, + { + "name": "home", + "ttl": 1200, + "rules": [ + { + "name": "index", + "request_url": "/index.htm" + } + ] + } + ] + + self.restrictions_list = [ + {"name": "website only", + "rules": [{"name": "mywebsite.com", + "referrer": "www.mywebsite.com", + "request_url": "/*" + }]}] + + resp = self.client.create_service( + service_name=self.service_name, + domain_list=self.domain_list, + origin_list=self.origin_list, + caching_list=self.caching_list, + restrictions_list=self.restrictions_list, + flavor_id=self.flavor_id, + log_delivery=self.log_delivery) + + self.service_url = resp.headers["location"] + + self.original_service_details = { + "name": self.service_name, + "domains": self.domain_list, + "origins": self.origin_list, + "caching": self.caching_list, + "restrictions": self.restrictions_list, + "flavor_id": self.flavor_id, + "log_delivery": self.log_delivery} + + self.client.wait_for_service_status( + location=self.service_url, + status='deployed', + abort_on_status='failed', + retry_interval=self.test_config.status_check_retry_interval, + retry_timeout=self.test_config.status_check_retry_timeout) + + resp = self.client.get_service(location=self.service_url) + body = resp.json() + self.assertEqual(resp.status_code, 200) + self.assertEqual(body['status'], 'deployed') + + @ddt.file_data('data_patch_service.json') + def test_patch_service(self, test_data): + + for item in test_data: + if 'skip_test' in item: + self.skipTest('Not Implemented - bug# 1433807') + + if ('domain' in item['path']) and ('value' in item): + if isinstance(item['value'], (list)): + item['value'][0]['domain'] = self._replace_domain( + domain=item['value'][0]) + else: + item['value']['domain'] = self._replace_domain( + domain=item['value']) + + patch = jsonpatch.JsonPatch(test_data) + expected_service_details = patch.apply(self.original_service_details) + + resp = self.client.patch_service(location=self.service_url, + request_body=test_data) + self.assertEqual(resp.status_code, 202) + + for item in test_data: + if 'origin' in item['path'] and ('value' in item): + if 'hostheadertype' in item['value']: + if item['value']['hostheadertype'] == 'custom': + for origin in expected_service_details['origins']: + if origin['origin'] == item['value']['origin']: + origin['hostheadertype'] = 'custom' + origin['hostheadervalue'] = item['value'][ + 'hostheadervalue'] + elif item['value']['hostheadertype'] == 'origin': + for origin in expected_service_details['origins']: + if origin['origin'] == item['value']['origin']: + origin['hostheadertype'] = 'origin' + origin['hostheadervalue'] = item['value'][ + 'origin'] + else: + for origin in expected_service_details['origins']: + origin['hostheadertype'] = 'domain' + origin['hostheadervalue'] = None + + self.client.wait_for_service_status( + location=self.service_url, + status='deployed', + abort_on_status='failed', + retry_interval=self.test_config.status_check_retry_interval, + retry_timeout=self.test_config.status_check_retry_timeout) + + resp = self.client.get_service(location=self.service_url) + body = resp.json() + self.assertEqual(body['status'], 'deployed') + + self.assert_patch_service_details(body, expected_service_details) + + def _replace_domain(self, domain): + if ('protocol' in domain): + if domain['protocol'] == 'https': + if (domain['certificate'] == u'shared'): + return self.generate_random_string(prefix='api-test-ssl') + + return self.generate_random_string(prefix='api-test-ssl') + '.com' + + @ddt.file_data('data_patch_service_negative.json') + def test_patch_service_HTTP_400(self, test_data): + + resp = self.client.patch_service(location=self.service_url, + request_body=test_data) + self.assertEqual(resp.status_code, 400) + + # nothing should have changed. + resp = self.client.get_service(location=self.service_url) + self.assertEqual(resp.status_code, 200) + + body = resp.json() + self.assertEqual(body['status'], 'deployed') + + self.assert_patch_service_details(body, self.original_service_details) + + def test_patch_service_claim_relinquish_domain(self): + newdomain = str(uuid.uuid4()) + ".com" + add_domain = ( + [{ + "op": "add", + "path": "/domains/-", + "value": {"domain": newdomain, "protocol": "http"} + }]) + remove_domain = ( + [{ + "op": "remove", + "path": "/domains/1" + }]) + + # add new domain + resp = self.client.patch_service(location=self.service_url, + request_body=add_domain) + self.assertEqual(resp.status_code, 202) + + # wait for the domain to be added + self.client.wait_for_service_status( + location=self.service_url, + status='deployed', + abort_on_status='failed', + retry_interval=self.test_config.status_check_retry_interval, + retry_timeout=self.test_config.status_check_retry_timeout) + + # make sure the new domain is added + resp = self.client.get_service(location=self.service_url) + body = resp.json() + self.assertEqual(body['status'], 'deployed') + self.assertEqual(body['domains'][-1]['domain'], newdomain) + + # remove the new domain + resp = self.client.patch_service(location=self.service_url, + request_body=remove_domain) + self.assertEqual(resp.status_code, 202) + + # wait for the domain to be removed + self.client.wait_for_service_status( + location=self.service_url, + status='deployed', + abort_on_status='failed', + retry_interval=self.test_config.status_check_retry_interval, + retry_timeout=self.test_config.status_check_retry_timeout) + # make sure the new domain is removed + resp = self.client.get_service(location=self.service_url) + body = resp.json() + self.assertEqual(body['status'], 'deployed') + for domain in body['domains']: + self.assertNotEqual(domain['domain'], newdomain) + + # add new domain, again + resp = self.client.patch_service(location=self.service_url, + request_body=add_domain) + self.assertEqual(resp.status_code, 202) + + # wait for the domain to be added + self.client.wait_for_service_status( + location=self.service_url, + status='deployed', + abort_on_status='failed', + retry_interval=self.test_config.status_check_retry_interval, + retry_timeout=self.test_config.status_check_retry_timeout) + + # make sure the new domain is added + resp = self.client.get_service(location=self.service_url) + body = resp.json() + self.assertEqual(body['status'], 'deployed') + self.assertEqual(body['domains'][-1]['domain'], newdomain) + + def test_patch_service_add_duplicate_domain(self): + # create second service + service_name = str(uuid.uuid1()) + duplicate_domain = str(uuid.uuid1()) + '.com' + domain_list = [{"domain": duplicate_domain, "protocol": "http"}] + + origin = str(uuid.uuid1()) + '.com' + origin_list = [{"origin": origin, + "port": 80, "ssl": False, "rules": []}] + + resp = self.client.create_service( + service_name=service_name, + domain_list=domain_list, + origin_list=origin_list, + flavor_id=self.flavor_id) + + service_url = resp.headers["location"] + + # wait until the service is deployed + self.client.wait_for_service_status( + location=service_url, + status='deployed', + abort_on_status='failed', + retry_interval=self.test_config.status_check_retry_interval, + retry_timeout=self.test_config.status_check_retry_timeout) + + resp = self.client.get_service(location=service_url) + body = resp.json() + self.assertEqual(resp.status_code, 200) + self.assertEqual(body['status'], 'deployed') + + # wait to make sure cassandra is eventually consistent + time.sleep(self.test_config.cassandra_consistency_wait_time) + + # patch original service with the duplicate domain + add_duplicate_domain = ( + [{ + "op": "add", + "path": "/domains/-", + "value": {"domain": duplicate_domain, "protocol": "http"} + }]) + + # add the duplicate domain + resp = self.client.patch_service(location=self.service_url, + request_body=add_duplicate_domain) + self.assertEqual(resp.status_code, 400) + + def tearDown(self): + self.client.delete_service(location=self.service_url) + if self.test_config.generate_flavors: + self.client.delete_flavor(flavor_id=self.flavor_id) + super(TestServicePatch, self).tearDown() + + +@ddt.ddt +class TestServicePatchWithLogDelivery(base.TestBase): + + """Tests for PATCH Services.""" + + def setUp(self): + super(TestServicePatchWithLogDelivery, self).setUp() + self.service_name = self.generate_random_string(prefix='api-test') + self.flavor_id = self.test_flavor + self.log_delivery = {"enabled": True} + + domain = self.generate_random_string(prefix='api-test-domain') + '.com' + self.domain_list = [ + { + "domain": domain, + "protocol": "http" + } + ] + + origin = self.generate_random_string(prefix='api-test-origin') + '.com' + self.origin_list = [ + { + "origin": origin, + "port": 80, + "ssl": False, + "rules": [ + { + "name": "default", + "request_url": "/*" + } + ], + "hostheadertype": "domain", + "hostheadervalue": None + } + ] + + self.caching_list = [ + { + "name": "default", + "ttl": 3600, + "rules": [ + { + "name": "default", + "request_url": "/*" + } + ] + }, + { + "name": "home", + "ttl": 1200, + "rules": [ + { + "name": "index", + "request_url": "/index.htm" + } + ] + } + ] + + self.restrictions_list = [ + {"name": "website only", + "rules": [{"name": "mywebsite.com", + "referrer": "www.mywebsite.com", + "request_url": "/*" + }]}] + + resp = self.client.create_service( + service_name=self.service_name, + domain_list=self.domain_list, + origin_list=self.origin_list, + caching_list=self.caching_list, + restrictions_list=self.restrictions_list, + flavor_id=self.flavor_id, + log_delivery=self.log_delivery) + + self.service_url = resp.headers["location"] + + self.original_service_details = { + "name": self.service_name, + "domains": self.domain_list, + "origins": self.origin_list, + "caching": self.caching_list, + "restrictions": self.restrictions_list, + "flavor_id": self.flavor_id, + "log_delivery": self.log_delivery} + + self.client.wait_for_service_status( + location=self.service_url, + status='deployed', + abort_on_status='failed', + retry_interval=self.test_config.status_check_retry_interval, + retry_timeout=self.test_config.status_check_retry_timeout) + + resp = self.client.get_service(location=self.service_url) + body = resp.json() + self.assertEqual(resp.status_code, 200) + self.assertEqual(body['status'], 'deployed') + + def _replace_domain(self, domain): + if ('protocol' in domain): + if domain['protocol'] == 'https': + if (domain['certificate'] == u'shared'): + return self.generate_random_string(prefix='api-test-ssl') + + return self.generate_random_string(prefix='api-test-ssl') + '.com' + + @ddt.file_data('data_patch_service.json') + def test_patch_service(self, test_data): + + for item in test_data: + if 'skip_test' in item: + self.skipTest('Not Implemented - bug# 1433807') + + if ('domain' in item['path']) and ('value' in item): + if isinstance(item['value'], (list)): + item['value'][0]['domain'] = self._replace_domain( + domain=item['value'][0]) + else: + item['value']['domain'] = self._replace_domain( + domain=item['value']) + + patch = jsonpatch.JsonPatch(test_data) + expected_service_details = patch.apply(self.original_service_details) + + resp = self.client.patch_service(location=self.service_url, + request_body=test_data) + self.assertEqual(resp.status_code, 202) + + for item in test_data: + if 'origin' in item['path'] and ('value' in item): + if 'hostheadertype' in item['value']: + if item['value']['hostheadertype'] == 'custom': + for origin in expected_service_details['origins']: + if origin['origin'] == item['value']['origin']: + origin['hostheadertype'] = 'custom' + origin['hostheadervalue'] = item['value'][ + 'hostheadervalue'] + elif item['value']['hostheadertype'] == 'origin': + for origin in expected_service_details['origins']: + if origin['origin'] == item['value']['origin']: + origin['hostheadertype'] = 'origin' + origin['hostheadervalue'] = item['value'][ + 'origin'] + else: + for origin in expected_service_details['origins']: + origin['hostheadertype'] = 'domain' + origin['hostheadervalue'] = None + + self.client.wait_for_service_status( + location=self.service_url, + status='deployed', + abort_on_status='failed', + retry_interval=self.test_config.status_check_retry_interval, + retry_timeout=self.test_config.status_check_retry_timeout) + + resp = self.client.get_service(location=self.service_url) + body = resp.json() + self.assertEqual(body['status'], 'deployed') + + self.assert_patch_service_details(body, expected_service_details) + + def tearDown(self): + self.client.delete_service(location=self.service_url) + if self.test_config.generate_flavors: + self.client.delete_flavor(flavor_id=self.flavor_id) + super(TestServicePatchWithLogDelivery, self).tearDown() + + @ddt.ddt class TestDefaultServiceFields(providers.TestProviderBase): diff --git a/tests/api/services/test_ssl_services.py b/tests/api/services/test_ssl_services.py index a2ef3069..e7447521 100644 --- a/tests/api/services/test_ssl_services.py +++ b/tests/api/services/test_ssl_services.py @@ -123,8 +123,9 @@ class TestPatchSSLService(base.TestBase): { "name": "default", "request_url": "/*" - } - ] + }], + "hostheadertype": "custom", + "hostheadervalue": "www.customweb.com" } ] diff --git a/tests/api/utils/schema/services.py b/tests/api/utils/schema/services.py index e7bd9f62..371864aa 100644 --- a/tests/api/utils/schema/services.py +++ b/tests/api/utils/schema/services.py @@ -43,7 +43,9 @@ origin = { 'minumum': 0, 'maximum': 100000}, 'ssl': {'type': 'boolean'}, - 'rules': {'type': 'array'}}, + 'rules': {'type': 'array'}, + 'hostheadertype': {'type': 'string'}, + 'hostheadervalue': {'type': ['string', 'null']}}, 'required': ['origin', 'port', 'ssl'], 'additionalProperties': False } diff --git a/tests/unit/model/helpers/test_origin.py b/tests/unit/model/helpers/test_origin.py index 20a1d81f..85ebfbb2 100644 --- a/tests/unit/model/helpers/test_origin.py +++ b/tests/unit/model/helpers/test_origin.py @@ -26,15 +26,15 @@ class TestOrigin(base.TestCase): @ddt.unpack @ddt.data({'origin_url': 'www.mydomain.com', - 'changed_origin_url': 'www.changed-domain.com'}, + 'changed_origin_url': 'www.changed-domain.com'}, {'origin_url': u'www.düsseldorf-Lörick.com', - 'changed_origin_url': u'www.düsseldorf.com' - }) + 'changed_origin_url': u'www.düsseldorf.com'}) def test_origin(self, origin_url, changed_origin_url): - port = 443 + port = 80 ssl = True - myorigin = origin.Origin(origin_url, port, ssl) + myorigin = origin.Origin(origin=origin_url, hostheadertype="origin", + hostheadervalue="", port=80, ssl=True) # test all properties # origin @@ -44,8 +44,8 @@ class TestOrigin(base.TestCase): # port self.assertEqual(myorigin.port, port) - myorigin.port = 80 - self.assertEqual(myorigin.port, 80) + myorigin.port = 443 + self.assertEqual(myorigin.port, 443) # ssl self.assertEqual(myorigin.ssl, ssl) diff --git a/tox.ini b/tox.ini index a7de86a9..57fc892c 100644 --- a/tox.ini +++ b/tox.ini @@ -20,6 +20,7 @@ deps = -r{toxinidir}/requirements/requirements.txt commands = pip install git+https://github.com/stackforge/opencafe.git#egg=cafe nosetests {posargs:--exclude=api --exclude=endtoend --nologcapture} + [tox:jenkins] downloadcache = ~/cache/pip