JBossWeb SVN: r2460 - in branches: 7.5.x/src/main/java/org/apache/catalina/security and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-06-16 07:00:39 -0400 (Mon, 16 Jun 2014)
New Revision: 2460
Modified:
branches/7.4.x/src/main/java/org/apache/catalina/security/SecurityClassLoad.java
branches/7.5.x/src/main/java/org/apache/catalina/security/SecurityClassLoad.java
Log:
Add missing patch for CVE-2014-0119, although it is hard to tell if it can be used in AS.
Modified: branches/7.4.x/src/main/java/org/apache/catalina/security/SecurityClassLoad.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/catalina/security/SecurityClassLoad.java 2014-06-13 15:12:30 UTC (rev 2459)
+++ branches/7.4.x/src/main/java/org/apache/catalina/security/SecurityClassLoad.java 2014-06-16 11:00:39 UTC (rev 2460)
@@ -39,6 +39,7 @@
loadCorePackage(loader);
loadLoaderPackage(loader);
+ loadServletsPackage(loader);
loadSessionPackage(loader);
loadUtilPackage(loader);
loadJavaxPackage(loader);
@@ -95,6 +96,18 @@
}
+ private static final void loadServletsPackage(ClassLoader loader)
+ throws Exception {
+ final String basePackage = "org.apache.catalina.servlets.";
+ // Avoid a possible memory leak in the DefaultServlet when running with
+ // a security manager. The DefaultServlet needs to load an XML parser
+ // when running under a security manager. We want this to be loaded by
+ // the container rather than a web application to prevent a memory leak
+ // via web application class loader.
+ loader.loadClass(basePackage + "DefaultServlet");
+ }
+
+
private final static void loadSessionPackage(ClassLoader loader)
throws Exception {
String basePackage = "org.apache.catalina.";
Modified: branches/7.5.x/src/main/java/org/apache/catalina/security/SecurityClassLoad.java
===================================================================
--- branches/7.5.x/src/main/java/org/apache/catalina/security/SecurityClassLoad.java 2014-06-13 15:12:30 UTC (rev 2459)
+++ branches/7.5.x/src/main/java/org/apache/catalina/security/SecurityClassLoad.java 2014-06-16 11:00:39 UTC (rev 2460)
@@ -39,6 +39,7 @@
loadCorePackage(loader);
loadLoaderPackage(loader);
+ loadServletsPackage(loader);
loadSessionPackage(loader);
loadUtilPackage(loader);
loadJavaxPackage(loader);
@@ -95,6 +96,18 @@
}
+ private static final void loadServletsPackage(ClassLoader loader)
+ throws Exception {
+ final String basePackage = "org.apache.catalina.servlets.";
+ // Avoid a possible memory leak in the DefaultServlet when running with
+ // a security manager. The DefaultServlet needs to load an XML parser
+ // when running under a security manager. We want this to be loaded by
+ // the container rather than a web application to prevent a memory leak
+ // via web application class loader.
+ loader.loadClass(basePackage + "DefaultServlet");
+ }
+
+
private final static void loadSessionPackage(ClassLoader loader)
throws Exception {
String basePackage = "org.apache.catalina.";
10 years, 6 months
JBossWeb SVN: r2459 - branches/7.5.x.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-06-13 11:12:30 -0400 (Fri, 13 Jun 2014)
New Revision: 2459
Modified:
branches/7.5.x/pom.xml
Log:
Update version numbers.
Modified: branches/7.5.x/pom.xml
===================================================================
--- branches/7.5.x/pom.xml 2014-06-13 15:05:24 UTC (rev 2458)
+++ branches/7.5.x/pom.xml 2014-06-13 15:12:30 UTC (rev 2459)
@@ -33,7 +33,7 @@
<groupId>org.jboss.web</groupId>
<artifactId>jbossweb</artifactId>
- <version>7.4.6.Final</version>
+ <version>7.5.0.Alpha</version>
<name>JBoss Web</name>
<description>Servlet 3.0 container</description>
@@ -45,7 +45,7 @@
<version.org.jboss.spec.javax.el>1.0.1.Final</version.org.jboss.spec.javax.el>
<version.org.jboss.spec.javax.servlet>1.0.1.Final</version.org.jboss.spec.javax.servlet>
<version.org.jboss.spec.javax.servlet.jsp>1.0.1.Final</version.org.jboss.spec.javax.servlet.jsp>
- <version.org.eclipse.jdt.core.compiler.ecj>4.2.2</version.org.eclipse.jdt.core.compiler.ecj>
+ <version.org.eclipse.jdt.core.compiler.ecj>4.3.1</version.org.eclipse.jdt.core.compiler.ecj>
<!-- Build configuration -->
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
10 years, 6 months
JBossWeb SVN: r2458 - branches.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-06-13 11:05:24 -0400 (Fri, 13 Jun 2014)
New Revision: 2458
Added:
branches/7.5.x/
Log:
New 7.5 branch.
10 years, 6 months
JBossWeb SVN: r2457 - tags.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-06-13 04:27:51 -0400 (Fri, 13 Jun 2014)
New Revision: 2457
Added:
tags/JBOSSWEB_7_4_6_FINAL/
Log:
New 7.4.6 web build.
10 years, 6 months
JBossWeb SVN: r2456 - branches/7.4.x.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-06-13 04:25:11 -0400 (Fri, 13 Jun 2014)
New Revision: 2456
Modified:
branches/7.4.x/pom.xml
Log:
New web build.
Modified: branches/7.4.x/pom.xml
===================================================================
--- branches/7.4.x/pom.xml 2014-06-12 11:27:01 UTC (rev 2455)
+++ branches/7.4.x/pom.xml 2014-06-13 08:25:11 UTC (rev 2456)
@@ -33,7 +33,7 @@
<groupId>org.jboss.web</groupId>
<artifactId>jbossweb</artifactId>
- <version>7.4.5.Final</version>
+ <version>7.4.6.Final</version>
<name>JBoss Web</name>
<description>Servlet 3.0 container</description>
10 years, 6 months
JBossWeb SVN: r2455 - in branches/7.4.x/src/main/java/org: jboss/web and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-06-12 07:27:01 -0400 (Thu, 12 Jun 2014)
New Revision: 2455
Modified:
branches/7.4.x/src/main/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
branches/7.4.x/src/main/java/org/jboss/web/CoyoteMessages.java
Log:
Port code cleanup from Tomcat for exception handling.
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2014-06-11 08:37:57 UTC (rev 2454)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2014-06-12 11:27:01 UTC (rev 2455)
@@ -103,6 +103,11 @@
*/
protected boolean needCRLFParse = false;
+ /**
+ * Flag that indicates if an error has occurred.
+ */
+ private boolean error;
+
// ------------------------------------------------------------- Properties
@@ -124,6 +129,8 @@
if (endChunk)
return -1;
+ checkError();
+
if (needCRLFParse) {
needCRLFParse = false;
// FIXME: parse CRLF could return 0 in NB
@@ -223,6 +230,7 @@
lastValid = 0;
endChunk = false;
needCRLFParse = false;
+ error = false;
}
@@ -278,6 +286,7 @@
// In non blocking mode, no new chunk follows, even if data was present
int n = readBytes();
if (n < 0) {
+ error = true;
throw MESSAGES.invalidChunkHeader();
} else if (n == 0) {
return false;
@@ -293,6 +302,7 @@
} else if (buf[pos] == Constants.SEMI_COLON) {
trailer = true;
} else if (buf[pos] < 0) {
+ error = true;
throw MESSAGES.invalidChunkHeader();
} else if (!trailer) {
//don't read data after the trailer
@@ -303,6 +313,7 @@
} else {
//we shouldn't allow invalid, non hex characters
//in the chunked header
+ error = true;
throw MESSAGES.invalidChunkHeader();
}
}
@@ -311,8 +322,10 @@
}
- if (readDigit == 0 || (result < 0))
+ if (readDigit == 0 || (result < 0)) {
+ error = true;
throw MESSAGES.invalidChunkHeader();
+ }
if (result == 0)
endChunk = true;
@@ -336,17 +349,26 @@
while (!eol) {
if (pos >= lastValid) {
- if (readBytes() <= 0)
+ if (readBytes() <= 0) {
+ error = true;
throw MESSAGES.invalidCrlf();
+ }
}
if (buf[pos] == Constants.CR) {
- if (crfound) throw MESSAGES.invalidCrlfTwoCr();
+ if (crfound) {
+ error = true;
+ throw MESSAGES.invalidCrlfTwoCr();
+ }
crfound = true;
} else if (buf[pos] == Constants.LF) {
- if (!crfound) throw MESSAGES.invalidCrlfNoCr();
+ if (!crfound) {
+ error = true;
+ throw MESSAGES.invalidCrlfNoCr();
+ }
eol = true;
} else {
+ error = true;
throw MESSAGES.invalidCrlf();
}
@@ -371,4 +393,10 @@
}
+ private void checkError() throws IOException {
+ if (error) {
+ throw new IOException(MESSAGES.chunkedFilterError());
+ }
+ }
+
}
Modified: branches/7.4.x/src/main/java/org/jboss/web/CoyoteMessages.java
===================================================================
--- branches/7.4.x/src/main/java/org/jboss/web/CoyoteMessages.java 2014-06-11 08:37:57 UTC (rev 2454)
+++ branches/7.4.x/src/main/java/org/jboss/web/CoyoteMessages.java 2014-06-12 11:27:01 UTC (rev 2455)
@@ -283,4 +283,7 @@
@Message(id = 2081, value = "No cipher match")
String noCipherMatch();
+ @Message(id = 2082, value = "Chunked input filter error")
+ String chunkedFilterError();
+
}
10 years, 6 months
JBossWeb SVN: r2454 - branches/7.4.x/src/main/java/org/apache/coyote/http11.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-06-11 04:37:57 -0400 (Wed, 11 Jun 2014)
New Revision: 2454
Modified:
branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11AprProcessor.java
Log:
BZ1106492: -1 is set for timeout, but the endpoint then uses the main connection timeout. Use instead max int like for NIO2 after an upgrade.
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11AprProcessor.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11AprProcessor.java 2014-06-06 15:54:38 UTC (rev 2453)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11AprProcessor.java 2014-06-11 08:37:57 UTC (rev 2454)
@@ -1299,6 +1299,7 @@
// Switch to raw bytes mode
inputBuffer.removeActiveFilters();
outputBuffer.removeActiveFilters();
+ timeout = Integer.MAX_VALUE;
}
}
10 years, 6 months
JBossWeb SVN: r2453 - 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-06-06 11:54:38 -0400 (Fri, 06 Jun 2014)
New Revision: 2453
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/server/WsHttpUpgradeHandler.java
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
Log:
Related to BZ1100491: Switch to the Tomcat websockets code for IO. With an added sync for text buffers.
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-06-06 15:52:54 UTC (rev 2452)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/FutureToSendHandler.java 2014-06-06 15:54:38 UTC (rev 2453)
@@ -25,8 +25,6 @@
import javax.websocket.SendHandler;
import javax.websocket.SendResult;
-import org.apache.coyote.http11.Http11AbstractProcessor;
-
/**
* Converts a Future to a SendHandler.
*/
@@ -75,11 +73,6 @@
ExecutionException {
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) {
- wsSession.writeBlock();
- }
latch.await();
} finally {
wsSession.unregisterFuture(this);
@@ -97,19 +90,10 @@
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) {
- 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 {
wsSession.unregisterFuture(this);
+
}
if (retval == false) {
throw new TimeoutException();
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-06-06 15:52:54 UTC (rev 2452)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 2014-06-06 15:54:38 UTC (rev 2453)
@@ -591,11 +591,9 @@
protected abstract void doWrite(SendHandler handler, ByteBuffer... data);
- 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) {
@@ -671,7 +669,7 @@
}
public void write() {
- synchronized (endpoint) {
+ synchronized (buffer) {
buffer.clear();
CoderResult cr = encoder.encode(message, buffer, true);
if (cr.isError()) {
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-06-06 15:52:54 UTC (rev 2452)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplClient.java 2014-06-06 15:54:38 UTC (rev 2453)
@@ -37,11 +37,6 @@
@Override
- protected void writeBlock() {
- }
-
-
- @Override
protected void doWrite(SendHandler handler, ByteBuffer... data) {
long timeout = getSendTimeout();
if (timeout < 1) {
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-06-06 15:52:54 UTC (rev 2452)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java 2014-06-06 15:54:38 UTC (rev 2453)
@@ -449,13 +449,6 @@
}
}
- /**
- * Force an autoblocking flush.
- */
- public void writeBlock() {
- wsRemoteEndpoint.writeBlock();
- }
-
private void fireEndpointOnClose(CloseReason closeReason) {
// Fire the onClose event
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-06-06 15:52:54 UTC (rev 2452)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java 2014-06-06 15:54:38 UTC (rev 2453)
@@ -44,6 +44,8 @@
*/
public class WsHttpUpgradeHandler implements HttpUpgradeHandler {
+ private final ClassLoader applicationClassLoader;
+
private Endpoint ep;
private EndpointConfig endpointConfig;
private WsServerContainer webSocketContainer;
@@ -57,6 +59,7 @@
public WsHttpUpgradeHandler() {
+ applicationClassLoader = Thread.currentThread().getContextClassLoader();
}
@@ -212,7 +215,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, false);
+ wsRemoteEndpointServer.onWritePossible(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-06-06 15:52:54 UTC (rev 2452)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java 2014-06-06 15:54:38 UTC (rev 2453)
@@ -71,17 +71,11 @@
this.buffers = buffers;
// This is definitely the same thread that triggered the write so a
// dispatch will be required.
- onWritePossible(true, false);
+ onWritePossible(true);
}
- @Override
- protected void writeBlock() {
- onWritePossible(false, true);
- }
-
-
- public synchronized void onWritePossible(boolean useDispatch, boolean block) {
+ public void onWritePossible(boolean useDispatch) {
if (buffers == null) {
// Servlet 3.1 will call the write listener once even if nothing
// was written
@@ -90,19 +84,20 @@
boolean complete = true;
try {
// If this is false there will be a call back when it is true
- while (block || sos.isReady()) {
+ while (sos.isReady()) {
complete = true;
for (ByteBuffer buffer : buffers) {
- if (buffer.hasRemaining()) {
- complete = false;
- sos.write(buffer.array(), buffer.arrayOffset(),
- buffer.limit());
- buffer.position(buffer.limit());
- break;
+ synchronized (buffer) {
+ if (buffer.hasRemaining()) {
+ complete = false;
+ sos.write(buffer.array(), buffer.arrayOffset(),
+ buffer.limit());
+ buffer.position(buffer.limit());
+ break;
+ }
}
}
if (complete) {
- timeoutExpiry = -1;
wsWriteTimeout.unregister(this);
clearHandler(null, useDispatch);
// Explicit flush for compatibility with buffered streams
10 years, 7 months
JBossWeb SVN: r2452 - in branches/7.4.x/src/main/java/org/apache: coyote/http11 and 1 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2014-06-06 11:52:54 -0400 (Fri, 06 Jun 2014)
New Revision: 2452
Modified:
branches/7.4.x/src/main/java/org/apache/catalina/connector/OutputBuffer.java
branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProcessor.java
branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioChannel.java
branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java
Log:
Related to BZ1100491: Switch to the Tomcat style for IO writes with the NIO2 connector for better reliability and results. Avoid some deadlocks caused by excessive locking.
Modified: branches/7.4.x/src/main/java/org/apache/catalina/connector/OutputBuffer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/catalina/connector/OutputBuffer.java 2014-06-06 15:10:52 UTC (rev 2451)
+++ branches/7.4.x/src/main/java/org/apache/catalina/connector/OutputBuffer.java 2014-06-06 15:52:54 UTC (rev 2452)
@@ -700,7 +700,8 @@
throw MESSAGES.cannotSetListenerWithoutUpgradeOrAsync();
}
this.writeListener = writeListener;
- coyoteResponse.action(ActionCode.ACTION_EVENT_WRITE_BEGIN, null);
+ coyoteResponse.action(ActionCode.ACTION_EVENT_WRITE_BEGIN,
+ (response.getRequest().getUpgradeHandler() != null) ? writeListener : null);
}
}
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProcessor.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProcessor.java 2014-06-06 15:10:52 UTC (rev 2451)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProcessor.java 2014-06-06 15:52:54 UTC (rev 2452)
@@ -38,6 +38,7 @@
import org.apache.coyote.http11.filters.SavedRequestInputFilter;
import org.apache.coyote.http11.filters.VoidInputFilter;
import org.apache.coyote.http11.filters.VoidOutputFilter;
+import org.apache.coyote.http11.upgrade.servlet31.WriteListener;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.HexUtils;
import org.apache.tomcat.util.buf.MessageBytes;
@@ -863,6 +864,7 @@
readNotifications = true;
} else if (actionCode == ActionCode.ACTION_EVENT_WRITE_BEGIN) {
outputBuffer.setNonBlocking(true);
+ outputBuffer.setWriteListener((WriteListener) param);
writeEvent(param);
} else if (actionCode == ActionCode.UPGRADE) {
// Switch to raw bytes mode
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java 2014-06-06 15:10:52 UTC (rev 2451)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java 2014-06-06 15:52:54 UTC (rev 2452)
@@ -29,6 +29,7 @@
import org.apache.coyote.ActionCode;
import org.apache.coyote.OutputBuffer;
import org.apache.coyote.Response;
+import org.apache.coyote.http11.upgrade.servlet31.WriteListener;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.buf.MessageBytes;
@@ -143,6 +144,11 @@
*/
private Semaphore semaphore = new Semaphore(1);
+ /**
+ * Associated write listener for upgrade mode.
+ */
+ private WriteListener listener = null;
+
/**
* Create a new instance of {@code InternalNioOutputBuffer}
*
@@ -194,31 +200,60 @@
this.completionHandler = new CompletionHandler<Integer, NioChannel>() {
@Override
- public synchronized void completed(Integer nBytes, NioChannel attachment) {
+ public void completed(Integer nBytes, NioChannel attachment) {
if (nBytes < 0) {
failed(new IOException(MESSAGES.failedWrite()), attachment);
return;
}
- if (!bbuf.hasRemaining()) {
- bbuf.clear();
- if (leftover.getLength() > 0) {
- int n = Math.min(leftover.getLength(), bbuf.remaining());
- bbuf.put(leftover.getBuffer(), leftover.getOffset(), n).flip();
- leftover.setOffset(leftover.getOffset() + n);
+ boolean notify = false;
+ boolean write = false;
+ synchronized (completionHandler) {
+ if (!bbuf.hasRemaining()) {
+ bbuf.clear();
+ if (leftover.getLength() > 0) {
+ int n = Math.min(leftover.getLength(), bbuf.remaining());
+ bbuf.put(leftover.getBuffer(), leftover.getOffset(), n).flip();
+ leftover.setOffset(leftover.getOffset() + n);
+ write = true;
+ } else {
+ response.setLastWrite(nBytes);
+ leftover.recycle();
+ semaphore.release();
+ if (processor.getWriteNotification()) {
+ notify = true;
+ }
+ }
} else {
- response.setLastWrite(nBytes);
- leftover.recycle();
- semaphore.release();
- if (/*!processor.isProcessing() && */processor.getWriteNotification()) {
- if (!endpoint.processChannel(attachment, SocketStatus.OPEN_WRITE)) {
+ write = true;
+ }
+ }
+ if (write) {
+ attachment.write(bbuf, writeTimeout, TimeUnit.MILLISECONDS, attachment, this);
+ }
+ if (notify) {
+ if (listener == null) {
+ if (!endpoint.processChannel(attachment, SocketStatus.OPEN_WRITE)) {
+ endpoint.closeChannel(attachment);
+ }
+ } else {
+ Thread thread = Thread.currentThread();
+ ClassLoader originalClassLoader = thread.getContextClassLoader();
+ try {
+ thread.setContextClassLoader(listener.getClass().getClassLoader());
+ synchronized (channel.getWriteLock()) {
+ listener.onWritePossible();
+ }
+ } catch (Exception e) {
+ processor.getResponse().setErrorException(e);
+ endpoint.removeEventChannel(attachment);
+ if (!endpoint.processChannel(attachment, SocketStatus.ERROR)) {
endpoint.closeChannel(attachment);
}
+ } finally {
+ thread.setContextClassLoader(originalClassLoader);
}
- return;
}
}
- // Write the remaining bytes
- attachment.write(bbuf, writeTimeout, TimeUnit.MILLISECONDS, attachment, this);
}
@Override
@@ -386,6 +421,13 @@
}
/**
+ * Set the associated write listener for upgrade mode.
+ */
+ public void setWriteListener(WriteListener listener) {
+ this.listener = listener;
+ }
+
+ /**
* Add an output filter to the filter library.
*
* @param filter
@@ -479,6 +521,11 @@
lastActiveFilter = -1;
committed = false;
finished = false;
+ listener = null;
+ if (semaphore.availablePermits() != 1) {
+ semaphore.drainPermits();
+ semaphore.release();
+ }
writeTimeout = (endpoint.getSoTimeout() > 0 ? endpoint.getSoTimeout()
: Integer.MAX_VALUE);
}
@@ -508,9 +555,6 @@
lastActiveFilter = -1;
committed = false;
finished = false;
- if (nonBlocking) {
- semaphore.release();
- }
nonBlocking = false;
}
@@ -820,24 +864,26 @@
if (leftover.getLength() > Constants.ASYNC_BUFFER_SIZE) {
response.setLastWrite(0);
}
- if (semaphore.tryAcquire()) {
- // Calculate the number of bytes that fit in the buffer
- int n = Math.min(leftover.getLength(), bbuf.capacity() - bbuf.position());
- bbuf.put(leftover.getBuffer(), leftover.getOffset(), n).flip();
- leftover.setOffset(leftover.getOffset() + n);
- boolean writeNotification = processor.getWriteNotification();
- processor.setWriteNotification(false);
- try {
- channel.write(bbuf, writeTimeout, TimeUnit.MILLISECONDS, channel, completionHandler);
- } catch (Exception e) {
- processor.getResponse().setErrorException(e);
- if (CoyoteLogger.HTTP_LOGGER.isDebugEnabled()) {
- CoyoteLogger.HTTP_LOGGER.errorWithNonBlockingWrite(e);
- }
+ }
+ if (semaphore.tryAcquire()) {
+ // Calculate the number of bytes that fit in the buffer
+ int n = Math.min(leftover.getLength(), bbuf.capacity() - bbuf.position());
+ bbuf.put(leftover.getBuffer(), leftover.getOffset(), n).flip();
+ leftover.setOffset(leftover.getOffset() + n);
+ boolean writeNotification = processor.getWriteNotification();
+ processor.setWriteNotification(false);
+ try {
+ channel.write(bbuf, writeTimeout, TimeUnit.MILLISECONDS, channel, completionHandler);
+ } catch (Exception e) {
+ processor.getResponse().setErrorException(e);
+ if (CoyoteLogger.HTTP_LOGGER.isDebugEnabled()) {
+ CoyoteLogger.HTTP_LOGGER.errorWithNonBlockingWrite(e);
}
- if (writeNotification && bbuf.hasRemaining()) {
- // Write did not complete inline, possible write notification
- processor.setWriteNotification(writeNotification);
+ }
+ if (semaphore.availablePermits() == 0) {
+ // Write did not complete inline, possible write notification
+ if (writeNotification) {
+ processor.setWriteNotification(true);
}
}
}
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioChannel.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioChannel.java 2014-06-06 15:10:52 UTC (rev 2451)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioChannel.java 2014-06-06 15:52:54 UTC (rev 2452)
@@ -189,6 +189,15 @@
private long id;
private ByteBuffer buffer;
+ private Object lock = new Object();
+ public Object getLock() {
+ return lock;
+ }
+ private Object writeLock = new Object();
+ public Object getWriteLock() {
+ return writeLock;
+ }
+
/**
* Create a new instance of {@code NioChannel}
*
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java 2014-06-06 15:10:52 UTC (rev 2451)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java 2014-06-06 15:52:54 UTC (rev 2452)
@@ -931,7 +931,7 @@
if (status == null) {
state = handler.process(channel);
} else {
- synchronized (channel) {
+ synchronized (channel.getLock()) {
state = handler.event(channel, status);
}
}
10 years, 7 months
JBossWeb SVN: r2451 - 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-06-06 11:10:52 -0400 (Fri, 06 Jun 2014)
New Revision: 2451
Modified:
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsHandshakeRequest.java
Log:
Add a flag to return the full URI.
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsHandshakeRequest.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsHandshakeRequest.java 2014-06-06 03:53:03 UTC (rev 2450)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/server/WsHandshakeRequest.java 2014-06-06 15:10:52 UTC (rev 2451)
@@ -37,6 +37,7 @@
*/
public class WsHandshakeRequest implements HandshakeRequest {
+ private static final Boolean FULL_URL = Boolean.getBoolean("org.apache.tomcat.websocket.server.WsHandshakeRequest.FULL_URL");
private final URI requestUri;
private final Map<String,List<String>> parameterMap;
private final String queryString;
@@ -56,28 +57,33 @@
httpSession = request.getSession(false);
// URI
- // Based on request.getRequestURL() implementation
- StringBuilder sb = new StringBuilder();
- String scheme = request.getScheme();
- int port = request.getServerPort();
- if (port < 0)
- port = 80; // Work around java.net.URL bug
+ StringBuilder sb = null;
+ if (FULL_URL) {
+ // Based on request.getRequestURL() implementation
+ sb = new StringBuilder();
+ String scheme = request.getScheme();
+ int port = request.getServerPort();
+ if (port < 0)
+ port = 80; // Work around java.net.URL bug
- if (scheme.equals("http")) {
- sb.append("ws");
- } else if (scheme.equals("https")) {
- sb.append("wss");
+ if (scheme.equals("http")) {
+ sb.append("ws");
+ } else if (scheme.equals("https")) {
+ sb.append("wss");
+ } else {
+ throw MESSAGES.unknownScheme(scheme);
+ }
+ sb.append("://");
+ sb.append(request.getServerName());
+ if ((scheme.equals("http") && (port != 80))
+ || (scheme.equals("https") && (port != 443))) {
+ sb.append(':');
+ sb.append(port);
+ }
+ sb.append(request.getRequestURI());
} else {
- throw MESSAGES.unknownScheme(scheme);
+ sb = new StringBuilder(request.getRequestURI());
}
- sb.append("://");
- sb.append(request.getServerName());
- if ((scheme.equals("http") && (port != 80))
- || (scheme.equals("https") && (port != 443))) {
- sb.append(':');
- sb.append(port);
- }
- sb.append(request.getRequestURI());
if (queryString != null) {
sb.append('?');
sb.append(queryString);
10 years, 7 months