Platform.java revision aefd3aaff8334d99f42cd8229e749e110aaf1d34
1/* 2 * Copyright (C) 2012 Square, Inc. 3 * Copyright (C) 2012 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17package com.squareup.okhttp.internal; 18 19import dalvik.system.SocketTagger; 20import java.io.OutputStream; 21import java.net.Socket; 22import java.net.SocketException; 23import java.net.URI; 24import java.net.URISyntaxException; 25import java.net.URL; 26import java.util.zip.Deflater; 27import java.util.zip.DeflaterOutputStream; 28import javax.net.ssl.SSLSocket; 29import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl; 30 31/** 32 * Access to proprietary Android APIs. Doesn't use reflection. 33 */ 34public final class Platform { 35 private static final Platform PLATFORM = new Platform(); 36 37 public static Platform get() { 38 return PLATFORM; 39 } 40 41 public void logW(String warning) { 42 System.logW(warning); 43 } 44 45 public void tagSocket(Socket socket) throws SocketException { 46 SocketTagger.get().tag(socket); 47 } 48 49 public void untagSocket(Socket socket) throws SocketException { 50 SocketTagger.get().untag(socket); 51 } 52 53 public URI toUriLenient(URL url) throws URISyntaxException { 54 return url.toURILenient(); 55 } 56 57 public void enableTlsExtensions(SSLSocket socket, String uriHost) { 58 if (socket instanceof OpenSSLSocketImpl) { 59 OpenSSLSocketImpl openSSLSocket = (OpenSSLSocketImpl) socket; 60 openSSLSocket.setUseSessionTickets(true); 61 openSSLSocket.setHostname(uriHost); 62 } 63 } 64 65 public void supportTlsIntolerantServer(SSLSocket socket) { 66 // In accordance with https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00 67 // the SCSV cipher is added to signal that a protocol fallback has taken place. 68 final String fallbackScsv = "TLS_FALLBACK_SCSV"; 69 boolean socketSupportsFallbackScsv = false; 70 String[] supportedCipherSuites = socket.getSupportedCipherSuites(); 71 for (int i = supportedCipherSuites.length - 1; i >= 0; i--) { 72 String supportedCipherSuite = supportedCipherSuites[i]; 73 if (fallbackScsv.equals(supportedCipherSuite)) { 74 socketSupportsFallbackScsv = true; 75 break; 76 } 77 } 78 if (socketSupportsFallbackScsv) { 79 // Add the SCSV cipher to the set of enabled ciphers. 80 String[] enabledCipherSuites = socket.getEnabledCipherSuites(); 81 String[] newEnabledCipherSuites = new String[enabledCipherSuites.length + 1]; 82 System.arraycopy(enabledCipherSuites, 0, 83 newEnabledCipherSuites, 0, enabledCipherSuites.length); 84 newEnabledCipherSuites[newEnabledCipherSuites.length - 1] = fallbackScsv; 85 socket.setEnabledCipherSuites(newEnabledCipherSuites); 86 } 87 socket.setEnabledProtocols(new String[]{"SSLv3"}); 88 } 89 90 /** 91 * Returns the negotiated protocol, or null if no protocol was negotiated. 92 */ 93 public byte[] getNpnSelectedProtocol(SSLSocket socket) { 94 return socket instanceof OpenSSLSocketImpl 95 ? ((OpenSSLSocketImpl) socket).getNpnSelectedProtocol() 96 : null; 97 } 98 99 /** 100 * Sets client-supported protocols on a socket to send to a server. The 101 * protocols are only sent if the socket implementation supports NPN. 102 */ 103 public void setNpnProtocols(SSLSocket socket, byte[] npnProtocols) { 104 if (socket instanceof OpenSSLSocketImpl) { 105 ((OpenSSLSocketImpl) socket).setNpnProtocols(npnProtocols); 106 } 107 } 108 109 /** 110 * Returns a deflater output stream that supports SYNC_FLUSH for SPDY name 111 * value blocks. This throws an {@link UnsupportedOperationException} on 112 * Java 6 and earlier where there is no built-in API to do SYNC_FLUSH. 113 */ 114 public OutputStream newDeflaterOutputStream( 115 OutputStream out, Deflater deflater, boolean syncFlush) { 116 return new DeflaterOutputStream(out, deflater, syncFlush); 117 } 118} 119