mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-25 07:42:06 +01:00
Merge branch '4.2'
This commit is contained in:
commit
08c228ef99
21 changed files with 3190 additions and 59 deletions
1474
resources/logo/smack-logo-plain.ai
Normal file
1474
resources/logo/smack-logo-plain.ai
Normal file
File diff suppressed because one or more lines are too long
58
resources/logo/smack-logo-plain.svg
Normal file
58
resources/logo/smack-logo-plain.svg
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1066.6667 800"
|
||||
height="800"
|
||||
width="1066.6667"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
version="1.1"><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6"><clipPath
|
||||
id="clipPath18"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path16"
|
||||
d="M 0,600 H 800 V 0 H 0 Z" /></clipPath><clipPath
|
||||
id="clipPath30"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path28"
|
||||
d="m 351.001,359.31 c -17.234,-7.3 -51.945,15.909 -51.945,15.909 v 0 c 0,0 31.115,-33.702 27.068,-47.102 v 0 c -4.048,-13.401 -44.827,-30.694 -44.827,-30.694 v 0 c 0,0 51.173,5.823 53.705,-8.205 v 0 c 2.528,-14.031 -3.951,-54.186 -3.951,-54.186 v 0 c 0,0 25.887,37.471 39.897,36.872 v 0 c 14.012,-0.597 39.902,-36.872 39.902,-36.872 v 0 c 0,0 -14.178,43.955 -3.952,54.186 v 0 c 10.225,10.229 53.706,8.205 53.706,8.205 v 0 c 0,0 -43.02,12.932 -44.827,30.694 v 0 c -1.81,17.759 27.07,47.102 27.07,47.102 v 0 c 0,0 -35.718,-23.04 -51.948,-15.909 v 0 c -16.232,7.13 -19.951,50.533 -19.951,50.533 v 0 c 0,0 -2.718,-43.232 -19.947,-50.533" /></clipPath><radialGradient
|
||||
id="radialGradient40"
|
||||
spreadMethod="pad"
|
||||
gradientTransform="matrix(89.254456,0,0,-89.254456,370.9502,322.4375)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
r="1"
|
||||
cy="0"
|
||||
cx="0"
|
||||
fy="0"
|
||||
fx="0"><stop
|
||||
id="stop36"
|
||||
offset="0"
|
||||
style="stop-opacity:1;stop-color:#fdbe10" /><stop
|
||||
id="stop38"
|
||||
offset="1"
|
||||
style="stop-opacity:1;stop-color:#f16422" /></radialGradient></defs><g
|
||||
transform="matrix(1.3333333,0,0,-1.3333333,0,800)"
|
||||
id="g10"><g
|
||||
id="g12"><g
|
||||
clip-path="url(#clipPath18)"
|
||||
id="g14"><g
|
||||
transform="translate(370.9482,472.6006)"
|
||||
id="g20"><path
|
||||
id="path22"
|
||||
style="fill:#fdbe10;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 0,0 6.213,-72.485 33.318,-84.392 27.104,-11.905 86.753,26.569 86.753,26.569 0,0 -48.228,-49.006 -45.209,-78.665 3.022,-29.661 74.864,-51.262 74.864,-51.262 0,0 -72.61,3.382 -89.688,-13.703 -17.078,-17.084 6.597,-90.49 6.597,-90.49 0,0 -43.237,60.579 -66.635,61.578 -23.4,1.003 -66.633,-61.578 -66.633,-61.578 0,0 10.826,67.062 6.601,90.49 -4.229,23.431 -89.694,13.703 -89.694,13.703 0,0 68.108,28.882 74.865,51.262 6.757,22.378 -45.21,78.665 -45.21,78.665 0,0 57.978,-38.76 86.757,-26.569 C -4.54,-72.2 0,0 0,0" /></g></g></g><g
|
||||
id="g24"><g
|
||||
clip-path="url(#clipPath30)"
|
||||
id="g26"><g
|
||||
id="g32"><g
|
||||
id="g34"><path
|
||||
id="path42"
|
||||
style="fill:url(#radialGradient40);stroke:none"
|
||||
d="m 351.001,359.31 c -17.234,-7.3 -51.945,15.909 -51.945,15.909 v 0 c 0,0 31.115,-33.702 27.068,-47.102 v 0 c -4.048,-13.401 -44.827,-30.694 -44.827,-30.694 v 0 c 0,0 51.173,5.823 53.705,-8.205 v 0 c 2.528,-14.031 -3.951,-54.186 -3.951,-54.186 v 0 c 0,0 25.887,37.471 39.897,36.872 v 0 c 14.012,-0.597 39.902,-36.872 39.902,-36.872 v 0 c 0,0 -14.178,43.955 -3.952,54.186 v 0 c 10.225,10.229 53.706,8.205 53.706,8.205 v 0 c 0,0 -43.02,12.932 -44.827,30.694 v 0 c -1.81,17.759 27.07,47.102 27.07,47.102 v 0 c 0,0 -35.718,-23.04 -51.948,-15.909 v 0 c -16.232,7.13 -19.951,50.533 -19.951,50.533 v 0 c 0,0 -2.718,-43.232 -19.947,-50.533" /></g></g></g></g></g></svg>
|
After Width: | Height: | Size: 3.7 KiB |
1353
resources/logo/smack-logo-with-text.ai
Normal file
1353
resources/logo/smack-logo-with-text.ai
Normal file
File diff suppressed because one or more lines are too long
90
resources/logo/smack-logo-with-text.svg
Normal file
90
resources/logo/smack-logo-with-text.svg
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1066.6667 800"
|
||||
height="800"
|
||||
width="1066.6667"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
version="1.1"><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6"><clipPath
|
||||
id="clipPath18"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path16"
|
||||
d="M 0,600 H 800 V 0 H 0 Z" /></clipPath><clipPath
|
||||
id="clipPath30"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path28"
|
||||
d="m 200.001,337.31 c -17.233,-7.3 -51.946,15.909 -51.946,15.909 v 0 c 0,0 31.116,-33.703 27.069,-47.103 v 0 c -4.048,-13.4 -44.827,-30.694 -44.827,-30.694 v 0 c 0,0 51.174,5.824 53.704,-8.204 v 0 c 2.528,-14.032 -3.951,-54.186 -3.951,-54.186 v 0 c 0,0 25.889,37.471 39.898,36.872 v 0 c 14.012,-0.598 39.902,-36.872 39.902,-36.872 v 0 c 0,0 -14.178,43.955 -3.951,54.186 v 0 c 10.224,10.229 53.705,8.204 53.705,8.204 v 0 c 0,0 -43.02,12.933 -44.827,30.694 v 0 c -1.811,17.761 27.07,47.103 27.07,47.103 v 0 c 0,0 -35.719,-23.04 -51.948,-15.909 v 0 c -16.232,7.131 -19.951,50.532 -19.951,50.532 v 0 c 0,0 -2.719,-43.23 -19.947,-50.532" /></clipPath><radialGradient
|
||||
id="radialGradient40"
|
||||
spreadMethod="pad"
|
||||
gradientTransform="matrix(89.254456,0,0,-89.254456,219.9502,300.4375)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
r="1"
|
||||
cy="0"
|
||||
cx="0"
|
||||
fy="0"
|
||||
fx="0"><stop
|
||||
id="stop36"
|
||||
offset="0"
|
||||
style="stop-opacity:1;stop-color:#fdbe10" /><stop
|
||||
id="stop38"
|
||||
offset="1"
|
||||
style="stop-opacity:1;stop-color:#f16422" /></radialGradient><clipPath
|
||||
id="clipPath50"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path48"
|
||||
d="M 0,600 H 800 V 0 H 0 Z" /></clipPath></defs><g
|
||||
transform="matrix(1.3333333,0,0,-1.3333333,0,800)"
|
||||
id="g10"><g
|
||||
id="g12"><g
|
||||
clip-path="url(#clipPath18)"
|
||||
id="g14"><g
|
||||
transform="translate(219.9482,450.6006)"
|
||||
id="g20"><path
|
||||
id="path22"
|
||||
style="fill:#fdbe10;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 0,0 6.213,-72.485 33.318,-84.392 27.104,-11.905 86.753,26.569 86.753,26.569 0,0 -48.228,-49.006 -45.208,-78.665 3.021,-29.661 74.863,-51.262 74.863,-51.262 0,0 -72.61,3.382 -89.688,-13.703 -17.079,-17.084 6.597,-90.49 6.597,-90.49 0,0 -43.237,60.579 -66.635,61.578 -23.4,1.003 -66.633,-61.578 -66.633,-61.578 0,0 10.826,67.062 6.601,90.49 -4.229,23.431 -89.694,13.703 -89.694,13.703 0,0 68.108,28.882 74.865,51.262 6.757,22.378 -45.21,78.665 -45.21,78.665 0,0 57.978,-38.76 86.757,-26.569 C -4.54,-72.2 0,0 0,0" /></g></g></g><g
|
||||
id="g24"><g
|
||||
clip-path="url(#clipPath30)"
|
||||
id="g26"><g
|
||||
id="g32"><g
|
||||
id="g34"><path
|
||||
id="path42"
|
||||
style="fill:url(#radialGradient40);stroke:none"
|
||||
d="m 200.001,337.31 c -17.233,-7.3 -51.946,15.909 -51.946,15.909 v 0 c 0,0 31.116,-33.703 27.069,-47.103 v 0 c -4.048,-13.4 -44.827,-30.694 -44.827,-30.694 v 0 c 0,0 51.174,5.824 53.704,-8.204 v 0 c 2.528,-14.032 -3.951,-54.186 -3.951,-54.186 v 0 c 0,0 25.889,37.471 39.898,36.872 v 0 c 14.012,-0.598 39.902,-36.872 39.902,-36.872 v 0 c 0,0 -14.178,43.955 -3.951,54.186 v 0 c 10.224,10.229 53.705,8.204 53.705,8.204 v 0 c 0,0 -43.02,12.933 -44.827,30.694 v 0 c -1.811,17.761 27.07,47.103 27.07,47.103 v 0 c 0,0 -35.719,-23.04 -51.948,-15.909 v 0 c -16.232,7.131 -19.951,50.532 -19.951,50.532 v 0 c 0,0 -2.719,-43.23 -19.947,-50.532" /></g></g></g></g><g
|
||||
id="g44"><g
|
||||
clip-path="url(#clipPath50)"
|
||||
id="g46"><g
|
||||
transform="translate(407.4561,274.8086)"
|
||||
id="g52"><path
|
||||
id="path54"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 3.747,-1.967 9.743,-3.935 15.833,-3.935 6.559,0 10.025,2.719 10.025,6.934 0,3.841 -2.999,6.185 -10.587,8.807 -10.494,3.747 -17.427,9.556 -17.427,18.833 0,10.773 9.089,18.925 23.891,18.925 7.216,0 12.369,-1.406 16.116,-3.186 l -3.186,-11.43 c -2.436,1.218 -7.026,2.997 -13.116,2.997 -6.184,0 -9.183,-2.903 -9.183,-6.09 0,-4.027 3.467,-5.809 11.712,-8.993 11.15,-4.124 16.303,-9.931 16.303,-18.924 0,-10.59 -8.057,-19.584 -25.392,-19.584 -7.213,0 -14.333,1.966 -17.894,3.934 z" /></g><g
|
||||
transform="translate(456.9297,291.3926)"
|
||||
id="g56"><path
|
||||
id="path58"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 0,5.716 -0.189,10.495 -0.376,14.615 H 11.71 l 0.562,-6.276 h 0.281 c 1.968,2.999 6.09,7.308 13.868,7.308 5.996,0 10.587,-3.092 12.554,-7.871 h 0.186 c 1.78,2.436 3.749,4.311 5.997,5.622 2.53,1.406 5.342,2.249 8.715,2.249 8.807,0 15.459,-6.185 15.459,-19.865 v -26.98 H 55.464 v 24.827 c 0,6.652 -2.154,10.493 -6.744,10.493 -3.373,0 -5.622,-2.248 -6.653,-4.967 -0.282,-1.028 -0.469,-2.434 -0.469,-3.559 V -31.198 H 27.731 v 25.672 c 0,5.713 -2.06,9.648 -6.652,9.648 -3.653,0 -5.808,-2.81 -6.65,-5.059 -0.47,-1.124 -0.564,-2.436 -0.564,-3.655 V -31.198 H 0 Z" /></g><g
|
||||
transform="translate(561.8691,281.835)"
|
||||
id="g60"><path
|
||||
id="path62"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -7.496,0 -13.304,-1.78 -13.304,-7.214 0,-3.653 2.435,-5.433 5.62,-5.433 3.467,0 6.466,2.341 7.403,5.247 C -0.094,-6.652 0,-5.808 0,-4.966 Z m 13.772,-10.587 c 0,-4.308 0.187,-8.525 0.749,-11.054 H 1.686 l -0.843,4.589 H 0.562 c -2.999,-3.654 -7.682,-5.621 -13.118,-5.621 -9.274,0 -14.802,6.746 -14.802,14.054 0,11.898 10.681,17.522 26.89,17.522 v 0.562 c 0,2.434 -1.312,5.901 -8.339,5.901 -4.685,0 -9.65,-1.593 -12.649,-3.374 l -2.623,9.091 c 3.185,1.779 9.463,4.122 17.802,4.122 15.272,0 20.049,-8.995 20.049,-19.768 z" /></g><g
|
||||
transform="translate(621.3672,261.3164)"
|
||||
id="g64"><path
|
||||
id="path66"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -2.529,-1.216 -7.309,-2.154 -12.742,-2.154 -14.803,0 -24.266,9.087 -24.266,23.517 0,13.399 9.181,24.361 26.233,24.361 3.749,0 7.87,-0.657 10.869,-1.78 L -2.155,33.355 c -1.687,0.75 -4.217,1.407 -7.964,1.407 -7.495,0 -12.366,-5.34 -12.273,-12.837 0,-8.433 5.621,-12.928 12.554,-12.928 3.373,0 5.996,0.561 8.151,1.499 z" /></g><g
|
||||
transform="translate(643.4795,286.6143)"
|
||||
id="g68"><path
|
||||
id="path70"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 h 0.188 c 1.031,1.967 2.155,3.841 3.278,5.526 l 9.276,13.868 H 29.888 L 13.492,0.845 32.23,-26.42 H 14.709 L 3.56,-7.588 0,-12.18 V -26.42 H -14.24 V 40.101 H 0 Z" /></g></g></g></g></svg>
|
After Width: | Height: | Size: 7 KiB |
|
@ -472,7 +472,16 @@ public abstract class ConnectionConfiguration {
|
|||
return enabledSaslMechanisms.contains(saslMechanism);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the explicitly enabled SASL mechanisms. May return <code>null</code> if no SASL mechanisms where
|
||||
* explicitly enabled, i.e. all SALS mechanisms supported and announced by the service will be considered.
|
||||
*
|
||||
* @return the enabled SASL mechanisms or <code>null</code>.
|
||||
*/
|
||||
public Set<String> getEnabledSaslMechanisms() {
|
||||
if (enabledSaslMechanisms == null) {
|
||||
return null;
|
||||
}
|
||||
return Collections.unmodifiableSet(enabledSaslMechanisms);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,9 +34,9 @@ import javax.security.auth.callback.CallbackHandler;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -90,10 +90,10 @@ public final class SASLAuthentication {
|
|||
* @return the registered SASLMechanism sorted by the level of preference.
|
||||
*/
|
||||
public static Map<String, String> getRegisterdSASLMechanisms() {
|
||||
Map<String, String> answer = new HashMap<String, String>();
|
||||
Map<String, String> answer = new LinkedHashMap<String, String>();
|
||||
synchronized (REGISTERED_MECHANISMS) {
|
||||
for (SASLMechanism mechanism : REGISTERED_MECHANISMS) {
|
||||
answer.put(mechanism.getClass().getName(), mechanism.getName());
|
||||
answer.put(mechanism.getClass().getName(), mechanism.toString());
|
||||
}
|
||||
}
|
||||
return answer;
|
||||
|
|
|
@ -226,6 +226,16 @@ public class SynchronizationPoint<E extends Exception> {
|
|||
}
|
||||
}
|
||||
|
||||
public E getFailureException() {
|
||||
connectionLock.lock();
|
||||
try {
|
||||
return failureException;
|
||||
}
|
||||
finally {
|
||||
connectionLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the condition to become something else as {@link State#RequestSent} or {@link State#Initial}.
|
||||
* {@link #reportSuccess()}, {@link #reportFailure()} and {@link #reportFailure(Exception)} will either set this
|
||||
|
|
|
@ -279,6 +279,11 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
|
|||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* Get the priority of this SASL mechanism. Lower values mean higher priority.
|
||||
*
|
||||
* @return the priority of this SASL mechanism.
|
||||
*/
|
||||
public abstract int getPriority();
|
||||
|
||||
public abstract void checkIfSuccessfulOrThrow() throws SmackException;
|
||||
|
@ -314,4 +319,9 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
|
|||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return "SASL Mech: " + getName() + ", Prio: " + getPriority();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2014-2016 Florian Schmaus
|
||||
* Copyright 2014-2017 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -23,6 +23,8 @@ import org.jivesoftware.smack.util.MAC;
|
|||
|
||||
public class SCRAMSHA1Mechanism extends ScramMechanism {
|
||||
|
||||
static final int PRIORITY = 110;
|
||||
|
||||
static {
|
||||
SHA_1_SCRAM_HMAC = new ScramHmac() {
|
||||
@Override
|
||||
|
@ -47,7 +49,7 @@ public class SCRAMSHA1Mechanism extends ScramMechanism {
|
|||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 110;
|
||||
return PRIORITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -249,6 +249,9 @@ public abstract class ScramMechanism extends SASLMechanism {
|
|||
}
|
||||
|
||||
protected String getChannelBindingName() {
|
||||
// Check if we are using TLS and if a "-PLUS" variant of this mechanism is enabled. Assuming that the "-PLUS"
|
||||
// variants always have precedence before the non-"-PLUS" variants this means that the server did not announce
|
||||
// the "-PLUS" variant, as otherwise we would have tried it.
|
||||
if (sslSession != null && connectionConfiguration.isEnabledSaslMechanism(getName() + "-PLUS")) {
|
||||
// Announce that we support Channel Binding, i.e., the '-PLUS' flavor of this SASL mechanism, but that we
|
||||
// believe the server does not.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Florian Schmaus
|
||||
* Copyright 2016-2017 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -32,7 +32,7 @@ public class ScramSha1PlusMechanism extends ScramPlusMechanism {
|
|||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 110;
|
||||
return SCRAMSHA1Mechanism.PRIORITY - 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,15 +17,16 @@
|
|||
package org.jivesoftware.smackx.bytestreams.ibb;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.jivesoftware.smack.AbstractConnectionClosedListener;
|
||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||
import org.jivesoftware.smack.Manager;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
|
@ -79,7 +80,7 @@ import org.jxmpp.jid.Jid;
|
|||
*
|
||||
* @author Henning Staib
|
||||
*/
|
||||
public final class InBandBytestreamManager implements BytestreamManager {
|
||||
public final class InBandBytestreamManager extends Manager implements BytestreamManager {
|
||||
|
||||
/**
|
||||
* Stanzas that can be used to encapsulate In-Band Bytestream data packets.
|
||||
|
@ -140,10 +141,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
private final static Random randomGenerator = new Random();
|
||||
|
||||
/* stores one InBandBytestreamManager for each XMPP connection */
|
||||
private final static Map<XMPPConnection, InBandBytestreamManager> managers = new HashMap<XMPPConnection, InBandBytestreamManager>();
|
||||
|
||||
/* XMPP connection */
|
||||
private final XMPPConnection connection;
|
||||
private final static Map<XMPPConnection, InBandBytestreamManager> managers = new WeakHashMap<>();
|
||||
|
||||
/*
|
||||
* assigns a user to a listener that is informed if an In-Band Bytestream request for this user
|
||||
|
@ -208,7 +206,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
* @param connection the XMPP connection
|
||||
*/
|
||||
private InBandBytestreamManager(XMPPConnection connection) {
|
||||
this.connection = connection;
|
||||
super(connection);
|
||||
|
||||
// register bytestream open packet listener
|
||||
this.initiationListener = new InitiationListener(this);
|
||||
|
@ -434,11 +432,13 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza);
|
||||
byteStreamRequest.setTo(targetJID);
|
||||
|
||||
final XMPPConnection connection = connection();
|
||||
|
||||
// sending packet will throw exception on timeout or error reply
|
||||
connection.createStanzaCollectorAndSend(byteStreamRequest).nextResultOrThrow();
|
||||
|
||||
InBandBytestreamSession inBandBytestreamSession = new InBandBytestreamSession(
|
||||
this.connection, byteStreamRequest, targetJID);
|
||||
connection, byteStreamRequest, targetJID);
|
||||
this.sessions.put(sessionID, inBandBytestreamSession);
|
||||
|
||||
return inBandBytestreamSession;
|
||||
|
@ -454,7 +454,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
*/
|
||||
protected void replyRejectPacket(IQ request) throws NotConnectedException, InterruptedException {
|
||||
IQ error = IQ.createErrorResponse(request, XMPPError.Condition.not_acceptable);
|
||||
this.connection.sendStanza(error);
|
||||
connection().sendStanza(error);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -467,7 +467,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
*/
|
||||
protected void replyResourceConstraintPacket(IQ request) throws NotConnectedException, InterruptedException {
|
||||
IQ error = IQ.createErrorResponse(request, XMPPError.Condition.resource_constraint);
|
||||
this.connection.sendStanza(error);
|
||||
connection().sendStanza(error);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -480,7 +480,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
*/
|
||||
protected void replyItemNotFoundPacket(IQ request) throws NotConnectedException, InterruptedException {
|
||||
IQ error = IQ.createErrorResponse(request, XMPPError.Condition.item_not_found);
|
||||
this.connection.sendStanza(error);
|
||||
connection().sendStanza(error);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -501,7 +501,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
* @return the XMPP connection
|
||||
*/
|
||||
protected XMPPConnection getConnection() {
|
||||
return this.connection;
|
||||
return connection();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -548,6 +548,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
* internal status, which includes removing this instance from the managers map.
|
||||
*/
|
||||
private void disableService() {
|
||||
final XMPPConnection connection = connection();
|
||||
|
||||
// remove manager from static managers map
|
||||
managers.remove(connection);
|
||||
|
|
|
@ -40,13 +40,12 @@ public class FaultTolerantNegotiator extends StreamNegotiator {
|
|||
|
||||
private final StreamNegotiator primaryNegotiator;
|
||||
private final StreamNegotiator secondaryNegotiator;
|
||||
private final XMPPConnection connection;
|
||||
|
||||
public FaultTolerantNegotiator(XMPPConnection connection, StreamNegotiator primary,
|
||||
StreamNegotiator secondary) {
|
||||
super(connection);
|
||||
this.primaryNegotiator = primary;
|
||||
this.secondaryNegotiator = secondary;
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,7 +63,7 @@ public class FaultTolerantNegotiator extends StreamNegotiator {
|
|||
@Override
|
||||
public InputStream createIncomingStream(final StreamInitiation initiation) throws SmackException, XMPPErrorException, InterruptedException {
|
||||
// This could be either an xep47 ibb 'open' iq or an xep65 streamhost iq
|
||||
IQ initationSet = initiateIncomingStream(connection, initiation);
|
||||
IQ initationSet = initiateIncomingStream(connection(), initiation);
|
||||
|
||||
StreamNegotiator streamNegotiator = determineNegotiator(initationSet);
|
||||
|
||||
|
|
|
@ -44,8 +44,6 @@ import org.jxmpp.jid.Jid;
|
|||
*/
|
||||
public class IBBTransferNegotiator extends StreamNegotiator {
|
||||
|
||||
private XMPPConnection connection;
|
||||
|
||||
private InBandBytestreamManager manager;
|
||||
|
||||
/**
|
||||
|
@ -54,7 +52,7 @@ public class IBBTransferNegotiator extends StreamNegotiator {
|
|||
* @param connection The connection which this negotiator works on.
|
||||
*/
|
||||
protected IBBTransferNegotiator(XMPPConnection connection) {
|
||||
this.connection = connection;
|
||||
super(connection);
|
||||
this.manager = InBandBytestreamManager.getByteStreamManager(connection);
|
||||
}
|
||||
|
||||
|
@ -75,7 +73,7 @@ public class IBBTransferNegotiator extends StreamNegotiator {
|
|||
*/
|
||||
this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID());
|
||||
|
||||
Stanza streamInitiation = initiateIncomingStream(this.connection, initiation);
|
||||
Stanza streamInitiation = initiateIncomingStream(connection(), initiation);
|
||||
return negotiateIncomingStream(streamInitiation);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,13 +43,11 @@ import org.jxmpp.jid.Jid;
|
|||
*/
|
||||
public class Socks5TransferNegotiator extends StreamNegotiator {
|
||||
|
||||
private XMPPConnection connection;
|
||||
|
||||
private Socks5BytestreamManager manager;
|
||||
|
||||
Socks5TransferNegotiator(XMPPConnection connection) {
|
||||
this.connection = connection;
|
||||
this.manager = Socks5BytestreamManager.getBytestreamManager(this.connection);
|
||||
super(connection);
|
||||
this.manager = Socks5BytestreamManager.getBytestreamManager(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,7 +73,7 @@ public class Socks5TransferNegotiator extends StreamNegotiator {
|
|||
*/
|
||||
this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID());
|
||||
|
||||
Stanza streamInitiation = initiateIncomingStream(this.connection, initiation);
|
||||
Stanza streamInitiation = initiateIncomingStream(connection(), initiation);
|
||||
return negotiateIncomingStream(streamInitiation);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.filetransfer;
|
||||
|
||||
import org.jivesoftware.smack.Manager;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
|
@ -42,7 +43,11 @@ import java.io.OutputStream;
|
|||
*
|
||||
* @author Alexander Wenckus
|
||||
*/
|
||||
public abstract class StreamNegotiator {
|
||||
public abstract class StreamNegotiator extends Manager {
|
||||
|
||||
protected StreamNegotiator(XMPPConnection connection) {
|
||||
super(connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* A event manager for stream initiation requests send to us.
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.pubsub;
|
||||
|
||||
import org.jxmpp.jid.BareJid;
|
||||
|
||||
public abstract class PubSubAssertionError extends AssertionError {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected PubSubAssertionError(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public static class DiscoInfoNodeAssertionError extends PubSubAssertionError {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
DiscoInfoNodeAssertionError(BareJid pubSubService, String nodeId) {
|
||||
super("PubSub service '" + pubSubService + "' returned disco info result for node '" + nodeId
|
||||
+ "', but it did not contain an Identity of type 'leaf' or 'collection' (and category 'pubsub'), which is not allowed according to XEP-60 5.3.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -16,6 +16,8 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.pubsub;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -34,6 +36,7 @@ import org.jivesoftware.smack.packet.EmptyResultIQ;
|
|||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.XMPPError;
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.packet.XMPPError.Condition;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
|
@ -246,12 +249,7 @@ public final class PubSubManager extends Manager {
|
|||
// XEP-60 5.3 states that
|
||||
// "The 'disco#info' result MUST include an identity with a category of 'pubsub' and a type of either 'leaf' or 'collection'."
|
||||
// If this is not the case, then we are dealing with an PubSub implementation that doesn't follow the specification.
|
||||
throw new AssertionError(
|
||||
"PubSub service '"
|
||||
+ pubSubService
|
||||
+ "' returned disco info result for node '"
|
||||
+ id
|
||||
+ "', but it did not contain an Identity of type 'leaf' or 'collection' (and category 'pubsub'), which is not allowed according to XEP-60 5.3.");
|
||||
throw new PubSubAssertionError.DiscoInfoNodeAssertionError(pubSubService, id);
|
||||
}
|
||||
nodeMap.put(id, node);
|
||||
}
|
||||
|
@ -260,6 +258,71 @@ public final class PubSubManager extends Manager {
|
|||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get a leaf node and create one if it does not already exist.
|
||||
*
|
||||
* @param id The unique ID of the node.
|
||||
* @return the leaf node.
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws XMPPErrorException
|
||||
* @since 4.2.1
|
||||
*/
|
||||
public LeafNode getOrCreateLeafNode(final String id)
|
||||
throws NoResponseException, NotConnectedException, InterruptedException, XMPPErrorException {
|
||||
try {
|
||||
return getNode(id);
|
||||
}
|
||||
catch (XMPPErrorException e1) {
|
||||
if (e1.getXMPPError().getCondition() == Condition.item_not_found) {
|
||||
try {
|
||||
return createNode(id);
|
||||
}
|
||||
catch (XMPPErrorException e2) {
|
||||
if (e2.getXMPPError().getCondition() == Condition.conflict) {
|
||||
// The node was created in the meantime, re-try getNode(). Note that this case should be rare.
|
||||
return getNode(id);
|
||||
}
|
||||
throw e2;
|
||||
}
|
||||
}
|
||||
throw e1;
|
||||
}
|
||||
catch (PubSubAssertionError.DiscoInfoNodeAssertionError e) {
|
||||
// This could be caused by Prosody bug #805 (see https://prosody.im/issues/issue/805). Prosody does not
|
||||
// answer to disco#info requests on the node ID, which makes it undecidable if a node is a leaf or
|
||||
// collection node.
|
||||
LOGGER.warning("The PubSub service " + pubSubService
|
||||
+ " threw an DiscoInfoNodeAssertionError, trying workaround for Prosody bug #805 (https://prosody.im/issues/issue/805)");
|
||||
return getOrCreateLeafNodeProsodyWorkaround(id);
|
||||
}
|
||||
}
|
||||
|
||||
private LeafNode getOrCreateLeafNodeProsodyWorkaround(final String id)
|
||||
throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
|
||||
try {
|
||||
return createNode(id);
|
||||
}
|
||||
catch (XMPPErrorException e1) {
|
||||
if (e1.getXMPPError().getCondition() == Condition.conflict) {
|
||||
Constructor<?> constructor = LeafNode.class.getDeclaredConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
LeafNode res;
|
||||
try {
|
||||
res = (LeafNode) constructor.newInstance(this, id);
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException e2) {
|
||||
throw new AssertionError(e2);
|
||||
}
|
||||
// TODO: How to verify that this is actually a leafe node and not a conflict with a collection node?
|
||||
return res;
|
||||
}
|
||||
throw e1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the nodes that currently exist as a child of the specified
|
||||
* collection node. If the service does not support collection nodes
|
||||
|
|
|
@ -180,6 +180,7 @@ public class IntTestUtil {
|
|||
ServiceAdministrationManager adminManager = ServiceAdministrationManager.getInstanceFor(connection);
|
||||
try {
|
||||
adminManager.deleteUser(accountToDelete);
|
||||
break;
|
||||
}
|
||||
catch (NoResponseException | XMPPErrorException | NotConnectedException | InterruptedException e) {
|
||||
LOGGER.log(Level.WARNING, "Exception deleting account for " + connection, e);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2015 Florian Schmaus
|
||||
* Copyright 2015-2017 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -40,6 +40,10 @@ public class WaitForClosingStreamElementTest extends AbstractSmackLowLevelIntegr
|
|||
Field closingStreamReceivedField = connection.getClass().getDeclaredField("closingStreamReceived");
|
||||
closingStreamReceivedField.setAccessible(true);
|
||||
SynchronizationPoint<?> closingStreamReceived = (SynchronizationPoint<?>) closingStreamReceivedField.get(connection);
|
||||
Exception failureException = closingStreamReceived.getFailureException();
|
||||
if (failureException != null) {
|
||||
throw new AssertionError("Sync poing yielded failure exception", failureException);
|
||||
}
|
||||
assertTrue(closingStreamReceived.wasSuccessful());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1424,26 +1424,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
|||
// unacknowledgedStanzas is not null.
|
||||
unacknowledgedStanzas = new ArrayBlockingQueue<>(QUEUE_SIZE);
|
||||
}
|
||||
// Check if the stream element should be put to the unacknowledgedStanza
|
||||
// queue. Note that we can not do the put() in sendStanzaInternal() and the
|
||||
// packet order is not stable at this point (sendStanzaInternal() can be
|
||||
// called concurrently).
|
||||
if (unacknowledgedStanzas != null && packet != null) {
|
||||
// If the unacknowledgedStanza queue is nearly full, request an new ack
|
||||
// from the server in order to drain it
|
||||
if (unacknowledgedStanzas.size() == 0.8 * XMPPTCPConnection.QUEUE_SIZE) {
|
||||
writer.write(AckRequest.INSTANCE.toXML().toString());
|
||||
writer.flush();
|
||||
}
|
||||
try {
|
||||
// It is important the we put the stanza in the unacknowledged stanza
|
||||
// queue before we put it on the wire
|
||||
unacknowledgedStanzas.put(packet);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
maybeAddToUnacknowledgedStanzas(packet);
|
||||
|
||||
CharSequence elementXml = element.toXML();
|
||||
if (elementXml instanceof XmlStringBuilder) {
|
||||
|
@ -1465,6 +1446,10 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
|||
try {
|
||||
while (!queue.isEmpty()) {
|
||||
Element packet = queue.remove();
|
||||
if (packet instanceof Stanza) {
|
||||
Stanza stanza = (Stanza) packet;
|
||||
maybeAddToUnacknowledgedStanzas(stanza);
|
||||
}
|
||||
writer.write(packet.toXML().toString());
|
||||
}
|
||||
writer.flush();
|
||||
|
@ -1523,6 +1508,29 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeAddToUnacknowledgedStanzas(Stanza stanza) throws IOException {
|
||||
// Check if the stream element should be put to the unacknowledgedStanza
|
||||
// queue. Note that we can not do the put() in sendStanzaInternal() and the
|
||||
// packet order is not stable at this point (sendStanzaInternal() can be
|
||||
// called concurrently).
|
||||
if (unacknowledgedStanzas != null && stanza != null) {
|
||||
// If the unacknowledgedStanza queue is nearly full, request an new ack
|
||||
// from the server in order to drain it
|
||||
if (unacknowledgedStanzas.size() == 0.8 * XMPPTCPConnection.QUEUE_SIZE) {
|
||||
writer.write(AckRequest.INSTANCE.toXML().toString());
|
||||
writer.flush();
|
||||
}
|
||||
try {
|
||||
// It is important the we put the stanza in the unacknowledged stanza
|
||||
// queue before we put it on the wire
|
||||
unacknowledgedStanzas.put(stanza);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue