com.fizzgate.util.WebUtils Maven / Gradle / Ivy
/*
* Copyright (C) 2020 the original author or authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package com.fizzgate.util;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.server.ServerWebExchange;
import com.fizzgate.config.SystemConfig;
import com.fizzgate.filter.FilterResult;
import com.fizzgate.plugin.auth.ApiConfig;
import com.fizzgate.plugin.auth.AuthPluginFilter;
import com.fizzgate.proxy.Route;
import com.fizzgate.util.Consts;
import com.fizzgate.util.JacksonUtils;
import com.fizzgate.util.NettyDataBufferUtils;
import com.fizzgate.util.Result;
import com.fizzgate.util.ThreadContext;
import com.fizzgate.util.Utils;
import reactor.core.publisher.Mono;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author hongqiaowei
*/
public abstract class WebUtils {
// TODO: don't log in this class
private static final Logger log = LoggerFactory.getLogger(WebUtils.class);
private static final String clientService = "cs@";
private static final String xForwardedFor = "X-Forwarded-For";
private static final String unknown = "unknown";
private static final String loopBack = "127.0.0.1";
private static final String binaryAddress = "0:0:0:0:0:0:0:1";
private static final String directResponse = "dr@";
private static final String response = " response ";
private static final String originIp = "oi@";
private static final String clientRequestPath = "crp@";
private static final String clientRequestPathPrefix = "crpp@";
private static final String clientRequestQuery = "crq@";
private static String gatewayPrefix = SystemConfig.DEFAULT_GATEWAY_PREFIX;
private static List appHeaders = Stream.of(SystemConfig.FIZZ_APP_ID) .collect(Collectors.toList());
private static List signHeaders = Stream.of(SystemConfig.FIZZ_SIGN) .collect(Collectors.toList());
private static List timestampHeaders = Stream.of(SystemConfig.FIZZ_TIMESTAMP).collect(Collectors.toList());
public static final String TRACE_ID = "traid@";
public static final String BACKEND_SERVICE = "bs@";
public static final String FILTER_CONTEXT = "fc@";
public static final String APPEND_HEADERS = "ahs@";
public static final String PREV_FILTER_RESULT = "pfr@";
public static final String BACKEND_PATH = "bp@";
public static final String ROUTE = "rout@";
public static boolean LOG_RESPONSE_BODY = false;
public static Set LOG_HEADER_SET = Collections.emptySet();
public static final String ADMIN_REQUEST = "ar@";
public static final String FIZZ_REQUEST = "fr@";
public static final String FAV_REQUEST = "fa@";
public static final String BODY_ENCRYPT = "b-ecyt";
public static final String ORIGINAL_ERROR = "origerr@";
public static final String IGNORE_PLUGIN = "ignPlg@";
private WebUtils() {
}
public static boolean ignorePlugin(ServerWebExchange exchange) {
return exchange.getAttributes().containsKey(IGNORE_PLUGIN);
}
public static boolean isFavReq(ServerWebExchange exchange) {
return exchange.getAttribute(FAV_REQUEST) != null;
}
public static boolean isAdminReq(ServerWebExchange exchange) {
return exchange.getAttribute(ADMIN_REQUEST) != null;
}
public static boolean isFizzReq(ServerWebExchange exchange) {
return exchange.getAttribute(FIZZ_REQUEST) != null;
}
public static void setGatewayPrefix(String p) {
gatewayPrefix = p;
}
public static void setAppHeaders(List hdrs) {
appHeaders = hdrs;
}
public static void setSignHeaders(List hdrs) {
signHeaders = hdrs;
}
public static void setTimestampHeaders(List hdrs) {
timestampHeaders = hdrs;
}
public static String getHeaderValue(ServerWebExchange exchange, String header) {
return exchange.getRequest().getHeaders().getFirst(header);
}
public static List getHeaderValues(ServerWebExchange exchange, String header) {
return exchange.getRequest().getHeaders().get(header);
}
public static boolean isDedicatedLineRequest(ServerWebExchange exchange) {
String v = exchange.getRequest().getHeaders().getFirst(SystemConfig.FIZZ_DL_ID);
return v != null;
}
public static String getAppId(ServerWebExchange exchange) {
HttpHeaders headers = exchange.getRequest().getHeaders();
for (int i = 0; i < appHeaders.size(); i++) {
String v = headers.getFirst(appHeaders.get(i));
if (v != null) {
return v;
}
}
return null;
}
public static String getTimestamp(ServerWebExchange exchange) {
HttpHeaders headers = exchange.getRequest().getHeaders();
for (int i = 0; i < timestampHeaders.size(); i++) {
String v = headers.getFirst(timestampHeaders.get(i));
if (v != null) {
return v;
}
}
return null;
}
public static String getSign(ServerWebExchange exchange) {
HttpHeaders headers = exchange.getRequest().getHeaders();
for (int i = 0; i < signHeaders.size(); i++) {
String v = headers.getFirst(signHeaders.get(i));
if (v != null) {
return v;
}
}
return null;
}
public static String getDedicatedLineId(ServerWebExchange exchange) {
return getHeaderValue(exchange, SystemConfig.FIZZ_DL_ID);
}
public static String getDedicatedLineTimestamp(ServerWebExchange exchange) {
return getHeaderValue(exchange, SystemConfig.FIZZ_DL_TS);
}
public static String getDedicatedLineSign(ServerWebExchange exchange) {
return getHeaderValue(exchange, SystemConfig.FIZZ_DL_SIGN);
}
public static String getClientService(ServerWebExchange exchange) {
String svc = exchange.getAttribute(clientService);
if (svc == null) {
String p = exchange.getRequest().getPath().value();
int secFS = p.indexOf(Consts.S.FORWARD_SLASH, 1);
if (secFS == -1) {
if (StringUtils.isBlank(gatewayPrefix) || Consts.S.FORWARD_SLASH_STR.equals(gatewayPrefix)) {
svc = p.substring(1);
} else {
String prefix = p.substring(1);
if (gatewayPrefix.equals(prefix) || SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
throw Utils.runtimeExceptionWithoutStack("no service in request path");
} else {
throw Utils.runtimeExceptionWithoutStack("request prefix is wrong and no service in request path");
}
}
} else {
String prefix = p.substring(0, secFS);
if (StringUtils.isBlank(gatewayPrefix) || Consts.S.FORWARD_SLASH_STR.equals(gatewayPrefix)) {
if (SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
int trdFS = p.indexOf(Consts.S.FORWARD_SLASH, secFS + 1);
if (trdFS == -1) {
svc = p.substring(secFS + 1);
} else {
svc = p.substring(secFS + 1, trdFS);
}
} else {
svc = p.substring(1, secFS);
}
} else {
if (gatewayPrefix.equals(prefix) || SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
int trdFS = p.indexOf(Consts.S.FORWARD_SLASH, secFS + 1);
if (trdFS == -1) {
trdFS = p.length();
}
svc = p.substring(secFS + 1, trdFS);
} else {
throw Utils.runtimeExceptionWithoutStack("wrong prefix " + prefix);
}
}
}
exchange.getAttributes().put(clientService, svc);
}
return svc;
}
public static void setBackendService(ServerWebExchange exchange, String service) {
exchange.getAttributes().put(BACKEND_SERVICE, service);
}
public static String getBackendService(ServerWebExchange exchange) {
return exchange.getAttribute(BACKEND_SERVICE);
}
public static byte getApiConfigType(ServerWebExchange exchange) {
ApiConfig ac = getApiConfig(exchange);
if (ac == null) {
return ApiConfig.Type.UNDEFINED;
} else {
return ac.type;
}
}
public static ApiConfig getApiConfig(ServerWebExchange exchange) {
Result authRes = (Result) getFilterResultDataItem(exchange, AuthPluginFilter.AUTH_PLUGIN_FILTER, AuthPluginFilter.RESULT);
if (authRes == null) {
return null;
}
return authRes.data;
}
public static Route getRoute(ServerWebExchange exchange) {
return exchange.getAttribute(ROUTE);
}
public static Mono response(ServerWebExchange exchange, HttpStatus status, HttpHeaders headers, String body) {
return response(exchange.getResponse(), status, headers, body);
}
public static Mono response(ServerHttpResponse clientResp, HttpStatus status, HttpHeaders headers, DataBuffer body) {
if (clientResp.isCommitted()) {
String s = body.toString(StandardCharsets.UTF_8);
String msg = "try to response: " + s + ", but server http response is committed and it's status: " + clientResp.getStatusCode();
log.warn(msg);
return Mono.error(Utils.runtimeExceptionWithoutStack(msg));
}
if (status != null) {
clientResp.setStatusCode(status);
}
if (headers != null) {
headers.forEach( (h, vs) -> {clientResp.getHeaders().addAll(h, vs);} );
}
if (body == null) {
body = NettyDataBufferUtils.EMPTY_DATA_BUFFER;
}
return clientResp.writeWith(Mono.just(body));
}
public static Mono response(ServerHttpResponse clientResp, HttpStatus status, HttpHeaders headers, ByteBuffer body) {
DataBuffer dataBuffer = null;
if (body != null) {
dataBuffer = clientResp.bufferFactory().wrap(body);
}
return response(clientResp, status, headers, dataBuffer);
}
public static Mono response(ServerHttpResponse clientResp, HttpStatus status, HttpHeaders headers, byte[] body) {
DataBuffer dataBuffer = null;
if (body != null) {
dataBuffer = clientResp.bufferFactory().wrap(body);
}
return response(clientResp, status, headers, dataBuffer);
}
public static Mono response(ServerHttpResponse clientResp, HttpStatus status, HttpHeaders headers, String body) {
DataBuffer dataBuffer = null;
if (body != null) {
dataBuffer = clientResp.bufferFactory().wrap(body.getBytes(StandardCharsets.UTF_8));
}
return response(clientResp, status, headers, dataBuffer);
}
public static Mono responseJson(ServerWebExchange exchange, HttpStatus status, HttpHeaders headers, Object body) {
if (headers == null) {
headers = new HttpHeaders();
}
headers.setContentType(MediaType.APPLICATION_JSON);
byte[] bytes = null;
if (body != null) {
bytes = JacksonUtils.writeValueAsBytes(body);
}
return response(exchange.getResponse(), status, headers, bytes);
}
public static Mono responseJson(ServerWebExchange exchange, HttpStatus status, HttpHeaders headers, String json) {
if (headers == null) {
headers = new HttpHeaders();
}
headers.setContentType(MediaType.APPLICATION_JSON);
return response(exchange, status, headers, json);
}
private static void bind(ServerWebExchange exchange, String filter, FilterResult fr) {
Map fc = getFilterContext(exchange);
fc.put(filter, fr);
fc.put(PREV_FILTER_RESULT, fr);
}
public static String getClientReqPath(ServerWebExchange exchange) {
String p = exchange.getAttribute(clientRequestPath);
if (p == null) {
// p = exchange.getRequest().getPath().value();
p = exchange.getRequest().getURI().getPath();
int secFS = p.indexOf(Consts.S.FORWARD_SLASH, 1);
if (secFS == -1) {
if (StringUtils.isBlank(gatewayPrefix) || Consts.S.FORWARD_SLASH_STR.equals(gatewayPrefix)) {
p = Consts.S.FORWARD_SLASH_STR;
} else {
String prefix = p.substring(1);
if (gatewayPrefix.equals(prefix) || SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
throw Utils.runtimeExceptionWithoutStack("no service and request path");
} else {
throw Utils.runtimeExceptionWithoutStack("request prefix is wrong, no service and request path");
}
}
} else {
String prefix = p.substring(0, secFS);
if (StringUtils.isBlank(gatewayPrefix) || Consts.S.FORWARD_SLASH_STR.equals(gatewayPrefix)) {
if (SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
int trdFS = p.indexOf(Consts.S.FORWARD_SLASH, secFS + 1);
if (trdFS == -1) {
p = Consts.S.FORWARD_SLASH_STR;
} else {
p = p.substring(trdFS);
}
} else {
p = p.substring(secFS);
}
} else {
if (gatewayPrefix.equals(prefix) || SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
int trdFS = p.indexOf(Consts.S.FORWARD_SLASH, secFS + 1);
if (trdFS == -1) {
p = Consts.S.FORWARD_SLASH_STR;
} else {
p = p.substring(trdFS);
}
} else {
throw Utils.runtimeExceptionWithoutStack("wrong prefix " + prefix);
}
}
}
exchange.getAttributes().put(clientRequestPath, p);
}
return p;
}
public static void setBackendPath(ServerWebExchange exchange, String path) {
exchange.getAttributes().put(BACKEND_PATH, path);
}
public static String getBackendPath(ServerWebExchange exchange) {
return exchange.getAttribute(BACKEND_PATH);
}
public static String getClientReqPathPrefix(ServerWebExchange exchange) {
String prefix = exchange.getAttribute(clientRequestPathPrefix);
if (prefix == null) {
String path = exchange.getRequest().getPath().value();
int secFS = path.indexOf(Consts.S.FORWARD_SLASH, 1);
if (secFS == -1) {
prefix = path.substring(1);
if (StringUtils.isBlank(gatewayPrefix) || Consts.S.FORWARD_SLASH_STR.equals(gatewayPrefix)) {
prefix = Consts.S.FORWARD_SLASH_STR;
} else {
if (gatewayPrefix.equals(prefix) || SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
prefix = prefix + Consts.S.FORWARD_SLASH;
} else {
throw Utils.runtimeExceptionWithoutStack("wrong prefix " + prefix);
}
}
} else {
prefix = path.substring(0, secFS);
if (StringUtils.isBlank(gatewayPrefix) || Consts.S.FORWARD_SLASH_STR.equals(gatewayPrefix)) {
if (SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
prefix = prefix + Consts.S.FORWARD_SLASH;
} else {
prefix = Consts.S.FORWARD_SLASH_STR;
}
} else {
if (gatewayPrefix.equals(prefix) || SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
prefix = prefix + Consts.S.FORWARD_SLASH;
} else {
throw Utils.runtimeExceptionWithoutStack("wrong prefix " + prefix);
}
}
}
exchange.getAttributes().put(clientRequestPathPrefix, prefix);
}
return prefix;
}
public static String getClientReqQuery(ServerWebExchange exchange) {
String qry = exchange.getAttribute(clientRequestQuery);
if (qry != null && StringUtils.EMPTY.equals(qry)) {
return null;
} else {
if (qry == null) {
URI uri = exchange.getRequest().getURI();
qry = uri.getQuery();
if (qry == null) {
exchange.getAttributes().put(clientRequestQuery, StringUtils.EMPTY);
} else {
if (StringUtils.indexOfAny(qry, Consts.S.LEFT_BRACE, Consts.S.FORWARD_SLASH, Consts.S.HASH) > 0) {
qry = uri.getRawQuery();
}
exchange.getAttributes().put(clientRequestQuery, qry);
}
}
return qry;
}
}
public static String getClientReqPathQuery(ServerWebExchange exchange) {
String pathQry = getClientReqPath(exchange);
MultiValueMap queryParams = exchange.getRequest().getQueryParams();
if (!queryParams.isEmpty()) {
String qry = toQueryString(queryParams);
pathQry = pathQry + Consts.S.QUESTION + qry;
}
return pathQry;
}
public static Map> getClientReqPathQueryTemplate(ServerWebExchange exchange) {
String pathQry = getClientReqPath(exchange);
MultiValueMap queryParams = exchange.getRequest().getQueryParams();
if (queryParams.isEmpty()) {
return Collections.singletonMap(pathQry, Collections.emptyList());
} else {
Map> queryStringTemplate = toQueryStringTemplate(queryParams);
Map.Entry> entry = queryStringTemplate.entrySet().iterator().next();
pathQry = pathQry + Consts.S.QUESTION + entry.getKey();
return Collections.singletonMap(pathQry, entry.getValue());
}
}
public static String appendQuery(String path, ServerWebExchange exchange) {
String qry = getClientReqQuery(exchange);
if (qry != null) {
return path + Consts.S.QUESTION + qry;
}
return path;
}
public static Map appendHeader(ServerWebExchange exchange, String name, String value) {
Map appendHeaders = getAppendHeaders(exchange);
appendHeaders.put(name, value);
return appendHeaders;
}
public static Map appendHeaders(ServerWebExchange exchange, Map headers) {
Map appendHeaders = getAppendHeaders(exchange);
headers.forEach(
(name, value) -> {
appendHeaders.put(name, value);
}
);
return appendHeaders;
}
public static Map getAppendHeaders(ServerWebExchange exchange) {
return (Map) exchange.getAttribute(APPEND_HEADERS);
}
public static HttpHeaders mergeAppendHeaders(ServerWebExchange exchange) {
ServerHttpRequest req = exchange.getRequest();
Map appendHeaders = getAppendHeaders(exchange);
/* if (appendHeaders.isEmpty()) {
return req.getHeaders();
} */
HttpHeaders hdrs = new HttpHeaders();
req.getHeaders().forEach(
(h, vs) -> {
hdrs.addAll(h, vs);
}
);
appendHeaders.forEach(
(h, v) -> {
List vs = hdrs.get(h);
if (vs != null && !vs.isEmpty()) {
vs.clear();
vs.add(v);
} else {
hdrs.add(h, v);
}
}
);
return hdrs;
}
public static void request2stringBuilder(ServerWebExchange exchange, StringBuilder b) {
ServerHttpRequest req = exchange.getRequest();
request2stringBuilder(WebUtils.getTraceId(exchange), req.getMethod(), req.getURI().toString(), req.getHeaders(), null, b);
}
public static void request2stringBuilder(String traceId, HttpMethod method, String uri, HttpHeaders headers, Object body, StringBuilder b) {
b.append(traceId).append(Consts.S.SPACE).append(method).append(Consts.S.SPACE).append(uri);
if (headers != null) {
final boolean[] f = {false};
LOG_HEADER_SET.forEach(
h -> {
String v = headers.getFirst(h);
if (v != null) {
if (!f[0]) {
b.append(Consts.S.LINE_SEPARATOR);
f[0] = true;
}
Utils.addTo(b, h, Consts.S.EQUAL, v, Consts.S.TWO_SPACE_STR);
}
}
);
}
// body to b
}
public static void response2stringBuilder(String traceId, ClientResponse clientResponse, StringBuilder b) {
b.append(traceId).append(response).append(clientResponse.statusCode());
HttpHeaders headers = clientResponse.headers().asHttpHeaders();
final boolean[] f = {false};
LOG_HEADER_SET.forEach(
h -> {
String v = headers.getFirst(h);
if (v != null) {
if (!f[0]) {
b.append(Consts.S.LINE_SEPARATOR);
f[0] = true;
}
Utils.addTo(b, h, Consts.S.EQUAL, v, Consts.S.TWO_SPACE_STR);
}
}
);
// body to b
}
private static Mono responseError(ServerWebExchange exchange, String filter, int code, String msg, Throwable t, boolean bindContext) {
// Mono reqBodyMono = getRequestBody(exchange);
// final DataBuffer[] reqBody = {null};
// if (reqBodyMono != null) {
// reqBodyMono.subscribe(
// db -> {
// reqBody[0] = db;
// DataBufferUtils.retain(reqBody[0]);
// }
// );
// }
exchange.getResponse().getHeaders().set(BODY_ENCRYPT, Consts.S.FALSE0);
String traceId = getTraceId(exchange);
// Schedulers.parallel().schedule(() -> {
StringBuilder b = ThreadContext.getStringBuilder();
request2stringBuilder(exchange, b);
// if (reqBody[0] != null) {
// DataBufferUtils.release(reqBody[0]);
// }
b.append(Consts.S.LINE_SEPARATOR);
b.append(filter).append(Consts.S.SPACE).append(code).append(Consts.S.SPACE).append(msg);
org.apache.logging.log4j.ThreadContext.put(Consts.TRACE_ID, traceId);
if (t == null) {
// log.error(b.toString(), LogService.BIZ_ID, traceId);
log.error(b.toString());
} else {
// log.error(b.toString(), LogService.BIZ_ID, traceId, t);
log.error(b.toString(), t);
Throwable[] suppressed = t.getSuppressed();
if (suppressed != null && suppressed.length != 0) {
log.error(StringUtils.EMPTY, suppressed[0]);
}
}
// });
if (filter != null) {
if (t == null) {
transmitFailFilterResult(exchange, filter);
} else {
transmitFailFilterResult(exchange, filter, t);
}
}
HttpStatus s = HttpStatus.OK;
if (SystemConfig.FIZZ_ERR_RESP_HTTP_STATUS_ENABLE) {
s = HttpStatus.resolve(code);
}
if (bindContext) {
return buildJsonDirectResponseAndBindContext(exchange, s, null, jsonRespBody(code, msg, traceId));
} else {
return buildJsonDirectResponse(exchange, s, null, jsonRespBody(code, msg, traceId));
}
}
public static Mono responseError(ServerWebExchange exchange, int code, String msg) {
return responseError(exchange, null, code, msg, null, false);
}
public static Mono responseError(ServerWebExchange exchange, String reporter, int code, String msg, Throwable t) {
return responseError(exchange, reporter, code, msg, t, false);
}
public static String getOriginIp(ServerWebExchange exchange) {
String ip = exchange.getAttribute(originIp);
if (ip == null) {
ServerHttpRequest req = exchange.getRequest();
String v = req.getHeaders().getFirst(xForwardedFor);
if (StringUtils.isBlank(v)) {
ip = req.getRemoteAddress().getAddress().getHostAddress();
} else {
ip = StringUtils.split(v, Consts.S.COMMA)[0].trim();
if (ip.equalsIgnoreCase(unknown)) {
ip = req.getRemoteAddress().getAddress().getHostAddress();
} else if (ip.equals(binaryAddress)) {
ip = loopBack;
}
}
exchange.getAttributes().put(originIp, ip);
}
return ip;
}
public static String getTraceId(ServerWebExchange exchange) {
String id = exchange.getAttribute(TRACE_ID);
if (id == null) {
id = exchange.getRequest().getId();
}
return id;
}
public static void traceDebug(Logger log, Function messageFactory) {
if (log.isDebugEnabled()) {
boolean traceEnabled = log.isTraceEnabled();
String logMessage = messageFactory.apply(traceEnabled);
if (traceEnabled) {
log.trace(logMessage);
} else {
log.debug(logMessage);
}
}
}
private static final String s0 = "{\"";
private static final String s1 = "\":";
private static final String s2 = ",\"";
private static final String s3 = "\":\"";
private static final String s4 = "\"";
private static final String s5 = ",\"traceId\":\"";
private static final String s6 = ",\"context\":\"";
private static final String s7 = "}";
public static String jsonRespBody(int code, @Nullable String msg) {
return jsonRespBody(code, msg, null, null);
}
public static String jsonRespBody(int code, @Nullable String msg, @Nullable String traceId) {
return jsonRespBody(code, msg, traceId, null);
}
public static String jsonRespBody(int code, @Nullable String msg, @Nullable String traceId, @Nullable Object context) {
StringBuilder b = ThreadContext.getStringBuilder(ThreadContext.sb0);
b.append(s0).append(SystemConfig.FIZZ_ERR_RESP_CODE_FIELD).append(s1).append(code);
if (StringUtils.isNotBlank(msg)) {
b.append(s2).append(SystemConfig.FIZZ_ERR_RESP_MSG_FIELD).append(s3).append(msg).append(s4);
}
if (traceId != null) {
b.append(s5).append(traceId).append(s4);
}
if (context != null) {
b.append(s6).append(context).append(s4);
}
b.append(s7);
return b.toString();
}
public static String toQueryString(MultiValueMap queryParams) {
StringBuilder b = ThreadContext.getStringBuilder(ThreadContext.sb0);
Set>> params = queryParams.entrySet();
int ps = params.size(), cnt = 0;
try {
for (Map.Entry> param : params) {
String name = param.getKey();
List values = param.getValue();
if (values.isEmpty()) {
b.append(name);
} else {
int vs = values.size();
for (int i = 0; i < vs; ) {
b.append(name);
String v = values.get(i);
if (v != null) {
b.append(Consts.S.EQUAL);
if (!Consts.S.EMPTY.equals(v)) {
/*if (StringUtils.indexOfAny(v, Consts.S.LEFT_BRACE, Consts.S.FORWARD_SLASH, Consts.S.HASH, Consts.S.EQUAL) > -1) {
b.append(URLEncoder.encode(v, Consts.C.UTF8));
} else {
b.append(v);
}*/
b.append(URLDecoder.decode(v, Consts.C.UTF8));
}
}
if ((++i) != vs) {
b.append(Consts.S.AND);
}
}
}
if ((++cnt) != ps) {
b.append(Consts.S.AND);
}
}
return b.toString();
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
}
public static Map> toQueryStringTemplate(MultiValueMap queryParams) {
StringBuilder b = ThreadContext.getStringBuilder(ThreadContext.sb0);
Set>> params = queryParams.entrySet();
int ps = params.size(), cnt = 0;
List paramValues = new ArrayList<>();
for (Map.Entry> param : params) {
String name = param.getKey();
List values = param.getValue();
if (values.isEmpty()) {
b.append(name);
} else {
int vs = values.size();
for (int i = 0; i < vs; ) {
b.append(name);
String v = values.get(i);
if (v != null) {
b.append(Consts.S.EQUAL);
if (!Consts.S.EMPTY.equals(v)) {
paramValues.add(v);
b.append(Consts.S.LEFT_BRACE).append(paramValues.size()).append(Consts.S.RIGHT_BRACE);
}
}
if ((++i) != vs) {
b.append(Consts.S.AND);
}
}
}
if ((++cnt) != ps) {
b.append(Consts.S.AND);
}
}
return Collections.singletonMap(b.toString(), paramValues);
}
// the method below will be deprecated.
@Deprecated
public static Mono getDirectResponse(ServerWebExchange exchange) {
return exchange.getAttribute(WebUtils.directResponse);
}
@Deprecated
public static Map getFilterContext(ServerWebExchange exchange) {
return exchange.getAttribute(FILTER_CONTEXT);
}
@Deprecated
public static FilterResult getFilterResult(ServerWebExchange exchange, String filter) {
return getFilterContext(exchange).get(filter);
}
@Deprecated
public static Map getFilterResultData(ServerWebExchange exchange, String filter) {
return getFilterResult(exchange, filter).data;
}
@Deprecated
public static Object getFilterResultDataItem(ServerWebExchange exchange, String filter, String key) {
return getFilterResultData(exchange, filter).get(key);
}
/**
* can replace with response(ServerWebExchange exchange, HttpStatus status, HttpHeaders headers, String body) method.
* @deprecated
*/
@Deprecated
public static Mono buildDirectResponse(ServerWebExchange exchange, HttpStatus status, HttpHeaders headers, String body) {
return buildDirectResponse(exchange.getResponse(), status, headers, body);
}
/**
* can replace with response(ServerHttpResponse clientResp, HttpStatus status, HttpHeaders headers, String body) method.
* @deprecated
*/
@Deprecated
public static Mono buildDirectResponse(ServerHttpResponse clientResp, HttpStatus status, HttpHeaders headers, String body) {
if (clientResp.isCommitted()) {
String msg = "try to response: " + body + ", but server http response is committed and it's status: " + clientResp.getStatusCode();
log.warn(msg);
return Mono.error(Utils.runtimeExceptionWithoutStack(msg));
}
if (status != null) {
clientResp.setStatusCode(status);
}
if (headers != null) {
headers.forEach( (h, vs) -> {clientResp.getHeaders().addAll(h, vs);} );
}
if (body == null) {
body = Consts.S.EMPTY;
}
return clientResp.writeWith(Mono.just(clientResp.bufferFactory().wrap(body.getBytes())));
}
/**
* can replace with responseJson(ServerWebExchange exchange, HttpStatus status, HttpHeaders headers, String json) method.
* @deprecated
*/
@Deprecated
public static Mono buildJsonDirectResponse(ServerWebExchange exchange, HttpStatus status, HttpHeaders headers, String json) {
if (headers == null) {
headers = new HttpHeaders();
}
headers.setContentType(MediaType.APPLICATION_JSON);
return buildDirectResponse(exchange, status, headers, json);
}
@Deprecated
public static Mono buildDirectResponseAndBindContext(ServerWebExchange exchange, HttpStatus status, HttpHeaders headers, String bodyContent) {
Mono mv = buildDirectResponse(exchange, status, headers, bodyContent);
exchange.getAttributes().put(WebUtils.directResponse, mv);
return mv;
}
@Deprecated
public static Mono buildJsonDirectResponseAndBindContext(ServerWebExchange exchange, HttpStatus status, HttpHeaders headers, String json) {
if (headers == null) {
headers = new HttpHeaders();
}
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
return buildDirectResponseAndBindContext(exchange, status, headers, json);
}
@Deprecated
public static void transmitSuccessFilterResult(ServerWebExchange exchange, String filter, Map data) {
FilterResult fr = FilterResult.SUCCESS_WITH(filter, data);
bind(exchange, filter, fr);
}
@Deprecated
public static Mono transmitSuccessFilterResultAndEmptyMono(ServerWebExchange exchange, String filter, Map data) {
transmitSuccessFilterResult(exchange, filter, data);
return Mono.empty();
}
@Deprecated
public static void transmitFailFilterResult(ServerWebExchange exchange, String filter) {
FilterResult fr = FilterResult.FAIL(filter);
bind(exchange, filter, fr);
}
@Deprecated
public static void transmitFailFilterResult(ServerWebExchange exchange, String filter, Throwable cause) {
FilterResult fr = FilterResult.FAIL_WITH(filter, cause);
bind(exchange, filter, fr);
}
@Deprecated
public static FilterResult getPrevFilterResult(ServerWebExchange exchange) {
return getFilterContext(exchange).get(PREV_FILTER_RESULT);
}
@Deprecated
public static Mono responseErrorAndBindContext(ServerWebExchange exchange, String filter, int code, String msg) {
return responseError(exchange, filter, code, msg, null, true);
}
@Deprecated
public static Mono responseErrorAndBindContext(ServerWebExchange exchange, String filter, int code, String msg, Throwable t) {
return responseError(exchange, filter, code, msg, t, true);
}
@Deprecated
public static Mono responseErrorAndBindContext(ServerWebExchange exchange, String filter, HttpStatus httpStatus) {
ServerHttpResponse response = exchange.getResponse();
String traceId = getTraceId(exchange);
StringBuilder b = ThreadContext.getStringBuilder();
request2stringBuilder(exchange, b);
b.append(Consts.S.LINE_SEPARATOR);
b.append(filter).append(Consts.S.SPACE).append(httpStatus);
// log.error(b.toString(), LogService.BIZ_ID, traceId);
org.apache.logging.log4j.ThreadContext.put(Consts.TRACE_ID, traceId);
log.error(b.toString());
transmitFailFilterResult(exchange, filter);
return buildDirectResponseAndBindContext(exchange, httpStatus, new HttpHeaders(), Consts.S.EMPTY);
}
@Deprecated
public static Mono responseErrorAndBindContext(ServerWebExchange exchange, String filter, HttpStatus httpStatus,
HttpHeaders headers, String content) {
ServerHttpResponse response = exchange.getResponse();
String traceId = getTraceId(exchange);
StringBuilder b = ThreadContext.getStringBuilder();
request2stringBuilder(exchange, b);
b.append(Consts.S.LINE_SEPARATOR);
b.append(filter).append(Consts.S.SPACE).append(httpStatus);
// log.error(b.toString(), LogService.BIZ_ID, traceId);
org.apache.logging.log4j.ThreadContext.put(Consts.TRACE_ID, traceId);
log.error(b.toString());
transmitFailFilterResult(exchange, filter);
headers = headers == null ? new HttpHeaders() : headers;
content = StringUtils.isBlank(content) ? Consts.S.EMPTY : content;
return buildDirectResponseAndBindContext(exchange, httpStatus, headers, content);
}
public static void setXForwardedFor(ServerWebExchange exchange, HttpHeaders headers) {
List values = headers.get(xForwardedFor);
if (CollectionUtils.isEmpty(values)) {
String originIp = getOriginIp(exchange);
headers.add(xForwardedFor, originIp);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy