基于springCloud gateway请求包含url包含{}大括号特殊字符的问题

您所在的位置:网站首页 大括号url编码 基于springCloud gateway请求包含url包含{}大括号特殊字符的问题

基于springCloud gateway请求包含url包含{}大括号特殊字符的问题

2023-11-14 01:33| 来源: 网络整理| 查看: 265

众所周知,springCloud gateway用的是异步请求方式,即webflux。

当拦截请求时,如url包含大括号“{}”特殊字符时,会报Failed to get request URI: xxx 异常。

此时需要正确请求访问,需要重写源码中相应方法:

package org.springframework.http.server.reactive; import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.cookie.Cookie; import io.netty.handler.ssl.SslHandler; import java.net.InetSocketAddress; import java.net.URI; import java.net.URISyntaxException; import java.util.Iterator; import java.util.Set; import javax.net.ssl.SSLSession; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.NettyDataBufferFactory; import org.springframework.http.HttpCookie; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import reactor.core.publisher.Flux; import reactor.ipc.netty.ByteBufFlux; import reactor.ipc.netty.http.server.HttpServerRequest; /** * 重写initUri(HttpServerRequest request)方法,处理请求参数中{}被网关拦截的问题 */ class ReactorServerHttpRequest extends AbstractServerHttpRequest { private final HttpServerRequest request; private final NettyDataBufferFactory bufferFactory; public ReactorServerHttpRequest(HttpServerRequest request, NettyDataBufferFactory bufferFactory) throws URISyntaxException { super(initUri(request), "", initHeaders(request)); Assert.notNull(bufferFactory, "DataBufferFactory must not be null"); this.request = request; this.bufferFactory = bufferFactory; } private static URI initUri(HttpServerRequest request) throws URISyntaxException { Assert.notNull(request, "HttpServerRequest must not be null"); return new URI(resolveBaseUrl(request).toString() + resolveRequestUri(request)); } private static URI resolveBaseUrl(HttpServerRequest request) throws URISyntaxException { String scheme = getScheme(request); String header = request.requestHeaders().get(HttpHeaderNames.HOST); if (header != null) { int portIndex; if (header.startsWith("[")) { portIndex = header.indexOf(58, header.indexOf(93)); } else { portIndex = header.indexOf(58); } if (portIndex != -1) { try { return new URI(scheme, (String)null, header.substring(0, portIndex), Integer.parseInt(header.substring(portIndex + 1)), (String)null, (String)null, (String)null); } catch (NumberFormatException var5) { throw new URISyntaxException(header, "Unable to parse port", portIndex); } } else { return new URI(scheme, header, (String)null, (String)null); } } else { InetSocketAddress localAddress = (InetSocketAddress)request.context().channel().localAddress(); return new URI(scheme, (String)null, localAddress.getHostString(), localAddress.getPort(), (String)null, (String)null, (String)null); } } private static String getScheme(HttpServerRequest request) { ChannelPipeline pipeline = request.context().channel().pipeline(); boolean ssl = pipeline.get(SslHandler.class) != null; return ssl ? "https" : "http"; } private static String resolveRequestUri(HttpServerRequest request) { String uri = request.uri(); for(int i = 0; i < uri.length(); ++i) { char c = uri.charAt(i); if (c == '/' || c == '?' || c == '#') { break; } if (c == ':' && i + 2 < uri.length() && uri.charAt(i + 1) == '/' && uri.charAt(i + 2) == '/') { for(int j = i + 3; j < uri.length(); ++j) { c = uri.charAt(j); if (c == '/' || c == '?' || c == '#') { return uri.substring(j); } } return ""; } } return uri; } private static HttpHeaders initHeaders(HttpServerRequest channel) { HttpHeaders headers = new HttpHeaders(); Iterator var2 = channel.requestHeaders().names().iterator(); while(var2.hasNext()) { String name = (String)var2.next(); headers.put(name, channel.requestHeaders().getAll(name)); } return headers; } public String getMethodValue() { return this.requesthod().name(); } protected MultiValueMap initCookies() { MultiValueMap cookies = new LinkedMultiValueMap(); Iterator var2 = this.request.cookies().keySet().iterator(); while(var2.hasNext()) { CharSequence name = (CharSequence)var2.next(); Iterator var4 = ((Set)this.request.cookies().get(name)).iterator(); while(var4.hasNext()) { Cookie cookie = (Cookie)var4.next(); HttpCookie httpCookie = new HttpCookie(name.toString(), cookie.value()); cookies.add(name.toString(), httpCookie); } } return cookies; } public InetSocketAddress getRemoteAddress() { return this.request.remoteAddress(); } @Nullable protected SslInfo initSslInfo() { SslHandler sslHandler = (SslHandler)this.request.context().channel().pipeline().get(SslHandler.class); if (sslHandler != null) { SSLSession session = sslHandler.engine().getSession(); return new DefaultSslInfo(session); } else { return null; } } public Flux getBody() { ByteBufFlux var10000 = this.request.receive().retain(); NettyDataBufferFactory var10001 = this.bufferFactory; var10001.getClass(); return var10000.map(var10001::wrap); } public T getNativeRequest() { return (T) this.request; } }

通过修改该类中的initUri方法实现“{}”特殊字符通过网关,不被拦截。

具体替换为:

private static URI initUri(HttpServerRequest request) throws URISyntaxException { Assert.notNull(request, "HttpServerRequest must not be null"); // 针对 特殊字符 { } 做替换处理 String requestUri = resolveRequestUri(request).replace("{", "%7B").replace("}", "%7D"); return new URI(resolveBaseUrl(request).toString() + requestUri); }

经测试,能正常访问。

ps:目前springBoot版本为:2.X。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3