Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.glassfish.webservices.monitoring.WebServiceTesterServlet Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2014 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright 2018-2022 Payara Foundation and/or its affiliates
/*
* WebServiceTesterServlet.java
*
* Created on August 6, 2004, 9:14 AM
*/
package org.glassfish.webservices.monitoring;
import com.sun.enterprise.deployment.WebServiceEndpoint;
import com.sun.enterprise.util.LocalStringManagerImpl;
import com.sun.tools.ws.spi.WSToolsObjectFactory;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.xml.ws.Service;
import jakarta.xml.ws.WebEndpoint;
import org.glassfish.jaxb.runtime.api.JAXBRIContext;
import org.glassfish.webservices.LogUtils;
import javax.xml.namespace.QName;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This servlet is responsible for testing web-services.
*
* @author Jerome Dochez
*/
public class WebServiceTesterServlet extends HttpServlet {
private static final Logger logger = LogUtils.getLogger();
private static final long serialVersionUID = -5744091836362541633L;
private final WebServiceEndpoint svcEP;
private static final Hashtable gsiClasses = new Hashtable();
private static final Hashtable ports = new Hashtable();
// resources...
private static final LocalStringManagerImpl localStrings = new LocalStringManagerImpl(WebServiceTesterServlet.class);
public static void invoke(HttpServletRequest request, HttpServletResponse response, WebServiceEndpoint endpoint) {
try {
WebServiceTesterServlet servlet = new WebServiceTesterServlet(endpoint);
response.setCharacterEncoding("UTF-8");
// Validate Host Header to help prevent Host Header Attacks
if (!servlet.isValidHostHeader(request)) {
throw new ServletException("Host Header does not appear to be valid - it does not appear to be a " +
"valid IPv6 literal, IPv4 dotted-decimal, or DNS name.");
}
if (request.getMethod().equalsIgnoreCase("GET")) {
servlet.doGet(request, response);
} else {
servlet.doPost(request, response);
}
} catch (Exception e) {
try (PrintWriter out = response.getWriter()){
out.print("" + localStrings
.getLocalString("enterprise.webservice.monitoring.methodInvocationException", "Method invocation exception")
+ " ");
out.print("" + localStrings.getLocalString("enterprise.webservice.monitoring.ExceptionDetails",
"Exceptions details : {0}", new Object[] { e.getMessage() }) + " ");
out.print(" ");
e.printStackTrace(out);
out.print(" ");
out.print("");
} catch (Exception ex) {
}
}
}
/**
* Creates a new instance of WebServiceTesterServlet
*
* @param ep endpoint to monitor
*/
public WebServiceTesterServlet(WebServiceEndpoint ep) {
svcEP = ep;
}
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
res.setContentType("text/html");
res.setHeader("pragma", "no-cache");
PrintWriter out = res.getWriter();
String requestURL = req.getRequestURL().toString();
Endpoint myEndpoint;
if (svcEP.implementedByWebComponent()) {
myEndpoint = WebServiceEngineImpl.getInstance().getEndpoint(req.getServletPath());
} else {
myEndpoint = WebServiceEngineImpl.getInstance().getEndpoint(req.getRequestURI());
}
String seiClassName = myEndpoint.getDescriptor().getServiceEndpointInterface();
ClassLoader testerCL = svcEP.getWebService().getBundleDescriptor().getClassLoader();
if (testerCL != null) {
Thread.currentThread().setContextClassLoader(testerCL);
}
// For now support Tester servlet for JAXWS based services only
try {
Class seiClass = Thread.currentThread().getContextClassLoader().loadClass(seiClassName);
if (seiClass.getAnnotation(jakarta.jws.WebService.class) == null) {
testerNotSupportedError(myEndpoint.getDescriptor().getServiceName(), out);
return;
}
} catch (ClassNotFoundException clnfEx) {
classNotAccessibleError(Thread.currentThread().getContextClassLoader(), seiClassName, out);
return;
}
initializePort(req, res);
Class clientSEI = gsiClasses.get(requestURL);
out.print(""
+ myEndpoint.getDescriptor().getServiceName().getLocalPart() + " "
+ localStrings.getLocalString("enterprise.webservice.monitoring.title", "Web Service Tester") + " ");
out.print("" + myEndpoint.getDescriptor().getServiceName().getLocalPart() + " "
+ localStrings.getLocalString("enterprise.webservice.monitoring.title", "Web Service Tester") + " ");
// Microsoft Internet Explorer does not handle properly
boolean isInternetExplorer = false;
String userAgent = req.getHeader("user-agent");
if (userAgent != null) {
isInternetExplorer = userAgent.indexOf("MSIE") != -1;
}
StringBuilder sb = new StringBuilder(URLDecoder.decode(requestURL));
sb.append("?WSDL");
out.print(" ");
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.line1",
"This form will allow you to test your web service implementation (WSDL File )",
sb.toString(), myEndpoint.getDescriptor().getServiceName().getLocalPart()));
out.print(" ");
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.line2",
"To invoke an operation, fill the method parameter(s) input boxes and click on the button labeled with the method name."));
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.methods", "Methods : "));
Method[] methods = clientSEI.getMethods();
for (Method m : methods) {
out.print("");
}
out.close();
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
res.setContentType("text/html");
res.setHeader("pragma", "no-cache");
PrintWriter out = res.getWriter();
String requestURL = req.getRequestURL().toString();
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.postTitle",
"Method invocation trace ", Locale.getDefault().getLanguage()));
String operationName = req.getParameter("action");
try {
Endpoint myEndpoint;
if (svcEP.implementedByWebComponent()) {
myEndpoint = WebServiceEngineImpl.getInstance().getEndpoint(req.getServletPath());
} else {
myEndpoint = WebServiceEngineImpl.getInstance().getEndpoint(req.getRequestURI());
}
Class clientSEI = gsiClasses.get(requestURL);
if (clientSEI == null) {
initializePort(req, res);
clientSEI = gsiClasses.get(requestURL);
}
Object port = ports.get(requestURL);
// find the right method...
Method[] methods = clientSEI.getMethods();
Method toInvoke = null;
for (Method m : methods) {
if (String.valueOf(m.getName()).equals(operationName)) {
toInvoke = m;
}
}
if (toInvoke == null) {
out.print("cannot \"action\" request parameter method");
} else {
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.methodInvocation",
" {0} Method invocation ", new Object[] { toInvoke.getName() }));
// register ourselves to receive the SOAP messages...
MessageListenerImpl listener = new MessageListenerImpl();
myEndpoint.addListener(listener);
Class[] parameterTypes = toInvoke.getParameterTypes();
Object[] parameterValues = new Object[parameterTypes.length];
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.methodTrace", "Method parameter(s) "));
out.print("");
out.print("");
out.print("Type ");
out.print("Value ");
out.print(" ");
for (int i = 0; i < parameterTypes.length; i++) {
out.print("");
String webValue = req.getParameter("PARAM" + toInvoke.getName() + i);
out.print("" + parameterTypes[i].getName() + " ");
out.print("" + encodeHTML(webValue) + " ");
parameterValues[i] = convertWebParam(parameterTypes[i], webValue);
out.print(" ");
}
out.print("
");
out.print(" ");
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.methodReturn", "Method returned ")
+ toInvoke.getReturnType().getName() + " : \"" + encodeHTML(toInvoke.invoke(port, parameterValues).toString())
+ " \"");
out.print(" ");
if (listener.getRequest() != null) {
// let's print the SOAP request
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.soapReq", "SOAP Request "));
dumpMessage(listener.getRequest(), out);
}
if (toInvoke.getAnnotation(jakarta.jws.Oneway.class) == null && listener.getRespose() != null) {
// let's print the SOAP request
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.soapResp", "SOAP Response "));
dumpMessage(listener.getRespose(), out);
}
myEndpoint.removeListener(listener);
}
} catch (Throwable e) {
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.serviceExceptionError",
"Service invocation threw an exception with message : {0}; Refer to the server log for more details ",
new Object[] { e.getMessage() }));
throw new ServletException(e);
}
out.print("");
out.close();
}
private void dumpMessage(MessageTrace message, PrintWriter out) throws Exception {
/*
* String xsl = ""+
* ""+
* "" + "" +
* "<>" + " " + " " +
* " ";
*/
// now transform it...
ByteArrayInputStream bais = new ByteArrayInputStream(message.getMessage(true).getBytes());
StreamSource ss = new StreamSource(bais);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
StreamResult sr = new StreamResult(baos);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.transform(ss, sr);
out.print("");
out.write(encodeHTML(baos.toString()));
out.print(" ");
}
private Object convertWebParam(Class targetParamType, String webValue) {
Object convertedValue = null;
if (webValue == null || webValue.length() == 0) {
return null;
}
if (String.class.equals(targetParamType)) {
convertedValue = webValue;
} else {
try {
if (int.class.equals(targetParamType) || Integer.class.equals(targetParamType)) {
convertedValue = Integer.valueOf(webValue);
}
if (boolean.class.equals(targetParamType) || Boolean.class.equals(targetParamType)) {
convertedValue = Boolean.valueOf(webValue);
}
if (char.class.equals(targetParamType) || (Character.class.equals(targetParamType))) {
convertedValue = webValue.charAt(0);
}
if (long.class.equals(targetParamType) || (Long.class.equals(targetParamType))) {
convertedValue = Long.valueOf(webValue);
}
if (float.class.equals(targetParamType) || (Float.class.equals(targetParamType))) {
convertedValue = Float.valueOf(webValue);
}
if (double.class.equals(targetParamType) || (Double.class.equals(targetParamType))) {
convertedValue = Double.valueOf(webValue);
}
if (byte.class.equals(targetParamType) || (Byte.class.equals(targetParamType))) {
convertedValue = Byte.valueOf(webValue);
}
if (short.class.equals(targetParamType) || (Short.class.equals(targetParamType))) {
convertedValue = new Short(webValue);
}
if (StringBuilder.class.equals(targetParamType)) {
convertedValue = new StringBuilder(webValue);
}
if (StringBuffer.class.equals(targetParamType)) {
convertedValue = new StringBuffer(webValue);
}
} catch (NumberFormatException nfe) {
System.out.println("Cannot convert " + webValue + " in " + targetParamType);
}
}
return convertedValue;
}
private void classNotAccessibleError(ClassLoader cl, String className, PrintWriter out) {
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.CNFTitle",
"Method invocation exception ", Locale.getDefault().getLanguage()));
if (cl == null) {
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.CNFServerError",
"Internal server error, debugging is not available "));
} else {
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.CNFerror2",
"Cannot load class {0} - Verify class presence in bundle ", new Object[] { className }));
}
out.print(" ");
out.print("");
out.close();
}
private void testerNotSupportedError(QName svcName, PrintWriter out) {
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.TesterNSTitle",
"Tester feature not supported ", Locale.getDefault().getLanguage()));
out.print("");
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.TesterNSerror2",
"Service {0} looks like a JAXRPC based webservice.", new Object[] { svcName }));
out.print(" ");
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.TesterNSdetail",
"Please note that the tester feature is supported for JAXWS based webservices only"));
out.print("");
out.print("");
out.close();
}
private void wsImportError(URL wsdlUrl, PrintWriter out) {
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.WsImportError",
"WsImport error for the the following wsdl ", Locale.getDefault().getLanguage()));
out.print("");
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.WsImportError2",
"Error generating artifacts for the following WSDL {0}", new Object[] { wsdlUrl }));
out.print(" ");
out.print(localStrings.getLocalString("enterprise.webservice.monitoring.WsImportError3",
"Possible causes can be" + "invoking https when the application is not configured for security", new Object[] { wsdlUrl }));
out.print("");
out.print("");
out.close();
}
private void initializePort(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
String requestURL = req.getRequestURL().toString();
Endpoint myEndpoint;
if (svcEP.implementedByWebComponent()) {
myEndpoint = WebServiceEngineImpl.getInstance().getEndpoint(req.getServletPath());
} else {
myEndpoint = WebServiceEngineImpl.getInstance().getEndpoint(req.getRequestURI());
}
// get our service qname
QName serviceName = new QName(myEndpoint.getDescriptor().getWsdlPort().getNamespaceURI(),
myEndpoint.getDescriptor().getWebService().getName());
// construct the WSDL http url
StringBuilder sb = new StringBuilder(URLDecoder.decode(requestURL));
sb.append("?WSDL");
URL[] urls = new URL[1];
String classesDir;
try {
URL wsdlUrl = new URL(sb.toString());
// create client artifacts
classesDir = wsImport(wsdlUrl);
if (classesDir == null) {
wsImportError(wsdlUrl, res.getWriter());
return;
}
urls[0] = (new File(classesDir)).toURL();
} catch (MalformedURLException mue) {
throw new ServletException(mue);
}
// we need a class loader to load the just created client artifacts. Save the current classloader
ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
// we now create a new classloader using the parent class loader
// which should be the shared application classloader. I don't want
// the application class loader to not get into client/server
// classes clashes.
// the immediate classloader is the WebApp classloader, its parent is the
// application classloader, we want the parent of that one
try (URLClassLoader testerCL = new URLClassLoader(urls, currentLoader.getParent())) {
Thread.currentThread().setContextClassLoader(testerCL);
String serviceClassName = getServiceClass(JAXBRIContext.mangleNameToClassName(serviceName.getLocalPart()), classesDir);
if (serviceClassName == null) {
throw new RuntimeException("Service Class not generated as expected");
}
Class serviceClass = testerCL.loadClass(serviceClassName);
Service service = Service.create(new URL(sb.toString()), serviceName);
if (service == null) {
throw new RuntimeException("Cannot load Service");
}
// find the right port... for this look at the @WebService annotation in SEI and get the portName
String portClassName = getPortClass(myEndpoint, serviceClass);
if (portClassName == null) {
throw new RuntimeException("Cannot find the correct port class.");
}
Class portClass = testerCL.loadClass(portClassName);
Object port = service.getPort(myEndpoint.getDescriptor().getWsdlPort(), portClass);
if (port == null) {
throw new RuntimeException("Cannot find the correct port class.");
}
ports.put(requestURL, port);
gsiClasses.put(requestURL, portClass);
} catch (Exception e) {
throw new ServletException(e);
} finally {
// restore the class loader
Thread.currentThread().setContextClassLoader(currentLoader);
// delete client artifacts, everything should be loaded or it failed
deleteDir(new File(classesDir));
}
}
private String wsImport(URL wsdlLocation) throws IOException {
File classesDir = new File(System.getProperty("java.io.tmpdir"));
// create a dumy file to have a unique temporary name for a directory
classesDir = File.createTempFile("jax-ws", "tester", classesDir);
if (!classesDir.delete()) {
logger.log(Level.WARNING, LogUtils.DELETE_DIR_FAILED, classesDir);
}
if (!classesDir.mkdirs()) {
logger.log(Level.SEVERE, LogUtils.CREATE_DIR_FAILED, classesDir);
}
String[] wsimportArgs = new String[14];
wsimportArgs[0] = "-d";
wsimportArgs[1] = classesDir.getAbsolutePath();
wsimportArgs[2] = "-keep";
wsimportArgs[3] = wsdlLocation.toExternalForm();
wsimportArgs[4] = "-Xendorsed";
wsimportArgs[5] = "-target";
wsimportArgs[6] = "2.1";
wsimportArgs[7] = "-extension";
String modulesDir = System.getProperty("com.sun.aas.installRoot") + File.separator + "modules" + File.separator;
wsimportArgs[8] = modulesDir + "jakarta.jws-api.jar";
wsimportArgs[10] = modulesDir + "webservices-osgi.jar";
wsimportArgs[11] = modulesDir + "jaxb-osgi.jar";
wsimportArgs[12] = modulesDir + "jakarta.xml.ws-api.jar";
wsimportArgs[13] = modulesDir + "jakarta.activation-api.jar";
WSToolsObjectFactory tools = WSToolsObjectFactory.newInstance();
logger.log(Level.INFO, LogUtils.WSIMPORT_INVOKE, wsdlLocation);
boolean success = tools.wsimport(System.out, wsimportArgs);
if (success) {
logger.log(Level.INFO, LogUtils.WSIMPORT_OK);
} else {
logger.log(Level.SEVERE, LogUtils.WSIMPORT_FAILED);
return null;
}
return classesDir.getAbsolutePath();
}
private String getServiceClass(String serviceClassName, String classesDirPath) {
// wsimport generated Service Class always is serviceQName.getLocalPart()+".class"
// So just look for this class and return that class
File classesDir = new File(classesDirPath);
if (!classesDir.exists()) {
return null;
}
List mycoll = getListOfFiles(classesDir);
File[] classes = mycoll.toArray(new File[mycoll.size()]);
String resolvedServiceClass = null;
String svcClass = null;
for (File f : classes) {
if (f.getName().endsWith(serviceClassName + "_Service.class")) {
resolvedServiceClass = f.getAbsolutePath().substring(classesDirPath.length() + 1);
} else {
if (f.getName().endsWith(serviceClassName + ".class")) {
svcClass = f.getAbsolutePath().substring(classesDirPath.length() + 1);
}
}
}
// Incase there is a clash JAXWS resolves the serviceClass
// to serviceName_Service.class Use the first if it is present
// Fix for issue 3403
if (resolvedServiceClass != null) {
svcClass = resolvedServiceClass;
}
if (svcClass != null) {
svcClass = svcClass.substring(0, svcClass.indexOf(".class"));
return svcClass.replace(File.separator, ".");
} else {
return null;
}
}
private String getPortClass(Endpoint ep, Class serviceClass) throws Exception {
for (Method m : serviceClass.getMethods()) {
WebEndpoint webEP = m.getAnnotation(WebEndpoint.class);
if (webEP == null || webEP.name() == null || webEP.name().length() == 0) {
continue;
}
String getPortMethodName = "get" + JAXBRIContext.mangleNameToClassName(webEP.name());
Method getPortMethod = serviceClass.getMethod(getPortMethodName, (Class[]) null);
return getPortMethod.getReturnType().getName();
}
return null;
}
private List getListOfFiles(File path) {
File[] files = path.listFiles();
List result = new ArrayList<>();
if (files != null) {
for (File f : files) {
if (f.isDirectory()) {
result.addAll(getListOfFiles(f));
} else {
result.add(f);
}
}
}
return result;
}
private void deleteDir(File path) {
if (path.exists() && path.isFile()) {
File[] files = path.listFiles();
if (files != null) {
for (File f : files) {
if (f.isDirectory()) {
deleteDir(f);
}
assert f.delete();
}
}
assert path.delete();
}
}
private String encodeHTML(String html) {
return html.replaceAll("<", "<").replaceAll(">", ">");
}
/**
* Method to test that the Host Header is valid and doesn't have any illegal characters, to help prevent Host Header
* Attacks.
*
* @param request The {@link HttpServletRequest} from the
* {@link WebServiceTesterServlet#invoke(HttpServletRequest, HttpServletResponse, WebServiceEndpoint)} method
* @return True if the Host Header is valid, false if it isn't
*/
private boolean isValidHostHeader(HttpServletRequest request) {
// Get the Host Header
String serverName = request.getServerName();
// Decode the Host Header
String decodedServerName = null;
try {
decodedServerName = URLDecoder.decode(serverName, "UTF-8");
} catch (UnsupportedEncodingException unsupportedEncodingException) {
logger.log(Level.WARNING, "Could not decode URL during validation, assuming Host Header is invalid.",
unsupportedEncodingException);
return false;
}
// Shouldn't Happen™, but just in case
if (decodedServerName == null) {
logger.log(Level.WARNING, "Host Header decoded to null during validation, assuming Host Header is invalid.");
return false;
}
// Check IPv6 literal: []
if (decodedServerName.startsWith("[") && decodedServerName.endsWith("]")) {
return true;
}
// Check IPv4 dotted-decimal: xxx.xxx.xxx.xxx
if (checkValidIpv4DottedDecimal(decodedServerName)) {
return true;
}
// Check DNS name is valid - ASCII alphanumerics and "-" only, no segment longer than 63 characters,
// sections separated with ".", possibly ending with "."
if (checkValidDnsName(decodedServerName)) {
return true;
}
// No match implies invalid host header / server name
return false;
}
// Split off for unit testing
protected static boolean checkValidIpv4DottedDecimal(String decodedServerName) {
return decodedServerName.matches(
"^((0|1\\d?\\d?|2[0-4]?\\d?|25[0-5]?|[3-9]\\d?)\\.){3}(0|1\\d?\\d?|2[0-4]?\\d?|25[0-5]?|[3-9]\\d?)$");
}
// Split off for unit testing
protected static boolean checkValidDnsName(String decodedServerName) {
// NOTE: HttpServletRequest.getServerName strips the port so no need to check
return decodedServerName.matches("((?!-)[\\w-]{1,63}(?