Ticket #9349: 0001-Handle-multiple-registrations-in-one-message-to-faci.patch

File 0001-Handle-multiple-registrations-in-one-message-to-faci.patch, 5.6 KB (added by dcf, 6 years ago)
  • facilitator/facilitator-reg-daemon

    From 081ee3c84b99e0b07502d1321851502b27b60776 Mon Sep 17 00:00:00 2001
    From: David Fifield <david@bamsoftware.com>
    Date: Thu, 26 Sep 2013 01:24:11 -0700
    Subject: [PATCH] Handle multiple registrations in one message to
     facilitator-reg-daemon.
    
    ---
     facilitator/facilitator-reg-daemon | 40 +++++++++++++++++++++++---------
     facilitator/facilitator-test       | 47 ++++++++++++++++++++++++++++++++++++++
     2 files changed, 76 insertions(+), 11 deletions(-)
    
    diff --git a/facilitator/facilitator-reg-daemon b/facilitator/facilitator-reg-daemon
    index a053bb2..d4ec80a 100755
    a b import socket 
    77import sys
    88import threading
    99import time
     10import urlparse
    1011
    1112import fac
    1213
    def log(msg): 
    7677    finally:
    7778        log_lock.release()
    7879
    79 def find_client_addr(body):
    80     """Find and parse the first client line of the form
    81         client=...
    82     Returns None if no client line was found."""
     80class Reg(object):
     81    def __init__(self):
     82        self.addr = None
     83
     84    @staticmethod
     85    def parse(s):
     86        pairs = urlparse.parse_qsl(s, keep_blank_values=True, strict_parsing=True)
     87        reg = Reg()
     88        for k, v in pairs:
     89            if k == "client":
     90                if reg.addr is not None:
     91                    raise ValueError("More than one \"client\" key found.")
     92                reg.addr = fac.parse_addr_spec(v)
     93        if reg.addr is None:
     94            raise ValueError("No \"client\" key found.")
     95        return reg
     96
     97def extract_registrations(body):
     98    """Parse each line and yield Reg objects."""
    8399    for line in body.splitlines():
    84         if line.startswith("client="):
    85             _, client_spec = line.split("=", 1)
    86             return fac.parse_addr_spec(client_spec)
    87     return None
     100        yield Reg.parse(line)
    88101
    89102class Handler(SocketServer.StreamRequestHandler):
    90103    def __init__(self, *args, **kwargs):
    class Handler(SocketServer.StreamRequestHandler): 
    117130        try:
    118131            ciphertext = b64_ciphertext.decode("base64")
    119132            plaintext = rsa.private_decrypt(ciphertext, RSA.pkcs1_oaep_padding)
    120             client_addr = find_client_addr(plaintext)
    121             log(u"registering %s" % safe_str(fac.format_addr(client_addr)))
    122             if fac.put_reg(FACILITATOR_ADDR, client_addr):
     133        except Exception, e:
     134            log("error decrypting: %s" % str(e))
     135            print >> self.wfile, "FAIL"
     136            raise
     137        try:
     138            for reg in find_client_addr(plaintext):
     139                log(u"registering %s" % safe_str(fac.format_addr(reg.addr)))
     140            if fac.put_reg(FACILITATOR_ADDR, reg.addr):
    123141                print >> self.wfile, "OK"
    124142            else:
    125143                print >> self.wfile, "FAIL"
  • facilitator/facilitator-test

    diff --git a/facilitator/facilitator-test b/facilitator/facilitator-test
    index cbd45f8..c6534b6 100755
    a b  
    22
    33import socket
    44import subprocess
     5import sys
    56import time
    67import unittest
    78
    89import fac
    910
     11import imp
     12dont_write_bytecode = sys.dont_write_bytecode
     13sys.dont_write_bytecode = True
     14reg_daemon = imp.load_source("reg_daemon", "facilitator-reg-daemon")
     15sys.dont_write_bytecode = dont_write_bytecode
     16del dont_write_bytecode
     17
    1018FACILITATOR_HOST = "127.0.0.1"
    1119FACILITATOR_PORT = 9002
    1220FACILITATOR_ADDR = (FACILITATOR_HOST, FACILITATOR_PORT)
    class ParseTransactionTest(unittest.TestCase): 
    188196    def test_newline(self):
    189197        self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X=\"ABC\" \nY=\"DEF\"")
    190198
     199class RegDaemonTest(unittest.TestCase):
     200    def testSingle(self):
     201        l = list(reg_daemon.extract_registrations(""))
     202        self.assertEqual(len(l), 0)
     203        l = list(reg_daemon.extract_registrations("client=1.2.3.4:1111"))
     204        self.assertEqual(len(l), 1)
     205        self.assertEqual(l[0].addr, ("1.2.3.4", 1111))
     206        l = list(reg_daemon.extract_registrations("client=1.2.3.4:1111\n"))
     207        self.assertEqual(len(l), 1)
     208        self.assertEqual(l[0].addr, ("1.2.3.4", 1111))
     209        l = list(reg_daemon.extract_registrations("foo=bar&client=1.2.3.4:1111&baz=quux"))
     210        self.assertEqual(len(l), 1)
     211        self.assertEqual(l[0].addr, ("1.2.3.4", 1111))
     212        l = list(reg_daemon.extract_registrations("foo=b%3dar&client=1.2.3.4%3a1111"))
     213        self.assertEqual(len(l), 1)
     214        self.assertEqual(l[0].addr, ("1.2.3.4", 1111))
     215        l = list(reg_daemon.extract_registrations("client=%5b1::2%5d:3333"))
     216        self.assertEqual(len(l), 1)
     217        self.assertEqual(l[0].addr, ("1::2", 3333))
     218
     219    def testMultiple(self):
     220        l = list(reg_daemon.extract_registrations("client=1.2.3.4:1111&foo=bar\nfoo=bar&client=5.6.7.8:2222"))
     221        self.assertEqual(len(l), 2)
     222        self.assertEqual(l[0].addr, ("1.2.3.4", 1111))
     223        self.assertEqual(l[1].addr, ("5.6.7.8", 2222))
     224        l = list(reg_daemon.extract_registrations("client=1.2.3.4:1111&foo=bar\nfoo=bar&client=%5b1::2%5d:3333"))
     225        self.assertEqual(len(l), 2)
     226        self.assertEqual(l[0].addr, ("1.2.3.4", 1111))
     227        self.assertEqual(l[1].addr, ("1::2", 3333))
     228
     229    def testInvalid(self):
     230        self.assertRaises(ValueError, reg_daemon.Reg.parse, "\n")
     231        # Missing "client".
     232        self.assertRaises(ValueError, reg_daemon.Reg.parse, "foo=bar")
     233        # More than one "client".
     234        self.assertRaises(ValueError, reg_daemon.Reg.parse, "client=1.2.3.4:1111&foo=bar&client=5.6.7.8:2222")
     235        # Single client with bad syntax.
     236        self.assertRaises(ValueError, reg_daemon.Reg.parse, "client=1.2.3.4,1111")
     237
    191238if __name__ == "__main__":
    192239    unittest.main()