package io.loli.sc.server.redirect.socket; import io.loli.sc.server.redirect.bean.Pair; import io.loli.sc.server.redirect.config.Config; import io.loli.sc.server.redirect.dao.ImageDao; import io.loli.sc.server.redirect.dao.LogDao; import io.loli.sc.server.redirect.file.Cache; import io.loli.sc.server.redirect.file.FileCache; import io.loli.storage.redirect.RedirectHandler; import io.loli.storage.redirect.RequestAuthFilter; import io.loli.util.concurrent.TaskExecutor; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Date; import java.util.LinkedHashSet; import java.util.Scanner; import java.util.Set; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.glassfish.grizzly.http.server.Request; import org.glassfish.grizzly.http.server.Response; import org.glassfish.grizzly.http.util.Header; import org.glassfish.grizzly.http.util.HttpStatus; import com.mysql.jdbc.StringUtils; public class RedirectFilter implements RequestAuthFilter { private static ImageDao imageDao = new ImageDao(); private static LogDao logDao = new LogDao(); private static final Cache cache = new FileCache(); private static final Logger logger = LogManager.getLogger(RedirectHandler.class); private static final TaskExecutor executor = new TaskExecutor(30); private static Set<String> blackList = new LinkedHashSet<String>(); { try (InputStream is = this.getClass().getResourceAsStream("/blacklist.txt");) { @SuppressWarnings("resource") Scanner scanner = new Scanner(is); while (scanner.hasNextLine()) { String str = scanner.nextLine(); if (str != null && !"".equals(str.trim())) { blackList.add(str); } } } catch (IOException e) { e.printStackTrace(); logger.error(e); e.printStackTrace(); } } private void send404(Response response) { response.setStatus(HttpStatus.NOT_FOUND_404); response.setContentType("image/png"); try (InputStream is = this.getClass().getResourceAsStream("/404.png"); OutputStream os = response.getOutputStream();) { byte[] b = new byte[1024]; while (is.read(b) >= 0) { os.write(b); } } catch (IOException e) { logger.error(e); } } public void sendOutput(String url, String contentType, Request req, Response resp) { InputStream input = null; try { OutputStream output = resp.getOutputStream(); long total = 0; if (Config.useCache) { byte[] bytes = cache.getBytes(url); total = bytes.length; input = new BufferedInputStream(new ByteArrayInputStream(bytes)); } else { Pair<Long, InputStream> pair = cache.get(url); input = pair.getValue(); total = pair.getKey(); } if ((!"".equals(contentType)) && null != contentType) { resp.setContentType(contentType); } resp.setHeader("Cache-Control", "max-age=15552000"); if (total != 0) { resp.setContentLengthLong(total); } byte[] buffer = new byte[2048]; for (int length = 0; (length = input.read(buffer)) > 0;) { output.write(buffer, 0, length); } } catch (Exception e) { e.printStackTrace(); send404(resp); } finally { if (input != null) { try { input.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* * 当配置为使用缓存且(未配置exclude或者url不包含exclude字符串)时,使用缓存 */ public void filter(final Request request, final Response response) { String referer = request.getHeader(Header.Referer); // Do with black list if (referer != null && !referer.trim().equals("") && !blackList.isEmpty()) { for (String site : blackList) { if (referer.startsWith(site)) { logger.warn("该网址被禁止访问, referer是" + referer); send403(response); return; } } } try { String code = request.getRequestURI(); logger.info("用户请求的url为:" + code); if (code.startsWith("/")) { code = code.substring(1); } // 缩略图 if (code.contains(".")) { String name = code.substring(0, code.indexOf(".")); if (name.length() == 7) { String format = code.substring(code.indexOf(".") + 1); if (name.endsWith("q")) { String origin = name.substring(0, 6) + "." + format; Pair<String, String> result = imageDao.findUrlByCode(origin); try { String squarePath = imageDao.findSquarePathByCode(origin); System.out.println(squarePath); if (StringUtils.isNullOrEmpty(squarePath)) { sendOutput(result.getKey(), result.getValue(), request, response); return; } String contentType = result.getValue(); sendOutput(squarePath, contentType, request, response); return; } catch (Exception e) { e.printStackTrace(); } } } } Pair<String, String> result = imageDao.findUrlByCode(code); if (StringUtils.isNullOrEmpty(result.getKey()) && code.length() == 6) { result = imageDao.findUrlLikeCode(code); } String url = result.getKey(); if (null == url || "".equals(url.trim())) { logger.warn("url为空"); send404(response); } else { logger.info("找到url为:" + url); String ip = request.getRemoteAddr(); if (ip != null && ip.equals("127.0.0.1")) { ip = request.getHeader("X-Real-IP"); } final String fip = ip; String ua = request.getHeader(Header.UserAgent); executor.execute(() -> logDao.save(url, ua, referer, fip, new Date())); sendOutput(url, result.getValue(), request, response); } } catch (Exception e) { e.printStackTrace(); send404(response); } } private void send403(Response response) { response.setStatus(HttpStatus.FORBIDDEN_403); response.setContentType("image/png"); try (InputStream is = this.getClass().getResourceAsStream("/403.png"); OutputStream os = response.getOutputStream();) { byte[] b = new byte[1024]; while (is.read(b) >= 0) { os.write(b); } } catch (IOException e) { logger.error(e); } } }