1a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath/* 2a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Copyright (C) 2013 Square, Inc. 3a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * 4a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Licensed under the Apache License, Version 2.0 (the "License"); 5a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * you may not use this file except in compliance with the License. 6a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * You may obtain a copy of the License at 7a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * 8a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * http://www.apache.org/licenses/LICENSE-2.0 9a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * 10a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Unless required by applicable law or agreed to in writing, software 11a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * distributed under the License is distributed on an "AS IS" BASIS, 12a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * See the License for the specific language governing permissions and 14a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * limitations under the License. 15a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath */ 16a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathpackage com.squareup.okhttp; 17a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 18a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathimport java.io.IOException; 19a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathimport java.util.LinkedHashSet; 20a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathimport java.util.Set; 21a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathimport javax.net.ssl.SSLHandshakeException; 22a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 23a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath/** 24a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * A blacklist of failed routes to avoid when creating a new connection to a 25a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * target address. This is used so that OkHttp can learn from its mistakes: if 26a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * there was a failure attempting to connect to a specific IP address, proxy 27a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * server or TLS mode, that failure is remembered and alternate routes are 28a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * preferred. 29a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath */ 30a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathpublic final class RouteDatabase { 31a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath private final Set<Route> failedRoutes = new LinkedHashSet<Route>(); 32a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 33a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath /** Records a failure connecting to {@code failedRoute}. */ 34a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath public synchronized void failed(Route failedRoute, IOException failure) { 35a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath failedRoutes.add(failedRoute); 36a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 37a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath if (!(failure instanceof SSLHandshakeException)) { 38a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath // If the problem was not related to SSL then it will also fail with 39a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath // a different TLS mode therefore we can be proactive about it. 40a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath failedRoutes.add(failedRoute.flipTlsMode()); 41a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 42a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 43a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 44a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath /** Records success connecting to {@code failedRoute}. */ 45a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath public synchronized void connected(Route route) { 46a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath failedRoutes.remove(route); 47a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 48a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 49a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath /** Returns true if {@code route} has failed recently and should be avoided. */ 50a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath public synchronized boolean shouldPostpone(Route route) { 51a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath return failedRoutes.contains(route); 52a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 53a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 54a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath public synchronized int failedRoutesCount() { 55a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath return failedRoutes.size(); 56a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 57a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath} 58