| OLD | NEW |
| (Empty) |
| 1 WebPageReplay Rule Language | |
| 2 =========================== | |
| 3 | |
| 4 WebPageReplay rules allows developers to customize record/replay handling. | |
| 5 | |
| 6 Motiviation | |
| 7 ----------- | |
| 8 | |
| 9 Web sites often require custom replay logic, e.g.: | |
| 10 | |
| 11 1. The recording uploads various metrics/logs to: | |
| 12 | |
| 13 http://example.com/gen_204?emsg=foo | |
| 14 | |
| 15 but, during replay, it uploads different parameters: | |
| 16 | |
| 17 http://example.com/gen_204?emsg=bar | |
| 18 | |
| 19 so (as-is) our replay fails. We want "*/gen_204" to always respond | |
| 20 "HTTP 204 No Change". | |
| 21 | |
| 22 2. The recording fetches data from one server: | |
| 23 | |
| 24 http://mirrorA.example.com/stuff | |
| 25 | |
| 26 but replay selects a different server: | |
| 27 | |
| 28 http://mirrorB.example.com/stuff | |
| 29 | |
| 30 which breaks replay. We want "mirror*.example.com/stuff" to be equivalent. | |
| 31 | |
| 32 3. The recorded URL + response contains a UID, e.g.: | |
| 33 | |
| 34 http://example.com?q=foo --> "you sent foo." | |
| 35 | |
| 36 but the replay asks for: | |
| 37 | |
| 38 http://example.com?q=bar --> replay error! | |
| 39 | |
| 40 We want it to reply "you sent bar." | |
| 41 | |
| 42 We could hack all the above rules into the code, but that can''t be (cleanly) ex
tended or open sourced. | |
| 43 | |
| 44 Instead, we want a simple config file of "predicate --> action" rules. | |
| 45 | |
| 46 | |
| 47 Format | |
| 48 ------ | |
| 49 | |
| 50 The JSON-formatted rule file is specified on the command line: | |
| 51 | |
| 52 replay.py ... --rules_path my_rules ... | |
| 53 | |
| 54 The rules file must contain an array of single-item objects, e.g.: | |
| 55 | |
| 56 [{"comment": "ignore me"}, | |
| 57 {"LogUrl": {"url": "example\\.com/logme.*"}}, | |
| 58 {"LogUrl": {"url": "example\\.com/someotherpath"}} | |
| 59 ] | |
| 60 | |
| 61 All "comment" items are ignored and support arbitrary values, e.g., a string | |
| 62 or commented-out rule(s). | |
| 63 | |
| 64 All other items must specify a string TYPE key and object ARGS value, e.g.: | |
| 65 | |
| 66 {"LogUrl": {"url": "example\\.com/test", "stop": false}} | |
| 67 | |
| 68 The default TYPE package is "rules" and the default rule_parser | |
| 69 "allowed_imports" is similarly restricted to only allow "rules" classes. | |
| 70 | |
| 71 The TYPE implementation class must match the Rule API defined in | |
| 72 "rules/rule.py": | |
| 73 | |
| 74 class Rule(object): | |
| 75 def IsType(self, rule_type_name): ... | |
| 76 def ApplyRule(self, return_value, request, response): ... | |
| 77 | |
| 78 The ARGS must match the rule-specific constructor, e.g.: | |
| 79 | |
| 80 class LogUrl(rule.Rule): | |
| 81 def __init__(self, url, stop=False): | |
| 82 self._url_re = re.compile(url) | |
| 83 self._stop = stop | |
| 84 ... | |
| 85 | |
| 86 All rules of the same rule_type_name are chained together and applied in the | |
| 87 same order as they appear in the input JSON file. | |
| 88 | |
| 89 | |
| 90 Rules | |
| 91 ------- | |
| 92 | |
| 93 ### rules.LogUrl: | |
| 94 | |
| 95 If the url pattern matches then log the request URL. | |
| OLD | NEW |