All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.wl4g.infra.common.web.WebUtils Maven / Gradle / Ivy

There is a newer version: 3.1.72
Show newest version
/*
 * Copyright 2017 ~ 2025 the original author or authors. James Wong 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.wl4g.infra.common.web;

import static com.wl4g.infra.common.lang.Assert2.notNull;
import static com.wl4g.infra.common.lang.Assert2.notNullOf;
import static com.wl4g.infra.common.lang.StringUtils2.isDomain;
import static java.lang.String.format;
import static java.lang.System.getenv;
import static java.util.Locale.US;
import static java.util.Objects.isNull;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.apache.commons.lang3.StringUtils.contains;
import static org.apache.commons.lang3.StringUtils.containsAny;
import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
import static org.apache.commons.lang3.StringUtils.isAnyBlank;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.apache.commons.lang3.StringUtils.join;
import static org.apache.commons.lang3.StringUtils.replaceIgnoreCase;
import static org.apache.commons.lang3.StringUtils.split;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Principal;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;

import org.apache.commons.lang3.StringUtils;

import com.google.common.annotations.Beta;
import com.wl4g.infra.common.collection.CollectionUtils2;
import com.wl4g.infra.common.lang.Assert2;
import com.wl4g.infra.common.lang.StringUtils2;

/**
 * {@link WebUtils}
 * 
 * @author James Wong <[email protected]>
 * @version 2022-04-01 v3.0.0
 * @since v3.0.0
 */
public abstract class WebUtils {

    /**
     * URL encode by UTF-8
     * 
     * @param url
     *            plain URL
     * @return
     */
    public static String safeEncodeURL(String url) {
        try {
            if (!contains(trimToEmpty(url).toLowerCase(US), URL_SEPAR_SLASH)) {
                return URLEncoder.encode(url, "UTF-8");
            }
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException(e);
        }
        return url;
    }

    /**
     * URL decode by UTF-8
     * 
     * @param url
     *            encode URL
     * @return
     */
    public static String safeDecodeURL(String url) {
        try {
            if (containsAny(trimToEmpty(url).toLowerCase(US), URL_SEPAR_SLASH, URL_SEPAR_QUEST, URL_SEPAR_COLON)) {
                return URLDecoder.decode(url, "UTF-8");
            }
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException(e);
        }
        return url;
    }

