tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

key-value-store.py (2017B)


      1 """Key-Value store server.
      2 
      3 The request takes "key=" and "value=" URL parameters. The key must be UUID
      4 generated by token().
      5 
      6 - When only the "key=" is specified, serves a 200 response whose body contains
      7  the stored value specified by the key. If the stored value doesn't exist,
      8  serves a 200 response with an empty body.
      9 - When both the "key=" and "value=" are specified, stores the pair and serves
     10  a 200 response without body.
     11 """
     12 
     13 
     14 def main(request, response):
     15    key = request.GET.get(b"key")
     16    value = request.GET.get(b"value")
     17 
     18    # Store the value.
     19    # We have two ways to check the truthiness of `value`:
     20    #   1. `if value`
     21    #   2. `if value != None`
     22    # While (1) is the most intuitive, we actually need (2), which is a looser
     23    # check. We need the looser check so that if the URL contains `&value=` to
     24    # set the value equal to the empty string (a case we need to support), this
     25    # condition still evaluates to true and we enter this branch.
     26    if value != None:
     27        # We opted for (2) above which is the looser of the truthiness tests
     28        # that lets empty strings into this branch. So you might think that when
     29        # the URL contains `&value=`, then the `value` variable here would be
     30        # equal `""`, but instead it equals the empty byte string. If you just
     31        # store that empty byte string into the stash and retrieve it later, you
     32        # actually get <Not set> because it doesn't recognize the empty byte
     33        # string as a real value, so we instead have to override it to the empty
     34        # normal string, and then we can store it for later use. This is
     35        # because we have to support storage and retrieval of empty strings.
     36        if type(value) is bytes and value == b'':
     37            value = ""
     38 
     39        request.server.stash.put(key, value)
     40        return (200, [], b"")
     41 
     42    # Get the value.
     43    data = request.server.stash.take(key)
     44    if not data and data != "":
     45        return (200, [], b"<Not set>")
     46    return (200, [], data)