mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support resin2 and jetty5
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
plugins {
|
||||
id("war")
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(8)
|
||||
}
|
||||
sourceCompatibility = JavaVersion.VERSION_1_6
|
||||
targetCompatibility = JavaVersion.VERSION_1_6
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("commons-fileupload:commons-fileupload:1.3.3")
|
||||
implementation("commons-beanutils:commons-beanutils:1.9.2")
|
||||
implementation("javax.websocket:javax.websocket-api:1.1")
|
||||
providedCompile("javax.servlet:servlet-api:2.5")
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import javax.servlet.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/12/24
|
||||
*/
|
||||
public class Base64ClassLoaderServlet extends ClassLoader implements Servlet {
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletConfig getServletConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
|
||||
String data = req.getParameter("data");
|
||||
try {
|
||||
byte[] bytes = decodeBase64(data);
|
||||
Object obj = defineClass(null, bytes, 0, bytes.length).newInstance();
|
||||
res.getWriter().print(obj);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static byte[] decodeBase64(String base64Str) throws Exception {
|
||||
try {
|
||||
Class<?> decoderClass = Class.forName("sun.misc.BASE64Decoder");
|
||||
return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str);
|
||||
} catch (Exception var4) {
|
||||
Class<?> decoderClass = Class.forName("java.util.Base64");
|
||||
Object decoder = decoderClass.getMethod("getDecoder").invoke((Object) null);
|
||||
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServletInfo() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import javax.servlet.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Wans
|
||||
* @since 2025/08/25
|
||||
*/
|
||||
public class BigIntegerClassLoaderServlet extends ClassLoader implements Servlet {
|
||||
|
||||
public BigIntegerClassLoaderServlet() {
|
||||
}
|
||||
|
||||
protected BigIntegerClassLoaderServlet(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletConfig getServletConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
|
||||
String data = req.getParameter("data");
|
||||
try {
|
||||
byte[] bytes = decodeBigInteger(data);
|
||||
new BigIntegerClassLoaderServlet(Thread.currentThread().getContextClassLoader()).defineClass(null, bytes, 0, bytes.length).newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static byte[] decodeBigInteger(String bigIntegerStr) throws Exception {
|
||||
Class<?> decoderClass = Class.forName("java.math.BigInteger");
|
||||
return (byte[]) decoderClass.getMethod("toByteArray").invoke(decoderClass.getConstructor(String.class, int.class).newInstance(bigIntegerStr, Character.MAX_RADIX));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServletInfo() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import javax.servlet.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class EmptyFilter implements Filter {
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletRequestEvent;
|
||||
import javax.servlet.ServletRequestListener;
|
||||
|
||||
public class EmptyListener implements ServletRequestListener {
|
||||
@Override
|
||||
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
|
||||
ServletRequest servletRequest = servletRequestEvent.getServletRequest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
|
||||
ServletRequest servletRequest = servletRequestEvent.getServletRequest();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.MessageHandler;
|
||||
import javax.websocket.Session;
|
||||
import java.io.IOException;
|
||||
|
||||
public class EmptyWebSocketEndpoint extends Endpoint implements MessageHandler.Whole<String> {
|
||||
private Session session;
|
||||
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig endpointConfig) {
|
||||
this.session = session;
|
||||
session.addMessageHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
try {
|
||||
session.getBasicRemote().sendText("Echo: " + message);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/12/10
|
||||
*/
|
||||
public class JavaReadObjServlet extends HttpServlet {
|
||||
byte[] decodeBase64(String base64Str) throws Exception {
|
||||
Class<?> decoderClass;
|
||||
try {
|
||||
decoderClass = Class.forName("sun.misc.BASE64Decoder");
|
||||
return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str);
|
||||
} catch (Exception ignored) {
|
||||
decoderClass = Class.forName("java.util.Base64");
|
||||
Object decoder = decoderClass.getMethod("getDecoder").invoke(null);
|
||||
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
try {
|
||||
String data = req.getParameter("data");
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(decodeBase64(data));
|
||||
ObjectInputStream bis = new ObjectInputStream(inputStream);
|
||||
bis.readObject();
|
||||
bis.close();
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/12/3
|
||||
*/
|
||||
public class ScriptEngineServlet extends HttpServlet {
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String data = req.getParameter("data");
|
||||
try {
|
||||
Object eval = new ScriptEngineManager().getEngineByName("js").eval(data);
|
||||
resp.getWriter().println(eval.toString());
|
||||
} catch (ScriptException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import javax.servlet.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2026/1/11
|
||||
*/
|
||||
public class ServletNameTestFilter implements Filter {
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/12/31
|
||||
*/
|
||||
public class TestInputStreamServlet extends HttpServlet {
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String one = req.getParameter("one");
|
||||
req.setCharacterEncoding("UTF-8");
|
||||
String body = null;
|
||||
InputStream inputStream = req.getInputStream();
|
||||
StringBuilder bodyBuilder = new StringBuilder();
|
||||
if (one != null) {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
int b;
|
||||
while ((b = inputStream.read()) != -1) {
|
||||
outputStream.write(b);
|
||||
}
|
||||
bodyBuilder.append(outputStream.toString("UTF-8"));
|
||||
outputStream.close();
|
||||
} else {
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
bodyBuilder.append(new String(buffer, 0, bytesRead, "UTF-8"));
|
||||
}
|
||||
}
|
||||
body = bodyBuilder.toString();
|
||||
resp.setContentType("text/html; charset=UTF-8");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
resp.getWriter().println(body);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/12/31
|
||||
*/
|
||||
public class TestReaderServlet extends HttpServlet {
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String one = req.getParameter("one");
|
||||
String body = null;
|
||||
BufferedReader reader = req.getReader();
|
||||
StringBuilder bodyBuilder = new StringBuilder();
|
||||
if (one != null) {
|
||||
int c;
|
||||
while ((c = reader.read()) != -1) {
|
||||
bodyBuilder.append((char) c);
|
||||
}
|
||||
} else {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
bodyBuilder.append(line);
|
||||
}
|
||||
}
|
||||
body = bodyBuilder.toString();
|
||||
resp.setContentType("text/html; charset=UTF-8");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
resp.getWriter().println(body);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/12/7
|
||||
*/
|
||||
public class TestServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
req.getMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
req.getMethod();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/11/26
|
||||
*/
|
||||
public class UploadServlet extends HttpServlet {
|
||||
|
||||
private static final String TEMP_DIRECTORY = "/tmp";
|
||||
private static final String UPLOAD_DIRECTORY = "/";
|
||||
private static final int MAX_FILE_SIZE = 1024 * 1024 * 10;
|
||||
private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50;
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
if (ServletFileUpload.isMultipartContent(request)) {
|
||||
DiskFileItemFactory factory = new DiskFileItemFactory();
|
||||
factory.setSizeThreshold(1024 * 1024);
|
||||
factory.setRepository(new File(TEMP_DIRECTORY));
|
||||
ServletFileUpload upload = new ServletFileUpload(factory);
|
||||
upload.setFileSizeMax(MAX_FILE_SIZE);
|
||||
upload.setSizeMax(MAX_REQUEST_SIZE);
|
||||
try {
|
||||
List<FileItem> items = upload.parseRequest(request);
|
||||
for (FileItem item : items) {
|
||||
if (!item.isFormField()) {
|
||||
String fileName = new File(item.getName()).getName();
|
||||
String uploadFolder = getServletContext().getRealPath(UPLOAD_DIRECTORY);
|
||||
if (uploadFolder == null) {
|
||||
// weblogic
|
||||
uploadFolder = ((File) getServletContext().getAttribute("javax.servlet.context.tempdir")).getParent() + File.separator + "war";
|
||||
}
|
||||
if (!uploadFolder.endsWith(File.separator)) {
|
||||
uploadFolder += File.separator;
|
||||
}
|
||||
String uploadPath = uploadFolder + fileName;
|
||||
File uploadFile = new File(uploadPath);
|
||||
item.write(uploadFile);
|
||||
response.getWriter().println("file upload success: " + uploadPath);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
response.getWriter().println("file upload failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import javax.servlet.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/1/3
|
||||
*/
|
||||
public class UrlMappingTestFilter implements Filter {
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.server.ServerApplicationConfig;
|
||||
import javax.websocket.server.ServerEndpointConfig;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class WebSocketConfig implements ServerApplicationConfig {
|
||||
@Override
|
||||
public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> scannedEndpointClasses) {
|
||||
Set<ServerEndpointConfig> result = new HashSet<ServerEndpointConfig>();
|
||||
ServerEndpointConfig config = ServerEndpointConfig.Builder
|
||||
.create(EmptyWebSocketEndpoint.class, "/empty-ws")
|
||||
.build();
|
||||
|
||||
result.add(config);
|
||||
System.out.println("websocket init success");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
|
||||
return scanned;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE web-app PUBLIC
|
||||
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
|
||||
"http://java.sun.com/dtd/web-app_2_3.dtd">
|
||||
<web-app>
|
||||
|
||||
<filter>
|
||||
<filter-name>urlMappingTestFilter</filter-name>
|
||||
<filter-class>UrlMappingTestFilter</filter-class>
|
||||
</filter>
|
||||
<filter>
|
||||
<filter-name>servletNameTestFilter</filter-name>
|
||||
<filter-class>ServletNameTestFilter</filter-class>
|
||||
</filter>
|
||||
<filter>
|
||||
<filter-name>emptyFilter</filter-name>
|
||||
<filter-class>EmptyFilter</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>urlMappingTestFilter</filter-name>
|
||||
<url-pattern>/b64</url-pattern>
|
||||
</filter-mapping>
|
||||
<filter-mapping>
|
||||
<filter-name>urlMappingTestFilter</filter-name>
|
||||
<url-pattern>/test</url-pattern>
|
||||
</filter-mapping>
|
||||
<filter-mapping>
|
||||
<filter-name>servletNameTestFilter</filter-name>
|
||||
<servlet-name>b64</servlet-name>
|
||||
</filter-mapping>
|
||||
<filter-mapping>
|
||||
<filter-name>servletNameTestFilter</filter-name>
|
||||
<servlet-name>biginteger</servlet-name>
|
||||
</filter-mapping>
|
||||
<filter-mapping>
|
||||
<filter-name>emptyFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>test</servlet-name>
|
||||
<servlet-class>TestServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>upload</servlet-name>
|
||||
<servlet-class>UploadServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>js</servlet-name>
|
||||
<servlet-class>ScriptEngineServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>java-deserialize</servlet-name>
|
||||
<servlet-class>JavaReadObjServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>b64</servlet-name>
|
||||
<servlet-class>Base64ClassLoaderServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>biginteger</servlet-name>
|
||||
<servlet-class>BigIntegerClassLoaderServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>reader</servlet-name>
|
||||
<servlet-class>TestReaderServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>inputStream</servlet-name>
|
||||
<servlet-class>TestInputStreamServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>test</servlet-name>
|
||||
<url-pattern>/test</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>upload</servlet-name>
|
||||
<url-pattern>/upload</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>js</servlet-name>
|
||||
<url-pattern>/js</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>java-deserialize</servlet-name>
|
||||
<url-pattern>/java_deserialize</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>b64</servlet-name>
|
||||
<url-pattern>/b64</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>biginteger</servlet-name>
|
||||
<url-pattern>/biginteger</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>reader</servlet-name>
|
||||
<url-pattern>/reader</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>inputStream</servlet-name>
|
||||
<url-pattern>/inputStream</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.html</welcome-file>
|
||||
</welcome-file-list>
|
||||
</web-app>
|
||||
@@ -0,0 +1 @@
|
||||
<h1>hello</h1>
|
||||
Reference in New Issue
Block a user