From 373bb21447e502eef7eff634bd2f38246a356bd7 Mon Sep 17 00:00:00 2001 From: Raul Luna Date: Mon, 27 May 2024 18:14:08 +0200 Subject: [PATCH] first version of jsp pages --- README.md | 9 +- backend/jsp/empty.jsp | 18 ++++ backend/jsp/garbage.jsp | 50 +++++++++++ backend/jsp/getIP.jsp | 102 ++++++++++++++++++++++ backend/{ => php}/empty.php | 0 backend/{ => php}/garbage.php | 0 backend/{ => php}/getIP.php | 0 backend/{ => php}/getIP_ipInfo_apikey.php | 0 backend/{ => php}/getIP_util.php | 0 9 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 backend/jsp/empty.jsp create mode 100644 backend/jsp/garbage.jsp create mode 100644 backend/jsp/getIP.jsp rename backend/{ => php}/empty.php (100%) mode change 100755 => 100644 rename backend/{ => php}/garbage.php (100%) mode change 100755 => 100644 rename backend/{ => php}/getIP.php (100%) mode change 100755 => 100644 rename backend/{ => php}/getIP_ipInfo_apikey.php (100%) mode change 100755 => 100644 rename backend/{ => php}/getIP_util.php (100%) diff --git a/README.md b/README.md index 407698895..179d45cc8 100755 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ This is a very lightweight speed test implemented in Javascript, using XMLHttpRe ## Compatibility All modern browsers are supported: IE11, latest Edge, latest Chrome, latest Firefox, latest Safari. + Works with mobile versions too. ## Features @@ -27,19 +28,23 @@ Works with mobile versions too. ## Server requirements + * A reasonably fast web server with Apache 2 (nginx, IIS also supported) -* PHP 5.4 or newer (other backends also available) +* Choose between: + * PHP 5.4 or newer (other backends also available) + * A JSP-capable Java container (Tomcat) * MySQL database to store test results (optional, Microsoft SQL Server, PostgreSQL and SQLite also supported) * A fast! internet connection ## Installation + Assuming you have PHP installed, the installation steps are quite simple. I set this up on a QNAP. For this example, I am using a folder called **speedtest** in my web share area. 1. Choose one of the example-xxx.html files in `examples` folder as your index.html if the default index.html does not fit. 2. Add: speedtest.js, speedtest_worker.js, and favicon.ico to your speedtest folder. -3. Download all of the backend folder into speedtest/backend. +3. Download all of the backend/php folder into speedtest/backend. 4. Download all of the results folder into speedtest/results. 5. Be sure your permissions allow execute (755). 6. Visit YOURSITE/speedtest/index.html and voila! diff --git a/backend/jsp/empty.jsp b/backend/jsp/empty.jsp new file mode 100644 index 000000000..ad71a20eb --- /dev/null +++ b/backend/jsp/empty.jsp @@ -0,0 +1,18 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<% + +response.setStatus(200); + +String corsParam = request.getParameter("cors"); +if (corsParam != null) { + response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Methods", "GET, POST"); + response.setHeader("Access-Control-Allow-Headers", "Content-Encoding, Content-Type"); +} + +response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, s-maxage=0"); +response.setHeader("Cache-Control", "post-check=0, pre-check=0"); +response.setHeader("Pragma", "no-cache"); +response.setHeader("Connection", "keep-alive"); +%> + diff --git a/backend/jsp/garbage.jsp b/backend/jsp/garbage.jsp new file mode 100644 index 000000000..9a89a425a --- /dev/null +++ b/backend/jsp/garbage.jsp @@ -0,0 +1,50 @@ + +<%@ page language="java" contentType="application/octet-stream" pageEncoding="UTF-8"%> +<%@ page import="java.security.SecureRandom"%> +<% + +response.setStatus(200); + +// Disable Compression +pageContext.getOut().clear(); +response.setHeader("Content-Description", "File Transfer"); +response.setHeader("Content-Disposition", "attachment; filename=random.dat"); +response.setHeader("Content-Transfer-Encoding", "binary"); + +String corsParam = request.getParameter("cors"); +if (corsParam != null) { + response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Methods", "GET, POST"); +} + +// Cache settings: never cache this request +response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, s-maxage=0"); +response.setHeader("Cache-Control", "post-check=0, pre-check=0"); +response.setHeader("Pragma", "no-cache"); + +// Determine how much data we should send +int chunks = getChunkCount( request ); + +// Generate data +SecureRandom random = new SecureRandom(); +byte[] data = new byte[1048576]; +random.nextBytes(data); + +// Deliver chunks of 1048576 bytes +for (int i = 0; i < chunks; i++) { + response.getOutputStream().write(data); + response.getOutputStream().flush(); +} + + +%> +<%! +public int getChunkCount( HttpServletRequest request ) { + String ckSizeParam = request.getParameter("ckSize"); + if (ckSizeParam == null || !ckSizeParam.matches("\\d+") || Integer.parseInt(ckSizeParam) <= 0) { + return 4; + } + int ckSize = Integer.parseInt(ckSizeParam); + return Math.min(ckSize, 1024); +} +%> \ No newline at end of file diff --git a/backend/jsp/getIP.jsp b/backend/jsp/getIP.jsp new file mode 100644 index 000000000..1395d6468 --- /dev/null +++ b/backend/jsp/getIP.jsp @@ -0,0 +1,102 @@ +<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ page import="java.net.URLConnection, + java.io.InputStreamReader, + java.io.BufferedReader, + java.net.URL, + java.net.HttpURLConnection, + java.util.regex.Pattern"%> +<% +response.setContentType("application/json; charset=utf-8"); + +String corsParam = request.getParameter("cors"); +if (corsParam != null) { + response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Methods", "GET, POST"); +} + +response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, s-maxage=0"); +response.setHeader("Cache-Control", "post-check=0, pre-check=0"); +response.setHeader("Pragma", "no-cache"); + + +// Main logic +String ip = getClientIp( request ); +String localIpInfo = getLocalOrPrivateIpInfo(ip); +if (localIpInfo != null) { + out.println( sendResponse(ip, localIpInfo, null, null) ); + return; +} +out.println( sendResponse(ip, null, null, null) ); + + +%> +<%! + +// get the client's ip +public String getClientIp(HttpServletRequest request) { + String ip = null; + if (request.getHeader("HTTP_CLIENT_IP") != null && !request.getHeader("HTTP_CLIENT_IP").isEmpty()) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } else if (request.getHeader("HTTP_X_REAL_IP") != null && !request.getHeader("HTTP_X_REAL_IP").isEmpty()) { + ip = request.getHeader("HTTP_X_REAL_IP"); + } else if (request.getHeader("HTTP_X_FORWARDED_FOR") != null && !request.getHeader("HTTP_X_FORWARDED_FOR").isEmpty()) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + ip = ip.split(",")[0]; // hosts are comma-separated, client is first + } else { + ip = request.getRemoteAddr(); + } + + if (ip.startsWith("::ffff:")) { + ip = ip.substring(7); + } + + return ip; +} + + +// Function to check if IP is private or local +String getLocalOrPrivateIpInfo(String ip) { + if ("::1".equals(ip)) { + return "localhost IPv6 access"; + } + if (ip.startsWith("fe80:")) { + return "link-local IPv6 access"; + } + if (ip.startsWith("127.")) { + return "localhost IPv4 access"; + } + if (ip.startsWith("10.") + || Pattern.matches("^172\\.(1[6-9]|2\\d|3[01])\\.", ip) + || ip.startsWith("192.168.") + || ip.startsWith("169.254.")) { + return "private IPv4 access"; + } + return null; +} + + +// Function to send response +String sendResponse(String ip, + String ipInfo, + String rawIspInfo, + String distance) { + StringBuilder processedString = new StringBuilder(ip); + if (ipInfo != null && !ipInfo.isEmpty()) { + processedString.append(" - ").append(ipInfo); + } + if (rawIspInfo != null && !rawIspInfo.isEmpty()) { + String country = rawIspInfo.substring(rawIspInfo.indexOf("\"country\":") + 11, rawIspInfo.indexOf("\",", rawIspInfo.indexOf("\"country\":"))).trim(); + processedString.append(", ").append(country); + } + if (distance != null && !distance.isEmpty()) { + processedString.append(" (").append(distance).append(")"); + } + return "{\"processedString\": \"" + processedString.toString() + "\", \"rawIspInfo\": " + rawIspInfo + "}"; +} + + + + + + +%> diff --git a/backend/empty.php b/backend/php/empty.php old mode 100755 new mode 100644 similarity index 100% rename from backend/empty.php rename to backend/php/empty.php diff --git a/backend/garbage.php b/backend/php/garbage.php old mode 100755 new mode 100644 similarity index 100% rename from backend/garbage.php rename to backend/php/garbage.php diff --git a/backend/getIP.php b/backend/php/getIP.php old mode 100755 new mode 100644 similarity index 100% rename from backend/getIP.php rename to backend/php/getIP.php diff --git a/backend/getIP_ipInfo_apikey.php b/backend/php/getIP_ipInfo_apikey.php old mode 100755 new mode 100644 similarity index 100% rename from backend/getIP_ipInfo_apikey.php rename to backend/php/getIP_ipInfo_apikey.php diff --git a/backend/getIP_util.php b/backend/php/getIP_util.php similarity index 100% rename from backend/getIP_util.php rename to backend/php/getIP_util.php