@Nullable private String getAcceptEncoding(ServerWebExchange exchange) { ServerHttpRequest request = exchange.getRequest(); String header = request.getHeaders().getFirst(HttpHeaders.ACCEPT_ENCODING); return (header != null ? header.toLowerCase() : null); }
/** * Send a redirect back to the HTTP client. * @param targetUrl the target URL to redirect to * @param exchange current exchange */ protected Mono<Void> sendRedirect(String targetUrl, ServerWebExchange exchange) { String transformedUrl = (isRemoteHost(targetUrl) ? targetUrl : exchange.transformUrl(targetUrl)); ServerHttpResponse response = exchange.getResponse(); response.getHeaders().setLocation(URI.create(transformedUrl)); response.setStatusCode(getStatusCode()); return Mono.empty(); }
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { exchange.getAttributes().put(REQUEST_TIME_BEGIN, System.currentTimeMillis()); return chain.filter(exchange).then( Mono.fromRunnable(() -> { Long startTime = exchange.getAttribute(REQUEST_TIME_BEGIN); if (startTime != null) { log.info(exchange.getRequest().getURI().getRawPath() + ": " + (System.currentTimeMillis() - startTime) + "ms"); } }) ); }
private HandshakeInfo createHandshakeInfo(ServerWebExchange exchange, ServerHttpRequest request, @Nullable String protocol, Map<String, Object> attributes) { URI uri = request.getURI(); // Copy request headers, as they might be pooled and recycled by // the server implementation once the handshake HTTP exchange is done. HttpHeaders headers = new HttpHeaders(); headers.addAll(request.getHeaders()); Mono<Principal> principal = exchange.getPrincipal(); String logPrefix = exchange.getLogPrefix(); InetSocketAddress remoteAddress = request.getRemoteAddress(); return new HandshakeInfo(uri, headers, principal, protocol, remoteAddress, attributes, logPrefix); }
@Override public final Mono<Void> writeTo(ServerWebExchange exchange, Context context) { writeStatusAndHeaders(exchange.getResponse()); Instant lastModified = Instant.ofEpochMilli(headers().getLastModified()); HttpMethod httpMethod = exchange.getRequest().getMethod(); if (SAFE_METHODS.contains(httpMethod) && exchange.checkNotModified(headers().getETag(), lastModified)) { return exchange.getResponse().setComplete(); } else { return writeToInternal(exchange, context); } }
@Test public void handleWhenNotOAuth2AuthenticatedThenStatus403() { Authentication token = new TestingAuthenticationToken("user", "pass"); ServerWebExchange exchange = mock(ServerWebExchange.class); when(exchange.getPrincipal()).thenReturn(Mono.just(token)); when(exchange.getResponse()).thenReturn(new MockServerHttpResponse()); this.accessDeniedHandler.handle(exchange, null).block(); assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); assertThat(exchange.getResponse().getHeaders().get("WWW-Authenticate")).isEqualTo( Arrays.asList("Bearer")); }
@Test // SPR-15674 (in comments) public void mutateDoesNotCreateNewSession() { WebTestClient client = WebTestClient .bindToWebHandler(exchange -> { if (exchange.getRequest().getURI().getPath().equals("/set")) { return exchange.getSession() .doOnNext(session -> session.getAttributes().put("foo", "bar")) .then(); } else { return exchange.getSession() .map(session -> session.getAttributeOrDefault("foo", "none")) .flatMap(value -> { DataBuffer buffer = toDataBuffer(value); return exchange.getResponse().writeWith(Mono.just(buffer)); }); } }) .build(); // Set the session attribute EntityExchangeResult<Void> result = client.get().uri("/set").exchange() .expectStatus().isOk().expectBody().isEmpty(); ResponseCookie session = result.getResponseCookies().getFirst("SESSION"); // Now get attribute client.mutate().build() .get().uri("/get") .cookie(session.getName(), session.getValue()) .exchange() .expectBody(String.class).isEqualTo("bar"); }
@Override public Mono<Void> render(@Nullable Map<String, ?> model, @Nullable MediaType contentType, ServerWebExchange exchange) { StringBuilder builder = new StringBuilder(); builder.append("name=").append(this.name).append('\n'); for (Map.Entry<String, ?> entry : model.entrySet()) { builder.append(entry.getKey()).append('=').append(entry.getValue()).append('\n'); } builder.setLength(builder.length() - 1); byte[] bytes = builder.toString().getBytes(StandardCharsets.UTF_8); ServerHttpResponse response = exchange.getResponse(); DataBuffer buffer = response.bufferFactory().wrap(bytes); response.getHeaders().setContentType(MediaType.TEXT_PLAIN); return response.writeWith(Mono.just(buffer)); } }
@Test public void preflightRequestWithoutCorsConfigurationProvider() throws Exception { String origin = "http://domain2.com"; ServerWebExchange exchange = createExchange(HttpMethod.OPTIONS, "/welcome.html", origin); Object actual = this.handlerMapping.getHandler(exchange).block(); assertNotNull(actual); assertNotSame(this.welcomeController, actual); assertNull(exchange.getResponse().getHeaders().getFirst(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); }
@Override public Mono<Void> render(@Nullable Map<String, ?> model, @Nullable MediaType mediaType, ServerWebExchange exchange) { ServerHttpResponse response = exchange.getResponse(); if (mediaType != null) { response.getHeaders().setContentType(mediaType); } model = new TreeMap<>(model); String value = this.name + ": " + model.toString(); ByteBuffer byteBuffer = ByteBuffer.wrap(value.getBytes(UTF_8)); DataBuffer dataBuffer = new DefaultDataBufferFactory().wrap(byteBuffer); return response.writeWith(Flux.just(dataBuffer)); } }
@Override public Mono<Void> render(@Nullable Map<String, ?> model, @Nullable MediaType contentType, ServerWebExchange exchange) { exchange.getResponse().getHeaders().setContentLanguage(locale); return Mono.empty(); } }
@Override public Mono<Void> handle(ServerWebExchange exchange) { if (exchange.getRequest().getQueryParams().containsKey("expire")) { return exchange.getSession().doOnNext(session -> { // Don't do anything, leave it expired... }).then(); } else if (exchange.getRequest().getQueryParams().containsKey("changeId")) { return exchange.getSession().flatMap(session -> session.changeSessionId().doOnSuccess(aVoid -> updateSessionAttribute(session))); } else if (exchange.getRequest().getQueryParams().containsKey("invalidate")) { return exchange.getSession().doOnNext(WebSession::invalidate).then(); } else { return exchange.getSession().doOnSuccess(this::updateSessionAttribute).then(); } }
@Override public Mono<Object> resolveArgument( MethodParameter parameter, BindingContext context, ServerWebExchange exchange) { Mono<WebSession> session = exchange.getSession(); ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameter.getParameterType()); return (adapter != null ? Mono.just(adapter.fromPublisher(session)) : Mono.from(session)); }
/** * Retrieve the model object for the given model name, either from the model * or from the request attributes. * @param modelName the name of the model object * @return the model object */ @SuppressWarnings("unchecked") @Nullable protected <T> T getModelObject(String modelName) { T modelObject = (T) this.model.get(modelName); if (modelObject == null) { modelObject = this.exchange.getAttribute(modelName); } return modelObject; }
@Override public Mono<Object> resolveArgument( MethodParameter parameter, BindingContext context, ServerWebExchange exchange) { Mono<Principal> principal = exchange.getPrincipal(); ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameter.getParameterType()); return (adapter != null ? Mono.just(adapter.fromPublisher(principal)) : Mono.from(principal)); }
@Override protected boolean matchMediaType(ServerWebExchange exchange) throws UnsupportedMediaTypeStatusException { try { MediaType contentType = exchange.getRequest().getHeaders().getContentType(); contentType = (contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM); return getMediaType().includes(contentType); } catch (InvalidMediaTypeException ex) { throw new UnsupportedMediaTypeStatusException("Can't parse Content-Type [" + exchange.getRequest().getHeaders().getFirst("Content-Type") + "]: " + ex.getMessage()); } } }
@Override protected WebHttpHandlerBuilder initHttpHandlerBuilder() { return WebHttpHandlerBuilder.webHandler(exchange -> { DefaultDataBufferFactory factory = new DefaultDataBufferFactory(); String text = exchange.getAttributes().toString(); DataBuffer buffer = factory.wrap(text.getBytes(StandardCharsets.UTF_8)); return exchange.getResponse().writeWith(Mono.just(buffer)); }); } }
@SuppressWarnings("unchecked") private <T> Mono<Void> write(T value, @Nullable MediaType contentType, ServerWebExchange exchange) { Publisher<T> input = Mono.justOrEmpty(value); ResolvableType elementType = ResolvableType.forClass(value.getClass()); return ((HttpMessageWriter<T>) this.writer).write( input, elementType, contentType, exchange.getResponse(), Hints.from(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix())); }
@Override @Nullable public CorsConfiguration getCorsConfiguration(ServerWebExchange exchange) { PathContainer lookupPath = exchange.getRequest().getPath().pathWithinApplication(); return this.corsConfigurations.entrySet().stream() .filter(entry -> entry.getKey().matches(lookupPath)) .map(Map.Entry::getValue) .findFirst() .orElse(null); }
@Test @Ignore public void getMatchingConditionWithCorsPreFlight() throws Exception { ServerWebExchange exchange = getExchange("OPTIONS"); exchange.getRequest().getHeaders().add("Origin", "http://example.com"); exchange.getRequest().getHeaders().add(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "PUT"); assertNotNull(new RequestMethodsRequestCondition().getMatchingCondition(exchange)); assertNotNull(new RequestMethodsRequestCondition(PUT).getMatchingCondition(exchange)); assertNull(new RequestMethodsRequestCondition(DELETE).getMatchingCondition(exchange)); }