diff --git a/src/com/owncloud/android/lib/common/OwnCloudClient.java b/src/com/owncloud/android/lib/common/OwnCloudClient.java index 10e46fd5..a0ab0855 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudClient.java +++ b/src/com/owncloud/android/lib/common/OwnCloudClient.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2017 ownCloud GmbH. + * Copyright (C) 2018 ownCloud GmbH. * Copyright (C) 2012 Bartek Przybylski * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -33,6 +33,8 @@ import android.net.Uri; import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory; import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials; +import com.owncloud.android.lib.common.interceptors.HttpInterceptor; +import com.owncloud.android.lib.common.interceptors.UserAgentInterceptor; import com.owncloud.android.lib.common.methods.HttpBaseMethod; import com.owncloud.android.lib.common.network.RedirectionPath; import com.owncloud.android.lib.common.utils.Log_OC; @@ -71,7 +73,6 @@ public class OwnCloudClient extends HttpClient { private static final String PARAM_SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header"; private static final boolean PARAM_SINGLE_COOKIE_HEADER_VALUE = true; private static final String PARAM_PROTOCOL_VERSION = "http.protocol.version"; - private static final String USER_AGENT_HEADER = "User-Agent"; private static byte[] sExhaustBuffer = new byte[1024]; @@ -104,6 +105,7 @@ public class OwnCloudClient extends HttpClient { private String mRedirectedLocation; private static OkHttpClient mOkHttpClient = null; + private static HttpInterceptor mOkHttpInterceptor = null; /** * Constructor @@ -143,18 +145,9 @@ public class OwnCloudClient extends HttpClient { super(connectionMgr); - String userAgent = OwnCloudClientManagerFactory.getUserAgent(); - if (mOkHttpClient == null) { mOkHttpClient = new OkHttpClient.Builder() - .addInterceptor(chain -> - chain.proceed( - chain.request() - .newBuilder() - .addHeader(USER_AGENT_HEADER, userAgent) - .build() - ) - ) + .addInterceptor(getBaseOkHttpInterceptor()) .protocols(Arrays.asList(Protocol.HTTP_1_1)) .followRedirects(false) .build(); @@ -180,6 +173,24 @@ public class OwnCloudClient extends HttpClient { clearCredentials(); } + /** + * {@link HttpInterceptor} singleton + * @return {@link HttpInterceptor} instance with user agent + */ + public HttpInterceptor getBaseOkHttpInterceptor() { + + if (mOkHttpInterceptor == null) { + mOkHttpInterceptor = new HttpInterceptor(). + addRequestInterceptor( + new UserAgentInterceptor( + OwnCloudClientManagerFactory.getUserAgent() + ) + ); + } + + return mOkHttpInterceptor; + } + private void applyProxySettings() { String proxyHost = System.getProperty("http.proxyHost"); String proxyPortSt = System.getProperty("http.proxyPort"); diff --git a/src/com/owncloud/android/lib/common/authentication/OwnCloudBasicCredentials.java b/src/com/owncloud/android/lib/common/authentication/OwnCloudBasicCredentials.java index 2e851762..0b7a6a7e 100644 --- a/src/com/owncloud/android/lib/common/authentication/OwnCloudBasicCredentials.java +++ b/src/com/owncloud/android/lib/common/authentication/OwnCloudBasicCredentials.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2016 ownCloud GmbH. + * Copyright (C) 2018 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,8 @@ package com.owncloud.android.lib.common.authentication; import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.interceptors.BasicAuthInterceptor; +import com.owncloud.android.lib.common.interceptors.HttpInterceptor; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthPolicy; @@ -38,6 +40,8 @@ import okhttp3.Credentials; public class OwnCloudBasicCredentials implements OwnCloudCredentials { + private static final String TAG = OwnCloudCredentials.class.getSimpleName(); + private String mUsername; private String mPassword; private boolean mAuthenticationPreemptive; @@ -61,15 +65,17 @@ public class OwnCloudBasicCredentials implements OwnCloudCredentials { List authPrefs = new ArrayList<>(1); authPrefs.add(AuthPolicy.BASIC); - client.getOkHttpClient().newBuilder() - .addInterceptor(chain -> - chain.proceed( - chain.request() - .newBuilder() - .addHeader("Authorization", Credentials.basic(mUsername, mPassword)) - .build() - ) - ).build(); + for (HttpInterceptor.RequestInterceptor requestInterceptor : + client.getBaseOkHttpInterceptor().getRequestInterceptors()) { + if (requestInterceptor instanceof BasicAuthInterceptor) { + return; + } + } + + client.getBaseOkHttpInterceptor() + .addRequestInterceptor( + new BasicAuthInterceptor(Credentials.basic(mUsername, mPassword)) + ); //TODO client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs); diff --git a/src/com/owncloud/android/lib/common/interceptors/BasicAuthInterceptor.java b/src/com/owncloud/android/lib/common/interceptors/BasicAuthInterceptor.java new file mode 100644 index 00000000..152b7c20 --- /dev/null +++ b/src/com/owncloud/android/lib/common/interceptors/BasicAuthInterceptor.java @@ -0,0 +1,42 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2018 ownCloud GmbH. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.common.interceptors; + +import okhttp3.Request; + +public class BasicAuthInterceptor implements HttpInterceptor.RequestInterceptor { + + private static final String AUTHORIZATION_HEADER = "Authorization"; + private String mCredentials; + + public BasicAuthInterceptor(String credentials) { + mCredentials = credentials; + } + + @Override + public Request intercept(Request request) { + return request.newBuilder().addHeader(AUTHORIZATION_HEADER, mCredentials).build(); + } +} \ No newline at end of file diff --git a/src/com/owncloud/android/lib/common/interceptors/HttpInterceptor.java b/src/com/owncloud/android/lib/common/interceptors/HttpInterceptor.java new file mode 100644 index 00000000..acb8336e --- /dev/null +++ b/src/com/owncloud/android/lib/common/interceptors/HttpInterceptor.java @@ -0,0 +1,94 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2018 ownCloud GmbH. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.common.interceptors; + +import java.io.IOException; +import java.util.ArrayList; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +/** + * Http interceptor to use multiple interceptors in the same {@link okhttp3.OkHttpClient} instance + * @author David González Verdugo + */ +public class HttpInterceptor implements Interceptor { + + private final ArrayList mRequestInterceptors = new ArrayList<>(); + private final ArrayList mResponseInterceptors = new ArrayList<>(); + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + + for (RequestInterceptor interceptor : mRequestInterceptors) { + request = interceptor.intercept(request); + } + + Response response = chain.proceed(request); + + for (ResponseInterceptor interceptor : mResponseInterceptors) { + response = interceptor.intercept(response); + } + + return response; + } + + public interface RequestInterceptor { + Request intercept(Request request) throws IOException; + } + + public interface ResponseInterceptor { + Response intercept(Response response) throws IOException; + } + + public HttpInterceptor addRequestInterceptor (RequestInterceptor requestInterceptor) { + mRequestInterceptors.add(requestInterceptor); + return this; + } + + public HttpInterceptor addResponseInterceptor (ResponseInterceptor responseInterceptor) { + mResponseInterceptors.add(responseInterceptor); + return this; + } + + public ArrayList getRequestInterceptors() { + return mRequestInterceptors; + } + + public ArrayList getResponseInterceptors() { + return mResponseInterceptors; + } + + public boolean requestWithCredentials () { + for (RequestInterceptor requestInterceptor : mRequestInterceptors) { + if (requestInterceptor instanceof BasicAuthInterceptor) { + return true; + } + } + return false; + } +} diff --git a/src/com/owncloud/android/lib/common/interceptors/UserAgentInterceptor.java b/src/com/owncloud/android/lib/common/interceptors/UserAgentInterceptor.java new file mode 100644 index 00000000..bd46fc0f --- /dev/null +++ b/src/com/owncloud/android/lib/common/interceptors/UserAgentInterceptor.java @@ -0,0 +1,42 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2018 ownCloud GmbH. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.common.interceptors; + +import okhttp3.Request; + +public class UserAgentInterceptor implements HttpInterceptor.RequestInterceptor { + + private static final String USER_AGENT_HEADER = "User-Agent"; + private String mUserAgent; + + public UserAgentInterceptor(String userAgent) { + mUserAgent = userAgent; + } + + @Override + public Request intercept(Request request) { + return request.newBuilder().addHeader(USER_AGENT_HEADER, mUserAgent).build(); + } +} \ No newline at end of file