001/** 002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.jboot.components.gateway; 017 018import com.alibaba.csp.sentinel.*; 019import com.alibaba.csp.sentinel.slots.block.BlockException; 020import com.alibaba.csp.sentinel.util.StringUtil; 021import com.jfinal.kit.LogKit; 022import io.jboot.support.sentinel.SentinelUtil; 023import io.jboot.utils.StrUtil; 024 025import javax.servlet.http.HttpServletRequest; 026import javax.servlet.http.HttpServletResponse; 027import java.io.IOException; 028 029public class GatewaySentinelProcesser { 030 031 032 public void process(GatewayHttpProxy proxy, String proxyUrl, JbootGatewayConfig config, HttpServletRequest req, HttpServletResponse resp, boolean skipExceptionRender) { 033 Entry entry = null; 034 String resourceName = SentinelUtil.buildResource(req); 035 try { 036 entry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_API_GATEWAY, EntryType.IN); 037 proxy.sendRequest(proxyUrl, req, resp); 038 } catch (BlockException ex) { 039 if (skipExceptionRender) { 040 GatewayErrorRender errorRender = JbootGatewayManager.me().getGatewayErrorRender(); 041 if (errorRender != null) { 042 errorRender.renderError(ex, GatewayErrorRender.sentinelBlockedError, config, req, resp); 043 } else { 044 processBlocked(config, req, resp); 045 } 046 } else { 047 proxy.setException(ex); 048 } 049 } finally { 050 if (proxy.getException() != null) { 051 Tracer.traceEntry(proxy.getException(), entry); 052 } 053 if (entry != null) { 054 entry.exit(); 055 } 056 } 057 } 058 059 060 private void processBlocked(JbootGatewayConfig config, HttpServletRequest req, HttpServletResponse resp) { 061 StringBuffer url = req.getRequestURL(); 062 063 if ("GET".equalsIgnoreCase(req.getMethod()) && StrUtil.isNotBlank(req.getQueryString())) { 064 url.append("?").append(req.getQueryString()); 065 } 066 067 try { 068 if (StringUtil.isNotBlank(config.getSentinelBlockPage())) { 069 String redirectUrl = config.getSentinelBlockPage() + "?http_referer=" + url.toString(); 070 resp.sendRedirect(redirectUrl); 071 } else if (config.getSentinelBlockJsonMap() != null && !config.getSentinelBlockJsonMap().isEmpty()) { 072 SentinelUtil.writeDefaultBlockedJson(resp, config.getSentinelBlockJsonMap()); 073 } else { 074 SentinelUtil.writeDefaultBlockedPage(resp); 075 } 076 } catch (IOException ex) { 077 LogKit.error(ex.toString(), ex); 078 } 079 } 080 081 082}