JBossWeb SVN: r2348 - branches/7.4.x/src/main/java/org/apache/jasper/compiler.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-01-20 15:30:54 -0500 (Mon, 20 Jan 2014)
New Revision: 2348
Modified:
branches/7.4.x/src/main/java/org/apache/jasper/compiler/ELParser.java
Log:
Port additional fix.
Modified: branches/7.4.x/src/main/java/org/apache/jasper/compiler/ELParser.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/jasper/compiler/ELParser.java 2014-01-20 16:43:32 UTC (rev 2347)
+++ branches/7.4.x/src/main/java/org/apache/jasper/compiler/ELParser.java 2014-01-20 20:30:54 UTC (rev 2348)
@@ -152,7 +152,7 @@
if (hasNext()) {
Token t2 = nextToken();
if (t2 instanceof Id) {
- s1 = s2;
+ s1 = s2.trim();
s2 = t2.toString();
if (hasNext()) {
curToken = nextToken();
@@ -161,7 +161,7 @@
}
}
if (curToken.toChar() == '(') {
- ELexpr.add(new ELNode.Function(s1.trim(), s2.trim()));
+ ELexpr.add(new ELNode.Function(s1, s2.trim()));
return true;
}
curToken = original;
10 years, 11 months
JBossWeb SVN: r2347 - branches/7.4.x/src/main/java/org/apache/jasper/compiler.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-01-20 11:43:32 -0500 (Mon, 20 Jan 2014)
New Revision: 2347
Modified:
branches/7.4.x/src/main/java/org/apache/jasper/compiler/ELParser.java
Log:
Port space handling fixes.
Modified: branches/7.4.x/src/main/java/org/apache/jasper/compiler/ELParser.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/jasper/compiler/ELParser.java 2014-01-20 16:42:59 UTC (rev 2346)
+++ branches/7.4.x/src/main/java/org/apache/jasper/compiler/ELParser.java 2014-01-20 16:43:32 UTC (rev 2347)
@@ -5,9 +5,9 @@
* The ASF licenses this file to You 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.
@@ -25,32 +25,31 @@
/**
* This class implements a parser for EL expressions.
- *
+ *
* It takes strings of the form xxx${..}yyy${..}zzz etc, and turn it into a
* ELNode.Nodes.
- *
+ *
* Currently, it only handles text outside ${..} and functions in ${ ..}.
- *
+ *
* @author Kin-man Chung
*/
public class ELParser {
- private Token curToken; // current token
+ private Token curToken; // current token
private Token prevToken; // previous token
+ private StringBuilder whiteSpace = new StringBuilder();
- private ELNode.Nodes expr;
+ private final ELNode.Nodes expr;
private ELNode.Nodes ELexpr;
private int index; // Current index of the expression
- private String expression; // The EL expression
-
+ private final String expression; // The EL expression
+
private char type;
- private boolean escapeBS; // is '\' an escape char in text outside EL?
-
private final boolean isDeferredSyntaxAllowedAsLiteral;
private static final String reservedWords[] = { "and", "div", "empty",
@@ -66,7 +65,7 @@
/**
* Parse an EL expression
- *
+ *
* @param expression
* The input expression string of the form Char* ('${' Char*
* '}')* Char*
@@ -76,7 +75,8 @@
*/
public static ELNode.Nodes parse(String expression,
boolean isDeferredSyntaxAllowedAsLiteral) {
- ELParser parser = new ELParser(expression, isDeferredSyntaxAllowedAsLiteral);
+ ELParser parser = new ELParser(expression,
+ isDeferredSyntaxAllowedAsLiteral);
while (parser.hasNextChar()) {
String text = parser.skipUntilEL();
if (text.length() > 0) {
@@ -91,23 +91,26 @@
}
/**
- * Parse an EL expression string '${...}'
- *
- * @return An ELNode.Nodes representing the EL expression TODO: Currently
- * only parsed into functions and text strings. This should be
- * rewritten for a full parser.
+ * Parse an EL expression string '${...}'. Currently only separates the EL
+ * into functions and everything else.
+ *
+ * @return An ELNode.Nodes representing the EL expression
+ *
+ * TODO: Can this be refactored to use the standard EL implementation?
*/
private ELNode.Nodes parseEL() {
StringBuilder buf = new StringBuilder();
ELexpr = new ELNode.Nodes();
+ curToken = null;
+ prevToken = null;
while (hasNext()) {
curToken = nextToken();
if (curToken instanceof Char) {
if (curToken.toChar() == '}') {
break;
}
- buf.append(curToken.toChar());
+ buf.append(curToken.toString());
} else {
// Output whatever is in buffer
if (buf.length() > 0) {
@@ -119,6 +122,9 @@
}
}
}
+ if (curToken != null) {
+ buf.append(curToken.getWhiteSpace());
+ }
if (buf.length() > 0) {
ELexpr.add(new ELNode.ELText(buf.toString()));
}
@@ -138,8 +144,9 @@
}
String s1 = null; // Function prefix
String s2 = curToken.toString(); // Function name
+ Token original = curToken;
if (hasNext()) {
- int mark = getIndex();
+ int mark = getIndex() - whiteSpace.length();
curToken = nextToken();
if (curToken.toChar() == ':') {
if (hasNext()) {
@@ -154,10 +161,10 @@
}
}
if (curToken.toChar() == '(') {
- ELexpr.add(new ELNode.Function(s1, s2));
+ ELexpr.add(new ELNode.Function(s1.trim(), s2.trim()));
return true;
}
- curToken = prevToken;
+ curToken = original;
setIndex(mark);
}
return false;
@@ -187,7 +194,7 @@
/**
* Skip until an EL expression ('${' || '#{') is reached, allowing escape
* sequences '\\' and '\$' and '\#'.
- *
+ *
* @return The text string up to the EL expression
*/
private String skipUntilEL() {
@@ -199,13 +206,14 @@
prev = 0;
if (ch == '\\') {
buf.append('\\');
- if (!escapeBS)
- prev = '\\';
- } else if (ch == '$' || (!isDeferredSyntaxAllowedAsLiteral && ch == '#')) {
+ prev = '\\';
+ } else if (ch == '$'
+ || (!isDeferredSyntaxAllowedAsLiteral && ch == '#')) {
buf.append(ch);
}
// else error!
- } else if (prev == '$' || (!isDeferredSyntaxAllowedAsLiteral && prev == '#')) {
+ } else if (prev == '$'
+ || (!isDeferredSyntaxAllowedAsLiteral && prev == '#')) {
if (ch == '{') {
this.type = prev;
prev = 0;
@@ -215,7 +223,7 @@
prev = 0;
}
if (ch == '\\' || ch == '$'
- || (!isDeferredSyntaxAllowedAsLiteral && ch == '#')) {
+ || (!isDeferredSyntaxAllowedAsLiteral && ch == '#')) {
prev = ch;
} else {
buf.append(ch);
@@ -236,6 +244,12 @@
return hasNextChar();
}
+ private String getAndResetWhiteSpace() {
+ String result = whiteSpace.toString();
+ whiteSpace = new StringBuilder();
+ return result;
+ }
+
/*
* @return The next token in the EL expression buffer.
*/
@@ -247,19 +261,20 @@
if (Character.isJavaIdentifierStart(ch)) {
StringBuilder buf = new StringBuilder();
buf.append(ch);
- while ((ch = peekChar()) != -1
- && Character.isJavaIdentifierPart(ch)) {
+ while (index < expression.length() &&
+ Character.isJavaIdentifierPart(
+ ch = expression.charAt(index))) {
buf.append(ch);
nextChar();
}
- return new Id(buf.toString());
+ return new Id(getAndResetWhiteSpace(), buf.toString());
}
if (ch == '\'' || ch == '"') {
return parseQuotedChars(ch);
} else {
// For now...
- return new Char(ch);
+ return new Char(getAndResetWhiteSpace(), ch);
}
}
return null;
@@ -287,7 +302,7 @@
buf.append(ch);
}
}
- return new QuotedString(buf.toString());
+ return new QuotedString(getAndResetWhiteSpace(), buf.toString());
}
/*
@@ -297,8 +312,10 @@
private void skipSpaces() {
while (hasNextChar()) {
- if (expression.charAt(index) > ' ')
+ char c = expression.charAt(index);
+ if (c > ' ')
break;
+ whiteSpace.append(c);
index++;
}
}
@@ -314,13 +331,6 @@
return expression.charAt(index++);
}
- private char peekChar() {
- if (index >= expression.length()) {
- return (char) -1;
- }
- return expression.charAt(index);
- }
-
private int getIndex() {
return index;
}
@@ -334,13 +344,24 @@
*/
private static class Token {
+ protected final String whiteSpace;
+
+ Token(String whiteSpace) {
+ this.whiteSpace = whiteSpace;
+ }
+
char toChar() {
return 0;
}
+ @Override
public String toString() {
- return "";
+ return whiteSpace;
}
+
+ String getWhiteSpace() {
+ return whiteSpace;
+ }
}
/*
@@ -349,12 +370,14 @@
private static class Id extends Token {
String id;
- Id(String id) {
+ Id(String whiteSpace, String id) {
+ super(whiteSpace);
this.id = id;
}
+ @Override
public String toString() {
- return id;
+ return whiteSpace + id;
}
}
@@ -365,16 +388,19 @@
private char ch;
- Char(char ch) {
+ Char(String whiteSpace, char ch) {
+ super(whiteSpace);
this.ch = ch;
}
+ @Override
char toChar() {
return ch;
}
+ @Override
public String toString() {
- return (new Character(ch)).toString();
+ return whiteSpace + ch;
}
}
@@ -385,12 +411,14 @@
private String value;
- QuotedString(String v) {
+ QuotedString(String whiteSpace, String v) {
+ super(whiteSpace);
this.value = v;
}
+ @Override
public String toString() {
- return value;
+ return whiteSpace + value;
}
}
@@ -398,6 +426,7 @@
return type;
}
+
protected static class TextBuilder extends ELNode.Visitor {
protected StringBuilder output = new StringBuilder();
10 years, 11 months
JBossWeb SVN: r2346 - branches/7.4.x/src/main/java/org/apache/jasper/compiler.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-01-20 11:42:59 -0500 (Mon, 20 Jan 2014)
New Revision: 2346
Modified:
branches/7.4.x/src/main/java/org/apache/jasper/compiler/PageInfo.java
branches/7.4.x/src/main/java/org/apache/jasper/compiler/Validator.java
Log:
Port Tomcat BZ56012: Imports now require a package
Modified: branches/7.4.x/src/main/java/org/apache/jasper/compiler/PageInfo.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/jasper/compiler/PageInfo.java 2014-01-17 14:30:55 UTC (rev 2345)
+++ branches/7.4.x/src/main/java/org/apache/jasper/compiler/PageInfo.java 2014-01-20 16:42:59 UTC (rev 2346)
@@ -405,17 +405,8 @@
/*
* extends
*/
- public void setExtends(String value, Node.PageDirective n) {
-
+ public void setExtends(String value) {
xtends = value;
-
- /*
- * If page superclass is top level class (i.e. not in a package)
- * explicitly import it. If this is not done, the compiler will assume
- * the extended class is in the same pkg as the generated servlet.
- */
- if (value.indexOf('.') < 0)
- n.addImport(value);
}
/**
Modified: branches/7.4.x/src/main/java/org/apache/jasper/compiler/Validator.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/jasper/compiler/Validator.java 2014-01-17 14:30:55 UTC (rev 2345)
+++ branches/7.4.x/src/main/java/org/apache/jasper/compiler/Validator.java 2014-01-20 16:42:59 UTC (rev 2346)
@@ -124,7 +124,7 @@
}
} else if ("extends".equals(attr)) {
if (pageInfo.getExtends(false) == null) {
- pageInfo.setExtends(value, n);
+ pageInfo.setExtends(value);
} else if (!pageInfo.getExtends(false).equals(value)) {
err.jspError(n.getStart(), MESSAGES.invalidConflictingPageDirectiveAttribute
(attr, pageInfo.getExtends(false), value));
10 years, 11 months
JBossWeb SVN: r2345 - branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-01-17 09:30:55 -0500 (Fri, 17 Jan 2014)
New Revision: 2345
Modified:
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/UpgradeUtil.java
Log:
Port WS patch: upgrade behavior tweaks.
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/UpgradeUtil.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/UpgradeUtil.java 2014-01-16 17:02:26 UTC (rev 2344)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/UpgradeUtil.java 2014-01-17 14:30:55 UTC (rev 2345)
@@ -119,11 +119,8 @@
// Sub-protocols
List<String> subProtocols = getTokensFromHeader(req,
"Sec-WebSocket-Protocol");
- if (!subProtocols.isEmpty()) {
- subProtocol = sec.getConfigurator().
- getNegotiatedSubprotocol(
- sec.getSubprotocols(), subProtocols);
- }
+ subProtocol = sec.getConfigurator().getNegotiatedSubprotocol(
+ sec.getSubprotocols(), subProtocols);
// Extensions
// Currently no extensions are supported by this implementation
@@ -149,18 +146,6 @@
}
resp.setHeader("Sec-WebSocket-Extensions", sb.toString());
}
- Endpoint ep;
- try {
- Class<?> clazz = sec.getEndpointClass();
- if (Endpoint.class.isAssignableFrom(clazz)) {
- ep = (Endpoint) sec.getConfigurator().getEndpointInstance(
- clazz);
- } else {
- ep = new PojoEndpointServer();
- }
- } catch (InstantiationException e) {
- throw new ServletException(e);
- }
WsHandshakeRequest wsRequest = new WsHandshakeRequest(req);
WsHandshakeResponse wsResponse = new WsHandshakeResponse();
@@ -178,6 +163,19 @@
}
}
+ Endpoint ep;
+ try {
+ Class<?> clazz = sec.getEndpointClass();
+ if (Endpoint.class.isAssignableFrom(clazz)) {
+ ep = (Endpoint) sec.getConfigurator().getEndpointInstance(
+ clazz);
+ } else {
+ ep = new PojoEndpointServer();
+ }
+ } catch (InstantiationException e) {
+ throw new ServletException(e);
+ }
+
// Small hack until the Servlet API provides a way to do this.
ServletRequest inner = req;
// Unwrap the request
10 years, 11 months
JBossWeb SVN: r2344 - in branches/7.4.x/src/main/java/org/apache/tomcat/websocket: server and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-01-16 12:02:26 -0500 (Thu, 16 Jan 2014)
New Revision: 2344
Modified:
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/FutureToSendHandler.java
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplClient.java
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
Log:
Name cleanup (flush became a blocking write of the remaining data).
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/FutureToSendHandler.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/FutureToSendHandler.java 2014-01-16 14:32:14 UTC (rev 2343)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/FutureToSendHandler.java 2014-01-16 17:02:26 UTC (rev 2344)
@@ -16,7 +16,6 @@
*/
package org.apache.tomcat.websocket;
-import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -79,11 +78,7 @@
// If inside a container thread, must use an autoblocking flush as the write
// event will never come to the Servlet layer until the container thread returns
if (latch.getCount() > 0 && Http11AbstractProcessor.containerThread.get() == Boolean.TRUE) {
- try {
- wsSession.forceFlush();
- } catch (IOException e) {
- throw new ExecutionException(e);
- }
+ wsSession.writeBlock();
}
latch.await();
} finally {
@@ -105,12 +100,12 @@
// If inside a container thread, must use an autoblocking flush as the write
// event will never come to the Servlet layer until the container thread returns
if (latch.getCount() > 0 && Http11AbstractProcessor.containerThread.get() == Boolean.TRUE) {
- // FIXME: this uses the IO timeout, so it adds to the timeout specified by the user
- try {
- wsSession.forceFlush();
- } catch (IOException e) {
- throw new ExecutionException(e);
- }
+ long nanoTime = System.nanoTime();
+ wsSession.writeBlock();
+ // Removing the time spent on IO from the specified timeout
+ // Note: it may wait more than what the user has specified
+ timeout = TimeUnit.NANOSECONDS.convert(timeout, unit) - (System.nanoTime() - nanoTime);
+ unit = TimeUnit.NANOSECONDS;
}
retval = latch.await(timeout, unit);
} finally {
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 2014-01-16 14:32:14 UTC (rev 2343)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 2014-01-16 17:02:26 UTC (rev 2344)
@@ -573,10 +573,11 @@
protected abstract void doWrite(SendHandler handler, ByteBuffer... data);
- protected abstract void doFlush() throws IOException;
+ protected abstract void writeBlock();
protected abstract boolean isMasked();
protected abstract void doClose();
+
private static void writeHeader(ByteBuffer headerBuffer, byte opCode,
ByteBuffer payload, boolean first, boolean last, boolean masked,
byte[] mask) {
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplClient.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplClient.java 2014-01-16 14:32:14 UTC (rev 2343)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplClient.java 2014-01-16 17:02:26 UTC (rev 2344)
@@ -16,7 +16,6 @@
*/
package org.apache.tomcat.websocket;
-import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;
@@ -38,7 +37,7 @@
@Override
- protected void doFlush() throws IOException {
+ protected void writeBlock() {
}
@@ -47,7 +46,6 @@
long timeout = getSendTimeout();
if (timeout < 1) {
timeout = Long.MAX_VALUE;
-
}
SendHandlerToCompletionHandler sh2ch =
new SendHandlerToCompletionHandler(handler);
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java 2014-01-16 14:32:14 UTC (rev 2343)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java 2014-01-16 17:02:26 UTC (rev 2344)
@@ -440,8 +440,8 @@
/**
* Force an autoblocking flush.
*/
- public void forceFlush() throws IOException {
- wsRemoteEndpoint.doFlush();
+ public void writeBlock() {
+ wsRemoteEndpoint.writeBlock();
}
private void fireEndpointOnClose(CloseReason closeReason) {
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 2014-01-16 14:32:14 UTC (rev 2343)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 2014-01-16 17:02:26 UTC (rev 2344)
@@ -353,7 +353,6 @@
WsRemoteEndpointImplClient wsRemoteEndpointClient =
new WsRemoteEndpointImplClient(channel);
-
WsSession wsSession = new WsSession(endpoint, wsRemoteEndpointClient,
this, null, null, null, null, null, subProtocol,
Collections.<String, String> emptyMap(), false,
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java 2014-01-16 14:32:14 UTC (rev 2343)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java 2014-01-16 17:02:26 UTC (rev 2344)
@@ -76,7 +76,7 @@
@Override
- protected void doFlush() throws IOException {
+ protected void writeBlock() {
onWritePossible(false, true);
}
10 years, 11 months
JBossWeb SVN: r2343 - branches/7.4.x/src/main/java/org/apache/jasper/runtime.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-01-16 09:32:14 -0500 (Thu, 16 Jan 2014)
New Revision: 2343
Modified:
branches/7.4.x/src/main/java/org/apache/jasper/runtime/PageContextImpl.java
Log:
Port patch for TC BZ56010: avoid IAE when using the constant for the default value.
Modified: branches/7.4.x/src/main/java/org/apache/jasper/runtime/PageContextImpl.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/jasper/runtime/PageContextImpl.java 2014-01-16 02:39:04 UTC (rev 2342)
+++ branches/7.4.x/src/main/java/org/apache/jasper/runtime/PageContextImpl.java 2014-01-16 14:32:14 UTC (rev 2343)
@@ -150,6 +150,9 @@
// initialize the initial out ...
depth = -1;
+ if (bufferSize == JspWriter.DEFAULT_BUFFER) {
+ bufferSize = Constants.DEFAULT_BUFFER_SIZE;
+ }
if (this.baseOut == null) {
this.baseOut = new JspWriterImpl(response, bufferSize, autoFlush);
} else {
10 years, 11 months
JBossWeb SVN: r2341 - in branches/7.4.x/src/main/java/org/apache/tomcat/websocket: server and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-01-15 12:23:55 -0500 (Wed, 15 Jan 2014)
New Revision: 2341
Modified:
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/FutureToSendHandler.java
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
Log:
Attempt another autoblocking technique. Uses a fake blocking write notification that would write all content and flush.
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/FutureToSendHandler.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/FutureToSendHandler.java 2014-01-15 15:17:33 UTC (rev 2340)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/FutureToSendHandler.java 2014-01-15 17:23:55 UTC (rev 2341)
@@ -74,26 +74,24 @@
@Override
public Void get() throws InterruptedException,
ExecutionException {
- // If inside a container thread, must use an autoblocking flush as the write
- // event will never come to the Servlet layer until the container thread returns
- if (Http11AbstractProcessor.containerThread.get() == Boolean.TRUE) {
- // FIXME: this uses the IO timeout rather than no timeout as per the API contract
- try {
- wsSession.forceFlush();
- } catch (IOException e) {
- throw new ExecutionException(e);
+ try {
+ wsSession.registerFuture(this);
+ // If inside a container thread, must use an autoblocking flush as the write
+ // event will never come to the Servlet layer until the container thread returns
+ if (latch.getCount() > 0 && Http11AbstractProcessor.containerThread.get() == Boolean.TRUE) {
+ try {
+ wsSession.forceFlush();
+ } catch (IOException e) {
+ throw new ExecutionException(e);
+ }
}
- } else {
- try {
- wsSession.registerFuture(this);
- latch.await();
- } finally {
- wsSession.unregisterFuture(this);
- }
- if (result.getException() != null) {
- throw new ExecutionException(result.getException());
- }
+ latch.await();
+ } finally {
+ wsSession.unregisterFuture(this);
}
+ if (result.getException() != null) {
+ throw new ExecutionException(result.getException());
+ }
return null;
}
@@ -101,31 +99,29 @@
public Void get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException,
TimeoutException {
- // If inside a container thread, must use an autoblocking flush as the write
- // event will never come to the Servlet layer until the container thread returns
- if (Http11AbstractProcessor.containerThread.get() == Boolean.TRUE) {
- // FIXME: this uses the IO timeout rather than the timeout specified by the user
- try {
- wsSession.forceFlush();
- } catch (IOException e) {
- throw new ExecutionException(e);
+ boolean retval = false;
+ try {
+ wsSession.registerFuture(this);
+ // If inside a container thread, must use an autoblocking flush as the write
+ // event will never come to the Servlet layer until the container thread returns
+ if (latch.getCount() > 0 && Http11AbstractProcessor.containerThread.get() == Boolean.TRUE) {
+ // FIXME: this uses the IO timeout, so it adds to the timeout specified by the user
+ try {
+ wsSession.forceFlush();
+ } catch (IOException e) {
+ throw new ExecutionException(e);
+ }
}
- } else {
- boolean retval = false;
- try {
- wsSession.registerFuture(this);
- retval = latch.await(timeout, unit);
- } finally {
- wsSession.unregisterFuture(this);
-
- }
- if (retval == false) {
- throw new TimeoutException();
- }
- if (result.getException() != null) {
- throw new ExecutionException(result.getException());
- }
+ retval = latch.await(timeout, unit);
+ } finally {
+ wsSession.unregisterFuture(this);
}
+ if (retval == false) {
+ throw new TimeoutException();
+ }
+ if (result.getException() != null) {
+ throw new ExecutionException(result.getException());
+ }
return null;
}
}
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java 2014-01-15 15:17:33 UTC (rev 2340)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java 2014-01-15 17:23:55 UTC (rev 2341)
@@ -231,7 +231,7 @@
public void onWritePossible() {
// Triggered by the poller so this isn't the same thread that
// triggered the write so no need for a dispatch
- wsRemoteEndpointServer.onWritePossible(false);
+ wsRemoteEndpointServer.onWritePossible(false, false);
}
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java 2014-01-15 15:17:33 UTC (rev 2340)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java 2014-01-15 17:23:55 UTC (rev 2341)
@@ -71,19 +71,17 @@
this.buffers = buffers;
// This is definitely the same thread that triggered the write so a
// dispatch will be required.
- onWritePossible(true);
+ onWritePossible(true, false);
}
@Override
protected void doFlush() throws IOException {
- if (timeoutExpiry != -1) {
- sos.flush();
- }
+ onWritePossible(false, true);
}
- public void onWritePossible(boolean useDispatch) {
+ public void onWritePossible(boolean useDispatch, boolean block) {
if (buffers == null) {
// Servlet 3.1 will call the write listener once even if nothing
// was written
@@ -92,7 +90,7 @@
boolean complete = true;
try {
// If this is false there will be a call back when it is true
- while (sos.isReady()) {
+ while (block || sos.isReady()) {
complete = true;
for (ByteBuffer buffer : buffers) {
if (buffer.hasRemaining()) {
10 years, 11 months
JBossWeb SVN: r2340 - branches/7.4.x/src/main/java/org/apache/catalina/core.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-01-15 10:17:33 -0500 (Wed, 15 Jan 2014)
New Revision: 2340
Modified:
branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java
Log:
Oops.
Modified: branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java 2014-01-15 15:16:07 UTC (rev 2339)
+++ branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java 2014-01-15 15:17:33 UTC (rev 2340)
@@ -547,8 +547,10 @@
Throwable throwable = asyncContext.getError();
if (throwable == null) {
throwable = response.getCoyoteResponse().getErrorException();
- if (throwable != null && !(throwable instanceof IOException)) {
- throwable = new IOException(throwable);
+ if (throwable != null){
+ if (!(throwable instanceof IOException)) {
+ throwable = new IOException(throwable);
+ }
} else {
throwable = new EOFException();
}
10 years, 11 months
JBossWeb SVN: r2339 - branches/7.4.x/src/main/java/org/apache/catalina/core.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-01-15 10:16:07 -0500 (Wed, 15 Jan 2014)
New Revision: 2339
Modified:
branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java
Log:
Obvious cleanup: don't wrap as an IOE if already a meaningful IOE.
Modified: branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java 2014-01-14 09:37:44 UTC (rev 2338)
+++ branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java 2014-01-15 15:16:07 UTC (rev 2339)
@@ -547,7 +547,7 @@
Throwable throwable = asyncContext.getError();
if (throwable == null) {
throwable = response.getCoyoteResponse().getErrorException();
- if (throwable != null) {
+ if (throwable != null && !(throwable instanceof IOException)) {
throwable = new IOException(throwable);
} else {
throwable = new EOFException();
10 years, 11 months
JBossWeb SVN: r2338 - branches/7.4.x/src/main/java/org/apache/catalina/authenticator.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-01-14 04:37:44 -0500 (Tue, 14 Jan 2014)
New Revision: 2338
Modified:
branches/7.4.x/src/main/java/org/apache/catalina/authenticator/SingleSignOn.java
Log:
BZ1027272 (part 1): Attempt to set the CCL and thread binding when expiring sessions from other contexts.
Modified: branches/7.4.x/src/main/java/org/apache/catalina/authenticator/SingleSignOn.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/catalina/authenticator/SingleSignOn.java 2014-01-10 15:09:14 UTC (rev 2337)
+++ branches/7.4.x/src/main/java/org/apache/catalina/authenticator/SingleSignOn.java 2014-01-14 09:37:44 UTC (rev 2338)
@@ -22,20 +22,26 @@
import static org.jboss.web.CatalinaMessages.MESSAGES;
import java.io.IOException;
+import java.security.AccessController;
import java.security.Principal;
+import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
+import org.apache.catalina.Context;
+import org.apache.catalina.Globals;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.Manager;
import org.apache.catalina.Realm;
import org.apache.catalina.Session;
import org.apache.catalina.SessionEvent;
import org.apache.catalina.SessionListener;
+import org.apache.catalina.ThreadBindingListener;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.util.LifecycleSupport;
@@ -505,7 +511,15 @@
reverse.remove(sessions[i]);
}
// Invalidate this session
- sessions[i].expire();
+ ClassLoader oldContextClassLoader = null;
+ try {
+ oldContextClassLoader = bindThread(sessions[i]);
+ sessions[i].expire();
+ } finally {
+ if (oldContextClassLoader != null) {
+ unbindThread(sessions[i], oldContextClassLoader);
+ }
+ }
}
// NOTE: Clients may still possess the old single sign on cookie,
@@ -515,6 +529,97 @@
}
+ protected ClassLoader bindThread(Session session) {
+
+ Manager manager = session.getManager();
+ Context context = null;
+ ClassLoader contextClassLoader = null;
+ ThreadBindingListener threadBindingListener = null;
+ if (manager != null && manager.getContainer() != null
+ && manager.getContainer() instanceof Context) {
+ context = (Context) manager.getContainer();
+ }
+ if (context != null) {
+ if (context.getLoader() != null && context.getLoader().getClassLoader() != null) {
+ contextClassLoader = context.getLoader().getClassLoader();
+ }
+ threadBindingListener = context.getThreadBindingListener();
+ }
+ if (threadBindingListener == null || contextClassLoader == null) {
+ return null;
+ }
+
+ if (Globals.IS_SECURITY_ENABLED) {
+ return AccessController.doPrivileged(new PrivilegedBind(contextClassLoader, threadBindingListener));
+ } else {
+ ClassLoader oldContextClassLoader =
+ Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(contextClassLoader);
+ threadBindingListener.bind();
+ return oldContextClassLoader;
+ }
+
+ }
+
+ protected class PrivilegedBind implements PrivilegedAction<ClassLoader> {
+ private ClassLoader contextClassLoader;
+ private ThreadBindingListener threadBindingListener;
+
+ PrivilegedBind(ClassLoader contextClassLoader, ThreadBindingListener threadBindingListener) {
+ this.contextClassLoader = contextClassLoader;
+ this.threadBindingListener = threadBindingListener;
+ }
+
+ public ClassLoader run() {
+ ClassLoader oldContextClassLoader =
+ Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(contextClassLoader);
+ threadBindingListener.bind();
+ return oldContextClassLoader;
+ }
+ }
+
+ protected void unbindThread(Session session, ClassLoader oldContextClassLoader) {
+
+ Manager manager = session.getManager();
+ Context context = null;
+ ThreadBindingListener threadBindingListener = null;
+ if (manager != null && manager.getContainer() != null
+ && manager.getContainer() instanceof Context) {
+ context = (Context) manager.getContainer();
+ }
+ if (context != null) {
+ threadBindingListener = context.getThreadBindingListener();
+ }
+ if (threadBindingListener == null) {
+ return;
+ }
+
+ if (Globals.IS_SECURITY_ENABLED) {
+ AccessController.doPrivileged(new PrivilegedUnbind(oldContextClassLoader, threadBindingListener));
+ } else {
+ threadBindingListener.unbind();
+ Thread.currentThread().setContextClassLoader(oldContextClassLoader);
+ }
+
+ }
+
+ protected class PrivilegedUnbind implements PrivilegedAction<Void> {
+ private ClassLoader oldContextClassLoader;
+ private ThreadBindingListener threadBindingListener;
+
+ PrivilegedUnbind(ClassLoader oldContextClassLoader, ThreadBindingListener threadBindingListener) {
+ this.oldContextClassLoader = oldContextClassLoader;
+ this.threadBindingListener = threadBindingListener;
+ }
+
+ public Void run() {
+ threadBindingListener.unbind();
+ Thread.currentThread().setContextClassLoader(oldContextClassLoader);
+ return null;
+ }
+ }
+
/**
* Logout the specified single sign on identifier from all sessions.
*
10 years, 11 months