Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoakim Erdfelt2013-12-13 19:28:15 +0000
committerJoakim Erdfelt2013-12-13 19:30:26 +0000
commit46ef022cf47c19eaea72ccb336ae436e5eaebeff (patch)
treeddabfe715891ce54f219a4a74911ea9517bb8adc /jetty-websocket/websocket-api/src
parent5c296c99d835b96caf4502145abbd897195fc70d (diff)
downloadorg.eclipse.jetty.project-46ef022cf47c19eaea72ccb336ae436e5eaebeff.tar.gz
org.eclipse.jetty.project-46ef022cf47c19eaea72ccb336ae436e5eaebeff.tar.xz
org.eclipse.jetty.project-46ef022cf47c19eaea72ccb336ae436e5eaebeff.zip
421314 - Websocket / Connect attempt with Chrome 32+ fails with "Some extension already uses the compress bit"
+ Reworked extension negotiation to be more consistent with the changes to the spec that Chrome 32 are introducing. Namely that first extension to claim RSV bit wins, all other conflicting extensions are ignored.
Diffstat (limited to 'jetty-websocket/websocket-api/src')
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java11
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java146
2 files changed, 125 insertions, 32 deletions
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java
index 8729131d34..f72359982b 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java
@@ -187,7 +187,7 @@ public class UpgradeRequest
{
return Collections.unmodifiableMap(parameters);
}
-
+
public String getProtocolVersion()
{
String version = getHeader("Sec-WebSocket-Version");
@@ -265,6 +265,15 @@ public class UpgradeRequest
this.cookies = cookies;
}
+ public void setExtensions(List<ExtensionConfig> configs)
+ {
+ this.extensions.clear();
+ if (configs != null)
+ {
+ this.extensions.addAll(configs);
+ }
+ }
+
public void setHeader(String name, List<String> values)
{
headers.put(name,values);
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java
index 329dbea81c..d7ade452aa 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java
@@ -18,8 +18,11 @@
package org.eclipse.jetty.websocket.api.extensions;
+import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -30,39 +33,99 @@ import org.eclipse.jetty.websocket.api.util.QuoteUtil;
*/
public class ExtensionConfig
{
+ /**
+ * Parse a single parameterized name.
+ *
+ * @param parameterizedName
+ * the parameterized name
+ * @return the ExtensionConfig
+ */
public static ExtensionConfig parse(String parameterizedName)
{
- Iterator<String> extListIter = QuoteUtil.splitAt(parameterizedName,";");
- String extToken = extListIter.next();
+ return new ExtensionConfig(parameterizedName);
+ }
- ExtensionConfig ext = new ExtensionConfig(extToken);
+ /**
+ * Parse enumeration of <code>Sec-WebSocket-Extensions</code> header values into a {@link ExtensionConfig} list
+ *
+ * @param valuesEnum
+ * the raw header values enum
+ * @return the list of extension configs
+ */
+ public static List<ExtensionConfig> parseEnum(Enumeration<String> valuesEnum)
+ {
+ List<ExtensionConfig> configs = new ArrayList<>();
- // now for parameters
- while (extListIter.hasNext())
+ if (valuesEnum != null)
{
- String extParam = extListIter.next();
- Iterator<String> extParamIter = QuoteUtil.splitAt(extParam,"=");
- String key = extParamIter.next().trim();
- String value = null;
- if (extParamIter.hasNext())
+ while (valuesEnum.hasMoreElements())
{
- value = extParamIter.next();
+ Iterator<String> extTokenIter = QuoteUtil.splitAt(valuesEnum.nextElement(),",");
+ while (extTokenIter.hasNext())
+ {
+ String extToken = extTokenIter.next();
+ configs.add(ExtensionConfig.parse(extToken));
+ }
}
- ext.setParameter(key,value);
}
- return ext;
+ return configs;
}
- private final String name;
- private Map<String, String> parameters;
+ /**
+ * Parse 1 or more raw <code>Sec-WebSocket-Extensions</code> header values into a {@link ExtensionConfig} list
+ *
+ * @param rawSecWebSocketExtensions
+ * the raw header values
+ * @return the list of extension configs
+ */
+ public static List<ExtensionConfig> parseList(String... rawSecWebSocketExtensions)
+ {
+ List<ExtensionConfig> configs = new ArrayList<>();
+
+ for (String rawValue : rawSecWebSocketExtensions)
+ {
+ Iterator<String> extTokenIter = QuoteUtil.splitAt(rawValue,",");
+ while (extTokenIter.hasNext())
+ {
+ String extToken = extTokenIter.next();
+ configs.add(ExtensionConfig.parse(extToken));
+ }
+ }
+
+ return configs;
+ }
- public ExtensionConfig(String name)
+ /**
+ * Convert a list of {@link ExtensionConfig} to a header value
+ *
+ * @param configs
+ * the list of extension configs
+ * @return the header value (null if no configs present)
+ */
+ public static String toHeaderValue(List<ExtensionConfig> configs)
{
- this.name = name;
- this.parameters = new HashMap<>();
+ if ((configs == null) || (configs.isEmpty()))
+ {
+ return null;
+ }
+ StringBuilder parameters = new StringBuilder();
+ boolean needsDelim = false;
+ for (ExtensionConfig ext : configs)
+ {
+ if (needsDelim)
+ {
+ parameters.append(", ");
+ }
+ parameters.append(ext.getParameterizedName());
+ needsDelim = true;
+ }
+ return parameters.toString();
}
+ private final String name;
+ private final Map<String, String> parameters;
+
/**
* Copy constructor
*/
@@ -73,12 +136,33 @@ public class ExtensionConfig
this.parameters.putAll(copy.parameters);
}
+ public ExtensionConfig(String parameterizedName)
+ {
+ Iterator<String> extListIter = QuoteUtil.splitAt(parameterizedName,";");
+ this.name = extListIter.next();
+ this.parameters = new HashMap<>();
+
+ // now for parameters
+ while (extListIter.hasNext())
+ {
+ String extParam = extListIter.next();
+ Iterator<String> extParamIter = QuoteUtil.splitAt(extParam,"=");
+ String key = extParamIter.next().trim();
+ String value = null;
+ if (extParamIter.hasNext())
+ {
+ value = extParamIter.next();
+ }
+ parameters.put(key,value);
+ }
+ }
+
public String getName()
{
return name;
}
- public int getParameter(String key, int defValue)
+ public final int getParameter(String key, int defValue)
{
String val = parameters.get(key);
if (val == null)
@@ -88,7 +172,7 @@ public class ExtensionConfig
return Integer.valueOf(val);
}
- public String getParameter(String key, String defValue)
+ public final String getParameter(String key, String defValue)
{
String val = parameters.get(key);
if (val == null)
@@ -98,7 +182,7 @@ public class ExtensionConfig
return val;
}
- public String getParameterizedName()
+ public final String getParameterizedName()
{
StringBuilder str = new StringBuilder();
str.append(name);
@@ -116,7 +200,7 @@ public class ExtensionConfig
return str.toString();
}
- public Set<String> getParameterKeys()
+ public final Set<String> getParameterKeys()
{
return parameters.keySet();
}
@@ -126,7 +210,7 @@ public class ExtensionConfig
*
* @return the parameter map
*/
- public Map<String, String> getParameters()
+ public final Map<String, String> getParameters()
{
return parameters;
}
@@ -137,25 +221,25 @@ public class ExtensionConfig
* @param other
* the other configuration.
*/
- public void init(ExtensionConfig other)
+ public final void init(ExtensionConfig other)
{
this.parameters.clear();
this.parameters.putAll(other.parameters);
}
- public void setParameter(String key, int value)
+ public final void setParameter(String key)
{
- parameters.put(key,Integer.toString(value));
+ parameters.put(key,null);
}
- public void setParameter(String key, String value)
+ public final void setParameter(String key, int value)
{
- parameters.put(key,value);
+ parameters.put(key,Integer.toString(value));
}
-
- public void setParameter(String key)
+
+ public final void setParameter(String key, String value)
{
- parameters.put(key,null);
+ parameters.put(key,value);
}
@Override

Back to the top