def readable(self, selector): sock, addr = self.sock.accept() conn = Connection(lambda properties: Session(link, properties)) conn.tracing(*self.traces) if self.auth: sasl = SASL(conn) sasl.tracing(*self.traces) sasl.server(self.mechanisms, passwords=self.passwords) sel = sasl else: sel = conn selector.register(ConnectionSelectable(sock, sel, self.tick, self.period, self.timeout))
def connection(): from connection import Connection from session import Session from link import Sender, Receiver, link from protocol import Fragment, Linkage a = Connection(lambda n: Session(n, link)) b = Connection(lambda n: Session(n, link)) a.id = "A" a.tracing = set(["ops", "err"]) b.id = "B" b.tracing = set(["ops", "err"]) def pump(): while a.pending() or b.pending(): b.write(a.read()) a.write(b.read()) s = Session("test-ssn", link) a.add(s) s2 = Session("test-ssn2", link) a.add(s2) a.open(hostname="asdf") b.open() s.begin() s2.begin() l = Sender("qwer", local=Linkage("S", "T")) s.add(l) l.attach() pump() bssn = [x for x in b.incoming.values() if x.name == "test-ssn"][0] bssn.begin() bl = bssn.links["qwer"] bl.attach() bl.flow(10) pump() l.settle(l.send(fragments=Fragment(True, True, 0, 0, "asdf"))) tag = l.send(delivery_tag="blah", fragments=Fragment(True, True, 0, 0, "asdf")) pump() ln = bssn.links["qwer"] x = ln.get() print "INCOMING XFR:", x ln.disposition(x.delivery_tag, "ACCEPTED") xfr = ln.get() print "INCOMING XFR:", xfr ln.disposition(xfr.delivery_tag, "ASDF") print "--" pump() print "--" print "DISPOSITION", l.get_remote(modified=True) l.settle(tag) l.detach() bl.detach() pump() s.end(True) pump() bssn.end(True) s2.end(True) a.close() b.close() pump()
def session(): from connection import Connection from session import Session from link import link, Sender, Receiver from protocol import Fragment, Linkage a = Connection(lambda n: Session(n, link)) a.tracing = set(["ops", "err"]) a.id = "A" b = Connection(lambda n: Session(n, link)) b.tracing = set(["err"]) b.id = "B" ssn = Session("test", link) a.add(ssn) ssn.begin() # nss = Session("test", link) # b.add(nss) def pump(): a.tick() b.tick() b.write(a.read()) a.write(b.read()) pump() nss = [s for s in b.incoming.values() if s.name == "test"][0] nss.begin() snd = Sender("L", "S", "T") ssn.add(snd) rcv = Receiver("L", "S", "T") nss.add(rcv) snd.attach() rcv.attach() rcv.flow(10) pump() snd.send(fragments=Fragment(True, True, 0, 0, "m1")) snd.send(fragments=Fragment(True, True, 0, 0, "m2")) dt3 = snd.send(fragments=Fragment(True, True, 0, 0, "m3")) pump() print "PENDING", rcv.pending() pump() snd.send(fragments=Fragment(True, True, 0, 0, "m4")) pump() xfrs = [] while rcv.pending(): x = rcv.get() xfrs.append(x) print "XFR", x rcv.disposition(xfrs[-1].delivery_tag, "ACCEPTED") pump() snd.send(fragments=Fragment(True, True, 0, 0, "m5")) pump() rcv.disposition(xfrs[0].delivery_tag, "ACCEPTED") print "----------" pump() print "----------" print "ssn.outgoing:", ssn.outgoing print "snd.unsettled:", snd.unsettled for xfr in xfrs[1:-1]: rcv.disposition(xfr.delivery_tag, "ACCEPTED") print "rcv.unsettled", rcv.unsettled print "rcv.pending()", rcv.pending() rcv.disposition(rcv.get().delivery_tag) pump() print "----------" print "ssn.outgoing:", ssn.outgoing print "snd.unsettled:", snd.unsettled print "settling:", dt3 snd.settle(dt3) print "ssn.outgoing:", ssn.outgoing print "snd.unsettled:", snd.unsettled for dt in list(snd.unsettled): snd.settle(dt) snd.detach() rcv.detach() pump() print "ssn.outgoing:", ssn.outgoing print "snd.unsettled:", snd.unsettled
class Connection: def __init__(self, auth=False): self.proto = ProtoConnection(self.session) self.auth = auth if self.auth: self.sasl = SASL(self.proto) else: self.sasl = self.proto self._lock = RLock() self.condition = Condition(self._lock) self.waiter = Waiter(self.condition) self.selector = Selector.default() self.timeout = 120 def tracing(self, *args, **kwargs): self.proto.tracing(*args, **kwargs) self.sasl.tracing(*args, **kwargs) def trace(self, *args, **kwargs): self.proto.trace(*args, **kwargs) @synchronized def connect(self, host, port): sock = socket.socket() sock.connect((host, port)) sock.setblocking(0) self.selector.register(ConnectionSelectable(sock, self, self.tick)) @synchronized def pending(self): return self.sasl.pending() @synchronized def peek(self, n=None): return self.sasl.peek(n) @synchronized def read(self, n=None): return self.sasl.read(n) @synchronized def write(self, bytes): self.sasl.write(bytes) @synchronized def closed(self): self.sasl.closed() @synchronized def error(self, exc): self.sasl.error(exc) @synchronized def tick(self, connection): self.proto.tick() self.sasl.tick() self.waiter.notify() @synchronized def open(self, **kwargs): if not kwargs.get("container_id"): kwargs["container_id"] = str(uuid4()) if "channel_max" not in kwargs: kwargs["channel_max"] = 65535 mechanism = kwargs.pop("mechanism", "ANONYMOUS") username = kwargs.pop("username", None) password = kwargs.pop("password", None) if self.auth: self.sasl.client(mechanism=mechanism, username=username, password=password) self.proto.open(**kwargs) if self.auth: self.wait(lambda: self.sasl.outcome is not None) if self.sasl.outcome != 0: raise Exception("authentication failed: %s" % self.sasl.outcome) def wait(self, predicate, timeout=DEFAULT): if timeout is DEFAULT: timeout = self.timeout self.selector.wakeup() if not self.waiter.wait(predicate, timeout): raise Timeout() @synchronized def session(self): ssn = Session(self) self.proto.add(ssn.proto) return ssn @synchronized def close(self): self.proto.close() self.wait(lambda: self.proto.close_rcvd)