| """Key-Value store server. |
| |
| The request takes "key=" and "value=" URL parameters. The key must be UUID |
| generated by token(). |
| |
| - When only the "key=" is specified, serves a 200 response whose body contains |
| the stored value specified by the key. If the stored value doesn't exist, |
| serves a 200 response with an empty body. |
| - When both the "key=" and "value=" are specified, stores the pair and serves |
| a 200 response without body. |
| """ |
| |
| |
| def main(request, response): |
| key = request.GET.get(b"key") |
| value = request.GET.get(b"value") |
| |
| # Store the value. |
| # We have two ways to check the truthiness of `value`: |
| # 1. `if value` |
| # 2. `if value != None` |
| # While (1) is the most intuitive, we actually need (2), which is a looser |
| # check. We need the looser check so that if the URL contains `&value=` to |
| # set the value equal to the empty string (a case we need to support), this |
| # condition still evaluates to true and we enter this branch. |
| if value != None: |
| # We opted for (2) above which is the looser of the truthiness tests |
| # that lets empty strings into this branch. So you might think that when |
| # the URL contains `&value=`, then the `value` variable here would be |
| # equal `""`, but instead it equals the empty byte string. If you just |
| # store that empty byte string into the stash and retrieve it later, you |
| # actually get <Not set> because it doesn't recognize the empty byte |
| # string as a real value, so we instead have to override it to the empty |
| # normal string, and then we can store it for later use. This is |
| # because we have to support storage and retrieval of empty strings. |
| if type(value) is bytes and value == b'': |
| value = "" |
| |
| request.server.stash.put(key, value) |
| return (200, [], b"") |
| |
| # Get the value. |
| data = request.server.stash.take(key) |
| if not data and data != "": |
| return (200, [], b"<Not set>") |
| return (200, [], data) |