Merge branch 'jetty-9.4.x' into 'jetty-9.4.x-websocket-sci-from-embedded'
This commit is contained in:
commit
49ee5ac3c0
46
VERSION.txt
46
VERSION.txt
|
@ -1,10 +1,52 @@
|
|||
jetty-9.4.19-SNAPSHOT
|
||||
jetty-9.4.20-SNAPSHOT
|
||||
|
||||
jetty-9.4.19.v20190610 - 10 June 2019
|
||||
+ 2909 Remove B64Code
|
||||
+ 3332 jetty-maven-plugin - transitive dependencies not loaded from
|
||||
"target/classes"
|
||||
+ 3498 WebSocket Session.suspend() now suspends incoming frames instead
|
||||
of reads
|
||||
+ 3534 Use System nanoTime, not currentTimeMillis for IdleTimeout
|
||||
+ 3550 Server becomes unresponsive after sitting idle from a load spike
|
||||
+ 3562 InetAccessHandler should be able to apply to a certain port or
|
||||
connector
|
||||
+ 3568 Make UserStore able to be started/stopped with its LoginService
|
||||
+ 3583 jetty-maven plugin in multi-module-project does not use files from
|
||||
/target/test-classes folder of dependent projects
|
||||
+ 3605 IdleTimeout with Jetty HTTP/2 and InputStreamResponseListener
|
||||
+ 3608 Reply with 400 Bad request to malformed WebSocket handshake
|
||||
+ 3616 Backport WebSocket SessionTracker from Jetty 10
|
||||
+ 3620 Use of `throwUnavailableOnStartupException=true` does not stop Server
|
||||
in jetty-home
|
||||
+ 3627 Only renew session id when spnego authentication is fully complete
|
||||
+ 3628 NPE in QueuedThreadPool.getReservedThreads()
|
||||
+ 3630 X-Forwarded-For missing last hextet for ipv6
|
||||
+ 3633 endpointIdentificationAlgorithm enabled by default
|
||||
jetty-ssl-context.xml
|
||||
+ 3653 access control exception if programmatic security manager is used
|
||||
+ 3655 Spaces missing on Cookies generated via RFC6265
|
||||
+ 3663 Remove deprecation of HttpClient replacement methods in WebSocketClient
|
||||
+ 3680 Bom manages non-existent infinispan-remote and infinispan-embedded
|
||||
dependencies due to config classifier
|
||||
+ 3683 Multipart file not deleted when client aborts upload
|
||||
+ 3690 Upgrade to asm 7.1
|
||||
+ 3713 Emit warning when invoking deprecated method in Jetty XML
|
||||
+ 3715 Improve Log.condensePackage performance
|
||||
+ 3722 HttpSessionListener.sessionDestroyed should be able to access webapp
|
||||
classes
|
||||
+ 3726 Remove OSGi export uses of servlet-api from jetty-util
|
||||
+ 3729 Make creation of java:comp/env threadsafe
|
||||
+ 3743 Update XmlConfiguration usage in Jetty to always use Constructors that
|
||||
provide Location information
|
||||
+ 3748 @Resource field not injected in Jetty Demo
|
||||
+ 3750 NPE in WebSocketClient.toString()
|
||||
+ 3751 Modern Configure DTD / FPI is used inconsistently
|
||||
|
||||
jetty-9.4.18.v20190429 - 29 April 2019
|
||||
+ 3476 IllegalStateException in WebSocket ConnectionState
|
||||
+ 3550 Server becomes unresponsive after sitting idle from a load spike
|
||||
+ 3563 Update to apache jasper 8.5.40
|
||||
+ 3573 Update jetty-bom for new infinispan artifacts.
|
||||
+ 3573 Update jetty-bom for new infinispan artifacts
|
||||
+ 3582 HeapByteBuffer cleared unexpected
|
||||
+ 3597 Session persistence broken from 9.4.13+
|
||||
+ 3609 Fix infinispan start module dependencies
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>apache-jsp</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>apache-jstl</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>example-async-rest</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.math.RoundingMode;
|
|||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
@ -67,12 +66,25 @@ public class AbstractRestServlet extends HttpServlet
|
|||
_appid = servletConfig.getInitParameter(APPID_PARAM);
|
||||
}
|
||||
|
||||
|
||||
public static String sanitize(String s)
|
||||
// TODO: consider using StringUtil.sanitizeFileSystemName instead of this?
|
||||
// might introduce jetty-util dependency though
|
||||
public static String sanitize(String str)
|
||||
{
|
||||
if (s==null)
|
||||
if (str == null)
|
||||
return null;
|
||||
return s.replace("<","?").replace("&","?").replace("\n","?");
|
||||
|
||||
char[] chars = str.toCharArray();
|
||||
int len = chars.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
char c = chars[i];
|
||||
if ((c <= 0x1F) || // control characters
|
||||
(c == '<') || (c == '&'))
|
||||
{
|
||||
chars[i] = '?';
|
||||
}
|
||||
}
|
||||
return String.valueOf(chars);
|
||||
}
|
||||
|
||||
protected String restURL(String item)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>example-async-rest</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<!--
|
||||
This is the jetty specific web application configuration file. When starting
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.examples</groupId>
|
||||
<artifactId>examples-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.examples</groupId>
|
||||
<artifactId>examples-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -36,9 +36,8 @@ public class FileServerXml
|
|||
{
|
||||
public static void main( String[] args ) throws Exception
|
||||
{
|
||||
Resource fileserverXml = Resource.newSystemResource("fileserver.xml");
|
||||
XmlConfiguration configuration = new XmlConfiguration(
|
||||
fileserverXml.getInputStream());
|
||||
Resource fileServerXml = Resource.newSystemResource("fileserver.xml");
|
||||
XmlConfiguration configuration = new XmlConfiguration(fileServerXml);
|
||||
Server server = (Server) configuration.configure();
|
||||
server.start();
|
||||
server.join();
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.io.IOException;
|
|||
import java.lang.management.ManagementFactory;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
|
@ -158,7 +157,7 @@ public class Http2Server
|
|||
public void destroy()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static Servlet servlet = new HttpServlet()
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-alpn-client</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-alpn-server</artifactId>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-alpn-parent</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-annotations</artifactId>
|
||||
|
|
|
@ -38,6 +38,8 @@ import org.eclipse.jetty.util.Loader;
|
|||
import org.eclipse.jetty.util.ManifestUtils;
|
||||
import org.eclipse.jetty.util.MultiException;
|
||||
import org.eclipse.jetty.util.MultiReleaseJarFile;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
|
@ -151,7 +153,7 @@ public class AnnotationParser
|
|||
if (name.endsWith(".class"))
|
||||
name = name.substring(0, name.length()-".class".length());
|
||||
|
||||
return name.replace('/', '.');
|
||||
return StringUtil.replace(name,'/', '.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -599,13 +601,12 @@ public class AnnotationParser
|
|||
if (className == null)
|
||||
return;
|
||||
|
||||
String tmp = className;
|
||||
className = className.replace('.', '/')+".class";
|
||||
URL resource = Loader.getResource(className);
|
||||
String classRef = TypeUtil.toClassReference(className);
|
||||
URL resource = Loader.getResource(classRef);
|
||||
if (resource!= null)
|
||||
{
|
||||
Resource r = Resource.newResource(resource);
|
||||
addParsedClass(tmp, r);
|
||||
addParsedClass(className, r);
|
||||
try (InputStream is = r.getInputStream())
|
||||
{
|
||||
scanClass(handlers, null, is);
|
||||
|
@ -626,7 +627,7 @@ public class AnnotationParser
|
|||
Class<?> cz = clazz;
|
||||
while (cz != Object.class)
|
||||
{
|
||||
String nameAsResource = cz.getName().replace('.', '/')+".class";
|
||||
String nameAsResource = TypeUtil.toClassReference(cz);
|
||||
URL resource = Loader.getResource(nameAsResource);
|
||||
if (resource!= null)
|
||||
{
|
||||
|
@ -671,17 +672,16 @@ public class AnnotationParser
|
|||
{
|
||||
MultiException me = new MultiException();
|
||||
|
||||
for (String s:classNames)
|
||||
for (String className : classNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
String name = s;
|
||||
s = s.replace('.', '/')+".class";
|
||||
URL resource = Loader.getResource(s);
|
||||
String classRef = TypeUtil.toClassReference(className);
|
||||
URL resource = Loader.getResource(classRef);
|
||||
if (resource!= null)
|
||||
{
|
||||
Resource r = Resource.newResource(resource);
|
||||
addParsedClass(name, r);
|
||||
addParsedClass(className, r);
|
||||
try (InputStream is = r.getInputStream())
|
||||
{
|
||||
scanClass(handlers, null, is);
|
||||
|
@ -690,7 +690,7 @@ public class AnnotationParser
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
me.add(new RuntimeException("Error scanning class "+s, e));
|
||||
me.add(new RuntimeException("Error scanning class "+className, e));
|
||||
}
|
||||
}
|
||||
me.ifExceptionThrow();
|
||||
|
@ -727,8 +727,9 @@ public class AnnotationParser
|
|||
{
|
||||
Path classpath = rootFile.toPath().relativize(file.toPath());
|
||||
String str = classpath.toString();
|
||||
str = str.substring(0, str.lastIndexOf(".class")).replace('/', '.').replace('\\', '.');
|
||||
|
||||
str = str.substring(0, str.lastIndexOf(".class"));
|
||||
str = StringUtil.replace(str, File.separatorChar, '.');
|
||||
|
||||
try
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -910,7 +911,7 @@ public class AnnotationParser
|
|||
//check file is a valid class file name
|
||||
if (isValidClassFileName(name) && isValidClassFilePath(name))
|
||||
{
|
||||
String shortName = name.replace('/', '.').substring(0,name.length()-6);
|
||||
String shortName = StringUtil.replace(name, '/', '.').substring(0, name.length() - 6);
|
||||
addParsedClass(shortName, Resource.newResource("jar:"+jar.getURI()+"!/"+entry.getNameInJar()));
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Scanning class from jar {}!/{}", jar, entry);
|
||||
|
|
|
@ -62,9 +62,7 @@ public class MultiPartConfigAnnotationHandler extends AbstractIntrospectableAnno
|
|||
//How to identify the correct Servlet? If the Servlet has no WebServlet annotation on it, does it mean that this MultipartConfig
|
||||
//annotation applies to all declared instances in web.xml/programmatically?
|
||||
//Assuming TRUE for now.
|
||||
|
||||
ServletHolder holder = getServletHolderForClass(clazz);
|
||||
if (holder != null)
|
||||
for (ServletHolder holder : _context.getServletHandler().getServlets(clazz))
|
||||
{
|
||||
Descriptor d = metaData.getOriginDescriptor(holder.getName()+".servlet.multipart-config");
|
||||
//if a descriptor has already set the value for multipart config, do not
|
||||
|
@ -76,21 +74,4 @@ public class MultiPartConfigAnnotationHandler extends AbstractIntrospectableAnno
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ServletHolder getServletHolderForClass (Class clazz)
|
||||
{
|
||||
ServletHolder holder = null;
|
||||
ServletHolder[] holders = _context.getServletHandler().getServlets();
|
||||
if (holders != null)
|
||||
{
|
||||
for (ServletHolder h : holders)
|
||||
{
|
||||
if (h.getClassName() != null && h.getClassName().equals(clazz.getName()))
|
||||
{
|
||||
holder = h;
|
||||
}
|
||||
}
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,8 +56,7 @@ public class RunAsAnnotationHandler extends AbstractIntrospectableAnnotationHand
|
|||
String role = runAs.value();
|
||||
if (role != null)
|
||||
{
|
||||
ServletHolder holder = getServletHolderForClass(clazz);
|
||||
if (holder != null)
|
||||
for (ServletHolder holder : _context.getServletHandler().getServlets(clazz))
|
||||
{
|
||||
MetaData metaData = _context.getMetaData();
|
||||
Descriptor d = metaData.getOriginDescriptor(holder.getName()+".servlet.run-as");
|
||||
|
@ -82,7 +81,6 @@ public class RunAsAnnotationHandler extends AbstractIntrospectableAnnotationHand
|
|||
else
|
||||
LOG.warn("Bad value for @RunAs annotation on class "+clazz.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation)
|
||||
|
@ -94,21 +92,4 @@ public class RunAsAnnotationHandler extends AbstractIntrospectableAnnotationHand
|
|||
{
|
||||
LOG.warn("@RunAs annotation ignored on method: "+className+"."+methodName+" "+signature);
|
||||
}
|
||||
|
||||
private ServletHolder getServletHolderForClass (Class clazz)
|
||||
{
|
||||
ServletHolder holder = null;
|
||||
ServletHolder[] holders = _context.getServletHandler().getServlets();
|
||||
if (holders != null)
|
||||
{
|
||||
for (ServletHolder h : holders)
|
||||
{
|
||||
if (h.getClassName() != null && h.getClassName().equals(clazz.getName()))
|
||||
{
|
||||
holder = h;
|
||||
}
|
||||
}
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,12 @@
|
|||
package org.eclipse.jetty.annotations;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
@ -42,6 +43,7 @@ import org.eclipse.jetty.toolchain.test.IO;
|
|||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.resource.PathResource;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -298,25 +300,17 @@ public class TestAnnotationParser
|
|||
|
||||
private void copyClass(Class<?> clazz, File basedir) throws IOException
|
||||
{
|
||||
String classname = clazz.getName().replace('.',File.separatorChar) + ".class";
|
||||
URL url = this.getClass().getResource('/'+classname);
|
||||
assertThat("URL for: " + classname,url,notNullValue());
|
||||
String classRef = TypeUtil.toClassReference(clazz);
|
||||
URL url = this.getClass().getResource('/' + classRef);
|
||||
assertThat("URL for: " + classRef, url, notNullValue());
|
||||
|
||||
String classpath = classname.substring(0,classname.lastIndexOf(File.separatorChar));
|
||||
FS.ensureDirExists(new File(basedir,classpath));
|
||||
Path outputFile = basedir.toPath().resolve(classRef);
|
||||
FS.ensureDirExists(outputFile.getParent());
|
||||
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
try
|
||||
try (InputStream in = url.openStream();
|
||||
OutputStream out = Files.newOutputStream(outputFile))
|
||||
{
|
||||
in = url.openStream();
|
||||
out = new FileOutputStream(new File(basedir,classname));
|
||||
IO.copy(in,out);
|
||||
}
|
||||
finally
|
||||
{
|
||||
IO.close(out);
|
||||
IO.close(in);
|
||||
IO.copy(in, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-ant</artifactId>
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.regex.Pattern;
|
|||
|
||||
import org.apache.tools.ant.AntClassLoader;
|
||||
import org.eclipse.jetty.util.PatternMatcher;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
@ -88,7 +89,7 @@ public class AntWebInfConfiguration extends WebInfConfiguration
|
|||
}
|
||||
catch (URISyntaxException e)
|
||||
{
|
||||
containerUris[i] = new URI(u.toString().replaceAll(" ", "%20"));
|
||||
containerUris[i] = new URI(URIUtil.encodeSpaces(u.toString()));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@ -53,341 +53,341 @@
|
|||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>apache-jsp</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>apache-jstl</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-client</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-java-client</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-java-server</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-openjdk8-client</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-openjdk8-server</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-conscrypt-client</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-conscrypt-server</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-server</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-annotations</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-ant</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.cdi</groupId>
|
||||
<artifactId>cdi-core</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.cdi</groupId>
|
||||
<artifactId>cdi-servlet</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-client</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-continuation</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-deploy</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-distribution</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
<type>zip</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-distribution</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
<type>tar.gz</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-client</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-server</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.gcloud</groupId>
|
||||
<artifactId>jetty-gcloud-session-manager</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-home</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
<type>zip</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-home</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
<type>tar.gz</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-client</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-common</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-hpack</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-http-client-transport</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http-spi</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-common</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-remote-query</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-embedded-query</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-hazelcast</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jaas</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jaspi</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jmx</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jndi</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.memcached</groupId>
|
||||
<artifactId>jetty-memcached-sessions</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-nosql</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-boot</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-boot-jsp</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-boot-warurl</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-httpservice</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-plus</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-proxy</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-quickstart</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-rewrite</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-security</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-spring</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-unixsocket</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util-ajax</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>javax-websocket-client-impl</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>javax-websocket-server-impl</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-api</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-client</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-common</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-server</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-servlet</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-xml</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.cdi</groupId>
|
||||
<artifactId>jetty-cdi-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cdi-2</artifactId>
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.util.Decorator</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.util.DecoratedObjectFactory</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.server.handler.ContextHandler.</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.server.handler.ContextHandler</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.servlet.ServletContextHandler</Arg>
|
||||
</Call>
|
||||
|
||||
<Get name="serverClasspathPattern">
|
||||
<Call name="add">
|
||||
<Arg>-org.eclipse.jetty.util.Decorator</Arg>
|
||||
</Call>
|
||||
<Call name="add">
|
||||
<Arg>-org.eclipse.jetty.util.DecoratedObjectFactory</Arg>
|
||||
</Call>
|
||||
<Call name="add">
|
||||
<Arg>-org.eclipse.jetty.server.handler.ContextHandler.</Arg>
|
||||
</Call>
|
||||
<Call name="add">
|
||||
<Arg>-org.eclipse.jetty.server.handler.ContextHandler</Arg>
|
||||
</Call>
|
||||
<Call name="add">
|
||||
<Arg>-org.eclipse.jetty.servlet.ServletContextHandler</Arg>
|
||||
</Call>
|
||||
</Get>
|
||||
</Configure>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.cdi</groupId>
|
||||
<artifactId>jetty-cdi-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cdi-core</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.cdi</groupId>
|
||||
<artifactId>jetty-cdi-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cdi-full-servlet</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.cdi</groupId>
|
||||
<artifactId>jetty-cdi-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cdi-servlet</artifactId>
|
||||
|
|
|
@ -23,6 +23,7 @@ import javax.naming.Reference;
|
|||
|
||||
import org.eclipse.jetty.plus.jndi.Resource;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.webapp.ClasspathPattern;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
||||
/**
|
||||
|
@ -45,22 +46,22 @@ public class JettyWeldInitializer
|
|||
initContext(webapp);
|
||||
|
||||
// webapp cannot change / replace weld classes
|
||||
webapp.addSystemClass("org.jboss.weld.");
|
||||
webapp.addSystemClass("org.jboss.classfilewriter.");
|
||||
webapp.addSystemClass("org.jboss.logging.");
|
||||
webapp.addSystemClass("com.google.common.");
|
||||
webapp.addSystemClass("org.eclipse.jetty.cdi.websocket.annotation.");
|
||||
|
||||
ClasspathPattern systemClasses = webapp.getSystemClasspathPattern();
|
||||
systemClasses.add("org.jboss.weld.");
|
||||
systemClasses.add("org.jboss.classfilewriter.");
|
||||
systemClasses.add("org.jboss.logging.");
|
||||
systemClasses.add("com.google.common.");
|
||||
systemClasses.add("org.eclipse.jetty.cdi.websocket.annotation.");
|
||||
|
||||
// don't hide weld classes from webapps (allow webapp to use ones from system classloader)
|
||||
webapp.prependServerClass("-org.eclipse.jetty.cdi.websocket.annotation.");
|
||||
webapp.prependServerClass("-org.eclipse.jetty.cdi.core.");
|
||||
webapp.prependServerClass("-org.eclipse.jetty.cdi.servlet.");
|
||||
webapp.addServerClass("-org.jboss.weld.");
|
||||
webapp.addServerClass("-org.jboss.classfilewriter.");
|
||||
webapp.addServerClass("-org.jboss.logging.");
|
||||
webapp.addServerClass("-com.google.common.");
|
||||
|
||||
ClasspathPattern serverClasses = webapp.getServerClasspathPattern();
|
||||
serverClasses.add("-org.eclipse.jetty.cdi.websocket.annotation.");
|
||||
serverClasses.add("-org.eclipse.jetty.cdi.core.");
|
||||
serverClasses.add("-org.eclipse.jetty.cdi.servlet.");
|
||||
serverClasses.add("-org.jboss.weld.");
|
||||
serverClasses.add("-org.jboss.classfilewriter.");
|
||||
serverClasses.add("-org.jboss.logging.");
|
||||
serverClasses.add("-com.google.common.");
|
||||
}
|
||||
|
||||
public static void initContext(ContextHandler handler) throws NamingException
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.cdi</groupId>
|
||||
<artifactId>jetty-cdi-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cdi-websocket</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.cdi</groupId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.cdi</groupId>
|
||||
<artifactId>jetty-cdi-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>test-cdi-webapp</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -22,12 +22,10 @@ import java.nio.ByteBuffer;
|
|||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentProvider;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpHeaderValue;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
@ -67,7 +65,6 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
|||
private final AtomicReference<SenderState> senderState = new AtomicReference<>(SenderState.IDLE);
|
||||
private final Callback commitCallback = new CommitCallback();
|
||||
private final IteratingCallback contentCallback = new ContentCallback();
|
||||
private final Callback trailersCallback = new TrailersCallback();
|
||||
private final Callback lastCallback = new LastCallback();
|
||||
private final HttpChannel channel;
|
||||
private HttpContent content;
|
||||
|
@ -444,15 +441,6 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
|||
*/
|
||||
protected abstract void sendContent(HttpExchange exchange, HttpContent content, Callback callback);
|
||||
|
||||
/**
|
||||
* Implementations should send the HTTP trailers and notify the given {@code callback} of the
|
||||
* result of this operation.
|
||||
*
|
||||
* @param exchange the exchange to send
|
||||
* @param callback the callback to notify
|
||||
*/
|
||||
protected abstract void sendTrailers(HttpExchange exchange, Callback callback);
|
||||
|
||||
protected void reset()
|
||||
{
|
||||
HttpContent content = this.content;
|
||||
|
@ -745,24 +733,14 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
|||
if (content == null)
|
||||
return;
|
||||
|
||||
HttpRequest request = exchange.getRequest();
|
||||
Supplier<HttpFields> trailers = request.getTrailers();
|
||||
boolean hasContent = content.hasContent();
|
||||
if (!hasContent)
|
||||
if (!content.hasContent())
|
||||
{
|
||||
if (trailers == null)
|
||||
{
|
||||
// No trailers or content to send, we are done.
|
||||
someToSuccess(exchange);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendTrailers(exchange, lastCallback);
|
||||
}
|
||||
// No content to send, we are done.
|
||||
someToSuccess(exchange);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Was any content sent while committing ?
|
||||
// Was any content sent while committing?
|
||||
ByteBuffer contentBuffer = content.getContent();
|
||||
if (contentBuffer != null)
|
||||
{
|
||||
|
@ -859,9 +837,7 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
|||
|
||||
if (lastContent)
|
||||
{
|
||||
HttpRequest request = exchange.getRequest();
|
||||
Supplier<HttpFields> trailers = request.getTrailers();
|
||||
sendContent(exchange, content, trailers == null ? lastCallback : trailersCallback);
|
||||
sendContent(exchange, content, lastCallback);
|
||||
return Action.IDLE;
|
||||
}
|
||||
|
||||
|
@ -925,28 +901,6 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
|
|||
}
|
||||
}
|
||||
|
||||
private class TrailersCallback implements Callback
|
||||
{
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
HttpExchange exchange = getHttpExchange();
|
||||
if (exchange == null)
|
||||
return;
|
||||
sendTrailers(exchange, lastCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
HttpContent content = HttpSender.this.content;
|
||||
if (content == null)
|
||||
return;
|
||||
content.failed(x);
|
||||
anyToFailure(x);
|
||||
}
|
||||
}
|
||||
|
||||
private class LastCallback implements Callback
|
||||
{
|
||||
@Override
|
||||
|
|
|
@ -59,7 +59,7 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
{
|
||||
try
|
||||
{
|
||||
new HeadersCallback(exchange, content, callback, getHttpChannel().getHttpConnection()).iterate();
|
||||
new HeadersCallback(exchange, content, callback).iterate();
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
|
@ -83,8 +83,8 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
HttpGenerator.Result result = generator.generateRequest(null, null, chunk, contentBuffer, lastContent);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Generated content ({} bytes) - {}/{}",
|
||||
contentBuffer == null ? -1 : contentBuffer.remaining(),
|
||||
result, generator);
|
||||
contentBuffer == null ? -1 : contentBuffer.remaining(),
|
||||
result, generator);
|
||||
switch (result)
|
||||
{
|
||||
case NEED_CHUNK:
|
||||
|
@ -94,8 +94,8 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
}
|
||||
case NEED_CHUNK_TRAILER:
|
||||
{
|
||||
callback.succeeded();
|
||||
return;
|
||||
chunk = bufferPool.acquire(httpClient.getRequestBufferSize(), false);
|
||||
break;
|
||||
}
|
||||
case FLUSH:
|
||||
{
|
||||
|
@ -138,21 +138,6 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendTrailers(HttpExchange exchange, Callback callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
new TrailersCallback(callback).iterate();
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
callback.failed(x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void reset()
|
||||
{
|
||||
|
@ -191,19 +176,17 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
private final HttpExchange exchange;
|
||||
private final Callback callback;
|
||||
private final MetaData.Request metaData;
|
||||
private final HttpConnectionOverHTTP httpConnectionOverHTTP;
|
||||
private ByteBuffer headerBuffer;
|
||||
private ByteBuffer chunkBuffer;
|
||||
private ByteBuffer contentBuffer;
|
||||
private boolean lastContent;
|
||||
private boolean generated;
|
||||
|
||||
public HeadersCallback(HttpExchange exchange, HttpContent content, Callback callback, HttpConnectionOverHTTP httpConnectionOverHTTP)
|
||||
public HeadersCallback(HttpExchange exchange, HttpContent content, Callback callback)
|
||||
{
|
||||
super(false);
|
||||
this.exchange = exchange;
|
||||
this.callback = callback;
|
||||
this.httpConnectionOverHTTP = httpConnectionOverHTTP;
|
||||
|
||||
HttpRequest request = exchange.getRequest();
|
||||
ContentProvider requestContent = request.getContent();
|
||||
|
@ -231,10 +214,10 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
HttpGenerator.Result result = generator.generateRequest(metaData, headerBuffer, chunkBuffer, contentBuffer, lastContent);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Generated headers ({} bytes), chunk ({} bytes), content ({} bytes) - {}/{}",
|
||||
headerBuffer == null ? -1 : headerBuffer.remaining(),
|
||||
chunkBuffer == null ? -1 : chunkBuffer.remaining(),
|
||||
contentBuffer == null ? -1 : contentBuffer.remaining(),
|
||||
result, generator);
|
||||
headerBuffer == null ? -1 : headerBuffer.remaining(),
|
||||
chunkBuffer == null ? -1 : chunkBuffer.remaining(),
|
||||
contentBuffer == null ? -1 : contentBuffer.remaining(),
|
||||
result, generator);
|
||||
switch (result)
|
||||
{
|
||||
case NEED_HEADER:
|
||||
|
@ -249,7 +232,8 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
}
|
||||
case NEED_CHUNK_TRAILER:
|
||||
{
|
||||
return Action.SUCCEEDED;
|
||||
chunkBuffer = httpClient.getByteBufferPool().acquire(httpClient.getRequestBufferSize(), false);
|
||||
break;
|
||||
}
|
||||
case FLUSH:
|
||||
{
|
||||
|
@ -260,11 +244,8 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
chunkBuffer = BufferUtil.EMPTY_BUFFER;
|
||||
if (contentBuffer == null)
|
||||
contentBuffer = BufferUtil.EMPTY_BUFFER;
|
||||
|
||||
httpConnectionOverHTTP.addBytesOut( BufferUtil.length(headerBuffer)
|
||||
+ BufferUtil.length(chunkBuffer)
|
||||
+ BufferUtil.length(contentBuffer));
|
||||
|
||||
long bytes = headerBuffer.remaining() + chunkBuffer.remaining() + contentBuffer.remaining();
|
||||
getHttpChannel().getHttpConnection().addBytesOut(bytes);
|
||||
endPoint.write(this, headerBuffer, chunkBuffer, contentBuffer);
|
||||
generated = true;
|
||||
return Action.SCHEDULED;
|
||||
|
@ -331,83 +312,6 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
}
|
||||
}
|
||||
|
||||
private class TrailersCallback extends IteratingCallback
|
||||
{
|
||||
private final Callback callback;
|
||||
private ByteBuffer chunkBuffer;
|
||||
|
||||
public TrailersCallback(Callback callback)
|
||||
{
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Action process() throws Throwable
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
HttpGenerator.Result result = generator.generateRequest(null, null, chunkBuffer, null, true);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Generated trailers {}/{}", result, generator);
|
||||
switch (result)
|
||||
{
|
||||
case NEED_CHUNK_TRAILER:
|
||||
{
|
||||
chunkBuffer = httpClient.getByteBufferPool().acquire(httpClient.getRequestBufferSize(), false);
|
||||
break;
|
||||
}
|
||||
case FLUSH:
|
||||
{
|
||||
EndPoint endPoint = getHttpChannel().getHttpConnection().getEndPoint();
|
||||
endPoint.write(this, chunkBuffer);
|
||||
return Action.SCHEDULED;
|
||||
}
|
||||
case SHUTDOWN_OUT:
|
||||
{
|
||||
shutdownOutput();
|
||||
return Action.SUCCEEDED;
|
||||
}
|
||||
case DONE:
|
||||
{
|
||||
return Action.SUCCEEDED;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new IllegalStateException(result.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
release();
|
||||
super.succeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
release();
|
||||
callback.failed(x);
|
||||
super.failed(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCompleteSuccess()
|
||||
{
|
||||
super.onCompleteSuccess();
|
||||
callback.succeeded();
|
||||
}
|
||||
|
||||
private void release()
|
||||
{
|
||||
httpClient.getByteBufferPool().release(chunkBuffer);
|
||||
chunkBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private class ByteBufferRecyclerCallback extends Callback.Nested
|
||||
{
|
||||
private final ByteBufferPool pool;
|
||||
|
@ -435,7 +339,9 @@ public class HttpSenderOverHTTP extends HttpSender
|
|||
public void failed(Throwable x)
|
||||
{
|
||||
for (ByteBuffer buffer : buffers)
|
||||
{
|
||||
pool.release(buffer);
|
||||
}
|
||||
super.failed(x);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-continuation</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-deploy</artifactId>
|
||||
|
|
|
@ -91,7 +91,7 @@ public class GlobalWebappConfigBinding implements AppLifeCycle.Binding
|
|||
|
||||
if (globalContextSettings.exists())
|
||||
{
|
||||
XmlConfiguration jettyXmlConfig = new XmlConfiguration(globalContextSettings.getInputStream());
|
||||
XmlConfiguration jettyXmlConfig = new XmlConfiguration(globalContextSettings);
|
||||
Resource resource = Resource.newResource(app.getOriginId());
|
||||
app.getDeploymentManager().scope(jettyXmlConfig,resource);
|
||||
jettyXmlConfig.configure(context);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<Set name="contextPath">/foo</Set>
|
||||
<Set name="war">
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-distribution</artifactId>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jetty-documentation</artifactId>
|
||||
<name>Jetty :: Documentation</name>
|
||||
|
|
|
@ -49,7 +49,7 @@ Copy and paste the following content as `$JETTY_BASE/webapps/jetty-wordpress.xml
|
|||
[source, xml, subs="{sub-order}"]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<Configure class="org.eclipse.jetty.servlet.ServletContextHandler">
|
||||
|
||||
<New id="root" class="java.lang.String">
|
||||
|
|
|
@ -32,7 +32,8 @@ ____
|
|||
|
||||
This configuration is essentially the multiple logger configuration with added configuration to the deployers to force a `WebAppClassLoader` change to use the server classpath over the webapps classpath for the logger specific classes.
|
||||
|
||||
The technique used by this configuration is to provide an link:{JDURL}org/eclipse/jetty/deploy/AppLifeCycle.Binding.html[AppLifeCycle.Binding] against the link:{JDURL}/org/eclipse/jetty/deploy/AppLifeCycle.html[`"deploying"`node] that modifies the link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#addSystemClass(java.lang.String)[WebAppContext.addSystemClass(String)] for the common logging classes.
|
||||
The technique used by this configuration is to provide an link:{JDURL}org/eclipse/jetty/deploy/AppLifeCycle.Binding.html[AppLifeCycle.Binding] against the link:{JDURL}/org/eclipse/jetty/deploy/AppLifeCycle.html[`"deploying"`node] that modifies the
|
||||
link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#getSystemClasspathPattern()[WebAppContext.getSystemClasspathPattern().add(String)] for the common logging classes.
|
||||
See https://github.com/jetty-project/jetty-webapp-logging/blob/master/src/main/java/org/eclipse/jetty/webapp/logging/CentralizedWebAppLoggingBinding.java[org.eclipse.jetty.logging.CentralizedWebAppLoggingBinding] for actual implementation.
|
||||
|
||||
A convenient replacement `logging` module has been created to bootstrap your `${jetty.base}` directory for capturing all Jetty server logging from multiple logging frameworks into a single logging output file managed by Logback.
|
||||
|
|
|
@ -94,9 +94,11 @@ From a context xml file, you reference the Server instance as a Ref:
|
|||
[source, xml, subs="{sub-order}"]
|
||||
----
|
||||
<!-- Expose the jetty infinispan classes for session serialization -->
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.session.infinispan.</Arg>
|
||||
</Call>
|
||||
<Get name="serverClasspathPattern">
|
||||
<Call name="add">
|
||||
<Arg>-org.eclipse.jetty.session.infinispan.</Arg>
|
||||
</Call>
|
||||
</Get>
|
||||
|
||||
|
||||
<!-- Get a reference to the InfinispanSessionIdManager -->
|
||||
|
@ -132,10 +134,12 @@ From a `WEB-INF/jetty-web.xml` file, you can reference the Server instance direc
|
|||
|
||||
[source, xml, subs="{sub-order}"]
|
||||
----
|
||||
<!-- Expose the jetty infinispan classes for session serialization -->
|
||||
<Call name="prependServerClass">
|
||||
<!-- Expose the jetty infinispan classes for session serialization -->
|
||||
<Get name="serverClasspathPattern">
|
||||
<Call name="add">
|
||||
<Arg>-org.eclipse.jetty.session.infinispan.</Arg>
|
||||
</Call>
|
||||
</Get>
|
||||
|
||||
<!-- Reference the server directly -->
|
||||
<Get name="server">
|
||||
|
@ -143,25 +147,25 @@ From a `WEB-INF/jetty-web.xml` file, you can reference the Server instance direc
|
|||
</Get>
|
||||
|
||||
<!-- Get a reference to the Cache via the InfinispanSessionIdManager -->
|
||||
<Ref id="idMgr">
|
||||
<Get id="cache" name="cache"/>
|
||||
</Ref>
|
||||
<Ref id="idMgr">
|
||||
<Get id="cache" name="cache"/>
|
||||
</Ref>
|
||||
|
||||
<!-- Apply the SessionIdManager and Cache to the InfinispanSessionManager -->
|
||||
<Set name="sessionHandler">
|
||||
<New class="org.eclipse.jetty.server.session.SessionHandler">
|
||||
<Arg>
|
||||
<New id="mgr" class="org.eclipse.jetty.session.infinispan.InfinispanSessionManager">
|
||||
<Set name="sessionIdManager">
|
||||
<Ref id="idMgr"/>
|
||||
</Set>
|
||||
<Set name="cache">
|
||||
<Ref id="cache">
|
||||
</Ref>
|
||||
</Set>
|
||||
<Set name="scavengeInterval">600</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
<Arg>
|
||||
<New id="mgr" class="org.eclipse.jetty.session.infinispan.InfinispanSessionManager">
|
||||
<Set name="sessionIdManager">
|
||||
<Ref id="idMgr"/>
|
||||
</Set>
|
||||
<Set name="cache">
|
||||
<Ref id="cache">
|
||||
</Ref>
|
||||
</Set>
|
||||
<Set name="scavengeInterval">600</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</New>
|
||||
</Set>
|
||||
----
|
||||
|
@ -178,7 +182,7 @@ staleIntervalSec::
|
|||
===== Using HotRod
|
||||
|
||||
If you're using the hotrod client - where serialization will be required - you will need to ensure that the hotrod marshalling software works with Jetty classloading.
|
||||
To do this, firstly ensure that you have included the lines containing the `prependServerClass` to your context xml file as shown above.
|
||||
To do this, firstly ensure that you have included the lines containing the `getServerClasspathPattern().add(...)` to your context xml file as shown above.
|
||||
|
||||
Then, create the file `${jetty.base}/resources/hotrod-client.properties`.
|
||||
Add the following line to this file:
|
||||
|
|
|
@ -77,7 +77,7 @@ Context files are normally located in `${jetty.base}/webapps/` (see `DeployerMan
|
|||
[source, xml, subs="{sub-order}"]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.eclipse.org/configure.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<Set name="contextPath">/test</Set>
|
||||
|
|
|
@ -79,7 +79,11 @@ Below is an example of implementing this feature using Jetty IoC XML format:
|
|||
[[classloading-setting-system-classes]]
|
||||
===== Setting System Classes
|
||||
|
||||
You can call the methods link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#setSystemClasses%28java.lang.String%5B%5D%29[org.eclipse.jetty.webapp.WebAppContext.setSystemClasses(String Array)] or link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#addSystemClass(java.lang.String)[org.eclipse.jetty.webapp.WebAppContext.addSystemClass(String)] to allow fine control over which classes are considered System classes.
|
||||
You can call the methods
|
||||
link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#setSystemClasses%28java.lang.String%5B%5D%29[WebAppContext.setSystemClasses(String[\])]
|
||||
or
|
||||
link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#getSystemClasspathPattern()[WebAppContext.getSystemClasspathPattern().add(String)]
|
||||
to allow fine control over which classes are considered system classes.
|
||||
|
||||
* A web application can see a System class.
|
||||
* A WEB-INF class cannot replace a System class.
|
||||
|
|
|
@ -34,7 +34,7 @@ Jetty applies `jetty-env.xml` on a per-webapp basis, and configures an instance
|
|||
----
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
..
|
||||
|
@ -57,7 +57,7 @@ Place the `jetty-env.xml` file in your web application's WEB-INF folder.
|
|||
----
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ For a more in-depth look at the syntax, see xref:jetty-xml-syntax[].
|
|||
[source, xml, subs="{sub-order}"]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
..
|
||||
|
|
|
@ -43,7 +43,7 @@ The selection of which configuration files to use is controlled by `start.jar` a
|
|||
----
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
...
|
||||
|
|
|
@ -34,7 +34,7 @@ The following XML configuration file creates some Java objects and sets some att
|
|||
[source, xml, subs="{sub-order}"]
|
||||
----
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<Configure id="foo" class="com.acme.Foo">
|
||||
<Set name="name">demo</Set>
|
||||
<Set name="nested">
|
||||
|
@ -89,13 +89,13 @@ The first two lines of an XML must reference the DTD to be used to validate the
|
|||
[source, xml, subs="{sub-order}"]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
...
|
||||
----
|
||||
|
||||
Typcically a good XML editor will fetch the DTD from the URL and use it to give syntax highlighting and validation while a configuration file is being edited.
|
||||
Some editors also allows DTD files to be locally cached.
|
||||
The URL may point to configure.dtd if you want the latest current version, or to a specific version like configure_9_0.dtd if you want a particular validation feature set.
|
||||
The URL may point to configure.dtd if you want the latest current version, or to a specific version like configure_9_3.dtd if you want a particular validation feature set.
|
||||
|
||||
Files that conform to the configure.dtd format are processed in Jetty by the `XmlConfiguration` class which may also validate the XML (using a version of the DTD from the classes jar file), but is by default run in a forgiving mode that tries to work around validation failures.
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.eclipse.jetty.http.HttpHeader;
|
|||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Jetty;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
public class HttpSenderOverFCGI extends HttpSender
|
||||
{
|
||||
|
@ -88,7 +89,7 @@ public class HttpSenderOverFCGI extends HttpSender
|
|||
for (HttpField field : headers)
|
||||
{
|
||||
String name = field.getName();
|
||||
String fcgiName = "HTTP_" + name.replaceAll("-", "_").toUpperCase(Locale.ENGLISH);
|
||||
String fcgiName = "HTTP_" + StringUtil.replace(name, '-', '_').toUpperCase(Locale.ENGLISH);
|
||||
fcgiHeaders.add(fcgiName, field.getValue());
|
||||
}
|
||||
|
||||
|
@ -125,10 +126,4 @@ public class HttpSenderOverFCGI extends HttpSender
|
|||
getHttpChannel().flush(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendTrailers(HttpExchange exchange, Callback callback)
|
||||
{
|
||||
callback.succeeded();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.net.URL;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
|
@ -35,6 +34,8 @@ import javax.servlet.ServletResponse;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Inspired by nginx's try_files functionality.
|
||||
* <p>
|
||||
|
@ -132,7 +133,7 @@ public class TryFilesFilter implements Filter
|
|||
path += info;
|
||||
if (!path.startsWith("/"))
|
||||
path = "/" + path;
|
||||
return value.replaceAll("\\$path", path);
|
||||
return StringUtil.replace(value, "$path", path);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.gcloud</groupId>
|
||||
<artifactId>gcloud-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-home</artifactId>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<!-- ================================================================ -->
|
||||
<!-- Configure the Jetty SetUIDListener -->
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-http-spi</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
|
|
|
@ -276,12 +276,9 @@ public class HttpField
|
|||
|
||||
public boolean isSameName(HttpField field)
|
||||
{
|
||||
@SuppressWarnings("ReferenceEquality")
|
||||
boolean sameObject = (field==this);
|
||||
|
||||
if (field==null)
|
||||
return false;
|
||||
if (sameObject)
|
||||
if (field==this)
|
||||
return true;
|
||||
if (_header!=null && _header==field.getHeader())
|
||||
return true;
|
||||
|
|
|
@ -33,7 +33,6 @@ import java.util.Set;
|
|||
import java.util.StringTokenizer;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.eclipse.jetty.util.ArrayTernaryTrie;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
|
@ -47,7 +46,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
*
|
||||
* <p>This class is not synchronized as it is expected that modifications will only be performed by a
|
||||
* single thread.
|
||||
*
|
||||
*
|
||||
* <p>The cookie handling provided by this class is guided by the Servlet specification and RFC6265.
|
||||
*
|
||||
*/
|
||||
|
@ -60,33 +59,33 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
private HttpField[] _fields;
|
||||
private int _size;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize an empty HttpFields.
|
||||
*/
|
||||
public HttpFields()
|
||||
{
|
||||
_fields=new HttpField[20];
|
||||
this(16); // Based on small sample of Chrome requests.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize an empty HttpFields.
|
||||
*
|
||||
*
|
||||
* @param capacity the capacity of the http fields
|
||||
*/
|
||||
public HttpFields(int capacity)
|
||||
{
|
||||
_fields=new HttpField[capacity];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize HttpFields from copy.
|
||||
*
|
||||
*
|
||||
* @param fields the fields to copy data from
|
||||
*/
|
||||
public HttpFields(HttpFields fields)
|
||||
{
|
||||
_fields=Arrays.copyOf(fields._fields,fields._fields.length+10);
|
||||
_fields=Arrays.copyOf(fields._fields,fields._fields.length);
|
||||
_size=fields._size;
|
||||
}
|
||||
|
||||
|
@ -94,22 +93,22 @@ public class HttpFields implements Iterable<HttpField>
|
|||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterator<HttpField> iterator()
|
||||
{
|
||||
return new Itr();
|
||||
return new ListItr();
|
||||
}
|
||||
|
||||
public ListIterator<HttpField> listIterator()
|
||||
{
|
||||
return new Itr();
|
||||
return new ListItr();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public Stream<HttpField> stream()
|
||||
{
|
||||
return StreamSupport.stream(Arrays.spliterator(_fields,0,_size),false);
|
||||
return Arrays.stream(_fields).limit(_size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,13 +117,15 @@ public class HttpFields implements Iterable<HttpField>
|
|||
*/
|
||||
public Set<String> getFieldNamesCollection()
|
||||
{
|
||||
final Set<String> set = new HashSet<>(_size);
|
||||
for (HttpField f : this)
|
||||
Set<String> set = null;
|
||||
for (int i=0;i<_size;i++)
|
||||
{
|
||||
if (f!=null)
|
||||
set.add(f.getName());
|
||||
HttpField f=_fields[i];
|
||||
if (set==null)
|
||||
set = new HashSet<>();
|
||||
set.add(f.getName());
|
||||
}
|
||||
return set;
|
||||
return set==null?Collections.emptySet():set;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,7 +140,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
/**
|
||||
* Get a Field by index.
|
||||
* @param index the field index
|
||||
* @param index the field index
|
||||
* @return A Field value or null if the Field value has not been set
|
||||
*/
|
||||
public HttpField getField(int index)
|
||||
|
@ -171,6 +172,22 @@ public class HttpFields implements Iterable<HttpField>
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<HttpField> getFields(HttpHeader header)
|
||||
{
|
||||
List<HttpField> fields = null;
|
||||
for (int i=0;i<_size;i++)
|
||||
{
|
||||
HttpField f=_fields[i];
|
||||
if (f.getHeader()==header)
|
||||
{
|
||||
if (fields==null)
|
||||
fields = new ArrayList<>();
|
||||
fields.add(f);
|
||||
}
|
||||
}
|
||||
return fields==null?Collections.emptyList():fields;
|
||||
}
|
||||
|
||||
public boolean contains(HttpField field)
|
||||
{
|
||||
for (int i=_size;i-->0;)
|
||||
|
@ -192,7 +209,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean contains(String name, String value)
|
||||
{
|
||||
for (int i=_size;i-->0;)
|
||||
|
@ -214,7 +231,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean containsKey(String name)
|
||||
{
|
||||
for (int i=_size;i-->0;)
|
||||
|
@ -231,7 +248,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
{
|
||||
return get(header);
|
||||
}
|
||||
|
||||
|
||||
public String get(HttpHeader header)
|
||||
{
|
||||
for (int i=0;i<_size;i++)
|
||||
|
@ -248,7 +265,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
{
|
||||
return get(name);
|
||||
}
|
||||
|
||||
|
||||
public String get(String header)
|
||||
{
|
||||
for (int i=0;i<_size;i++)
|
||||
|
@ -269,24 +286,30 @@ public class HttpFields implements Iterable<HttpField>
|
|||
public List<String> getValuesList(HttpHeader header)
|
||||
{
|
||||
final List<String> list = new ArrayList<>();
|
||||
for (HttpField f : this)
|
||||
if (f.getHeader()==header)
|
||||
for (int i=0;i<_size;i++)
|
||||
{
|
||||
HttpField f = _fields[i];
|
||||
if (f.getHeader() == header)
|
||||
list.add(f.getValue());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get multiple header of the same name
|
||||
*
|
||||
*
|
||||
* @return List the header values
|
||||
* @param name the case-insensitive field name
|
||||
*/
|
||||
public List<String> getValuesList(String name)
|
||||
{
|
||||
final List<String> list = new ArrayList<>();
|
||||
for (HttpField f : this)
|
||||
for (int i=0;i<_size;i++)
|
||||
{
|
||||
HttpField f = _fields[i];
|
||||
if (f.getName().equalsIgnoreCase(name))
|
||||
list.add(f.getValue());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -301,8 +324,9 @@ public class HttpFields implements Iterable<HttpField>
|
|||
public boolean addCSV(HttpHeader header,String... values)
|
||||
{
|
||||
QuotedCSV existing = null;
|
||||
for (HttpField f : this)
|
||||
for (int i=0;i<_size;i++)
|
||||
{
|
||||
HttpField f = _fields[i];
|
||||
if (f.getHeader()==header)
|
||||
{
|
||||
if (existing==null)
|
||||
|
@ -310,7 +334,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
existing.addValue(f.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String value = addCSV(existing,values);
|
||||
if (value!=null)
|
||||
{
|
||||
|
@ -319,7 +343,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add comma separated values, but only if not already
|
||||
* present.
|
||||
|
@ -330,8 +354,9 @@ public class HttpFields implements Iterable<HttpField>
|
|||
public boolean addCSV(String name,String... values)
|
||||
{
|
||||
QuotedCSV existing = null;
|
||||
for (HttpField f : this)
|
||||
for (int i=0;i<_size;i++)
|
||||
{
|
||||
HttpField f = _fields[i];
|
||||
if (f.getName().equalsIgnoreCase(name))
|
||||
{
|
||||
if (existing==null)
|
||||
|
@ -348,14 +373,14 @@ public class HttpFields implements Iterable<HttpField>
|
|||
return false;
|
||||
}
|
||||
|
||||
protected String addCSV(QuotedCSV existing,String... values)
|
||||
protected String addCSV(QuotedCSV existing, String... values)
|
||||
{
|
||||
// remove any existing values from the new values
|
||||
boolean add = true;
|
||||
if (existing!=null && !existing.isEmpty())
|
||||
{
|
||||
add = false;
|
||||
|
||||
|
||||
for (int i=values.length;i-->0;)
|
||||
{
|
||||
String unquoted = QuotedCSV.unquote(values[i]);
|
||||
|
@ -365,7 +390,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
add = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (add)
|
||||
{
|
||||
StringBuilder value = new StringBuilder();
|
||||
|
@ -380,12 +405,12 @@ public class HttpFields implements Iterable<HttpField>
|
|||
if (value.length()>0)
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get multiple field values of the same name, split
|
||||
* Get multiple field values of the same name, split
|
||||
* as a {@link QuotedCSV}
|
||||
*
|
||||
* @return List the values with OWS stripped
|
||||
|
@ -499,7 +524,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
for (int i=0;i<_size;i++)
|
||||
{
|
||||
final HttpField f = _fields[i];
|
||||
|
||||
|
||||
if (f.getName().equalsIgnoreCase(name) && f.getValue()!=null)
|
||||
{
|
||||
final int first=i;
|
||||
|
@ -513,7 +538,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
{
|
||||
if (field==null)
|
||||
{
|
||||
while (i<_size)
|
||||
while (i<_size)
|
||||
{
|
||||
field=_fields[i++];
|
||||
if (field.getName().equalsIgnoreCase(name) && field.getValue()!=null)
|
||||
|
@ -613,7 +638,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
if (!put)
|
||||
add(field);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a field.
|
||||
*
|
||||
|
@ -905,7 +930,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
{
|
||||
_size=0;
|
||||
}
|
||||
|
||||
|
||||
public void add(HttpField field)
|
||||
{
|
||||
if (field!=null)
|
||||
|
@ -1083,37 +1108,36 @@ public class HttpFields implements Iterable<HttpField>
|
|||
return values.getValues();
|
||||
}
|
||||
|
||||
|
||||
private class Itr implements ListIterator<HttpField>
|
||||
private class ListItr implements ListIterator<HttpField>
|
||||
{
|
||||
int _cursor; // index of next element to return
|
||||
int _last=-1;
|
||||
int _current =-1;
|
||||
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
public boolean hasNext()
|
||||
{
|
||||
return _cursor != _size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpField next()
|
||||
public HttpField next()
|
||||
{
|
||||
int i = _cursor;
|
||||
if (i >= _size)
|
||||
if (_cursor == _size)
|
||||
throw new NoSuchElementException();
|
||||
_cursor = i + 1;
|
||||
return _fields[_last=i];
|
||||
_current = _cursor++;
|
||||
return _fields[_current];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove()
|
||||
public void remove()
|
||||
{
|
||||
if (_last<0)
|
||||
if (_current <0)
|
||||
throw new IllegalStateException();
|
||||
|
||||
System.arraycopy(_fields,_last+1,_fields,_last,--_size-_last);
|
||||
_cursor=_last;
|
||||
_last=-1;
|
||||
_size--;
|
||||
System.arraycopy(_fields, _current +1,_fields, _current,_size- _current);
|
||||
_fields[_size]=null;
|
||||
_cursor= _current;
|
||||
_current =-1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1127,7 +1151,8 @@ public class HttpFields implements Iterable<HttpField>
|
|||
{
|
||||
if (_cursor == 0)
|
||||
throw new NoSuchElementException();
|
||||
return _fields[_last=--_cursor];
|
||||
_current = --_cursor;
|
||||
return _fields[_current];
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1144,10 +1169,10 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
@Override
|
||||
public void set(HttpField field)
|
||||
{
|
||||
if (_last<0)
|
||||
{
|
||||
if (_current <0)
|
||||
throw new IllegalStateException();
|
||||
_fields[_last] = field;
|
||||
_fields[_current] = field;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1156,8 +1181,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
_fields = Arrays.copyOf(_fields,_fields.length+1);
|
||||
System.arraycopy(_fields,_cursor,_fields,_cursor+1,_size++);
|
||||
_fields[_cursor++] = field;
|
||||
_last=-1;
|
||||
_current =-1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ public class MimeTypes
|
|||
int charset=type.toString().indexOf(";charset=");
|
||||
if (charset>0)
|
||||
{
|
||||
String alt=type.toString().replace(";charset=","; charset=");
|
||||
String alt = StringUtil.replace(type.toString(), ";charset=", "; charset=");
|
||||
CACHE.put(alt,type);
|
||||
TYPES.put(alt,type.asBuffer());
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.MultipartConfigElement;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.Part;
|
||||
|
@ -299,9 +298,8 @@ public class MultiPartFormInputStream
|
|||
*/
|
||||
public void cleanUp() throws IOException
|
||||
{
|
||||
if (_temporary && _file != null && _file.exists())
|
||||
if (!_file.delete())
|
||||
throw new IOException("Could Not Delete File");
|
||||
if (_temporary)
|
||||
delete();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -398,31 +396,21 @@ public class MultiPartFormInputStream
|
|||
*/
|
||||
public void deleteParts()
|
||||
{
|
||||
if (!_parsed)
|
||||
return;
|
||||
|
||||
Collection<Part> parts;
|
||||
try
|
||||
{
|
||||
parts = getParts();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
MultiException err = null;
|
||||
for (Part p : parts)
|
||||
for (List<Part> parts : _parts.values())
|
||||
{
|
||||
try
|
||||
for (Part p : parts)
|
||||
{
|
||||
((MultiPart)p).cleanUp();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (err == null)
|
||||
err = new MultiException();
|
||||
err.add(e);
|
||||
try
|
||||
{
|
||||
((MultiPart)p).cleanUp();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (err == null)
|
||||
err = new MultiException();
|
||||
err.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
_parts.clear();
|
||||
|
@ -477,6 +465,9 @@ public class MultiPartFormInputStream
|
|||
{
|
||||
if (_err != null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("MultiPart parsing failure ", _err);
|
||||
|
||||
_err.addSuppressed(new Throwable());
|
||||
if (_err instanceof IOException)
|
||||
throw (IOException)_err;
|
||||
|
@ -495,7 +486,9 @@ public class MultiPartFormInputStream
|
|||
if (_parsed)
|
||||
return;
|
||||
_parsed = true;
|
||||
|
||||
|
||||
MultiPartParser parser = null;
|
||||
Handler handler = new Handler();
|
||||
try
|
||||
{
|
||||
// initialize
|
||||
|
@ -531,9 +524,7 @@ public class MultiPartFormInputStream
|
|||
contentTypeBoundary = QuotedStringTokenizer.unquote(value(_contentType.substring(bstart, bend)).trim());
|
||||
}
|
||||
|
||||
Handler handler = new Handler();
|
||||
MultiPartParser parser = new MultiPartParser(handler, contentTypeBoundary);
|
||||
|
||||
parser = new MultiPartParser(handler, contentTypeBoundary);
|
||||
byte[] data = new byte[_bufferSize];
|
||||
int len;
|
||||
long total = 0;
|
||||
|
@ -545,7 +536,6 @@ public class MultiPartFormInputStream
|
|||
|
||||
if (len > 0)
|
||||
{
|
||||
|
||||
// keep running total of size of bytes read from input and throw an exception if exceeds MultipartConfigElement._maxRequestSize
|
||||
total += len;
|
||||
if (_config.getMaxRequestSize() > 0 && total > _config.getMaxRequestSize())
|
||||
|
@ -595,6 +585,10 @@ public class MultiPartFormInputStream
|
|||
catch (Throwable e)
|
||||
{
|
||||
_err = e;
|
||||
|
||||
// Notify parser if failure occurs
|
||||
if (parser != null)
|
||||
parser.parse(BufferUtil.EMPTY_BUFFER, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -742,6 +736,16 @@ public class MultiPartFormInputStream
|
|||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Early EOF {}", MultiPartFormInputStream.this);
|
||||
|
||||
try
|
||||
{
|
||||
if (_part != null)
|
||||
_part.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOG.warn("part could not be closed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void reset()
|
||||
|
|
|
@ -131,12 +131,8 @@ public class MultiPartParser
|
|||
private HttpTokens.Token next(ByteBuffer buffer)
|
||||
{
|
||||
byte ch = buffer.get();
|
||||
|
||||
HttpTokens.Token t = HttpTokens.TOKENS[0xff & ch];
|
||||
|
||||
if (DEBUG)
|
||||
LOG.debug("token={}",t);
|
||||
|
||||
switch(t.getType())
|
||||
{
|
||||
case CNTL:
|
||||
|
@ -271,6 +267,9 @@ public class MultiPartParser
|
|||
/* ------------------------------------------------------------------------------- */
|
||||
private void parsePreamble(ByteBuffer buffer)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("parsePreamble({})", BufferUtil.toDetailString(buffer));
|
||||
|
||||
if (_partialBoundary > 0)
|
||||
{
|
||||
int partial = _delimiterSearch.startsWith(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining(), _partialBoundary);
|
||||
|
@ -307,6 +306,9 @@ public class MultiPartParser
|
|||
/* ------------------------------------------------------------------------------- */
|
||||
private void parseDelimiter(ByteBuffer buffer)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("parseDelimiter({})", BufferUtil.toDetailString(buffer));
|
||||
|
||||
while (__delimiterStates.contains(_state) && hasNextByte(buffer))
|
||||
{
|
||||
HttpTokens.Token t = next(buffer);
|
||||
|
@ -354,6 +356,9 @@ public class MultiPartParser
|
|||
*/
|
||||
protected boolean parseMimePartHeaders(ByteBuffer buffer)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("parseMimePartHeaders({})", BufferUtil.toDetailString(buffer));
|
||||
|
||||
// Process headers
|
||||
while (_state == State.BODY_PART && hasNextByte(buffer))
|
||||
{
|
||||
|
@ -575,6 +580,8 @@ public class MultiPartParser
|
|||
|
||||
protected boolean parseOctetContent(ByteBuffer buffer)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("parseOctetContent({})", BufferUtil.toDetailString(buffer));
|
||||
|
||||
// Starts With
|
||||
if (_partialBoundary > 0)
|
||||
|
|
|
@ -217,6 +217,7 @@ public class MultiPartFormInputStreamTest
|
|||
|
||||
@Test
|
||||
public void testNoBody()
|
||||
throws Exception
|
||||
{
|
||||
String body = "";
|
||||
|
||||
|
@ -277,6 +278,7 @@ public class MultiPartFormInputStreamTest
|
|||
|
||||
@Test
|
||||
public void testWhitespaceBodyWithCRLF()
|
||||
throws Exception
|
||||
{
|
||||
String whitespace = " \n\n\n\r\n\r\n\r\n\r\n";
|
||||
|
||||
|
@ -292,6 +294,7 @@ public class MultiPartFormInputStreamTest
|
|||
|
||||
@Test
|
||||
public void testWhitespaceBody()
|
||||
throws Exception
|
||||
{
|
||||
String whitespace = " ";
|
||||
|
||||
|
@ -400,6 +403,7 @@ public class MultiPartFormInputStreamTest
|
|||
|
||||
@Test
|
||||
public void testRequestTooBig ()
|
||||
throws Exception
|
||||
{
|
||||
MultipartConfigElement config = new MultipartConfigElement(_dirname, 60, 100, 50);
|
||||
MultiPartFormInputStream mpis = new MultiPartFormInputStream(new ByteArrayInputStream(_multi.getBytes()),
|
||||
|
@ -415,6 +419,7 @@ public class MultiPartFormInputStreamTest
|
|||
|
||||
@Test
|
||||
public void testRequestTooBigThrowsErrorOnGetParts ()
|
||||
throws Exception
|
||||
{
|
||||
MultipartConfigElement config = new MultipartConfigElement(_dirname, 60, 100, 50);
|
||||
MultiPartFormInputStream mpis = new MultiPartFormInputStream(new ByteArrayInputStream(_multi.getBytes()),
|
||||
|
@ -434,6 +439,7 @@ public class MultiPartFormInputStreamTest
|
|||
|
||||
@Test
|
||||
public void testFileTooBig()
|
||||
throws Exception
|
||||
{
|
||||
MultipartConfigElement config = new MultipartConfigElement(_dirname, 40, 1024, 30);
|
||||
MultiPartFormInputStream mpis = new MultiPartFormInputStream(new ByteArrayInputStream(_multi.getBytes()),
|
||||
|
@ -449,6 +455,7 @@ public class MultiPartFormInputStreamTest
|
|||
|
||||
@Test
|
||||
public void testFileTooBigThrowsErrorOnGetParts()
|
||||
throws Exception
|
||||
{
|
||||
MultipartConfigElement config = new MultipartConfigElement(_dirname, 40, 1024, 30);
|
||||
MultiPartFormInputStream mpis = new MultiPartFormInputStream(new ByteArrayInputStream(_multi.getBytes()),
|
||||
|
@ -550,6 +557,7 @@ public class MultiPartFormInputStreamTest
|
|||
|
||||
@Test
|
||||
public void testCROnlyRequest()
|
||||
throws Exception
|
||||
{
|
||||
String str = "--AaB03x\r" +
|
||||
"content-disposition: form-data; name=\"field1\"\r" +
|
||||
|
@ -576,6 +584,7 @@ public class MultiPartFormInputStreamTest
|
|||
|
||||
@Test
|
||||
public void testCRandLFMixRequest()
|
||||
throws Exception
|
||||
{
|
||||
String str = "--AaB03x\r" +
|
||||
"content-disposition: form-data; name=\"field1\"\r" +
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
public class QuotedCSVTest
|
||||
{
|
||||
@Test
|
||||
|
@ -111,13 +111,13 @@ public class QuotedCSVTest
|
|||
{
|
||||
if (buffer.toString().contains("DELETE"))
|
||||
{
|
||||
String s = buffer.toString().replace("DELETE","");
|
||||
String s = StringUtil.strip(buffer.toString(), "DELETE");
|
||||
buffer.setLength(0);
|
||||
buffer.append(s);
|
||||
}
|
||||
if (buffer.toString().contains("APPEND"))
|
||||
{
|
||||
String s = buffer.toString().replace("APPEND","Append")+"!";
|
||||
String s = StringUtil.replace(buffer.toString(), "APPEND", "Append") + "!";
|
||||
buffer.setLength(0);
|
||||
buffer.append(s);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.eclipse.jetty.server.ServerConnector;
|
|||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -167,7 +168,7 @@ public class ProxyProtocolTest
|
|||
|
||||
// String is: "MAGIC VER|CMD FAM|PROT LEN SRC_ADDR DST_ADDR SRC_PORT DST_PORT PP2_TYPE_SSL LEN CLIENT VERIFY PP2_SUBTYPE_SSL_VERSION LEN 1.2"
|
||||
String request1 = "0D0A0D0A000D0A515549540A 21 11 001A 0A000004 0A000005 8420 22B8 20 000B 01 00000000 21 0003 312E32";
|
||||
request1 = request1.replace(" ", "");
|
||||
request1 = StringUtil.strip(request1, " ");
|
||||
SocketChannel channel = SocketChannel.open();
|
||||
channel.connect(new InetSocketAddress("localhost", connector.getLocalPort()));
|
||||
channel.write(ByteBuffer.wrap(TypeUtil.fromHexString(request1)));
|
||||
|
|
|
@ -18,16 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.http2.client;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -35,7 +25,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -58,10 +47,14 @@ import org.eclipse.jetty.server.Response;
|
|||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class TrailersTest extends AbstractTest
|
||||
{
|
||||
|
@ -289,7 +282,7 @@ public class TrailersTest extends AbstractTest
|
|||
|
||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
assertTrue( frames.size()==3, frames.toString());
|
||||
assertEquals(3, frames.size(), frames.toString());
|
||||
|
||||
HeadersFrame headers = (HeadersFrame)frames.get(0);
|
||||
DataFrame data = (DataFrame)frames.get(1);
|
||||
|
@ -298,7 +291,7 @@ public class TrailersTest extends AbstractTest
|
|||
assertFalse(headers.isEndStream());
|
||||
assertFalse(data.isEndStream());
|
||||
assertTrue(trailers.isEndStream());
|
||||
assertTrue(trailers.getMetaData().getFields().get(trailerName).equals(trailerValue));
|
||||
assertEquals(trailers.getMetaData().getFields().get(trailerName), trailerValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -358,6 +351,5 @@ public class TrailersTest extends AbstractTest
|
|||
|
||||
assertTrue(serverLatch.await(5, TimeUnit.SECONDS));
|
||||
assertTrue(clientLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -39,7 +39,7 @@ public class MetaDataBuilder
|
|||
private HostPortHttpField _authority;
|
||||
private String _path;
|
||||
private long _contentLength=Long.MIN_VALUE;
|
||||
private HttpFields _fields = new HttpFields(10);
|
||||
private HttpFields _fields = new HttpFields();
|
||||
private HpackException.StreamException _streamException;
|
||||
private boolean _request;
|
||||
private boolean _response;
|
||||
|
@ -255,7 +255,7 @@ public class MetaDataBuilder
|
|||
}
|
||||
finally
|
||||
{
|
||||
_fields = new HttpFields(Math.max(10, fields.size() + 5));
|
||||
_fields = new HttpFields(Math.max(16, fields.size() + 5));
|
||||
_request = false;
|
||||
_response = false;
|
||||
_status = null;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -56,42 +56,57 @@ public class HttpSenderOverHTTP2 extends HttpSender
|
|||
String path = relativize(request.getPath());
|
||||
HttpURI uri = HttpURI.createHttpURI(request.getScheme(), request.getHost(), request.getPort(), path, null, request.getQuery(), null);
|
||||
MetaData.Request metaData = new MetaData.Request(request.getMethod(), uri, HttpVersion.HTTP_2, request.getHeaders());
|
||||
Supplier<HttpFields> trailers = request.getTrailers();
|
||||
metaData.setTrailerSupplier(trailers);
|
||||
HeadersFrame headersFrame = new HeadersFrame(metaData, null, trailers == null && !content.hasContent());
|
||||
HttpChannelOverHTTP2 channel = getHttpChannel();
|
||||
Promise<Stream> promise = new Promise<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
channel.setStream(stream);
|
||||
((IStream)stream).setAttachment(channel);
|
||||
long idleTimeout = request.getIdleTimeout();
|
||||
if (idleTimeout >= 0)
|
||||
stream.setIdleTimeout(idleTimeout);
|
||||
Supplier<HttpFields> trailerSupplier = request.getTrailers();
|
||||
metaData.setTrailerSupplier(trailerSupplier);
|
||||
|
||||
if (content.hasContent() && !expects100Continue(request))
|
||||
HeadersFrame headersFrame;
|
||||
Promise<Stream> promise;
|
||||
if (content.hasContent())
|
||||
{
|
||||
headersFrame = new HeadersFrame(metaData, null, false);
|
||||
promise = new HeadersPromise(request, callback)
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
boolean advanced = content.advance();
|
||||
boolean lastContent = trailers == null && content.isLast();
|
||||
if (advanced || lastContent)
|
||||
super.succeeded(stream);
|
||||
if (expects100Continue(request))
|
||||
{
|
||||
DataFrame dataFrame = new DataFrame(stream.getId(), content.getByteBuffer(), lastContent);
|
||||
stream.data(dataFrame, callback);
|
||||
return;
|
||||
// Don't send the content yet.
|
||||
callback.succeeded();
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean advanced = content.advance();
|
||||
boolean lastContent = content.isLast();
|
||||
if (advanced || lastContent)
|
||||
sendContent(stream, content, trailerSupplier, callback);
|
||||
else
|
||||
callback.succeeded();
|
||||
}
|
||||
}
|
||||
callback.succeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Throwable failure)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
HttpFields trailers = trailerSupplier == null ? null : trailerSupplier.get();
|
||||
boolean endStream = trailers == null || trailers.size() == 0;
|
||||
headersFrame = new HeadersFrame(metaData, null, endStream);
|
||||
promise = new HeadersPromise(request, callback)
|
||||
{
|
||||
callback.failed(failure);
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
super.succeeded(stream);
|
||||
if (endStream)
|
||||
callback.succeeded();
|
||||
else
|
||||
sendTrailers(stream, trailers, callback);
|
||||
}
|
||||
};
|
||||
}
|
||||
// TODO optimize the send of HEADERS and DATA frames.
|
||||
HttpChannelOverHTTP2 channel = getHttpChannel();
|
||||
channel.getSession().newStream(headersFrame, promise, channel.getStreamListener());
|
||||
}
|
||||
|
||||
|
@ -118,24 +133,67 @@ public class HttpSenderOverHTTP2 extends HttpSender
|
|||
{
|
||||
if (content.isConsumed())
|
||||
{
|
||||
// The superclass calls sendContent() one more time after the last content.
|
||||
// This is necessary for HTTP/1.1 to generate the terminal chunk (with trailers),
|
||||
// but it's not necessary for HTTP/2 so we just succeed the callback.
|
||||
callback.succeeded();
|
||||
}
|
||||
else
|
||||
{
|
||||
Stream stream = getHttpChannel().getStream();
|
||||
Supplier<HttpFields> trailers = exchange.getRequest().getTrailers();
|
||||
DataFrame frame = new DataFrame(stream.getId(), content.getByteBuffer(), trailers == null && content.isLast());
|
||||
stream.data(frame, callback);
|
||||
Supplier<HttpFields> trailerSupplier = exchange.getRequest().getTrailers();
|
||||
sendContent(stream, content, trailerSupplier, callback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendTrailers(HttpExchange exchange, Callback callback)
|
||||
private void sendContent(Stream stream, HttpContent content, Supplier<HttpFields> trailerSupplier, Callback callback)
|
||||
{
|
||||
Supplier<HttpFields> trailers = exchange.getRequest().getTrailers();
|
||||
MetaData metaData = new MetaData(HttpVersion.HTTP_2, trailers.get());
|
||||
Stream stream = getHttpChannel().getStream();
|
||||
boolean lastContent = content.isLast();
|
||||
HttpFields trailers = null;
|
||||
boolean endStream = false;
|
||||
if (lastContent)
|
||||
{
|
||||
trailers = trailerSupplier == null ? null : trailerSupplier.get();
|
||||
endStream = trailers == null || trailers.size() == 0;
|
||||
}
|
||||
DataFrame dataFrame = new DataFrame(stream.getId(), content.getByteBuffer(), endStream);
|
||||
HttpFields fTrailers = trailers;
|
||||
stream.data(dataFrame, endStream || !lastContent ? callback : Callback.from(() -> sendTrailers(stream, fTrailers, callback), callback::failed));
|
||||
}
|
||||
|
||||
private void sendTrailers(Stream stream, HttpFields trailers, Callback callback)
|
||||
{
|
||||
MetaData metaData = new MetaData(HttpVersion.HTTP_2, trailers);
|
||||
HeadersFrame trailersFrame = new HeadersFrame(stream.getId(), metaData, null, true);
|
||||
stream.headers(trailersFrame, callback);
|
||||
}
|
||||
|
||||
private class HeadersPromise implements Promise<Stream>
|
||||
{
|
||||
private final HttpRequest request;
|
||||
private final Callback callback;
|
||||
|
||||
private HeadersPromise(HttpRequest request, Callback callback)
|
||||
{
|
||||
this.request = request;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
HttpChannelOverHTTP2 channel = getHttpChannel();
|
||||
channel.setStream(stream);
|
||||
((IStream)stream).setAttachment(channel);
|
||||
long idleTimeout = request.getIdleTimeout();
|
||||
if (idleTimeout >= 0)
|
||||
stream.setIdleTimeout(idleTimeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
callback.failed(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.http2.client.http;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.HttpRequest;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.util.DeferredContentProvider;
|
||||
import org.eclipse.jetty.client.util.StringContentProvider;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.http.MetaData;
|
||||
import org.eclipse.jetty.http2.api.Stream;
|
||||
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
|
||||
import org.eclipse.jetty.http2.frames.DataFrame;
|
||||
import org.eclipse.jetty.http2.frames.HeadersFrame;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class RequestTrailersTest extends AbstractTest
|
||||
{
|
||||
@Test
|
||||
public void testEmptyTrailersWithoutContent() throws Exception
|
||||
{
|
||||
testEmptyTrailers(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyTrailersWithEagerContent() throws Exception
|
||||
{
|
||||
testEmptyTrailers("eager_content");
|
||||
}
|
||||
|
||||
private void testEmptyTrailers(String content) throws Exception
|
||||
{
|
||||
CountDownLatch trailersLatch = new CountDownLatch(1);
|
||||
start(new ServerSessionListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
|
||||
{
|
||||
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields());
|
||||
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), response, null, true);
|
||||
stream.headers(responseFrame, Callback.NOOP);
|
||||
return new Stream.Listener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onHeaders(Stream stream, HeadersFrame frame)
|
||||
{
|
||||
trailersLatch.countDown();
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
HttpRequest request = (HttpRequest)client.newRequest("localhost", connector.getLocalPort());
|
||||
HttpFields trailers = new HttpFields();
|
||||
request.trailers(() -> trailers);
|
||||
if (content != null)
|
||||
request.content(new StringContentProvider(content));
|
||||
|
||||
ContentResponse response = request.send();
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
|
||||
// The client must not send the trailers.
|
||||
assertFalse(trailersLatch.await(1, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyTrailersWithDeferredContent() throws Exception
|
||||
{
|
||||
start(new ServerSessionListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
|
||||
{
|
||||
return new Stream.Listener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onData(Stream stream, DataFrame dataFrame, Callback callback)
|
||||
{
|
||||
callback.succeeded();
|
||||
// We should not receive an empty HEADERS frame for the
|
||||
// trailers, but instead a DATA frame with endStream=true.
|
||||
if (dataFrame.isEndStream())
|
||||
{
|
||||
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields());
|
||||
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), response, null, true);
|
||||
stream.headers(responseFrame, Callback.NOOP);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
HttpRequest request = (HttpRequest)client.newRequest("localhost", connector.getLocalPort());
|
||||
HttpFields trailers = new HttpFields();
|
||||
request.trailers(() -> trailers);
|
||||
DeferredContentProvider content = new DeferredContentProvider();
|
||||
request.content(content);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
request.send(result ->
|
||||
{
|
||||
assertTrue(result.isSucceeded());
|
||||
assertEquals(HttpStatus.OK_200, result.getResponse().getStatus());
|
||||
latch.countDown();
|
||||
});
|
||||
|
||||
// Send deferred content after a while.
|
||||
Thread.sleep(1000);
|
||||
content.offer(ByteBuffer.wrap("deferred_content".getBytes(StandardCharsets.UTF_8)));
|
||||
content.close();
|
||||
|
||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyTrailersWithEmptyDeferredContent() throws Exception
|
||||
{
|
||||
start(new ServerSessionListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
|
||||
{
|
||||
return new Stream.Listener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onData(Stream stream, DataFrame dataFrame, Callback callback)
|
||||
{
|
||||
callback.succeeded();
|
||||
// We should not receive an empty HEADERS frame for the
|
||||
// trailers, but instead a DATA frame with endStream=true.
|
||||
if (dataFrame.isEndStream())
|
||||
{
|
||||
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields());
|
||||
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), response, null, true);
|
||||
stream.headers(responseFrame, Callback.NOOP);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
HttpRequest request = (HttpRequest)client.newRequest("localhost", connector.getLocalPort());
|
||||
HttpFields trailers = new HttpFields();
|
||||
request.trailers(() -> trailers);
|
||||
DeferredContentProvider content = new DeferredContentProvider();
|
||||
request.content(content);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
request.send(result ->
|
||||
{
|
||||
assertTrue(result.isSucceeded());
|
||||
assertEquals(HttpStatus.OK_200, result.getResponse().getStatus());
|
||||
latch.countDown();
|
||||
});
|
||||
|
||||
// Send deferred content after a while.
|
||||
Thread.sleep(1000);
|
||||
content.close();
|
||||
|
||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>infinispan-common</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>infinispan-embedded-query</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>infinispan-embedded</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>infinispan-remote-query</artifactId>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<!-- ============================================================= -->
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-parent</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>infinispan-remote</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>9.4.19-SNAPSHOT</version>
|
||||
<version>9.4.20-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
|
|
|
@ -307,9 +307,36 @@ abstract public class WriteFlusher
|
|||
|
||||
private void fail(Callback callback, Throwable... suppressed)
|
||||
{
|
||||
FailedState failed = (FailedState)_state.get();
|
||||
Throwable cause;
|
||||
loop:
|
||||
while (true)
|
||||
{
|
||||
State state = _state.get();
|
||||
|
||||
switch (state.getType())
|
||||
{
|
||||
case FAILED:
|
||||
{
|
||||
FailedState failed = (FailedState)state;
|
||||
cause = failed.getCause();
|
||||
break loop;
|
||||
}
|
||||
|
||||
case IDLE:
|
||||
for (Throwable t : suppressed)
|
||||
LOG.warn(t);
|
||||
return;
|
||||
|
||||
default:
|
||||
Throwable t = new IllegalStateException();
|
||||
if (!_state.compareAndSet(state, new FailedState(t)))
|
||||
continue;
|
||||
|
||||
cause = t;
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
|
||||
Throwable cause = failed.getCause();
|
||||
for (Throwable t : suppressed)
|
||||
{
|
||||
if (t != cause)
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLEngineResult;
|
||||
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
||||
|
@ -41,6 +40,7 @@ import org.eclipse.jetty.io.EndPoint;
|
|||
import org.eclipse.jetty.io.WriteFlusher;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.Invocable;
|
||||
|
@ -584,7 +584,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("unwrap net_filled={} {} encryptedBuffer={} unwrapBuffer={} appBuffer={}",
|
||||
net_filled,
|
||||
unwrapResult.toString().replace('\n', ' '),
|
||||
StringUtil.replace(unwrapResult.toString(), '\n', ' '),
|
||||
BufferUtil.toSummaryString(_encryptedInput),
|
||||
BufferUtil.toDetailString(app_in),
|
||||
BufferUtil.toDetailString(buffer));
|
||||
|
@ -895,7 +895,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
|||
}
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("wrap {} {} ioDone={}/{}",
|
||||
wrapResult.toString().replace('\n', ' '),
|
||||
StringUtil.replace(wrapResult.toString(), '\n', ' '),
|
||||
BufferUtil.toSummaryString(_encryptedOutput),
|
||||
_sslEngine.isInboundDone(),
|
||||
_sslEngine.isOutboundDone());
|
||||
|
|
|
@ -18,14 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.io;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -43,10 +35,18 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class WriteFlusherTest
|
||||
{
|
||||
@Test
|
||||
|
@ -159,6 +159,43 @@ public class WriteFlusherTest
|
|||
assertTrue(flusher.isIdle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallbackThrows() throws Exception
|
||||
{
|
||||
ByteArrayEndPoint endPoint = new ByteArrayEndPoint(new byte[0], 100);
|
||||
|
||||
AtomicBoolean incompleteFlush = new AtomicBoolean(false);
|
||||
WriteFlusher flusher = new WriteFlusher(endPoint)
|
||||
{
|
||||
@Override
|
||||
protected void onIncompleteFlush()
|
||||
{
|
||||
incompleteFlush.set(true);
|
||||
}
|
||||
};
|
||||
|
||||
FutureCallback callback = new FutureCallback()
|
||||
{
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
super.succeeded();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
};
|
||||
|
||||
try (StacklessLogging stacklessLogging = new StacklessLogging(WriteFlusher.class))
|
||||
{
|
||||
flusher.write(callback, BufferUtil.toBuffer("How now brown cow!"));
|
||||
callback.get(100, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
assertEquals("How now brown cow!", endPoint.takeOutputString());
|
||||
assertTrue(callback.isDone());
|
||||
assertFalse(incompleteFlush.get());
|
||||
assertTrue(flusher.isIdle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseWhileBlocking() throws Exception
|
||||
{
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue