mirror of
https://github.com/yacy/yacy_search_server.git
synced 2024-09-19 00:01:41 +02:00
fix servlet class exist check to use default path only (in Jetty8YaCyDefaultServlet)
- del redundant doget code in yacydefaultservlet - small declaration code opts - del obsolete libt/proxyservlet.java
This commit is contained in:
parent
9da87c0c7f
commit
d6760df3e5
|
@ -1,418 +0,0 @@
|
|||
// package de.spieleck.servlets;
|
||||
// ProxyServlet - serving pages from foreign servers....
|
||||
//
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.lang.Integer;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.*;
|
||||
|
||||
/**
|
||||
* Serves pages which are fetched from another HTTP-Server
|
||||
* useful for going thru firewalls and other trickery...
|
||||
* <P>
|
||||
* The communication is somewhat this way:
|
||||
* <UL>
|
||||
* <LI>Client requests data from servlet
|
||||
* <LI>Servlet interprets path and requests data from remote server
|
||||
* <LI>Servlet obtains answer from remote server and forwards it to client
|
||||
* <LI>Client obtains answer
|
||||
* </UL>
|
||||
* <P>
|
||||
* XXX There is a problem with If-Modified and If-None-Match requests:
|
||||
* the 304 Not Modified answer does not go thru the servelet in the
|
||||
* backward direction. It could be that the HttpServletResponse does hava
|
||||
* some sideeffects which are not helpfull in this special situation.
|
||||
* This type of request is currently avoided by removing all "If-" requests.
|
||||
* <br />
|
||||
* <b>Note:</b> This servlet is actually buggy. It is buggy since it does
|
||||
* not solve all problems, it only solves the problems I needed to solve.
|
||||
* Many thanks to Thorsten Gast the creator of dirjack
|
||||
* for pointing at least some bugs.
|
||||
* @author <a href="mailto:frank -at- spieleck.de">Frank Nestel</a>.
|
||||
*/
|
||||
|
||||
public class ProxyServlet extends HttpServlet
|
||||
{
|
||||
/**
|
||||
* "Official" HTTP line end
|
||||
*/
|
||||
public final static String CRLF = "\r\n";
|
||||
public final static String LF = "\n";
|
||||
|
||||
/**
|
||||
* remote path
|
||||
*/
|
||||
protected String remotePath;
|
||||
|
||||
/**
|
||||
* remote server
|
||||
*/
|
||||
protected String remoteServer;
|
||||
|
||||
/**
|
||||
* Port at remote server
|
||||
*/
|
||||
protected int remotePort;
|
||||
|
||||
/**
|
||||
* Debug mode?
|
||||
*/
|
||||
protected boolean debugFlag;
|
||||
|
||||
/** Init
|
||||
*/
|
||||
public void init(ServletConfig config)
|
||||
throws ServletException
|
||||
{
|
||||
super.init(config);
|
||||
remotePath = getInitParameter("remotePath");
|
||||
remoteServer = getInitParameter("remoteServer");
|
||||
String remotePortStr= getInitParameter("remotePort");
|
||||
if ( remotePath == null || remoteServer == null )
|
||||
throw new ServletException(
|
||||
"Servlet needs remotePath & remoteServer.");
|
||||
if ( remotePortStr != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
remotePort = Integer.parseInt(remotePortStr);
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
throw new ServletException("Port must be a number!");
|
||||
}
|
||||
}
|
||||
else
|
||||
remotePort = 80;
|
||||
if ( "".equals(remotePath) )
|
||||
remotePath = ""; // XXX ??? "/"
|
||||
else if ( remotePath.charAt(0) != '/' )
|
||||
remotePath = "/"+remotePath;
|
||||
debugFlag = "true".equals(getInitParameter("debug"));
|
||||
//
|
||||
log("remote="+remoteServer+" "+remotePort+" "+remotePath);
|
||||
}
|
||||
|
||||
/// Returns a string containing information about the author, version, and
|
||||
// copyright of the servlet.
|
||||
public String getServletInfo()
|
||||
{
|
||||
return "Online redirecting content.";
|
||||
}
|
||||
|
||||
/// Services a single request from the client.
|
||||
// @param req the servlet request
|
||||
// @param req the servlet response
|
||||
// @exception ServletException when an exception has occurred
|
||||
public void service( HttpServletRequest req, HttpServletResponse res )
|
||||
throws ServletException, IOException
|
||||
{
|
||||
//
|
||||
// Connect to "remote" server:
|
||||
Socket sock;
|
||||
OutputStream out;
|
||||
InputStream in;
|
||||
//
|
||||
try
|
||||
{
|
||||
sock = new Socket(remoteServer, remotePort); // !!!!!!!!
|
||||
out = new BufferedOutputStream(sock.getOutputStream());
|
||||
in = new BufferedInputStream(sock.getInputStream());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
res.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
||||
"Socket opening: "+remoteServer+" "+remotePort);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
//
|
||||
// Build up a HTTP request from pure strings:
|
||||
StringBuffer sb = new StringBuffer(200);
|
||||
sb.append(req.getMethod());
|
||||
sb.append(' ');
|
||||
String pi = req.getPathInfo();
|
||||
sb.append(remotePath);
|
||||
if ( pi != null )
|
||||
{
|
||||
appendCleaned(sb, pi);
|
||||
}
|
||||
else
|
||||
sb.append("/");
|
||||
if ( req.getQueryString() != null )
|
||||
{
|
||||
sb.append('?');
|
||||
appendCleaned(sb, req.getQueryString());
|
||||
}
|
||||
sb.append(' ');
|
||||
sb.append("HTTP/1.0");
|
||||
sb.append(CRLF);
|
||||
log(sb.toString());
|
||||
out.write(sb.toString().getBytes());
|
||||
java.util.Enumeration en = req.getHeaderNames();
|
||||
while ( en.hasMoreElements() )
|
||||
{
|
||||
String k = (String) en.nextElement();
|
||||
// Filter incoming headers:
|
||||
if ( "Host".equalsIgnoreCase(k) )
|
||||
{
|
||||
sb.setLength(0);
|
||||
sb.append(k);
|
||||
sb.append(": ");
|
||||
sb.append(remoteServer);
|
||||
sb.append(":");
|
||||
sb.append(remotePort);
|
||||
sb.append(CRLF);
|
||||
log("c["+k+"]: "+sb+" "+req.getHeader(k));
|
||||
out.write(sb.toString().getBytes());
|
||||
}
|
||||
//
|
||||
// Throw away persistant connections between servers
|
||||
// Throw away request potentially causing a 304 response.
|
||||
else if (
|
||||
! "Connection".equalsIgnoreCase(k)
|
||||
&& ! "If-Modified-Since".equalsIgnoreCase(k)
|
||||
&& ! "If-None-Match".equalsIgnoreCase(k)
|
||||
)
|
||||
{
|
||||
sb.setLength(0);
|
||||
sb.append(k);
|
||||
sb.append(": ");
|
||||
sb.append(req.getHeader(k));
|
||||
sb.append(CRLF);
|
||||
log("=["+k+"]: "+req.getHeader(k));
|
||||
out.write(sb.toString().getBytes());
|
||||
}
|
||||
else
|
||||
{
|
||||
log("*["+k+"]: "+req.getHeader(k));
|
||||
}
|
||||
}
|
||||
// Finish request header by an empty line
|
||||
out.write(CRLF.getBytes());
|
||||
// Copy post data
|
||||
InputStream inr = req.getInputStream();
|
||||
copyStream(inr, out);
|
||||
out.flush();
|
||||
log("Remote request finished. Reading answer.");
|
||||
|
||||
// Now we have finished the outgoing request.
|
||||
// We'll now see, what is coming back from remote:
|
||||
|
||||
// Get the answer, treat its header and copy the stream data:
|
||||
if ( treatHeader(in, req, res) )
|
||||
{
|
||||
log("+ copyStream");
|
||||
// if ( debugFlag ) res.setContentType("text/plain");
|
||||
out = res.getOutputStream();
|
||||
copyStream(in, out);
|
||||
}
|
||||
else
|
||||
log("- copyStream");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log("out-in.open!");
|
||||
// res.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
||||
// "out-in open!");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
// out.close();
|
||||
in.close();
|
||||
sock.close();
|
||||
}
|
||||
catch (IOException ignore)
|
||||
{
|
||||
log("Exception "+ignore);
|
||||
}
|
||||
}
|
||||
|
||||
public static void appendCleaned(StringBuffer sb, String str)
|
||||
{
|
||||
for(int i = 0; i < str.length(); i++)
|
||||
{
|
||||
char ch = str.charAt(i);
|
||||
if ( ch == ' ' )
|
||||
sb.append("%20");
|
||||
else
|
||||
sb.append(ch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Forward and filter header from backend Request.
|
||||
*/
|
||||
private boolean treatHeader(InputStream in,
|
||||
HttpServletRequest req,
|
||||
HttpServletResponse res)
|
||||
throws ServletException
|
||||
{
|
||||
boolean retval = true;
|
||||
byte[] lineBytes = new byte[4096];
|
||||
int len;
|
||||
String line;
|
||||
|
||||
try
|
||||
{
|
||||
// Read the first line of the request.
|
||||
len = readLine(in, lineBytes );
|
||||
if ( len == -1 || len == 0 )
|
||||
throw new ServletException( "No Request found in Data." );
|
||||
{
|
||||
String line2 = new String( lineBytes, 0, len );
|
||||
log("head: "+line2+" "+len);
|
||||
}
|
||||
|
||||
// We mainly skip the header by the foreign server
|
||||
// assuming, that we can handle protocoll mismatch or so!
|
||||
res.setHeader("viaJTTP","JTTP");
|
||||
|
||||
// Some more headers require special care ....
|
||||
boolean firstline = true;
|
||||
// Shortcut evaluation skips the read on first time!
|
||||
while ( firstline || ((len=readLine(in,lineBytes)) > 0) )
|
||||
{
|
||||
line = new String( lineBytes, 0, len );
|
||||
int colonPos = line.indexOf( ":" );
|
||||
if ( firstline && colonPos == -1 )
|
||||
{
|
||||
// Special first line considerations ...
|
||||
String headl[] = wordStr(line);
|
||||
log("head: "+line+" "+headl.length);
|
||||
try
|
||||
{
|
||||
res.setStatus(Integer.parseInt(headl[1]));
|
||||
}
|
||||
catch ( NumberFormatException ignore )
|
||||
{
|
||||
log("ID exception: "+headl);
|
||||
}
|
||||
catch ( Exception panik )
|
||||
{
|
||||
log("First line invalid!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if ( colonPos != -1 )
|
||||
{
|
||||
String head = line.substring(0,colonPos);
|
||||
// XXX Skip LWS (what is LWS)
|
||||
int i = colonPos + 1;
|
||||
while ( isLWS(line.charAt(i)) ) i++;
|
||||
String value= line.substring(i);
|
||||
log("<"+head+">=<"+ value+">");
|
||||
if ( head.equalsIgnoreCase("Location") )
|
||||
{
|
||||
// res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
|
||||
// res.setHeader(head, value );
|
||||
log("Location cutted: "+value);
|
||||
}
|
||||
else if ( head.equalsIgnoreCase( "Content-type" ) )
|
||||
res.setContentType( value );
|
||||
else if ( head.equalsIgnoreCase( "Content-length" ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
int cLen = Integer.parseInt( value );
|
||||
retval = ( cLen > 0 );
|
||||
res.setContentLength(cLen);
|
||||
}
|
||||
catch ( NumberFormatException ignore ) {}
|
||||
}
|
||||
// Generically treat unknown headers
|
||||
else
|
||||
{
|
||||
log("^- generic.");
|
||||
res.setHeader(head, value );
|
||||
}
|
||||
}
|
||||
// XXX We do not treat multiline continuation Headers here
|
||||
// which have not occured anywhere yet.
|
||||
firstline = false;
|
||||
}
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
log("Header skip problem:");
|
||||
throw new ServletException("Header skip problem: "+e.getMessage());
|
||||
}
|
||||
log( "--------------" );
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a RFC2616 line from an InputStream:
|
||||
*/
|
||||
public int readLine(InputStream in, byte[] b )
|
||||
throws IOException
|
||||
{
|
||||
int off2 = 0;
|
||||
while ( off2 < b.length )
|
||||
{
|
||||
int r = in.read();
|
||||
if ( r == -1 )
|
||||
{
|
||||
if (off2 == 0 )
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
if ( r == 13 )
|
||||
continue;
|
||||
if ( r == 10 )
|
||||
break;
|
||||
b[off2] = (byte) r;
|
||||
++off2;
|
||||
}
|
||||
return off2;
|
||||
}
|
||||
|
||||
/** Copy a file from in to out.
|
||||
* Sub-classes can override this in order to do filtering of some sort.
|
||||
*/
|
||||
public void copyStream( InputStream in, OutputStream out )
|
||||
throws IOException
|
||||
{
|
||||
BufferedInputStream bin = new BufferedInputStream(in);
|
||||
int b;
|
||||
while ( ( b = bin.read() ) != -1 )
|
||||
out.write(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a blank separated string into
|
||||
*/
|
||||
public String[] wordStr( String inp )
|
||||
{
|
||||
StringTokenizer tok = new StringTokenizer(inp, " ");
|
||||
int i, n = tok.countTokens();
|
||||
String[] res = new String[n];
|
||||
for(i = 0; i < n; i++ )
|
||||
res[i] = tok.nextToken();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* XXX Should identify RFC2616 LWS
|
||||
*/
|
||||
protected boolean isLWS(char c)
|
||||
{
|
||||
return c == ' ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Capture awaay the standard servlet log ..
|
||||
*/
|
||||
public void log(String msg)
|
||||
{
|
||||
if ( debugFlag )
|
||||
System.err.println("## "+msg);
|
||||
}
|
||||
}
|
|
@ -169,7 +169,7 @@ public class Jetty8YaCyDefaultServlet extends YaCyDefaultServlet implements Reso
|
|||
final int p = pathInContext.lastIndexOf('.');
|
||||
if (p >= 0) {
|
||||
String pathofClass = pathInContext.substring(0, p) + ".class";
|
||||
Resource classresource = getResource(pathofClass);
|
||||
Resource classresource = _resourceBase.addPath(pathofClass);
|
||||
// Does a class resource exist?
|
||||
if (classresource != null && classresource.exists() && !classresource.isDirectory()) {
|
||||
hasClass = true;
|
||||
|
|
|
@ -232,137 +232,6 @@ public abstract class YaCyDefaultServlet extends HttpServlet {
|
|||
return r;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
String servletPath = null;
|
||||
String pathInfo = null;
|
||||
Enumeration<String> reqRanges = null;
|
||||
Boolean included = request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null;
|
||||
if (included != null && included.booleanValue()) {
|
||||
servletPath = (String) request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
|
||||
pathInfo = (String) request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO);
|
||||
if (servletPath == null) {
|
||||
servletPath = request.getServletPath();
|
||||
pathInfo = request.getPathInfo();
|
||||
}
|
||||
} else {
|
||||
included = Boolean.FALSE;
|
||||
servletPath = _pathInfoOnly ? "/" : request.getServletPath();
|
||||
pathInfo = request.getPathInfo();
|
||||
|
||||
// Is this a Range request?
|
||||
reqRanges = request.getHeaders(HeaderFramework.RANGE);
|
||||
if (!hasDefinedRange(reqRanges)) {
|
||||
reqRanges = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (pathInfo.startsWith("/currentyacypeer/")) pathInfo = pathInfo.substring(16);
|
||||
String pathInContext = URIUtil.addPaths(servletPath, pathInfo);
|
||||
boolean endsWithSlash = (pathInfo == null ? request.getServletPath() : pathInfo).endsWith(URIUtil.SLASH);
|
||||
|
||||
// Find the resource and content
|
||||
Resource resource = null;
|
||||
HttpContent content = null;
|
||||
try {
|
||||
String pathofClass = null;
|
||||
|
||||
// Look for a class resource
|
||||
boolean hasClass = false;
|
||||
if (reqRanges == null && !endsWithSlash) {
|
||||
final int p = pathInContext.lastIndexOf('.');
|
||||
if (p >= 0) {
|
||||
pathofClass = pathInContext.substring(0, p) + ".class";
|
||||
resource = getResource(pathofClass);
|
||||
// Does a class resource exist?
|
||||
if (resource != null && resource.exists() && !resource.isDirectory()) {
|
||||
hasClass = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find resource
|
||||
resource = getResource(pathInContext);
|
||||
|
||||
if (ConcurrentLog.isFine("FILEHANDLER")) {
|
||||
ConcurrentLog.fine("FILEHANDLER","YaCyDefaultServlet: uri=" + request.getRequestURI() + " resource=" + resource + (content != null ? " content" : ""));
|
||||
}
|
||||
|
||||
// Handle resource
|
||||
if (!hasClass && (resource == null || !resource.exists())) {
|
||||
if (included) {
|
||||
throw new FileNotFoundException("!" + pathInContext);
|
||||
}
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
} else if (!resource.isDirectory()) {
|
||||
if (endsWithSlash && pathInContext.length() > 1) {
|
||||
String q = request.getQueryString();
|
||||
pathInContext = pathInContext.substring(0, pathInContext.length() - 1);
|
||||
if (q != null && q.length() != 0) {
|
||||
pathInContext += "?" + q;
|
||||
}
|
||||
response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(_servletContext.getContextPath(), pathInContext)));
|
||||
} else {
|
||||
// ensure we have content
|
||||
if (content == null) {
|
||||
content = new HttpContent.ResourceAsHttpContent(resource, _mimeTypes.getMimeByExtension(resource.toString()), response.getBufferSize(), _etags);
|
||||
}
|
||||
|
||||
if (hasClass) { // this is a YaCy servlet, handle the template
|
||||
handleTemplate(pathInfo, request, response);
|
||||
} else {
|
||||
if (included.booleanValue() || passConditionalHeaders(request, response, resource, content)) {
|
||||
sendData(request, response, included.booleanValue(), resource, content, reqRanges);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!endsWithSlash || (pathInContext.length() == 1 && request.getAttribute("org.eclipse.jetty.server.nullPathInfo") != null)) {
|
||||
StringBuffer buf = request.getRequestURL();
|
||||
synchronized (buf) {
|
||||
int param = buf.lastIndexOf(";");
|
||||
if (param < 0) {
|
||||
buf.append('/');
|
||||
} else {
|
||||
buf.insert(param, '/');
|
||||
}
|
||||
String q = request.getQueryString();
|
||||
if (q != null && q.length() != 0) {
|
||||
buf.append('?');
|
||||
buf.append(q);
|
||||
}
|
||||
response.setContentLength(0);
|
||||
response.sendRedirect(response.encodeRedirectURL(buf.toString()));
|
||||
}
|
||||
} else { // look for a welcome file
|
||||
String welcomeFileName = getWelcomeFile (pathInContext);
|
||||
if (welcomeFileName != null) {
|
||||
RequestDispatcher rd = request.getRequestDispatcher(welcomeFileName);
|
||||
if (rd != null) rd.forward(request, response);
|
||||
} else { // send directory listing
|
||||
content = new HttpContent.ResourceAsHttpContent(resource, _mimeTypes.getMimeByExtension(resource.toString()), _etags);
|
||||
if (included.booleanValue() || passConditionalHeaders(request, response, resource, content)) {
|
||||
sendDirectory(request, response, resource, pathInContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
ConcurrentLog.logException(e);
|
||||
if (!response.isCommitted()) {
|
||||
response.sendError(500, e.getMessage());
|
||||
}
|
||||
} finally {
|
||||
if (content != null) {
|
||||
content.release();
|
||||
} else if (resource != null) {
|
||||
resource.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected boolean hasDefinedRange(Enumeration<String> reqRanges) {
|
||||
return (reqRanges != null && reqRanges.hasMoreElements());
|
||||
|
@ -396,19 +265,18 @@ public abstract class YaCyDefaultServlet extends HttpServlet {
|
|||
* Finds a matching welcome file for the supplied path.
|
||||
* The filename to look is set as servlet context init parameter
|
||||
* default is "index.html"
|
||||
* @param path in context
|
||||
* @param pathInContext path in context
|
||||
* @return The path of the matching welcome file in context or null.
|
||||
*/
|
||||
protected String getWelcomeFile(String pathInContext) {
|
||||
if (_welcomes == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < _welcomes.length; i++) {
|
||||
String welcome_in_context = URIUtil.addPaths(pathInContext, _welcomes[i]);
|
||||
for (String _welcome : _welcomes) {
|
||||
String welcome_in_context = URIUtil.addPaths(pathInContext, _welcome);
|
||||
Resource welcome = getResource(welcome_in_context);
|
||||
if (welcome != null && welcome.exists()) {
|
||||
return _welcomes[i];
|
||||
return _welcome;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -429,8 +297,7 @@ public abstract class YaCyDefaultServlet extends HttpServlet {
|
|||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] data = null;
|
||||
|
||||
String base = URIUtil.addPaths(request.getRequestURI(), URIUtil.SLASH);
|
||||
|
||||
String dir = resource.getListHTML(base, pathInContext.length() > 1);
|
||||
|
@ -440,7 +307,7 @@ public abstract class YaCyDefaultServlet extends HttpServlet {
|
|||
return;
|
||||
}
|
||||
|
||||
data = dir.getBytes("UTF-8");
|
||||
byte[] data = dir.getBytes("UTF-8");
|
||||
response.setContentType("text/html; charset=UTF-8");
|
||||
response.setContentLength(data.length);
|
||||
response.getOutputStream().write(data);
|
||||
|
@ -701,7 +568,7 @@ public abstract class YaCyDefaultServlet extends HttpServlet {
|
|||
if (targetFile.exists() && targetFile.isFile() && targetFile.canRead()) {
|
||||
String mimeType = Classification.ext2mime(targetExt, "text/html");
|
||||
|
||||
InputStream fis = null;
|
||||
InputStream fis;
|
||||
long fileSize = targetFile.length();
|
||||
|
||||
if (fileSize <= Math.min(4 * 1024 * 1204, MemoryControl.available() / 100)) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user