@Override public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) { HandlerFunction<?> handlerFunction = (HandlerFunction<?>) handler; ServerRequest request = exchange.getRequiredAttribute(RouterFunctions.REQUEST_ATTRIBUTE); return handlerFunction.handle(request) .map(response -> new HandlerResult(handlerFunction, response, HANDLER_FUNCTION_RETURN_TYPE)); } }
public static void addOriginalRequestUrl(ServerWebExchange exchange, URI url) { exchange.getAttributes().computeIfAbsent(GATEWAY_ORIGINAL_REQUEST_URL_ATTR, s -> new LinkedHashSet<>()); LinkedHashSet<URI> uris = exchange.getRequiredAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR); uris.add(url); }
protected Mono<Resource> getResource(ServerWebExchange exchange) { String name = HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE; PathContainer pathWithinHandler = exchange.getRequiredAttribute(name); String path = processPath(pathWithinHandler.value()); if (!StringUtils.hasText(path) || isInvalidPath(path)) { return Mono.empty(); } if (isInvalidEncodedPath(path)) { return Mono.empty(); } Assert.state(this.resolverChain != null, "ResourceResolverChain not initialized"); Assert.state(this.transformerChain != null, "ResourceTransformerChain not initialized"); return this.resolverChain.resolveResource(exchange, path, getLocations()) .flatMap(resource -> this.transformerChain.transform(exchange, resource)); }
@Override public Mono<Void> handle(ServerWebExchange exchange) { Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR); List<GatewayFilter> gatewayFilters = route.getFilters(); List<GatewayFilter> combined = new ArrayList<>(this.globalFilters); combined.addAll(gatewayFilters); //TODO: needed or cached? AnnotationAwareOrderComparator.sort(combined); if (logger.isDebugEnabled()) { logger.debug("Sorted gatewayFilterFactories: "+ combined); } return new DefaultGatewayFilterChain(combined).filter(exchange); }
private void changeSchemeIfIsWebSocketUpgrade(ServerWebExchange exchange) { // Check the Upgrade URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); String scheme = requestUrl.getScheme().toLowerCase(); String upgrade = exchange.getRequest().getHeaders().getUpgrade(); // change the scheme if the socket client send a "http" or "https" if ("WebSocket".equalsIgnoreCase(upgrade) && ("http".equals(scheme) || "https".equals(scheme))) { String wsScheme = convertHttpToWs(scheme); URI wsRequestUrl = UriComponentsBuilder.fromUri(requestUrl).scheme(wsScheme).build().toUri(); exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, wsRequestUrl); if (log.isTraceEnabled()) { log.trace("changeSchemeTo:[" + wsRequestUrl + "]"); } } }
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); String scheme = requestUrl.getScheme(); if (isAlreadyRouted(exchange) || !"forward".equals(scheme)) { return chain.filter(exchange); } setAlreadyRouted(exchange); //TODO: translate url? if (log.isTraceEnabled()) { log.trace("Forwarding to URI: "+requestUrl); } return this.dispatcherHandler.getIfAvailable().handle(exchange); } }
@Test public void happyPathLbPlusScheme() { MockServerHttpRequest request = MockServerHttpRequest .get("http://localhost/getb") .build(); ServerWebExchange webExchange = testFilter(request, "lb:http://myhost"); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("http").hasHost("myhost"); String schemePrefix = webExchange.getRequiredAttribute(GATEWAY_SCHEME_PREFIX_ATTR); assertThat(schemePrefix).isEqualTo("lb"); }
@Test public void shouldFilterAndKeepHostPathAsSpecified() { URI uri = UriComponentsBuilder.fromUriString("forward://host/outage").build().toUri(); exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri); ArgumentCaptor<ServerWebExchange> captor = ArgumentCaptor.forClass(ServerWebExchange.class); forwardRoutingFilter.filter(exchange, chain); verify(dispatcherHandler).handle(captor.capture()); ServerWebExchange webExchange = captor.getValue(); URI forwardedUrl = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(forwardedUrl).hasScheme("forward").hasHost("host").hasPath("/outage"); }
@Test public void encodedUrl() { URI url = UriComponentsBuilder.fromUriString("http://localhost/abc def/get").buildAndExpand().encode().toUri(); // prove that it is encoded assertThat(url.getRawPath()).isEqualTo("/abc%20def/get"); assertThat(url).hasPath("/abc def/get"); MockServerHttpRequest request = MockServerHttpRequest .method(HttpMethod.GET, url) .build(); ServerWebExchange webExchange = testFilter(request, "http://myhost/abc%20def/get"); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("http").hasHost("myhost") .hasPath("/abc def/get"); // prove that it is not double encoded assertThat(uri.getRawPath()).isEqualTo("/abc%20def/get"); }
@Test public void noQueryParams() { MockServerHttpRequest request = MockServerHttpRequest .get("http://localhost/get") .build(); ServerWebExchange webExchange = testFilter(request, URI.create("lb://service1")); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("http").hasHost("service1-host1"); }
@Test public void instanceOverrideNonSecureScheme() { MockServerHttpRequest request = MockServerHttpRequest .get("https://localhost") .build(); URI lbUri = URI.create("lb://service1"); ServerWebExchange webExchange = testFilter(request, lbUri); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("http").hasHost("service1-host1"); }
private void testPrefixPathFilter(String prefix, String path, String expectedPath) { GatewayFilter filter = new PrefixPathGatewayFilterFactory().apply(c -> c.setPrefix(prefix)); MockServerHttpRequest request = MockServerHttpRequest .get("http://localhost" + path) .build(); ServerWebExchange exchange = MockServerWebExchange.from(request); GatewayFilterChain filterChain = mock(GatewayFilterChain.class); ArgumentCaptor<ServerWebExchange> captor = ArgumentCaptor.forClass(ServerWebExchange.class); when(filterChain.filter(captor.capture())).thenReturn(Mono.empty()); filter.filter(exchange, filterChain); ServerWebExchange webExchange = captor.getValue(); assertThat(webExchange.getRequest().getURI()).hasPath(expectedPath); LinkedHashSet<URI> uris = webExchange.getRequiredAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR); assertThat(uris).contains(request.getURI()); }
@Test public void instanceOverrideSecureScheme() { MockServerHttpRequest request = MockServerHttpRequest .get("http://localhost") .build(); URI lbUri = URI.create("lb://service1"); ServerWebExchange webExchange = testFilter(request, lbUri, 443); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("https").hasHost("service1-host1"); }
@Test public void instanceOverrideSecureSchemePrefix() { MockServerHttpRequest request = MockServerHttpRequest .get("https://localhost") .build(); URI lbUri = URI.create("http://service1"); ServerWebExchange exchange = MockServerWebExchange.from(request); exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR, "lb"); ServerWebExchange webExchange = testFilter(exchange, lbUri, 443); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("http").hasHost("service1-host1"); }
@Test public void instanceOverrideNonSecureSchemePrefix() { MockServerHttpRequest request = MockServerHttpRequest .get("http://localhost") .build(); URI lbUri = URI.create("https://service1"); ServerWebExchange exchange = MockServerWebExchange.from(request); exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR, "lb"); ServerWebExchange webExchange = testFilter(exchange, lbUri, 8081); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("https").hasHost("service1-host1"); }
@Test public void happyPathLb() { MockServerHttpRequest request = MockServerHttpRequest .get("http://localhost/getb") .build(); ServerWebExchange webExchange = testFilter(request, "lb://myhost"); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("lb").hasHost("myhost"); }
@Test public void noQueryParams() { MockServerHttpRequest request = MockServerHttpRequest .get("http://localhost/get") .build(); ServerWebExchange webExchange = testFilter(request, "http://myhost"); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("http").hasHost("myhost"); }
@Test public void happyPath() { MockServerHttpRequest request = MockServerHttpRequest .get("http://localhost/get?a=b") .build(); URI lbUri = URI.create("lb://service1?a=b"); ServerWebExchange webExchange = testFilter(request, lbUri); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("http").hasHost("service1-host1") .hasParameter("a", "b"); }
@Test public void happyPathWithAttributeRatherThanScheme() { MockServerHttpRequest request = MockServerHttpRequest .get("ws://localhost/get?a=b") .build(); URI lbUri = URI.create("ws://service1?a=b"); exchange = MockServerWebExchange.from(request); exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR, "lb"); ServerWebExchange webExchange = testFilter(exchange, lbUri, 8081); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("ws").hasHost("service1-host1") .hasParameter("a", "b"); }
@Test public void happyPath() { MockServerHttpRequest request = MockServerHttpRequest .get("http://localhost/get?a=b") .build(); ServerWebExchange webExchange = testFilter(request, "http://myhost/mypath"); URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); assertThat(uri).hasScheme("http").hasHost("myhost") .hasPath("/get") .hasParameter("a", "b"); }