'This callback is used to handle opening stream tag of the incoming stream.
In the case of client session it just make some validation.
Server session also sends server headers and if the stream valid the features node.
Used internally.'

def _stream_open(self, ns=None, tag='stream', attrs={}):

    text = '<?xml    version="1.0"    encoding="utf-8"?>\n<stream:stream'
    if (self.TYP == 'client'):
        text += ('    to="%s"' % self.peer)
    else:
        text += ('    id="%s"' % self.ID)
        if (not attrs.has_key('to')):
            text += ('    from="%s"' % self._owner.servernames[0])
        else:
            text += ('    from="%s"' % attrs['to'])
    if attrs.has_key('xml:lang'):
        text += ('    xml:lang="%s"' % attrs['xml:lang'])
    if self.xmlns:
        xmlns = self.xmlns
    else:
        xmlns = NS_SERVER
    text += ('    xmlns:db="%s"    xmlns:stream="%s"    xmlns="%s"' % (NS_DIALBACK, NS_STREAMS, xmlns))
    if (attrs.has_key('version') or (self.TYP == 'client')):
        text += '    version="1.0"'
    self.sendnow((text + '>'))
    self.set_stream_state(STREAM__OPENED)
    if (self.TYP == 'client'):
        return
    if (tag != 'stream'):
        return self.terminate_stream(STREAM_INVALID_XML)
    if (ns != NS_STREAMS):
        return self.terminate_stream(STREAM_INVALID_NAMESPACE)
    if (self.Stream.xmlns != self.xmlns):
        return self.terminate_stream(STREAM_BAD_NAMESPACE_PREFIX)
    if (not attrs.has_key('to')):
        return self.terminate_stream(STREAM_IMPROPER_ADDRESSING)
    if (attrs['to'] not in self._owner.servernames):
        return self.terminate_stream(STREAM_HOST_UNKNOWN)
    self.ourname = attrs['to'].lower()
    if ((self.TYP == 'server') and attrs.has_key('version')):
        features = Node('stream:features')
        if (NS_TLS in self.waiting_features):
            features.NT.starttls.setNamespace(NS_TLS)
            features.T.starttls.NT.required
        if (NS_SASL in self.waiting_features):
            features.NT.mechanisms.setNamespace(NS_SASL)
            for mec in self._owner.SASL.mechanisms:
                features.T.mechanisms.NT.mechanism = mec
        else:
            if (NS_BIND in self.waiting_features):
                features.NT.bind.setNamespace(NS_BIND)
            if (NS_SESSION in self.waiting_features):
                features.NT.session.setNamespace(NS_SESSION)
        self.sendnow(features)
