Merge remote-tracking branch 'origin/jetty-9.3.x' into jetty-9.4.x
This commit is contained in:
commit
611e79945c
|
@ -156,6 +156,7 @@ public class HttpParser
|
||||||
private int _responseStatus;
|
private int _responseStatus;
|
||||||
private int _headerBytes;
|
private int _headerBytes;
|
||||||
private boolean _host;
|
private boolean _host;
|
||||||
|
private boolean _headerComplete;
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------------- */
|
||||||
private volatile State _state=State.START;
|
private volatile State _state=State.START;
|
||||||
|
@ -730,6 +731,7 @@ public class HttpParser
|
||||||
setState(State.END);
|
setState(State.END);
|
||||||
BufferUtil.clear(buffer);
|
BufferUtil.clear(buffer);
|
||||||
handle=_handler.headerComplete()||handle;
|
handle=_handler.headerComplete()||handle;
|
||||||
|
_headerComplete=true;
|
||||||
handle=_handler.messageComplete()||handle;
|
handle=_handler.messageComplete()||handle;
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
@ -800,6 +802,7 @@ public class HttpParser
|
||||||
setState(State.END);
|
setState(State.END);
|
||||||
BufferUtil.clear(buffer);
|
BufferUtil.clear(buffer);
|
||||||
handle=_handler.headerComplete()||handle;
|
handle=_handler.headerComplete()||handle;
|
||||||
|
_headerComplete=true;
|
||||||
handle=_handler.messageComplete()||handle;
|
handle=_handler.messageComplete()||handle;
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
@ -1057,22 +1060,26 @@ public class HttpParser
|
||||||
case EOF_CONTENT:
|
case EOF_CONTENT:
|
||||||
setState(State.EOF_CONTENT);
|
setState(State.EOF_CONTENT);
|
||||||
handle=_handler.headerComplete()||handle;
|
handle=_handler.headerComplete()||handle;
|
||||||
|
_headerComplete=true;
|
||||||
return handle;
|
return handle;
|
||||||
|
|
||||||
case CHUNKED_CONTENT:
|
case CHUNKED_CONTENT:
|
||||||
setState(State.CHUNKED_CONTENT);
|
setState(State.CHUNKED_CONTENT);
|
||||||
handle=_handler.headerComplete()||handle;
|
handle=_handler.headerComplete()||handle;
|
||||||
|
_headerComplete=true;
|
||||||
return handle;
|
return handle;
|
||||||
|
|
||||||
case NO_CONTENT:
|
case NO_CONTENT:
|
||||||
setState(State.END);
|
setState(State.END);
|
||||||
handle=_handler.headerComplete()||handle;
|
handle=_handler.headerComplete()||handle;
|
||||||
|
_headerComplete=true;
|
||||||
handle=_handler.messageComplete()||handle;
|
handle=_handler.messageComplete()||handle;
|
||||||
return handle;
|
return handle;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
setState(State.CONTENT);
|
setState(State.CONTENT);
|
||||||
handle=_handler.headerComplete()||handle;
|
handle=_handler.headerComplete()||handle;
|
||||||
|
_headerComplete=true;
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1426,39 +1433,30 @@ public class HttpParser
|
||||||
LOG.warn("parse exception: {} in {} for {}",e.toString(),_state,_handler);
|
LOG.warn("parse exception: {} in {} for {}",e.toString(),_state,_handler);
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
LOG.debug(e);
|
LOG.debug(e);
|
||||||
|
badMessage();
|
||||||
|
|
||||||
switch(_state)
|
|
||||||
{
|
|
||||||
case CLOSED:
|
|
||||||
break;
|
|
||||||
case CLOSE:
|
|
||||||
_handler.earlyEOF();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setState(State.CLOSE);
|
|
||||||
_handler.badMessage(400,"Bad Message "+e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch(Exception|Error e)
|
catch(Exception|Error e)
|
||||||
{
|
{
|
||||||
BufferUtil.clear(buffer);
|
BufferUtil.clear(buffer);
|
||||||
|
|
||||||
LOG.warn("parse exception: "+e.toString()+" for "+_handler,e);
|
LOG.warn("parse exception: "+e.toString()+" for "+_handler,e);
|
||||||
|
badMessage();
|
||||||
switch(_state)
|
|
||||||
{
|
|
||||||
case CLOSED:
|
|
||||||
break;
|
|
||||||
case CLOSE:
|
|
||||||
_handler.earlyEOF();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setState(State.CLOSE);
|
|
||||||
_handler.badMessage(400,null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void badMessage()
|
||||||
|
{
|
||||||
|
if (_headerComplete)
|
||||||
|
{
|
||||||
|
_handler.earlyEOF();
|
||||||
|
}
|
||||||
|
else if (_state!=State.CLOSED)
|
||||||
|
{
|
||||||
|
setState(State.CLOSE);
|
||||||
|
_handler.badMessage(400,_requestHandler!=null?"Bad Request":"Bad Response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean parseContent(ByteBuffer buffer)
|
protected boolean parseContent(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
|
@ -1677,6 +1675,7 @@ public class HttpParser
|
||||||
_contentChunk=null;
|
_contentChunk=null;
|
||||||
_headerBytes=0;
|
_headerBytes=0;
|
||||||
_host=false;
|
_host=false;
|
||||||
|
_headerComplete=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------------- */
|
||||||
|
|
|
@ -219,11 +219,15 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque
|
||||||
@Override
|
@Override
|
||||||
public void earlyEOF()
|
public void earlyEOF()
|
||||||
{
|
{
|
||||||
|
_httpConnection.getGenerator().setPersistent(false);
|
||||||
// If we have no request yet, just close
|
// If we have no request yet, just close
|
||||||
if (_metadata.getMethod() == null)
|
if (_metadata.getMethod() == null)
|
||||||
_httpConnection.close();
|
_httpConnection.close();
|
||||||
else if (onEarlyEOF())
|
else if (onEarlyEOF() || _delayedForContent)
|
||||||
|
{
|
||||||
|
_delayedForContent = false;
|
||||||
handle();
|
handle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -298,6 +298,7 @@ public class AsyncRequestReadTest
|
||||||
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||||
assertThat(in.readLine(),containsString("HTTP/1.1 200 OK"));
|
assertThat(in.readLine(),containsString("HTTP/1.1 200 OK"));
|
||||||
assertThat(in.readLine(),containsString("Content-Length:"));
|
assertThat(in.readLine(),containsString("Content-Length:"));
|
||||||
|
assertThat(in.readLine(),containsString("Connection: close"));
|
||||||
assertThat(in.readLine(),containsString("Server:"));
|
assertThat(in.readLine(),containsString("Server:"));
|
||||||
in.readLine();
|
in.readLine();
|
||||||
assertThat(in.readLine(),containsString("XXXXXXX"));
|
assertThat(in.readLine(),containsString("XXXXXXX"));
|
||||||
|
|
|
@ -49,6 +49,7 @@ import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpTester;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.io.EofException;
|
import org.eclipse.jetty.io.EofException;
|
||||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||||
|
@ -695,6 +696,54 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBlockingReadBadChunk() throws Exception
|
||||||
|
{
|
||||||
|
configureServer(new ReadHandler());
|
||||||
|
|
||||||
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
|
{
|
||||||
|
client.setSoTimeout(600000);
|
||||||
|
OutputStream os = client.getOutputStream();
|
||||||
|
InputStream is = client.getInputStream();
|
||||||
|
|
||||||
|
os.write((
|
||||||
|
"GET /data HTTP/1.1\r\n" +
|
||||||
|
"host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" +
|
||||||
|
"content-type: unknown\r\n" +
|
||||||
|
"transfer-encoding: chunked\r\n" +
|
||||||
|
"\r\n"
|
||||||
|
).getBytes());
|
||||||
|
os.flush();
|
||||||
|
Thread.sleep(50);
|
||||||
|
os.write((
|
||||||
|
"a\r\n" +
|
||||||
|
"123456890\r\n"
|
||||||
|
).getBytes());
|
||||||
|
os.flush();
|
||||||
|
|
||||||
|
Thread.sleep(50);
|
||||||
|
os.write((
|
||||||
|
"4\r\n" +
|
||||||
|
"abcd\r\n"
|
||||||
|
).getBytes());
|
||||||
|
os.flush();
|
||||||
|
|
||||||
|
Thread.sleep(50);
|
||||||
|
os.write((
|
||||||
|
"X\r\n" +
|
||||||
|
"abcd\r\n"
|
||||||
|
).getBytes());
|
||||||
|
os.flush();
|
||||||
|
|
||||||
|
HttpTester.Response response = HttpTester.parseResponse(HttpTester.from(is));
|
||||||
|
|
||||||
|
assertThat(response.getStatus(),is(200));
|
||||||
|
assertThat(response.getContent(),containsString("EofException"));
|
||||||
|
assertThat(response.getContent(),containsString("Early EOF"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBlockingWhileWritingResponseContent() throws Exception
|
public void testBlockingWhileWritingResponseContent() throws Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -186,7 +186,28 @@ public class HttpServerTestFixture
|
||||||
response.getOutputStream().print("Hello world\r\n");
|
response.getOutputStream().print("Hello world\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static class ReadHandler extends AbstractHandler
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||||
|
{
|
||||||
|
baseRequest.setHandled(true);
|
||||||
|
response.setStatus(200);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InputStream in = request.getInputStream();
|
||||||
|
String input= IO.toString(in);
|
||||||
|
response.getWriter().printf("read %d%n",input.length());
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
response.getWriter().printf("caught %s%n",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected static class DataHandler extends AbstractHandler
|
protected static class DataHandler extends AbstractHandler
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -162,11 +162,8 @@ public class PostServletTest
|
||||||
req.append("\r\n");
|
req.append("\r\n");
|
||||||
req.append("\r\n");
|
req.append("\r\n");
|
||||||
|
|
||||||
try (StacklessLogging scope = new StacklessLogging(ServletHandler.class))
|
String resp = connector.getResponse(req.toString());
|
||||||
{
|
assertThat(resp,startsWith("HTTP/1.1 200 OK")); // exception eaten by handler
|
||||||
String resp = connector.getResponses(req.toString());
|
|
||||||
assertThat(resp,is("")); // Aborted before response committed
|
|
||||||
}
|
|
||||||
assertTrue(complete.await(5,TimeUnit.SECONDS));
|
assertTrue(complete.await(5,TimeUnit.SECONDS));
|
||||||
assertThat(ex0.get(),not(nullValue()));
|
assertThat(ex0.get(),not(nullValue()));
|
||||||
assertThat(ex1.get(),not(nullValue()));
|
assertThat(ex1.get(),not(nullValue()));
|
||||||
|
@ -181,31 +178,26 @@ public class PostServletTest
|
||||||
req.append("Transfer-Encoding: chunked\r\n");
|
req.append("Transfer-Encoding: chunked\r\n");
|
||||||
req.append("\r\n");
|
req.append("\r\n");
|
||||||
|
|
||||||
try (StacklessLogging scope = new StacklessLogging(ServletHandler.class))
|
LocalConnector.LocalEndPoint endp=connector.executeRequest(req.toString());
|
||||||
{
|
Thread.sleep(1000);
|
||||||
LocalConnector.LocalEndPoint endp=connector.executeRequest(req.toString());
|
assertFalse(posted.get());
|
||||||
Thread.sleep(1000);
|
|
||||||
assertFalse(posted.get());
|
|
||||||
|
|
||||||
req.setLength(0);
|
req.setLength(0);
|
||||||
// intentionally bad (not a valid chunked char here)
|
// intentionally bad (not a valid chunked char here)
|
||||||
for (int i=1024;i-->0;)
|
for (int i=1024;i-->0;)
|
||||||
req.append("xxxxxxxxxxxx");
|
req.append("xxxxxxxxxxxx");
|
||||||
req.append("\r\n");
|
req.append("\r\n");
|
||||||
req.append("\r\n");
|
req.append("\r\n");
|
||||||
|
|
||||||
endp.addInput(req.toString());
|
endp.addInput(req.toString());
|
||||||
|
|
||||||
endp.waitUntilClosedOrIdleFor(1,TimeUnit.SECONDS);
|
endp.waitUntilClosedOrIdleFor(1,TimeUnit.SECONDS);
|
||||||
String resp = endp.takeOutputString();
|
String resp = endp.takeOutputString();
|
||||||
|
|
||||||
assertThat("resp", resp, containsString("HTTP/1.1 400 "));
|
assertThat(resp,startsWith("HTTP/1.1 200 OK")); // exception eaten by handler
|
||||||
|
assertTrue(complete.await(5,TimeUnit.SECONDS));
|
||||||
}
|
assertThat(ex0.get(),not(nullValue()));
|
||||||
|
assertThat(ex1.get(),not(nullValue()));
|
||||||
// null because it was never dispatched!
|
|
||||||
assertThat(ex0.get(),nullValue());
|
|
||||||
assertThat(ex1.get(),nullValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,15 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.server;
|
package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import org.eclipse.jetty.annotations.AnnotationConfiguration;
|
import org.eclipse.jetty.annotations.AnnotationConfiguration;
|
||||||
|
@ -35,6 +38,7 @@ import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||||
import org.eclipse.jetty.toolchain.test.FS;
|
import org.eclipse.jetty.toolchain.test.FS;
|
||||||
import org.eclipse.jetty.toolchain.test.IO;
|
import org.eclipse.jetty.toolchain.test.IO;
|
||||||
|
import org.eclipse.jetty.toolchain.test.JAR;
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
import org.eclipse.jetty.toolchain.test.OS;
|
import org.eclipse.jetty.toolchain.test.OS;
|
||||||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||||
|
@ -47,7 +51,6 @@ import org.eclipse.jetty.webapp.MetaInfConfiguration;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||||
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
||||||
import org.junit.Assert;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility to build out exploded directory WebApps, in the /target/tests/ directory, for testing out servers that use javax.websocket endpoints.
|
* Utility to build out exploded directory WebApps, in the /target/tests/ directory, for testing out servers that use javax.websocket endpoints.
|
||||||
|
@ -82,7 +85,7 @@ public class WSServer
|
||||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||||
String endpointPath = clazz.getName().replace('.','/') + ".class";
|
String endpointPath = clazz.getName().replace('.','/') + ".class";
|
||||||
URL classUrl = cl.getResource(endpointPath);
|
URL classUrl = cl.getResource(endpointPath);
|
||||||
Assert.assertThat("Class URL for: " + clazz,classUrl,notNullValue());
|
assertThat("Class URL for: " + clazz,classUrl,notNullValue());
|
||||||
File destFile = new File(classesDir,OS.separators(endpointPath));
|
File destFile = new File(classesDir,OS.separators(endpointPath));
|
||||||
FS.ensureDirExists(destFile.getParentFile());
|
FS.ensureDirExists(destFile.getParentFile());
|
||||||
File srcFile = new File(classUrl.toURI());
|
File srcFile = new File(classUrl.toURI());
|
||||||
|
@ -93,7 +96,31 @@ public class WSServer
|
||||||
{
|
{
|
||||||
copyClass(endpointClass);
|
copyClass(endpointClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void copyLib(Class<?> clazz, String jarFileName) throws URISyntaxException, IOException
|
||||||
|
{
|
||||||
|
webinf = new File(contextDir,"WEB-INF");
|
||||||
|
FS.ensureDirExists(webinf);
|
||||||
|
File libDir = new File(webinf,"lib");
|
||||||
|
FS.ensureDirExists(libDir);
|
||||||
|
File jarFile = new File(libDir, jarFileName);
|
||||||
|
|
||||||
|
URL codeSourceURL = clazz.getProtectionDomain().getCodeSource().getLocation();
|
||||||
|
assertThat("Class CodeSource URL is file scheme", codeSourceURL.getProtocol(), is("file"));
|
||||||
|
|
||||||
|
File sourceCodeSourceFile = new File(codeSourceURL.toURI());
|
||||||
|
if (sourceCodeSourceFile.isDirectory())
|
||||||
|
{
|
||||||
|
LOG.info("Creating " + jarFile + " from " + sourceCodeSourceFile);
|
||||||
|
JAR.create(sourceCodeSourceFile, jarFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG.info("Copying " + sourceCodeSourceFile + " to " + jarFile);
|
||||||
|
IO.copy(sourceCodeSourceFile, jarFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void copyWebInf(String testResourceName) throws IOException
|
public void copyWebInf(String testResourceName) throws IOException
|
||||||
{
|
{
|
||||||
webinf = new File(contextDir,"WEB-INF");
|
webinf = new File(contextDir,"WEB-INF");
|
||||||
|
@ -173,7 +200,7 @@ public class WSServer
|
||||||
contexts = new ContextHandlerCollection();
|
contexts = new ContextHandlerCollection();
|
||||||
handlers.addHandler(contexts);
|
handlers.addHandler(contexts);
|
||||||
server.setHandler(handlers);
|
server.setHandler(handlers);
|
||||||
|
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
String host = connector.getHost();
|
String host = connector.getHost();
|
||||||
|
|
|
@ -204,6 +204,33 @@ public class WebSocketUpgradeFilterTest
|
||||||
return server15.getServer();
|
return server15.getServer();
|
||||||
}});
|
}});
|
||||||
|
|
||||||
|
// WSUF from web.xml, SCI active, apply app-ws configuration via ServletContextListener with WEB-INF/lib/jetty-http.jar
|
||||||
|
|
||||||
|
cases.add(new Object[]{"wsuf/WebAppContext/web.xml/ServletContextListener/jetty-http.jar", new ServerProvider()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Server newServer() throws Exception
|
||||||
|
{
|
||||||
|
File testDir = MavenTestingUtils.getTargetTestingDir("WSUF-webxml");
|
||||||
|
|
||||||
|
WSServer server = new WSServer(testDir, "/");
|
||||||
|
|
||||||
|
server.copyWebInf("wsuf-config-via-listener.xml");
|
||||||
|
server.copyClass(InfoSocket.class);
|
||||||
|
server.copyClass(InfoContextAttributeListener.class);
|
||||||
|
// Add a jetty-http.jar to ensure that the classloader constraints
|
||||||
|
// and the WebAppClassloader setup is sane and correct
|
||||||
|
// The odd version string is present to capture bad regex behavior in Jetty
|
||||||
|
server.copyLib(org.eclipse.jetty.http.pathmap.PathSpec.class, "jetty-http-9.99.999.jar");
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
WebAppContext webapp = server.createWebAppContext();
|
||||||
|
server.deployWebapp(webapp);
|
||||||
|
|
||||||
|
return server.getServer();
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
|
||||||
// WSUF from web.xml, SCI active, apply app-ws configuration via Servlet.init
|
// WSUF from web.xml, SCI active, apply app-ws configuration via Servlet.init
|
||||||
|
|
||||||
cases.add(new Object[]{"wsuf/WebAppContext/web.xml/Servlet.init", (ServerProvider) () ->
|
cases.add(new Object[]{"wsuf/WebAppContext/web.xml/Servlet.init", (ServerProvider) () ->
|
||||||
|
|
Loading…
Reference in New Issue