diff --git a/CHANGES.md b/CHANGES.md index 3cca82755..69f57bb58 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,6 @@ +# UNRELEASED +- [FIXED] Enable proxy support for session cookie and IAM authentication. + # 2.20.0 (2021-08-26) - [FIXED] Type of `sinceSeq` can be also a `String` besides an `Integer`. - [DEPRECATED] This library is now deprecated and will be EOL on Dec 31 2021. diff --git a/cloudant-client/src/main/java/com/cloudant/client/api/ClientBuilder.java b/cloudant-client/src/main/java/com/cloudant/client/api/ClientBuilder.java index 5b1dc4078..fd36219b2 100644 --- a/cloudant-client/src/main/java/com/cloudant/client/api/ClientBuilder.java +++ b/cloudant-client/src/main/java/com/cloudant/client/api/ClientBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright © 2015, 2020 IBM Corp. All rights reserved. + * Copyright © 2015, 2021 IBM Corp. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at @@ -257,7 +257,7 @@ public CloudantClient build() { // Create IAM cookie interceptor and set in HttpConnection interceptors IamCookieInterceptor cookieInterceptor = new IamCookieInterceptor(this.iamApiKey, - this.url.toString()); + this.url.toString(), this.proxyURL); props.addRequestInterceptors(cookieInterceptor); props.addResponseInterceptors(cookieInterceptor); @@ -274,7 +274,9 @@ else if (this.username != null && this.password != null) { //make interceptor if both username and password are not null //Create cookie interceptor and set in HttpConnection interceptors - CookieInterceptor cookieInterceptor = new CookieInterceptor(username, password, this.url.toString()); + CookieInterceptor cookieInterceptor = new CookieInterceptor(username, password, + this.url.toString(), this.proxyURL); + props.addRequestInterceptors(cookieInterceptor); props.addResponseInterceptors(cookieInterceptor); diff --git a/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/CookieInterceptor.java b/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/CookieInterceptor.java index b8fee0bf8..7be66cf38 100644 --- a/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/CookieInterceptor.java +++ b/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/CookieInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright © 2015, 2019 IBM Corp. All rights reserved. + * Copyright © 2015, 2021 IBM Corp. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at @@ -21,6 +21,7 @@ import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; +import java.net.URL; import java.net.URLEncoder; import java.util.Locale; import java.util.logging.Level; @@ -41,13 +42,26 @@ public class CookieInterceptor extends CookieInterceptorBase { * @param baseURL The base URL to use when constructing an `_session` request. */ public CookieInterceptor(String username, String password, String baseURL) { + this(username, password, baseURL, null); + } + + /** + * Constructs a cookie interceptor with proxy url. + * Credentials should be supplied not URL encoded, this class + * will perform the necessary URL encoding. + * + * @param username The username to use when getting the cookie (not URL encoded) + * @param password The password to use when getting the cookie (not URL encoded) + * @param baseURL The base URL to use when constructing an `_session` request. + * @param proxyURL The URL of the proxy server + */ + public CookieInterceptor(String username, String password, String baseURL, URL proxyURL) { // Use form encoding for the user/pass submission - super(baseURL, "/_session", "application/x-www-form-urlencoded"); + super(baseURL, "/_session", "application/x-www-form-urlencoded", proxyURL); try { this.auth = String.format("name=%s&password=%s", URLEncoder.encode(username, "UTF-8") - , URLEncoder.encode(password, "UTF-8")) + , URLEncoder.encode(password, "UTF-8")) .getBytes("UTF-8"); - ; } catch (UnsupportedEncodingException e) { //all JVMs should support UTF-8, so this should not happen throw new RuntimeException(e); diff --git a/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/CookieInterceptorBase.java b/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/CookieInterceptorBase.java index c68da056a..c0200926c 100644 --- a/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/CookieInterceptorBase.java +++ b/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/CookieInterceptorBase.java @@ -1,5 +1,5 @@ /* - * Copyright © 2017, 2019 IBM Corp. All rights reserved. + * Copyright © 2017, 2021 IBM Corp. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at @@ -59,13 +59,15 @@ public abstract class CookieInterceptorBase implements HttpConnectionRequestInte private final CookieManager cookieManager = new CookieManager(); private final ReadWriteLock sessionLock = new ReentrantReadWriteLock(true); private volatile UUID sessionId = UUID.randomUUID(); + private final URL proxyURL; /** * @param baseUrl the server URL to get cookies from * @param endpoint the server endpoint to get cookies from * @param requestMimeType the MIME Content-Type to use for the session request + * @param proxyURL the proxy URL */ - protected CookieInterceptorBase(String baseUrl, String endpoint, String requestMimeType) { + protected CookieInterceptorBase(String baseUrl, String endpoint, String requestMimeType, URL proxyURL) { try { baseUrl = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl; endpoint = endpoint.startsWith("/") ? endpoint : "/" + endpoint; @@ -77,6 +79,16 @@ protected CookieInterceptorBase(String baseUrl, String endpoint, String requestM logger.log(Level.SEVERE, "Failed to create URL for session endpoint", e); throw new RuntimeException(e); } + this.proxyURL = proxyURL; + } + + /** + * @param baseUrl the server URL to get cookies from + * @param endpoint the server endpoint to get cookies from + * @param requestMimeType the MIME Content-Type to use for the session request + */ + protected CookieInterceptorBase(String baseUrl, String endpoint, String requestMimeType) { + this(baseUrl, endpoint, requestMimeType, null); } /** @@ -129,6 +141,10 @@ HttpConnection makeSessionRequest(URL url, byte[] payload, String contentMimeTyp conn.requestProperties.put("accept", "application/json"); conn.setRequestBody(payload); + if (proxyURL != null) { + conn.connectionFactory.setProxy(this.proxyURL); + } + //when we request the session we need all interceptors except this one conn.requestInterceptors.addAll(context.connection.requestInterceptors); diff --git a/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/IamCookieInterceptor.java b/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/IamCookieInterceptor.java index 2a14e72f9..0c512d5b9 100644 --- a/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/IamCookieInterceptor.java +++ b/cloudant-http/src/main/java/com/cloudant/http/internal/interceptors/IamCookieInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright © 2019 IBM Corp. All rights reserved. + * Copyright © 2019, 2021 IBM Corp. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at @@ -34,7 +34,11 @@ public class IamCookieInterceptor extends CookieInterceptorBase { private final byte[] tokenRequestPayload; public IamCookieInterceptor(String apiKey, String baseUrl) { - super(baseUrl, "/_iam_session", null); + this(apiKey, baseUrl, null); + } + + public IamCookieInterceptor(String apiKey, String baseUrl, URL proxyURL) { + super(baseUrl, "/_iam_session", null, proxyURL); // Read iamServer from system property, or set default try {