    /**
     * Extract top level domain string. 
* *
     *extDomainString("my.wl4g.com")                         =>  my.wl4g.com
     *extDomainString("//my.wl4g.com/myapp1")                =>  my.wl4g.com
     *extDomainString("/myapp1/api/v2/list")                 =>  ""
     *extDomainString("http://my.wl4g.com.cn/myapp1")        =>  my.wl4g.com.cn
     *extDomainString("https://my2.my1.wl4g.com:80/myapp1")  =>  my2.my1.wl4g.com
     * 
* * @param hostOrUri * @return */ public static String extDomainString(String hostOrUri) { if (isBlank(hostOrUri)) { return hostOrUri; } hostOrUri = safeDecodeURL(hostOrUri); String domain = hostOrUri; // Is host? if (containsAny(hostOrUri, '/')) { // Is URI? domain = URI.create(hostOrUri).getHost(); } // Check domain available? // isTrueOf(isDomain(domain), format("hostOrUri: %s", hostOrUri)); if (!isDomain(domain) || isBlank(domain)) { return EMPTY; } return domain; } /** * Extract top level domain string.
* *
     *extTopDomainString("my.wl4g.com")                         =>  wl4g.com
     *extTopDomainString("//my.wl4g.com/myapp1")                =>  wl4g.com
     *extTopDomainString("/myapp1/api/v2/list")                 =>  ""
     *extTopDomainString("http://my.wl4g.com.cn/myapp1")        =>  wl4g.com.cn
     *extTopDomainString("https://my2.my1.wl4g.com:80/myapp1")  =>  wl4g.com
     * 
* * @param hostOrUri * @return */ public static String extTopDomainString(String hostOrUri) { String domain = extDomainString(hostOrUri); if (isBlank(domain)) { // Available? return EMPTY; } String[] parts = split(domain, "."); int endIndex = 2; if (domain.endsWith("com.cn")) { // Special parse endIndex = 3; } StringBuffer topDomain = new StringBuffer(); for (int i = 0; i < parts.length; i++) { if (i >= (parts.length - endIndex)) { topDomain.append(parts[i]); if (i < (parts.length - 1)) { topDomain.append("."); } } } return topDomain.toString(); } /** * Check whether the URI is relative to the path. * * e.g.
* *
     * isRelativeUri("//my.wl4g.com/myapp1") = false 
* isRelativeUri("http://my.wl4g.com/myapp1") = false
* isRelativeUri("https://my.wl4g.com:80/myapp1") = false
* isRelativeUri("/myapp1/api/v2/list") = true
*
* * @param uri * @return */ public static boolean isRelativeUri(String uri) { if (isBlank(uri)) return false; return isBlank(URI.create(safeDecodeURL(uri)).getScheme()) && !uri.startsWith("//"); } /** * Domain names equals two URIs are equal (including secondary and tertiary * domain names, etc. Exact matching) * * e.g.
* *
     * isEqualWithDomain("http://my.wl4g.com/myapp1","http://my.wl4g.com/myapp2")=true
     * isEqualWithDomain("http://my1.domin.com/myapp1","http://my.wl4g.com/myapp2")=false
     * isEqualWithDomain("http://my.wl4g.com:80/myapp1","http://my.wl4g.com:8080/myapp2")=true
     * isEqualWithDomain("https://my.wl4g.com:80/myapp1","http://my.wl4g.com:8080/myapp2")=true
     * isEqualWithDomain("http://localhost","http://localhost:8080/myapp2")=true
     * isEqualWithDomain("http://127.0.0.1","http://127.0.0.1:8080/myapp2")=true
     * 
* * @param uria * @param urib * @return */ public static boolean isEqualWithDomain(String uria, String urib) { if (isNull(uria) || isNull(urib)) { return false; } return URI.create(safeDecodeURL(uria)).getHost().equals(URI.create(safeDecodeURL(urib)).getHost()); } /** * Check whether the wildcard domain uri belongs to the same origin.
* * e.g: * *
     * {@link #isSameWildcardOrigin}("http://*.aa.domain.com/API/v2", "http://bb.aa.domain.com/API/v2", true) == true
     * {@link #isSameWildcardOrigin}("http://*.aa.domain.com/API/v2", "https://bb.aa.domain.com/API/v2", true) == false
     * {@link #isSameWildcardOrigin}("http://*.aa.domain.com/api/v2/", "http://bb.aa.domain.com/API/v2", true) == true
     * {@link #isSameWildcardOrigin}("http://bb.*.domain.com", "https://bb.aa.domain.com", false) == true
     * {@link #isSameWildcardOrigin}("http://*.aa.domain.com", "https://bb.aa.domain.com", true) == false
     * {@link #isSameWildcardOrigin}("http://*.aa.domain.com:8080", "http://bb.aa.domain.com:8080/", true) == true
     * {@link #isSameWildcardOrigin}("http://*.aa.domain.com:8080", "http://bb.aa.domain.com:8443/v2/xx", true) == true
     * {@link #isSameWildcardOrigin}("http://*.aa.domain.com:*", "http://bb.aa.domain.com:8443/v2/xx", true) == true
     * 
* * @param defWildcardUri * Definition wildcard URI * @param requestUri * @param checkScheme * @return */ public static boolean isSameWildcardOrigin(String defWildcardUri, String requestUri, boolean checkScheme) { if (isBlank(defWildcardUri) || isBlank(requestUri)) return false; if (defWildcardUri.equals(requestUri)) // URL equaled? return true; // Scheme matched? URI uri1 = URI.create(defWildcardUri); URI uri2 = URI.create(requestUri); final boolean schemeMatched = uri1.getScheme().equalsIgnoreCase(uri2.getScheme()); if (checkScheme && !schemeMatched) return false; // Hostname equaled? String hostname1 = extractWildcardEndpoint(defWildcardUri); String hostname2 = extractWildcardEndpoint(requestUri); if (equalsIgnoreCase(hostname1, hostname2)) return true; // Hostname wildcard matched? boolean wildcardHostnameMatched = false; String[] parts1 = split(hostname1, "."); String[] parts2 = split(hostname2, "."); for (int i = 0; i < parts1.length; i++) { if (equalsIgnoreCase(parts1[i], "*")) { if (i < (hostname1.length() - 1) && i < (hostname2.length() - 1)) { String compare1 = join(parts1, ".", i + 1, parts1.length); String compare2 = join(parts2, ".", i + 1, parts2.length); if (equalsIgnoreCase(compare1, compare2)) { wildcardHostnameMatched = true; break; } } } } // Check scheme matched. if (checkScheme && wildcardHostnameMatched) { return schemeMatched; } return wildcardHostnameMatched; } /** * Extract domain text from {@link URI}.
* Uri resolution cannot be used here because it may fail when there are * wildcards, e.g, * {@link URI#create}("http://*.aa.domain.com/api/v2/).getHost() is * null.
* *
     * {@link #extractWildcardHostName}("http://*.domain.com/v2/xx") --> *.domain.com
     * {@link #extractWildcardHostName}("http://*.aa.domain.com:*") --> *.aa.domain.com
     * {@link #extractWildcardHostName}("http://*.bb.domain.com:8080/v2/xx") --> *.bb.domain.com
     * 
* * @param wildcardUri * @return */ public static String extractWildcardEndpoint(String wildcardUri) { if (isEmpty(wildcardUri)) return EMPTY; wildcardUri = trimToEmpty(safeEncodeURL(wildcardUri)).toLowerCase(US); String noPrefix = wildcardUri.substring(wildcardUri.indexOf(URL_SEPAR_PROTO) + URL_SEPAR_PROTO.length()); int slashIndex = noPrefix.indexOf(URL_SEPAR_SLASH); String serverName = noPrefix; if (slashIndex > 0) { serverName = noPrefix.substring(0, slashIndex); } // Check domain valid // e.g: // http://*.domain.com:8080 [allow] // http://*.domain.com:* [allow] // http://*.aa.*.domain.com [not allow] String hostname = serverName; if (serverName.contains(URL_SEPAR_COLON)) { hostname = serverName.substring(0, serverName.indexOf(URL_SEPAR_COLON)); } Assert2.isTrue(hostname.indexOf("*") == hostname.lastIndexOf("*"), "Illegal serverName: %s, contains multiple wildcards!", serverName); return safeDecodeURL(hostname); } /** * Determine whether the requested URL belongs to the domain. e.g:
* withInDomain("my.domain.com","http://my.domain.com/myapp") = true
* withInDomain("my.domain.com","https://my.domain.com/myapp") = true
* withInDomain("my.domain.com","https://my1.domain.com/myapp") = false *
* withInDomain("*.domain.com", "https://other1.domain.com/myapp") = true *
* * @param domain * @param url * @return */ public static boolean withInDomain(String domain, String url) { notNull(domain, "'domain' must not be null"); notNull(url, "'requestUrl' must not be null"); try { String hostname = new URI(safeDecodeURL(cleanURI(url))).getHost(); if (!domain.contains("*")) { Assert2.isTrue(isDomain(domain), String.format("Illegal domain[%s] name format", domain)); return equalsIgnoreCase(domain, hostname); } if (domain.startsWith("*")) { return equalsIgnoreCase(domain.substring(1), hostname.substring(hostname.indexOf("."))); } return false; } catch (URISyntaxException e) { throw new IllegalArgumentException(e); } } /** * Determine whether the requested URL belongs to the base URI. e.g:
* withInURL("https://domain/myapp/login","https://domain/myapp/login?t=123") * == true
* withInURL("https://domain/myapp","https://domain/myapp/login?t=123") == * true
* withInURL("https://domain/myapp/login?r=abc","https://domain/myapp/login?t=123") * == true
* withInURL("https://domain/myapp/login?r=abc","http://domain/myapp/login?t=123") * == false
*
* * @param baseUrl * @param url * @return */ public static boolean withInURL(String baseUrl, String url) { if (baseUrl == null || url == null) { return false; } try { // If it's a URL in decoding format URI baseUrl0 = new URI(safeDecodeURL(cleanURI(baseUrl))); URI uri0 = new URI(safeDecodeURL(cleanURI(url))); return (StringUtils.startsWithIgnoreCase(uri0.getRawPath(), baseUrl0.getRawPath()) && StringUtils.equalsIgnoreCase(uri0.getScheme(), baseUrl0.getScheme()) && StringUtils.equalsIgnoreCase(uri0.getHost(), baseUrl0.getHost()) && uri0.getPort() == baseUrl0.getPort()); } catch (Exception e) { // Ignore } return false; } /** * Obtain base URI for default.
* *
     * getBaseURIForDefault("http", "my.com", 8080) == "http://my.com:8080"
     * getBaseURIForDefault("http", "my.com", 80) == "http://my.com"
     * getBaseURIForDefault("https", "my.com", 443) == "https://my.com"
     * getBaseURIForDefault("https", "my.com", -1) == "https://my.com"
     * 
* * @param scheme * @param serverName * @param port * @return */ public static String getBaseURIForDefault(String scheme, String serverName, int port) { notNull(scheme, "Http request scheme must not be empty"); notNull(serverName, "Http request serverName must not be empty"); StringBuffer baseUri = new StringBuffer(scheme).append("://").append(serverName); if (port > 0) { Assert2.isTrue((port > 0 && port < 65536), "Http server port must be greater than 0 and less than 65536"); if (!((equalsIgnoreCase(scheme, "HTTP") && port == 80) || (equalsIgnoreCase(scheme, "HTTPS") && port == 443))) { baseUri.append(":").append(port); } } return baseUri.toString(); } /** * Clean request URI.
* *
     * cleanURI("https://my.domain.com//myapp///index?t=123") => "https://my.domain.com/myapp/index?t=123"
     * 
* * @param uri * @return */ @Beta public static String cleanURI(String uri) { if (isBlank(uri)) { return uri; } // Check syntax uri = URI.create(uri).toString(); /** * Cleaning.
* Note: that you cannot change the original URI case. */ try { String encodeUrl = safeEncodeURL(uri); String pathUrl = encodeUrl, schema = EMPTY; if (encodeUrl.toLowerCase(US).contains(URL_SEPAR_PROTO)) { // Start from "://" int startIndex = encodeUrl.toLowerCase(US).indexOf(URL_SEPAR_PROTO); schema = encodeUrl.substring(0, startIndex) + URL_SEPAR_PROTO; pathUrl = encodeUrl.substring(startIndex + URL_SEPAR_PROTO.length()); } // Cleanup for: '/shopping/order//list' => '/shopping/order/list' String lastCleanUrl = pathUrl; for (int i = 0; i < 256; i++) { // https://www.ietf.org/rfc/rfc2616.txt#3.2.1 String cleanUrl = replaceIgnoreCase(lastCleanUrl, (URL_SEPAR_SLASH2).toUpperCase(), URL_SEPAR_SLASH); if (StringUtils.equals(cleanUrl, lastCleanUrl)) { break; } else { lastCleanUrl = cleanUrl; } } return safeDecodeURL(schema + lastCleanUrl); } catch (Exception e) { throw new IllegalArgumentException(e); } } /** * To query URL parameters. * *
     * toQueryParams("application=iam-example&redirect_url=http://my.com/index") == {application->iam-example, redirect_url=>http://my.com/index}
     * toQueryParams("application=iam-example&redirect_url=http://my.com/index/#/me") == {application->iam-example, redirect_url=>http://my.com/index/#/me}
     * 
* * @param urlQuery * @return */ public static Map toQueryParams(@Nullable String urlQuery) { Map parameters = new LinkedHashMap<>(4); if (isBlank(urlQuery)) return parameters; try { // Remove the character to the left of the '?' int separQuestIndex = urlQuery.lastIndexOf("?"); if (separQuestIndex > 0) { urlQuery = urlQuery.substring(separQuestIndex + 1); } String[] paramPairs = urlQuery.split("&"); for (int i = 0; i < paramPairs.length; i++) { String[] parts = trimToEmpty(paramPairs[i]).split("="); if (parts.length >= 2) { parameters.put(parts[0], parts[1]); } } return parameters; } catch (Exception e) { throw new IllegalArgumentException(format("Illegal parameter format. '%s'", urlQuery), e); } } /** * Gets multi map first value. * * @param params * @return */ public static String getMultiMapFirstValue(@Nullable Map> params, String name) { if (isNull(params)) { return null; } return params.entrySet() .stream() .filter(e -> equalsIgnoreCase(e.getKey(), name)) .map(e -> CollectionUtils2.isEmpty(e.getValue()) ? e.getValue().get(0) : null) .filter(e -> !isNull(e)) .findFirst() .orElse(null); } /** * Map to query URL * * @param uri * @param queryParams * @return */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static String applyQueryURL(@Nullable String uri, @Nullable Map queryParams) { if (CollectionUtils2.isEmpty(queryParams) || isBlank(uri)) { return uri; } URI _uri = URI.create(uri); // Merge origin-older uri query parameters. Map mergeParams = new HashMap<>(toQueryParams(_uri.getQuery())); mergeParams.putAll(queryParams); // Gets base URI. StringBuffer url = new StringBuffer(uri); // Relative path? if (!isAnyBlank(_uri.getScheme(), _uri.getHost())) { url.setLength(0); // Reset url.append(getBaseURIForDefault(_uri.getScheme(), _uri.getHost(), _uri.getPort())); url.append(_uri.getPath()); } if (url.lastIndexOf("?") == -1) { url.append("?"); } // To URI parameters string for (Iterator it = mergeParams.keySet().iterator(); it.hasNext();) { Object key = it.next(); url.append(key); url.append("="); // Prevents any occurrence of a value string null Object value = mergeParams.get(key); if (value != null) { url.append(value); // "null" } if (it.hasNext()) { url.append("&"); } } return url.toString(); } /** * Is true
* * @param value * @return Return TRUE with true/t/y/yes/on/1/enabled */ public static boolean isTrue(String value) { return isTrue(value, false); } /** * Is true
* * @param value * @param defaultValue * @return Return TRUE with true/t/y/yes/on/1/enabled */ public static boolean isTrue(String value, boolean defaultValue) { return StringUtils2.isTrue(value, defaultValue); } /** * Check that the requested resource is a base media file? * * @param path * @return */ public static boolean isMediaRequest(String path) { String ext = StringUtils2.getFilenameExtension(path); for (String media : MEDIA_BASE) { if (equalsIgnoreCase(ext, media)) { return true; } } return false; } /** * Is XHR Request * * @param extractor * @return */ public static boolean isXHRRequest(@NotNull WebRequestExtractor extractor) { notNullOf(extractor, "extractor"); return equalsIgnoreCase(extractor.getHeaderValue("X-Requested-With"), "XMLHttpRequest"); } /** * Web Request extractor wrapper, It is mainly to solve the request types of * different models or protocols, such as: * Xxx{@link javax.servlet.ServletRequest} or {@link HttpServletRequest} or * {@link org.springframework.web.servlet.function.ServerRequest}(reactive) * etc * * @author James Wong * @version v1.0 2020-09-15 * @since */ public static interface WebRequestExtractor { /** * Gets request Id.
* * Spring reactor HTTP request refer to: * {@link org.springframework.web.server.ServerWebExchange.LOG_ID} * * @return */ default @Nullable String getRequestId() { return null; } /** * Gets web request URI. * * @return */ default @Nullable URI getRequestURI() { return null; } /** * Gets web request authenticated principal. * * @return */ default @Nullable Principal getPrincipal() { return null; } /** * Gets web request method. * * @return */ default String getMethod() { return null; } /** * Gets web request scheme. * * @return */ default String getScheme() { return null; } /** * Gets web request remote host. * * @return */ default String getHost() { return null; } /** * Gets web request port. * * @return */ default Integer getPort() { return null; } /** * Gets web request path. * * @return */ default String getPath() { return null; } /** * Gets request an collection of all the query parameter names this * request contains. If the request has no query parameter, this method * returns an null collection. * * @return */ default Collection getQueryNames() { return null; } /** * Gets query parameter by name. * * @param name * @return */ default @Nullable String getQueryValue(String name) { return null; } /** * Gets headers parameter by name. * * @param name * @return */ default @Nullable String getHeaderValue(String name) { return null; } /** * Returns an collection of all the header names this request contains. * If the request has no headers, this method returns an null * collection. * * @return */ default Collection getHeaderNames() { return null; } /** * Gets cookie value by name. * * @param name * @return */ default @Nullable String getCookieValue(String name) { return null; } /** * Gets cookie names. * * @return */ default @Nullable Collection getCookieNames() { return null; } } /** * URL scheme(HTTPS) */ public static final String URL_SCHEME_HTTPS = "https"; /** * URL scheme(HTTP) */ public static final String URL_SCHEME_HTTP = "http"; /** * URL separator(/) */ public static final String URL_SEPAR_SLASH = "%2f"; /** * URL double separator(//) */ public static final String URL_SEPAR_SLASH2 = URL_SEPAR_SLASH + URL_SEPAR_SLASH; /** * URL separator(?) */ public static final String URL_SEPAR_QUEST = "%3f"; /** * URL colon separator(:) */ public static final String URL_SEPAR_COLON = "%3a"; /** * Protocol separators, such as * https://my.domain.com=>https%3A%2F%2Fmy.domain.com */ public static final String URL_SEPAR_PROTO = URL_SEPAR_COLON + URL_SEPAR_SLASH + URL_SEPAR_SLASH; /** * Request the header key name of real client IP.
* *
     *  一、没有使用代理服务器的情况:
     *        REMOTE_ADDR = 您的 IP
     *        HTTP_VIA = 没数值或不显示
     *        HTTP_X_FORWARDED_FOR = 没数值或不显示
     *  二、使用透明代理服务器的情况:Transparent Proxies
     *        REMOTE_ADDR = 最后一个代理服务器 IP 
     *        HTTP_VIA = 代理服务器 IP
     *        HTTP_X_FORWARDED_FOR = 您的真实 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
     *     这类代理服务器还是将您的信息转发给您的访问对象,无法达到隐藏真实身份的目的。
     *  三、使用普通匿名代理服务器的情况:Anonymous Proxies
     *        REMOTE_ADDR = 最后一个代理服务器 IP 
     *        HTTP_VIA = 代理服务器 IP
     *        HTTP_X_FORWARDED_FOR = 代理服务器 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
     *     隐藏了您的真实IP,但是向访问对象透露了您是使用代理服务器访问他们的。
     *  四、使用欺骗性代理服务器的情况:Distorting Proxies
     *        REMOTE_ADDR = 代理服务器 IP 
     *        HTTP_VIA = 代理服务器 IP 
     *        HTTP_X_FORWARDED_FOR = 随机的 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
     *     告诉了访问对象您使用了代理服务器,但编造了一个虚假的随机IP代替您的真实IP欺骗它。
     *  五、使用高匿名代理服务器的情况:High Anonymity Proxies (Elite proxies)
     *        REMOTE_ADDR = 代理服务器 IP
     *        HTTP_VIA = 没数值或不显示
     *        HTTP_X_FORWARDED_FOR = 没数值或不显示 ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
     * 
*/ public static final String[] HEADER_REAL_IP = { "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "X-Real-IP", "REMOTE_ADDR", "Remote-Addr", "RemoteAddr", // RemoteAddr "REMOTE_IP", "Remote-Ip", "RemoteIp", // RemoteIp: Aliyun-SLB "HTTP_X_FORWARDED_FOR", "Http-X-Forwarded-For", "HttpXForwardedFor", // HttpXForwardedFor "HTTP_X_FORWARDED", "Http-X-Forwarded", "HttpXForwarded", // HttpXForwarded "HTTP_Client_IP", "Http-Client-Ip", "HttpClientIp", // HttpClientIp "HTTP_X_CLUSTER_CLIENT_IP", "Http-X-Cluster-Client-Ip", "HttpXClusterClientIp", // HttpXClusterClientIp "HTTP_FORWARDED_FOR", "Http-Forwarded-For", "HttpForwardedFor", // HttpForwardedFor "HTTP_VIA ", "Http-Via", "HttpVia" }; // HttpVia /** * Request the header key name of real protocol scheme. */ public static final String[] HEADER_REAL_PROTOCOL = { "X-Forwarded-Proto" }; /** * Request the header key name of real host */ public static final String[] HEADER_REAL_HOST = { "Host" }; /** * Common media file suffix definitions */ public static final String[] MEDIA_BASE = new String[] { "ico", "icon", "css", "js", "html", "shtml", "htm", "jsp", "jspx", "jsf", "aspx", "asp", "php", "jpeg", "jpg", "png", "bmp", "gif", "tif", "pic", "swf", "svg", "ttf", "eot", "eot@", "woff", "woff2", "wd3", "txt", "doc", "docx", "wps", "ppt", "pptx", "pdf", "excel", "xls", "xlsx", "avi", "wav", "mp3", "amr", "mp4", "aiff", "rar", "tar.gz", "tar", "zip", "gzip", "ipa", "plist", "apk", "7-zip" }; /** * Unified exception handling stack trace parameter name. */ public static final String PARAM_STACKTRACE = getenv().getOrDefault("INFRA_REQUEST_STACKTRACE_PARAM", "x-stacktrace"); public static final Predicate defaultStringAnyFilter = name -> true; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy