@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")); }
public DefaultClientRequestBuilder(ClientRequest other) { Assert.notNull(other, "ClientRequest must not be null"); this.method = other.method(); this.url = other.url(); headers(headers -> headers.addAll(other.headers())); cookies(cookies -> cookies.addAll(other.cookies())); attributes(attributes -> attributes.putAll(other.attributes())); body(other.body()); }
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); }; }
@Override public Mono<ClientResponse> exchange(ClientRequest clientRequest) { Assert.notNull(clientRequest, "ClientRequest must not be null"); HttpMethod httpMethod = clientRequest.method(); URI url = clientRequest.url(); String logPrefix = clientRequest.logPrefix(); return this.connector .connect(httpMethod, url, httpRequest -> clientRequest.writeTo(httpRequest, this.strategies)) .doOnRequest(n -> logRequest(clientRequest)) .doOnCancel(() -> logger.debug(logPrefix + "Cancel signal (to close connection)")) .map(httpResponse -> { logResponse(httpResponse, logPrefix); return new DefaultClientResponse(httpResponse, this.strategies, logPrefix); }); }
@Test public void filterWhenRefreshTokenNullThenShouldRefreshFalse() { OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.registration, "principalName", this.accessToken); ClientRequest request = ClientRequest.create(GET, URI.create("https://example.com")) .attributes(oauth2AuthorizedClient(authorizedClient)) .build(); this.function.filter(request, this.exchange).block(); List<ClientRequest> requests = this.exchange.getRequests(); assertThat(requests).hasSize(1); ClientRequest request0 = requests.get(0); assertThat(request0.headers().getFirst(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer token-0"); assertThat(request0.url().toASCIIString()).isEqualTo("https://example.com"); assertThat(request0.method()).isEqualTo(HttpMethod.GET); assertThat(getBody(request0)).isEmpty(); }
@Test public void basicAuthenticationUsernamePassword() { ClientRequest request = ClientRequest.create(HttpMethod.GET, DEFAULT_URL).build(); ClientResponse response = mock(ClientResponse.class); ExchangeFunction exchange = r -> { assertTrue(r.headers().containsKey(HttpHeaders.AUTHORIZATION)); assertTrue(r.headers().getFirst(HttpHeaders.AUTHORIZATION).startsWith("Basic ")); return Mono.just(response); }; ExchangeFilterFunction auth = ExchangeFilterFunctions.basicAuthentication("foo", "bar"); assertFalse(request.headers().containsKey(HttpHeaders.AUTHORIZATION)); ClientResponse result = auth.filter(request, exchange).block(); assertEquals(response, result); }
/** * 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()); }
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); }
@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); }; }
@Test public void requestHeaderAndCookie() { this.builder.build().get().uri("/path").accept(MediaType.APPLICATION_JSON) .cookies(cookies -> cookies.add("id", "123")) // SPR-16178 .exchange(); ClientRequest request = verifyAndGetRequest(); assertEquals("application/json", request.headers().getFirst("Accept")); assertEquals("123", request.cookies().getFirst("id")); verifyNoMoreInteractions(this.exchangeFunction); }
private Mono<OAuth2AuthorizedClient> authorizeWithRefreshToken(ClientRequest request, ExchangeFunction next, OAuth2AuthorizedClient authorizedClient) { ClientRegistration clientRegistration = authorizedClient .getClientRegistration(); String tokenUri = clientRegistration .getProviderDetails().getTokenUri(); ClientRequest refreshRequest = ClientRequest.create(HttpMethod.POST, URI.create(tokenUri)) .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .headers(headers -> headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret())) .body(refreshTokenBody(authorizedClient.getRefreshToken().getTokenValue())) .build(); return next.exchange(refreshRequest) .flatMap(response -> response.body(oauth2AccessTokenResponse())) .map(accessTokenResponse -> new OAuth2AuthorizedClient(authorizedClient.getClientRegistration(), authorizedClient.getPrincipalName(), accessTokenResponse.getAccessToken(), accessTokenResponse.getRefreshToken())) .map(result -> { Authentication principal = (Authentication) request.attribute( AUTHENTICATION_ATTR_NAME).orElse(new PrincipalNameAuthentication(authorizedClient.getPrincipalName())); HttpServletRequest httpRequest = (HttpServletRequest) request.attributes().get( HTTP_SERVLET_REQUEST_ATTR_NAME); HttpServletResponse httpResponse = (HttpServletResponse) request.attributes().get( HTTP_SERVLET_RESPONSE_ATTR_NAME); this.authorizedClientRepository.saveAuthorizedClient(result, principal, httpRequest, httpResponse); return result; }) .publishOn(Schedulers.elastic()); }
private ClientRequest.Builder initRequestBuilder() { if (defaultRequest != null) { defaultRequest.accept(this); } return ClientRequest.create(this.httpMethod, initUri()) .headers(headers -> headers.addAll(initHeaders())) .cookies(cookies -> cookies.addAll(initCookies())) .attributes(attributes -> attributes.putAll(this.attributes)); }
@Override public String method(ClientRequest request) { return request.method().name(); }
@Test public void url() throws URISyntaxException { URI url1 = new URI("http://example.com/foo"); URI url2 = new URI("http://example.com/bar"); ClientRequest.Builder builder = ClientRequest.create(DELETE, url1); assertEquals(url1, builder.build().url()); builder.url(url2); assertEquals(url2, builder.build().url()); }
/** * 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); } }; }
@Override public String url(ClientRequest request) { return request.url().toString(); }
@Test public void bodyClass() { String body = "foo"; Publisher<String> publisher = Mono.just(body); ClientRequest result = ClientRequest.create(POST, URI.create("http://example.com")) .body(publisher, String.class).build(); List<HttpMessageWriter<?>> messageWriters = new ArrayList<>(); messageWriters.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes())); ExchangeStrategies strategies = mock(ExchangeStrategies.class); when(strategies.messageWriters()).thenReturn(messageWriters); MockClientHttpRequest request = new MockClientHttpRequest(GET, "/"); result.writeTo(request, strategies).block(); assertNotNull(request.getBody()); StepVerifier.create(request.getBody()) .expectNextCount(1) .verifyComplete(); }