Fix regression for handling the case where the server terminates the stream.

The processing loop was continuing to call __read_xml after </stream>
was received, which caused SyntaxErrors (can't find starting element).

This should fix issue #102
This commit is contained in:
Lance Stout 2011-09-22 01:32:44 -04:00
parent cf7fcf496e
commit 0b83edf439

View file

@ -1084,7 +1084,12 @@ class XMLStream(object):
# new connections. # new connections.
if not self.session_started_event.is_set(): if not self.session_started_event.is_set():
self.send_raw(self.stream_header, now=True) self.send_raw(self.stream_header, now=True)
self.__read_xml() if not self.__read_xml():
# If the server terminated the stream, end processing
break
except SyntaxError as e:
log.error("Error reading from XML stream.")
self.exception(e)
except KeyboardInterrupt: except KeyboardInterrupt:
log.debug("Keyboard Escape Detected in _process") log.debug("Keyboard Escape Detected in _process")
self.stop.set() self.stop.set()
@ -1115,40 +1120,35 @@ class XMLStream(object):
""" """
depth = 0 depth = 0
root = None root = None
try: for event, xml in ET.iterparse(self.filesocket, (b'end', b'start')):
for (event, xml) in ET.iterparse(self.filesocket, if event == b'start':
(b'end', b'start')): if depth == 0:
if event == b'start': # We have received the start of the root element.
if depth == 0: root = xml
# We have received the start of the root element. # Perform any stream initialization actions, such
root = xml # as handshakes.
# Perform any stream initialization actions, such self.stream_end_event.clear()
# as handshakes. self.start_stream_handler(root)
self.stream_end_event.clear() depth += 1
self.start_stream_handler(root) if event == b'end':
depth += 1 depth -= 1
if event == b'end': if depth == 0:
depth -= 1 # The stream's root element has closed,
if depth == 0: # terminating the stream.
# The stream's root element has closed, log.debug("End of stream recieved")
# terminating the stream. self.stream_end_event.set()
log.debug("End of stream recieved") return False
self.stream_end_event.set() elif depth == 1:
return False # We only raise events for stanzas that are direct
elif depth == 1: # children of the root element.
# We only raise events for stanzas that are direct try:
# children of the root element. self.__spawn_event(xml)
try: except RestartStream:
self.__spawn_event(xml) return True
except RestartStream: if root is not None:
return True # Keep the root element empty of children to
if root: # save on memory use.
# Keep the root element empty of children to root.clear()
# save on memory use.
root.clear()
except SyntaxError:
log.error("Error reading from XML stream.")
self.disconnect(self.auto_reconnect)
log.debug("Ending read XML loop") log.debug("Ending read XML loop")
def _build_stanza(self, xml, default_ns=None): def _build_stanza(self, xml, default_ns=None):