public static ExchangeFilterFunction setInstance(Mono<Instance> instance) { return (request, next) -> instance.map(i -> ClientRequest.from(request) .attribute(ATTRIBUTE_INSTANCE, i) .build()) .switchIfEmpty(request.url().isAbsolute() ? Mono.just(request) : Mono.error( new ResolveInstanceException("Could not resolve Instance"))) .flatMap(next::exchange); }
/** * Return a filter that applies HTTP Basic Authentication to the request * headers via {@link HttpHeaders#setBasicAuth(String, String)}. * @param user the user * @param password the password * @return the filter to add authentication headers with * @see HttpHeaders#setBasicAuth(String, String) * @see HttpHeaders#setBasicAuth(String, String, Charset) */ public static ExchangeFilterFunction basicAuthentication(String user, String password) { return (request, next) -> next.exchange(ClientRequest.from(request) .headers(headers -> headers.setBasicAuth(user, password)) .build()); }
/** * Variant of {@link #basicAuthentication(String, String)} that looks up * the {@link Credentials Credentials} in a * {@link #BASIC_AUTHENTICATION_CREDENTIALS_ATTRIBUTE request attribute}. * @return the filter to use * @see Credentials * @deprecated as of Spring 5.1 in favor of using * {@link HttpHeaders#setBasicAuth(String, String)} while building the request. */ @Deprecated public static ExchangeFilterFunction basicAuthentication() { return (request, next) -> { Object attr = request.attributes().get(BASIC_AUTHENTICATION_CREDENTIALS_ATTRIBUTE); if (attr instanceof Credentials) { Credentials cred = (Credentials) attr; return next.exchange(ClientRequest.from(request) .headers(headers -> headers.setBasicAuth(cred.username, cred.password)) .build()); } else { return next.exchange(request); } }; }
public static ExchangeFilterFunction setDefaultAcceptHeader() { return (request, next) -> { if (request.headers().getAccept().isEmpty()) { Boolean isRequestForLogfile = request.attribute(ATTRIBUTE_ENDPOINT) .map(Endpoint.LOGFILE::equals) .orElse(false); List<MediaType> acceptedHeaders = isRequestForLogfile ? DEFAULT_LOGFILE_ACCEPT_MEDIATYPES : DEFAULT_ACCEPT_MEDIATYPES; return next.exchange(ClientRequest.from(request) .headers(headers -> headers.setAccept(acceptedHeaders)) .build()); } return next.exchange(request); }; }
private ClientRequest bearer(ClientRequest request, OAuth2AuthorizedClient authorizedClient) { return ClientRequest.from(request) .headers(headers -> headers.setBearerAuth(authorizedClient.getAccessToken().getTokenValue())) .build(); }
private ClientRequest bearer(ClientRequest request, OAuth2AuthorizedClient authorizedClient) { return ClientRequest.from(request) .headers(headers -> headers.setBearerAuth(authorizedClient.getAccessToken().getTokenValue())) .build(); }
public static ExchangeFilterFunction addHeaders(HttpHeadersProvider httpHeadersProvider) { return toExchangeFilterFunction((instance, request, next) -> { ClientRequest newRequest = ClientRequest.from(request) .headers(headers -> headers.addAll(httpHeadersProvider.getHeaders( instance))) .build(); return next.exchange(newRequest); }); }
log.trace("Absolute URL '{}' for instance {} not rewritten", request.url(), instance.getId()); if (request.url().toString().equals(instance.getRegistration().getManagementUrl())) { return next.exchange(ClientRequest.from(request) .attribute(ATTRIBUTE_ENDPOINT, Endpoint.ACTUATOR_INDEX) .build()); newUrl ); ClientRequest newRequest = ClientRequest.from(request) .attribute(ATTRIBUTE_ENDPOINT, endpoint.get().getId()) .url(newUrl)
@Override public void subscribe(CoreSubscriber<? super ClientResponse> subscriber) { final ClientRequest.Builder builder = ClientRequest.from(this.request); Context context = subscriber.currentContext(); this.next.exchange(builder.build()).subscribe(new WebClientTracerSubscriber( subscriber, context, findOrCreateSpan(builder), this)); }
private ClientRequest withClientCookies(ClientRequest request) { return ClientRequest.from(request) .cookies( c -> { c.addAll(clientCookies()); }).build(); }
@Test public void from() throws URISyntaxException { ClientRequest other = ClientRequest.create(GET, URI.create("http://example.com")) .header("foo", "bar") .cookie("baz", "qux").build(); ClientRequest result = ClientRequest.from(other) .headers(httpHeaders -> httpHeaders.set("foo", "baar")) .cookies(cookies -> cookies.set("baz", "quux")) .build(); assertEquals(new URI("http://example.com"), result.url()); assertEquals(GET, result.method()); assertEquals(1, result.headers().size()); assertEquals("baar", result.headers().getFirst("foo")); assertEquals(1, result.cookies().size()); assertEquals("quux", result.cookies().getFirst("baz")); }
@Test public void shouldApplyExchangeFilter() { prepareResponse(response -> response.setHeader("Content-Type", "text/plain") .setBody("Hello Spring!")); WebClient filteredClient = this.webClient.mutate() .filter((request, next) -> { ClientRequest filteredRequest = ClientRequest.from(request).header("foo", "bar").build(); return next.exchange(filteredRequest); }) .build(); Mono<String> result = filteredClient.get() .uri("/greeting?name=Spring") .retrieve() .bodyToMono(String.class); StepVerifier.create(result) .expectNext("Hello Spring!") .expectComplete() .verify(Duration.ofSeconds(3)); expectRequestCount(1); expectRequest(request -> assertEquals("bar", request.getHeader("foo"))); }
private ClientRequest applyUriDefaults(ClientRequest request) { URI requestUri = request.url(); if (!StringUtils.isEmpty(requestUri.getHost())) { return request; } try { requestUri = new URI("http", requestUri.getUserInfo(), "localhost", 8080, requestUri.getPath(), requestUri.getQuery(), requestUri.getFragment()); return ClientRequest.from(request).url(requestUri).build(); } catch (URISyntaxException ex) { throw new IllegalStateException(ex); } }
/** * Return a filter that adds an Authorization header for HTTP Basic Authentication. * @param username the username to use * @param password the password to use * @return the {@link ExchangeFilterFunction} that adds the Authorization header */ public static ExchangeFilterFunction basicAuthentication(String username, String password) { Assert.notNull(username, "'username' must not be null"); Assert.notNull(password, "'password' must not be null"); return ExchangeFilterFunction.ofRequestProcessor( clientRequest -> { String authorization = authorization(username, password); ClientRequest<?> authorizedRequest = ClientRequest.from(clientRequest) .header(HttpHeaders.AUTHORIZATION, authorization) .body(clientRequest.inserter()); return Mono.just(authorizedRequest); }); }
private ClientRequest bearer(ClientRequest request, OAuth2AuthorizedClient authorizedClient) { return ClientRequest.from(request) .headers(headers -> headers.setBearerAuth(authorizedClient.getAccessToken().getTokenValue())) .build(); }
private ClientRequest bearer(ClientRequest request, OAuth2AuthorizedClient authorizedClient) { return ClientRequest.from(request) .headers(headers -> headers.setBearerAuth(authorizedClient.getAccessToken().getTokenValue())) .build(); }
/** * Create a session-bound {@link WebClient} to be used by {@link VaultTemplate} for * Vault communication given {@link VaultEndpointProvider} and * {@link ClientHttpConnector} for calls that require an authenticated context. * {@link VaultEndpointProvider} is used to contribute host and port details for * relative URLs typically used by the Template API. Subclasses may override this * method to customize the {@link WebClient}. * * @param endpointProvider must not be {@literal null}. * @param connector must not be {@literal null}. * @return the {@link WebClient} used for Vault communication. * @since 2.1 */ protected WebClient doCreateSessionWebClient(VaultEndpointProvider endpointProvider, ClientHttpConnector connector) { Assert.notNull(endpointProvider, "VaultEndpointProvider must not be null"); Assert.notNull(connector, "ClientHttpConnector must not be null"); ExchangeFilterFunction filter = ofRequestProcessor(request -> vaultTokenSupplier .getVaultToken().map(token -> { return ClientRequest.from(request).headers(headers -> { headers.set(VaultHttpHeaders.VAULT_TOKEN, token.getToken()); }).build(); })); return doCreateWebClient(endpointProvider, connector).mutate().filter(filter) .build(); }
@Override public void subscribe(CoreSubscriber<? super ClientResponse> subscriber) { final ClientRequest.Builder builder = ClientRequest.from(this.request); Context context = subscriber.currentContext(); this.next.exchange(builder.build()).subscribe(new WebClientTracerSubscriber( subscriber, context, findOrCreateSpan(builder), this)); }
@Bean WebClient githubWebClient(final GithubProperties props) { return WebClient.builder() .baseUrl(props.getBaseUrl()) .filter((request, next) -> next.exchange( ClientRequest.from(request) .header(AUTHORIZATION, basicAuthorization(props.getToken())) .build())) .build(); }
@Bean public CommandLineRunner tweetBot(TwitterOAuth twitterOAuth, ReactiveTweetRepository tweetRepo) { return args -> { MultiValueMap<String, String> body = new LinkedMultiValueMap<>(); String tracks = "#cltjug,#FathersDay"; if (args.length > 0) { log.info("Using arguments as tracks"); tracks = String.join(",", args); } log.info("Filtering tracks [{}]", tracks); body.add("track", tracks); WebClient webClient = WebClient.create() .filter((currentRequest, next) -> next.exchange(ClientRequest.from(currentRequest) .header(HttpHeaders.AUTHORIZATION, twitterOAuth.oAuth1Header( currentRequest.url(), currentRequest.method(), body.toSingleValueMap())) .build())); Flux<Tweet> tweets = webClient .post() .uri(TwitterApiEndpoint.TWITTER_STREAM_API_STATUS_FILTER_URL) .contentType(MediaType.APPLICATION_FORM_URLENCODED) .body(BodyInserters.fromFormData(body)) .exchange() .flatMapMany(clientResponse -> clientResponse.bodyToFlux(Tweet.class)); tweetRepo.saveAll(tweets).subscribe(System.out::println); }; }