public static Session.Feature parseSessionFeature(XmlPullParser parser) throws XmlPullParserException, IOException { ParserUtils.assertAtStartTag(parser); final int initialDepth = parser.getDepth(); boolean optional = false; if (!parser.isEmptyElementTag()) { outerloop: while(true) { int event = parser.next(); switch (event) { case XmlPullParser.START_TAG: String name = parser.getName(); switch (name) { case Session.Feature.OPTIONAL_ELEMENT: optional = true; break; } break; case XmlPullParser.END_TAG: if (parser.getDepth() == initialDepth) { break outerloop; } } } } return new Session.Feature(optional); }
@SuppressWarnings("deprecation") protected void bindResourceAndEstablishSession(String resource) throws XMPPErrorException, IOException, SmackException { // Wait until either: // - the servers last features stanza has been parsed // - the timeout occurs LOGGER.finer("Waiting for last features to be received before continuing with resource binding"); lastFeaturesReceived.checkIfSuccessOrWait(); if (!hasFeature(Bind.ELEMENT, Bind.NAMESPACE)) { // Server never offered resource binding, which is REQURIED in XMPP client and // server implementations as per RFC6120 7.2 throw new ResourceBindingNotOfferedException(); } // Resource binding, see RFC6120 7. // Note that we can not use IQReplyFilter here, since the users full JID is not yet // available. It will become available right after the resource has been successfully bound. Bind bindResource = Bind.newSet(resource); PacketCollector packetCollector = createPacketCollectorAndSend(new StanzaIdFilter(bindResource), bindResource); Bind response = packetCollector.nextResultOrThrow(); // Set the connections user to the result of resource binding. It is important that we don't infer the user // from the login() arguments and the configurations service name, as, for example, when SASL External is used, // the username is not given to login but taken from the 'external' certificate. user = response.getJid(); serviceName = XmppStringUtils.parseDomain(user); Session.Feature sessionFeature = getFeature(Session.ELEMENT, Session.NAMESPACE); // Only bind the session if it's announced as stream feature by the server, is not optional and not disabled // For more information see http://tools.ietf.org/html/draft-cridland-xmpp-session-01 if (sessionFeature != null && !sessionFeature.isOptional() && !getConfiguration().isLegacySessionDisabled()) { Session session = new Session(); packetCollector = createPacketCollectorAndSend(new StanzaIdFilter(session), session); packetCollector.nextResultOrThrow(); } }
protected final void parseFeatures(XmlPullParser parser) throws XmlPullParserException, IOException, SmackException { streamFeatures.clear(); final int initialDepth = parser.getDepth(); while (true) { int eventType = parser.next(); if (eventType == XmlPullParser.START_TAG && parser.getDepth() == initialDepth + 1) { ExtensionElement streamFeature = null; String name = parser.getName(); String namespace = parser.getNamespace(); switch (name) { case StartTls.ELEMENT: streamFeature = PacketParserUtils.parseStartTlsFeature(parser); break; case Mechanisms.ELEMENT: streamFeature = new Mechanisms(PacketParserUtils.parseMechanisms(parser)); break; case Bind.ELEMENT: streamFeature = Bind.Feature.INSTANCE; break; case Session.ELEMENT: streamFeature = PacketParserUtils.parseSessionFeature(parser); break; case Compress.Feature.ELEMENT: streamFeature = PacketParserUtils.parseCompressionFeature(parser); break; default: ExtensionElementProvider<ExtensionElement> provider = ProviderManager.getStreamFeatureProvider(name, namespace); if (provider != null) { streamFeature = provider.parse(parser); } break; } if (streamFeature != null) { // 将特性放入列表中 addStreamFeature(streamFeature); } } else if (eventType == XmlPullParser.END_TAG && parser.getDepth() == initialDepth) { break; } } if (hasFeature(Mechanisms.ELEMENT, Mechanisms.NAMESPACE)) { // Only proceed with SASL auth if TLS is disabled or if the server doesn't announce it if (!hasFeature(StartTls.ELEMENT, StartTls.NAMESPACE) || config.getSecurityMode() == SecurityMode.disabled) { // connecting算事完成了 saslFeatureReceived.reportSuccess(); } } // If the server reported the bind feature then we are that that we did SASL and maybe // STARTTLS. We can then report that the last 'stream:features' have been parsed if (hasFeature(Bind.ELEMENT, Bind.NAMESPACE)) { if (!hasFeature(Compress.Feature.ELEMENT, Compress.NAMESPACE) || !config.isCompressionEnabled()) { // This was was last features from the server is either it did not contain // compression or if we disabled it lastFeaturesReceived.reportSuccess(); } } afterFeaturesReceived(); }
private String bindResourceAndEstablishSession(String resource) throws XMPPException { // Wait until server sends response containing the <bind> element synchronized (this) { if (!resourceBinded) { try { wait(30000); } catch (InterruptedException e) { // Ignore } } } if (!resourceBinded) { // Server never offered resource binding throw new XMPPException("Resource binding not offered by server"); } Bind bindResource = new Bind(); bindResource.setResource(resource); PacketCollector collector = connection .createPacketCollector(new PacketIDFilter(bindResource.getPacketID())); // Send the packet connection.sendPacket(bindResource); // Wait up to a certain number of seconds for a response from the server. Bind response = (Bind) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); collector.cancel(); if (response == null) { throw new XMPPException("No response from the server."); } // If the server replied with an error, throw an exception. else if (response.getType() == IQ.Type.ERROR) { throw new XMPPException(response.getError()); } String userJID = response.getJid(); if (sessionSupported) { Session session = new Session(); collector = connection.createPacketCollector(new PacketIDFilter(session.getPacketID())); // Send the packet connection.sendPacket(session); // Wait up to a certain number of seconds for a response from the server. IQ ack = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); collector.cancel(); if (ack == null) { throw new XMPPException("No response from the server."); } // If the server replied with an error, throw an exception. else if (ack.getType() == IQ.Type.ERROR) { throw new XMPPException(ack.getError()); } } else { // Server never offered session establishment throw new XMPPException("Session establishment not offered by server"); } return userJID; }
private String bindResourceAndEstablishSession(String resource) throws XMPPException { // Wait until server sends response containing the <bind> element synchronized (this) { long endTime = System.currentTimeMillis() + 30000; while (!resourceBinded && (System.currentTimeMillis() < endTime)) { try { wait(Math.abs(System.currentTimeMillis() - endTime)); } catch (InterruptedException e) { // Ignore } } } if (!resourceBinded) { // Server never offered resource binding throw new XMPPException("Resource binding not offered by server"); } Bind bindResource = new Bind(); bindResource.setResource(resource); PacketCollector collector = connection .createPacketCollector(new PacketIDFilter(bindResource.getPacketID())); // Send the packet connection.sendPacket(bindResource); // Wait up to a certain number of seconds for a response from the server. Bind response = (Bind) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); collector.cancel(); if (response == null) { throw new XMPPException("No response from the server."); } // If the server replied with an error, throw an exception. else if (response.getType() == IQ.Type.ERROR) { throw new XMPPException(response.getError()); } String userJID = response.getJid(); if (sessionSupported) { Session session = new Session(); collector = connection.createPacketCollector(new PacketIDFilter(session.getPacketID())); // Send the packet connection.sendPacket(session); // Wait up to a certain number of seconds for a response from the server. IQ ack = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); collector.cancel(); if (ack == null) { throw new XMPPException("No response from the server."); } // If the server replied with an error, throw an exception. else if (ack.getType() == IQ.Type.ERROR) { throw new XMPPException(ack.getError()); } } else { // Server never offered session establishment throw new XMPPException("Session establishment not offered by server"); } return userJID; }
private String bindResourceAndEstablishSession(String resource) throws XMPPException { // Wait until server sends response containing the <bind> element synchronized (this) { if (!resourceBinded) { try { wait(30000); } catch (InterruptedException e) { // Ignore } } } if (!resourceBinded) { // Server never offered resource binding throw new XMPPException("Resource binding not offered by server"); } Bind bindResource = new Bind(); bindResource.setResource(resource); PacketCollector collector = connection .createPacketCollector(new PacketIDFilter(bindResource.getPacketID())); // Send the packet connection.sendPacket(bindResource); // Wait up to a certain number of seconds for a response from the server. Bind response = (Bind) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); collector.cancel(); if (response == null) { throw new XMPPException("No response from the server."); } // If the server replied with an error, throw an exception. else if (response.getType() == IQ.Type.ERROR) { throw new XMPPException(response.getError()); } String userJID = response.getJid(); if (sessionSupported) { Session session = new Session(); collector = connection.createPacketCollector(new PacketIDFilter(session.getPacketID())); // Send the packet connection.sendPacket(session); // Wait up to a certain number of seconds for a response from the server. IQ ack = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); collector.cancel(); if (ack == null) { throw new XMPPException("No response from the server."); } // If the server replied with an error, throw an exception. else if (ack.getType() == IQ.Type.ERROR) { throw new XMPPException(ack.getError()); } } return userJID; }
private String bindResourceAndEstablishSession(String resource) throws XMPPException { // Wait until server sends response containing the <bind> element synchronized (this) { if (!resourceBinded) { try { wait(30000); } catch (InterruptedException e) { // Ignore } } } if (!resourceBinded) { // Server never offered resource binding throw new XMPPException("Resource binding not offered by server"); } Bind bindResource = new Bind(); bindResource.setResource(resource); PacketCollector collector = connection .createPacketCollector(new PacketIDFilter(bindResource .getPacketID())); // Send the packet connection.sendPacket(bindResource); // Wait up to a certain number of seconds for a response from the // server. Bind response = (Bind) collector.nextResult(SmackConfiguration .getPacketReplyTimeout()); collector.cancel(); if (response == null) { throw new XMPPException("No response from the server."); } // If the server replied with an error, throw an exception. else if (response.getType() == IQ.Type.ERROR) { throw new XMPPException(response.getError()); } String userJID = response.getJid(); if (sessionSupported) { Session session = new Session(); collector = connection.createPacketCollector(new PacketIDFilter( session.getPacketID())); // Send the packet connection.sendPacket(session); // Wait up to a certain number of seconds for a response from the // server. IQ ack = (IQ) collector.nextResult(SmackConfiguration .getPacketReplyTimeout()); collector.cancel(); if (ack == null) { throw new XMPPException("No response from the server."); } // If the server replied with an error, throw an exception. else if (ack.getType() == IQ.Type.ERROR) { throw new XMPPException(ack.getError()); } } else { // Server never offered session establishment throw new XMPPException( "Session establishment not offered by server"); } return userJID; }
private String bindResourceAndEstablishSession(String resource) throws XMPPException { // Wait until server sends response containing the <bind> element synchronized (this) { if (!resourceBinded) { try { wait(30000); } catch (InterruptedException e) { // Ignore } } } if (!resourceBinded) { // Server never offered resource binding throw new XMPPException("Resource binding not offered by server"); } Bind bindResource = new Bind(); bindResource.setResource(resource); PacketCollector collector = connection .createPacketCollector(new PacketIDFilter(bindResource.getID())); // Send the packet connection.sendPacket(bindResource); // Wait up to a certain number of seconds for a response from the // server. Bind response = (Bind) collector.nextResult(SmackConfiguration .getPacketReplyTimeout()); collector.cancel(); if (response == null) { throw new XMPPException("No response from the server."); } // If the server replied with an error, throw an exception. else if (response.getType() == IQ.Type.error) { throw new XMPPException(response.getError()); } String userJID = response.getJid(); if (sessionSupported) { Session session = new Session(); collector = connection.createPacketCollector(new PacketIDFilter( session.getID())); // Send the packet connection.sendPacket(session); // Wait up to a certain number of seconds for a response from the // server. IQ ack = (IQ) collector.nextResult(SmackConfiguration .getPacketReplyTimeout()); collector.cancel(); if (ack == null) { throw new XMPPException("No response from the server."); } // If the server replied with an error, throw an exception. else if (ack.getType() == IQ.Type.error) { throw new XMPPException(ack.getError()); } } return userJID; }