zoukankan      html  css  js  c++  java
  • OkHttp 官方wiki 翻译 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
    MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

    目录

    Calls

    wiki/Calls

    Http客户端的工作就是,接收用户的请求和产生返回结果。理论上这很简单,但在实践中却很棘手。

    • Requests :每一个Http请求都包含了一个URL,一个请求方式(像GET或POST),一系列的请求头。Requests中同样也可能包含了一个请求体:一个特定内容类型的数据流。
    • Responses:每一个应答请求的响应包含了一个响应状态码,一些响应头,以及可选的响应体。

    Rewriting Requests 重写请求

    When you provide OkHttp with an HTTP request, you’re describing the request at a high-level: “fetch me this URL with these headers.” For correctness and efficiency, OkHttp rewrites your request before transmitting it.

    当您向OkHttp提供HTTP请求时,您将在高级别描述请求:“使用这些头抓取此URL。”为了正确性和效率,OkHttp在传输请求之前会重写它。

    OkHttp may add headers that are absent from the original request, including Content-Length, Transfer-Encoding, User-Agent, Host, Connection, and Content-Type. It will add an Accept-Encoding header for transparent response compression unless the header is already present. If you’ve got cookies, OkHttp will add a Cookie header with them.

    OkHttp会在原始请求上添加缺少的头部数据。同时也会添加Accept-Encoding头部字段来压缩响应结果,除非这个头部字段已经存在。当获取到Cookies时,OkHttp也会使用它们来添加Cookie头部字段。

    Some requests will have a cached response. When this cached response isn’t fresh, OkHttp can do a conditional GET to download an updated response if it’s newer than what’s cached. This requires headers like If-Modified-Since and If-None-Match to be added.

    一些请求会有一个缓存的响应,当这个缓存的响应已经过时了(不新鲜)的时候,OkHttp可以做一个条件的GET来下载更新的响应,如果它比缓存的更新。这需要添加If-Modified-Since和If-None-Match等头部。

    Rewriting Responses 重写响应

    If transparent compression was used, OkHttp will drop the corresponding response headers Content-Encoding and Content-Length because they don’t apply to the decompressed response body.

    如果使用透明压缩,OkHttp将丢弃相应的响应头Content-Encoding和Content-Length,因为它们不适用于解压缩的响应体。

    If a conditional GET was successful, responses from the network and cache are merged as directed by the spec.

    如果条件GET请求成功,则根据规范合并来自网络和缓存的响应。

    Follow-up Requests 后续请求

    When your requested URL has moved, the webserver will return a response code like 302 to indicate the document’s new URL. OkHttp will follow the redirect to retrieve a final response.

    当您请求的URL已经移除时,网络服务器将返回一个响应代码(如302)以指示文档的新URL。 OkHttp将遵循重定向以获取最终响应。

    If the response issues an authorization challenge, OkHttp will ask the Authenticator (if one is configured) to satisfy the challenge. If the authenticator supplies a credential, the request is retried with that credential included.

    如果响应发出授权挑战,OkHttp将要求Authenticator(如果已配置)来满足挑战。 如果身份验证者提供证书,那么请求将重新包含该凭证

    如果获取的响应结果需要授权信息,OkHttp会调用Authenticator接口(如果已配置)来提供授权信息。如果认证者提供了证书,那么OkHttp会附带授权证书重新发起请求。

    Retrying Requests 重发请求

    Sometimes connections fail: either a pooled connection was stale and disconnected, or the webserver itself couldn’t be reached. OkHttp will retry the request with a different route if one is available.

    有时连接失败:池连接过时并断开连接,或者无法访问网络服务器本身。 OkHttp将使用不同的可用路由重试该请求。

    如果网络连接失败,例如连接池过时,断线或者服务器无法到达,OkHttp会尝试使用不同的可用路由线路重新发起请求。

    总结

    With rewrites, redirects, follow-ups and retries, your simple request may yield many requests and responses. OkHttp uses Call to model the task of satisfying your request through however many intermediate requests and responses are necessary. Typically this isn’t many! But it’s comforting to know that your code will continue to work if your URLs are redirected or if you failover to an alternate IP address.

    通过重写,重定向,后续请求和重试,您的简单请求可能会产生许多请求和响应。 OkHttp使用Call来建立满足您的请求的任务,通过可能需要许多中间请求和响应。通常这不是很多! 但是这是令人安慰的事,如果您知道您的代码将继续工作,假如您的URL被重定向或者如果您的失效备援转移到备用IP地址。

    Calls可以使用两种不同的方式来执行:

    • Synchronous 同步 :发起请求的线程会阻塞直到读取到响应内容
    • Asynchronous 异步:您在任何线程上排队请求,并在响应可读时回调到另一个线程。

    Calls can be canceled from any thread. This will fail the call if it hasn’t yet completed! Code that is writing the request body or reading the response body will suffer an IOException when its call is canceled.

    可以在任何一个线程中取消Calls请求。当Call请求还没完成时,这将使Calls请求失效。在取消了Call请求后,编写request请求或者读取response响应体的代码,会发生IOException异常。

    Dispatch 调度

    For synchronous calls, you bring your own thread and are responsible for managing how many simultaneous requests you make. Too many simultaneous connections wastes resources; too few harms latency.

    对于同步调用,您自带线程,并负责管理您进行的多个 同时的/并发 请求。 同时连接太多浪费资源; 太少的危害延迟。

    For asynchronous calls, Dispatcher implements policy for maximum simultaneous requests. You can set maximums per-webserver (default is 5), and overall (default is 64).

    对于异步调用,Dispatcher实现最大同时请求的策略。 您可以设置每个网络服务器的最大值(默认值为5),或者全部(默认值为64)。

    Connections

    okhttp/wiki/Connections

    Although you provide only the URL, OkHttp plans its connection to your webserver using three types: URL, Address, and Route.

    虽然您只提供URL,但是OkHttp计划使用URL,Address或Route路由三种类型来与服务器进行连接。

    URLs 网址

    URLs are fundamental to HTTP and the Internet. In addition to being a universal, decentralized naming scheme for everything on the web, they also specify how to access web resources.

    URL是HTTP和互联网的基础。除了为网络上的所有内容提供一个通用、分散的命名方案,同时也能指定如何访问网络资源。

    URLs是抽象的:

    They specify that the call may be plaintext (http) or encrypted (https), but not which cryptographic algorithms should be used. Nor do they specify how to verify the peer's certificates (the HostnameVerifier) or which certificates can be trusted (the SSLSocketFactory).

    URL可以指定请求是明文的(http)或者加密的(https),但是不需要使用哪种加密算法。它们也没有指定如何验证对等的证书,或者哪些证书可以被信任。

    They don't specify whether a specific proxy server should be used or how to authenticate with that proxy server.

    他们不指定是否应该使用特定的代理服务器,或者如何使用该代理服务器进行身份验证。

    They're also concrete: each URL identifies a specific path (like /square/okhttp) and query (like ?q=sharks&lang=en). Each webserver hosts many URLs.

    它们也是具体的:每一个URL标识一个特定的路径和查询。每一个Web服务器都有许多URL。

    Addresses 地址

    Addresses specify a webserver (like github.com) and all of the static configuration necessary to connect to that server: the port number, HTTPS settings, and preferred network protocols (like HTTP/2 or SPDY).

    地址指定Web服务器以及连接到该服务器所需的所有静态配置:端口号,HTTPS设置和首选的网络协议。

    URLs that share the same address may also share the same underlying TCP socket connection. Sharing a connection has substantial performance benefits: lower latency, higher throughput (due to TCP slow start) and conserved battery. OkHttp uses a ConnectionPool that automatically reuses HTTP/1.x connections and multiplexes HTTP/2 and SPDY connections.

    共享相同地址的URL也可以共享相同的底层TCP套接字连接。共享连接具有显著的性能优势: 更低的延迟,更高的吞吐量(得益于TCP慢启动)和保护电池。OKHttp使用连接池来自动复用 HTTP/1.X 连接和多路的 HTTP/2 和 SPDY 连接。

    In OkHttp some fields of the address come from the URL (scheme, hostname, port) and the rest come from the OkHttpClient.

    在OkHttp中,地址的某些字段来自于URL(scheme,主机名,端口),其余部分则来自OkHttpClient。

    Routes 路由

    Routes supply the dynamic information necessary to actually connect to a webserver. This is the specific IP address to attempt (as discovered by a DNS query), the exact proxy server to use (if a ProxySelector is in use), and which version of TLS to negotiate (for HTTPS connections).

    路由提供实际连接到网络服务器所需的动态信息。这是要尝试的特定IP地址(通过DNS查询发现),要使用的确切代理服务器(如果启用了ProxySelector),以及要协商的TLS版本(用于HTTPS连接)。

    There may be many routes for a single address. For example, a webserver that is hosted in multiple datacenters may yield multiple IP addresses in its DNS response.

    单个地址可能有很多路由。例如,托管在多个数据中心中的Web服务器,可能会在其DNS响应中产生多个IP地址。

    总结

    When you request a URL with OkHttp, here's what it does:

    • It uses the URL and configured OkHttpClient to create an address. This address specifies how we'll connect to the webserver.
    • It attempts to retrieve a connection with that address from the connection pool.
    • If it doesn't find a connection in the pool, it selects a route to attempt. This usually means making a DNS request to get the server's IP addresses. It then selects a TLS version and proxy server if necessary.
    • If it's a new route, it connects by building either a direct socket connection, a TLS tunnel (for HTTPS over an HTTP proxy), or a direct TLS connection. It does TLS handshakes as necessary.
    • It sends the HTTP request and reads the response.

    当使用OkHttp来请求一个URL时,它做了如下事情:

    • 它使用URL和已经配置的OkHttpClient来创建一个地址。这个地址指定了我们如何连接到Web服务器。
    • 它尝试从连接池中检索该地址的连接。
    • 如果没有在池中找到连接,它会尝试选择一个路由。这通常意味着要求DNS服务器的IP地址。然后,如果需要,可以选择TLS版本和代理服务器。
    • 如果这是一条新的路由,则通过构建直接套接字连接,一个TLS隧道(通过HTTP代理的HTTPS),或者一个直接的TLS连接进行连接。根据需要,OkHttp会进行TLS握手。
    • 会发送HTTP请求并读取响应。

    If there's a problem with the connection, OkHttp will select another route and try again. This allows OkHttp to recover when a subset of a server's addresses are unreachable. It's also useful when a pooled connection is stale or if the attempted TLS version is unsupported.

    如果连接有问题,OkHttp将选择另一个路由,然后重试。 这允许OkHttp在服务器地址的一个子集不可达时恢复。 当池连接过时或者尝试的TLS版本不受支持时也很有用。

    Once the response has been received, the connection will be returned to the pool so it can be reused for a future request. Connections are evicted from the pool after a period of inactivity.

    一旦接收到响应,此次连接将被返回到连接池中,以便在将来的请求中可以重用它。 连接在一段时间不活动之后 被逐出/被赶出 池。

    Interceptors

    wiki/Interceptors

    Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls. Here's a simple interceptor that logs the outgoing request and the incoming response.

    Interceptors是一种强大的机制,可以监视、重写和重试Call请求。下面是一个简单的拦截器,它记录发出的请求和返回的响应。

    class LoggingInterceptor implements Interceptor {
        @Override
        public Response intercept(Interceptor.Chain chain) throws IOException {
            String time = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS", Locale.getDefault()).format(new Date());
            System.out.println("--------------------------------  " + time + "  --------------------------------");
            Request request = chain.request();//发出的请求
            System.out.println("【url】" + request.url() + "
    【con】" + chain.connection() + "
    【headers】" + request.headers());
    
            Response response = chain.proceed(request);//生成与请求对应的响应。这里是所有HTTP工作发生的地方
            System.out.println("
    【url】" + response.request().url() + "
    【headers】" + response.headers());
    
            System.out.println("------------------------------------------------------------------");
            return response;
        }
    }

    A call to chain.proceed(request) is a critical part of each interceptor’s implementation. This simple-looking method is where all the HTTP work happens, producing a response to satisfy the request.

    在每一个拦截器实现中,其中一个关键部分就是调用chain.proceed(request)。这个简单的方法是所有HTTP工作发生的地方,调用后将生成与请求对应的响应。

    Interceptors can be chained. Suppose you have both a compressing interceptor and a checksumming interceptor: you'll need to decide whether data is compressed and then checksummed, or checksummed and then compressed. OkHttp uses lists to track interceptors, and interceptors are called in order.

    拦截器可以链接。假设有一个压缩拦截器和一个校验和拦截器:你需要决定数据是否先被压缩,然后校验和;或者先校验和,然后再压缩。OkHttp使用列表来跟踪拦截器,并按顺序调用拦截器。

    两种拦截器

    Interceptors are registered as either application or network interceptors. We'll use the LoggingInterceptor defined above to show the difference.

    OkHttp中的拦截器可以注册为应用程序拦截器或者网络拦截器。在下面的例子中将使用上面定义的LogginInterceptor拦截器来显示两种拦截器的区别。

    private static void loggingInterceptor(boolean isApplicationInterceptor) throws IOException {
        OkHttpClient client;
        if (isApplicationInterceptor) client = new OkHttpClient.Builder().addInterceptor(new LoggingInterceptor()).build();
        else client = new OkHttpClient.Builder().addNetworkInterceptor(new LoggingInterceptor()).build();
    
        Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").header("User-Agent", "OkHttp Example").build();
    
        Response response = client.newCall(request).execute();
        if (!response.isSuccessful()) throw new IOException("异常码:" + response);
    
        System.out.println("【响应url】" + response.request().url());
        response.body().close();
    }

    应用程序拦截器

    Register an application interceptor by calling addInterceptor() on OkHttpClient.Builder:

    可以在OkHttpClient.Builder中调用addInterceptor()方法来注册一个应用程序拦截器:

    The URL http:// to https://, and OkHttp follows this redirect automatically. Our application interceptor is called once and the response returned from chain.proceed() has the redirected response:

    上文中的URL http:// 重定向到 https:// ,OkHttp会自动跟踪这个重定向。应用程序拦截器只被调用一次,从chain.proceed()方法返回的响应结果,具有重定向的响应结果。结果输出如下:

    --------------------------------  2017.09.11 16:34:56 596  --------------------------------
    【url】http://publicobject.com/helloworld.txt    //只有一次请求,即原始的请求
    【con】null
    【headers】User-Agent: OkHttp Example
    
    【url】https://publicobject.com/helloworld.txt
    【headers】Server: nginx/1.10.0 (Ubuntu)
    Date: Mon, 11 Sep 2017 08:35:55 GMT
    Content-Type: text/plain
    Content-Length: 1759
    Last-Modified: Tue, 27 May 2014 02:35:47 GMT
    Connection: keep-alive
    ETag: "5383fa03-6df"
    Accept-Ranges: bytes
    ------------------------------------------------------------------
    【响应url】https://publicobject.com/helloworld.txt    //返回的响应结果具有重定向的响应结果

    We can see that we were redirected because response.request().url() is different from request.url(). The two log statements log two different URLs.

    从输出中可以看到,响应结果被重定向了,两个日志语句记录了两个不同的URL。

    网络拦截器

    Registering a network interceptor is quite similar. Call addNetworkInterceptor() instead of addInterceptor():

    注册网络拦截器和注册应用程序拦截器非常类似。只需在OkHttpClient.Builder上调用addNetworkInterceptor()即可。

    When we run this code, the interceptor runs twice. Once for the initial request to http:// , and another for the redirect to https://.

    当运行该代码时,网络拦截器将运行两次。第一次是最初的请求,第二次是重定向后的请求。

    --------------------------------  2017.09.11 16:41:37 244  --------------------------------
    【url】http://publicobject.com/helloworld.txt        //第一次是最初的请求
    【con】Connection{publicobject.com:80, proxy=DIRECT hostAddress=publicobject.com/54.187.32.157:80 cipherSuite=none protocol=http/1.1}
    【headers】User-Agent: OkHttp Example
    Host: publicobject.com
    Connection: Keep-Alive
    Accept-Encoding: gzip
    
    【url】http://publicobject.com/helloworld.txt
    【headers】Server: nginx/1.10.0 (Ubuntu)
    Date: Mon, 11 Sep 2017 08:42:35 GMT
    Content-Type: text/html
    Content-Length: 194
    Connection: keep-alive
    Location: https://publicobject.com/helloworld.txt
    ------------------------------------------------------------------
    --------------------------------  2017.09.11 16:41:38 319  --------------------------------
    【url】https://publicobject.com/helloworld.txt        //第二次是重定向后的请求
    【con】Connection{publicobject.com:443, proxy=DIRECT hostAddress=publicobject.com/54.187.32.157:443 cipherSuite=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 protocol=http/1.1}
    【headers】User-Agent: OkHttp Example
    Host: publicobject.com
    Connection: Keep-Alive
    Accept-Encoding: gzip
    
    【url】https://publicobject.com/helloworld.txt
    【headers】Server: nginx/1.10.0 (Ubuntu)
    Date: Mon, 11 Sep 2017 08:42:36 GMT
    Content-Type: text/plain
    Content-Length: 1759
    Last-Modified: Tue, 27 May 2014 02:35:47 GMT
    Connection: keep-alive
    ETag: "5383fa03-6df"
    Accept-Ranges: bytes
    ------------------------------------------------------------------
    【响应url】https://publicobject.com/helloworld.txt    //返回的响应结果具有重定向的响应结果

    The network requests also contain more data, such as the Accept-Encoding: gzip header added by OkHttp to advertise support for response compression. The network interceptor's Chain has a non-null Connection that can be used to interrogate the IP address and TLS configuration that were used to connect to the webserver.

    上面的网络请求同时还包含更多的数据,例如由OkHttp添加的gzip头部字段,用于支持压缩响应结果。网络拦截器的 Chain 具有一个非空的 Connection,其可用于查询连接到Web服务器的IP地址和TLS配置。

    在两种拦截器间选择

    这两个拦截器链都有相对优点。

    Application interceptors

    • Don't need to worry about intermediate responses like redirects and retries.
    • Are always invoked once, even if the HTTP response is served from the cache.
    • Observe the application's original intent. Unconcerned with OkHttp-injected headers like If-None-Match.
    • Permitted to short-circuit and not call Chain.proceed().
    • Permitted to retry and make multiple calls to Chain.proceed().

    应用程序拦截器

    • 不需要担心比如重定向和重试的中间响应。
    • 总是被调用一次,即使HTTP响应结果是从缓存中获取的。
    • 监控应用程序的原始意图。不关心OkHttp注入的头部字段,例如If-None-Match。
    • 允许短路,并不调用Chain.proceed()。
    • 允许重试,并多次调用Chain.proceed()。

    Network Interceptors

    • Able to operate on intermediate responses like redirects and retries.
    • Not invoked for cached responses that short-circuit the network.
    • Observe the data just as it will be transmitted over the network.
    • Access to the Connection that carries the request.

    网络拦截器

    • 能够对中间的响应进行操作,比如重定向和重试。
    • 当发生网络短路时,不调用缓存的响应结果。
    • 就像数据在网络上传输一样监控数据。
    • 访问承载请求的连接。

    Rewriting Requests 重写请求

    Interceptors can add, remove, or replace request headers. They can also transform the body of those requests that have one. For example, you can use an application interceptor to add request body compression if you're connecting to a webserver known to support it.

    拦截器可以添加,删除或者替换请求头,同时也可以改变请求中包含的请求体。例如,如果你知道要连接的Web服务器支持请求体压缩,那么你就可以使用一个应用程序拦截器来添加请求体压缩。

    public class Test {
        public static final String TEXT = "This interceptor compresses the HTTP request body. Many webservers can't handle this!" //
                + "此拦截器压缩HTTP请求体。 许多Web服务器无法处理这个!";
        public static void main(String[] args) throws IOException {
            OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new GzipRequestInterceptor()).build();//addNetworkInterceptor
            RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain; charset=UTF-8"), TEXT);//请求数据
            Request request = new Request.Builder().url("https://qgy18.com/node/").post(requestBody).build();
    
            System.out.println("【原始数据长度】" + TEXT.getBytes().length + "【请求body长度】" + request.body().contentLength());//159
            Response response = client.newCall(request).execute(); //响应
            System.out.println("【响应body长度】" + response.body().contentLength());//-1
            System.out.println("【响应中的请求body长度】" + response.request().body().contentLength());//-1
        }
    }
    /**
     * This interceptor compresses the HTTP request body. Many webservers can't handle this!
     * 此拦截器压缩HTTP请求体。 许多Web服务器无法处理这个!
     */
    class GzipRequestInterceptor implements Interceptor {
        @Override
        public Response intercept(Interceptor.Chain chain) throws IOException {
            final Request originalReq = chain.request();
            //生成与请求对应的响应
            if (originalReq.body() == null || originalReq.header("Content-Encoding") != null) return chain.proceed(originalReq);
            RequestBody compressedRequestBody = new RequestBody() {
                @Override
                public MediaType contentType() {
                    return originalReq.body().contentType();
                }
                @Override
                public long contentLength() {//我草泥马,这里的长度到底要怎么搞?
                    return -1; // We don't know the compressed length in advance提前!
                }
                @Override
                public void writeTo(BufferedSink sink) throws IOException {
                    BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
                    originalReq.body().writeTo(gzipSink);
                    gzipSink.close();
                }
            };
            Request compressedRequest = originalReq.newBuilder()//
                    .header("content-encoding", "gzip")//添加、删除或者替换请求头
                    .method(originalReq.method(), compressedRequestBody)//改变请求体
                    .build();
    
            //我草泥马,我怎么拿到请求体中的内容?
            Response response = chain.proceed(compressedRequest);//重新生成与请求对应的响应
            return response;
        }
    }

    Rewriting Responses 重写响应

    Symmetrically, interceptors can rewrite response headers and transform the response body. This is generally more dangerous than rewriting request headers because it may violate the webserver's expectations!

    相应的,拦截器同样可以重写响应头部并改变响应体。这通常比重写请求头更危险,因为它可能违反了Web服务器的期望。

    If you're in a tricky situation and prepared to deal with the consequences, rewriting response headers is a powerful way to work around problems. For example, you can fix a server's misconfigured Cache-Control response header to enable better response caching:

    如果你处在一个复杂的环境中,并且准备处理这些结果,那么重写响应头是解决问题的一种很有效的方法。例如,你可以修复服务器错误配置的Cache-Control响应头,来启用更好的响应缓存。

    // Dangerous interceptor that rewrites the server's cache-control header.
    class ReWriteCacheControlInterceptor implements Interceptor {
        @Override
        public Response intercept(Interceptor.Chain chain) throws IOException {
            Response originalResponse = chain.proceed(chain.request());
            return originalResponse.newBuilder()
                    .header("Cache-Control", "max-age=60")//重写响应头部并改变响应体
                    .build();
        }
    }

    Typically this approach works best when it complements a corresponding fix on the webserver!

    通常,这种方法在对Web服务器的"相应修复进行补充时",效果是最好的。

    Availability 可用性

    OkHttp's interceptors require OkHttp 2.2 or better. Unfortunately, interceptors do not work with OkUrlFactory, or the libraries that build on it, including Retrofit ≤ 1.8 and Picasso ≤ 2.4.

    OkHttp的拦截器需要OkHttp2.2或者更高的版本。不幸的是,拦截器目前无法与OkUrlFactory进行工作,或者建立在它之上的库,包括小于1.8版本的Retrofit和小于2.4的Picasso。

    HTTPS

    wiki/HTTPS

    OkHttp试图平衡两个相互冲突的问题:

    • Connectivity to as many hosts as possible. That includes advanced hosts that run the latest versions of boringssl and less out of date hosts running older versions of OpenSSL.

      尽可能多地连接到主机。其中包括高级的、运行最新版本的boringssl的主机,以及少部分过时的、运行较旧版本的OpenSSL的主机。

    • Security of the connection. This includes verification of the remote webserver with certificates and the privacy of data exchanged with strong ciphers.

      连接安全性。这包括使用证书验证远程Web服务器,以及使用强密码交换数据的隐私。

    When negotiating谈判、交涉 a connection to an HTTPS server, OkHttp needs to know which TLS versions and cipher suites to offer. A client that wants to maximize connectivity would include obsolete TLS versions and weak-by-design cipher suites. A strict client that wants to maximize security would be limited to only the latest TLS version and strongest cipher suites.

    在与HTTPS服务器进行连接时,OkHttp需要知道需要提供哪个TLS版本和密码组。客户端如果想要最大化连接性,则需要包括过时的TLS版本和弱设计的密码组。一个严格的客户端如果想要最大化安全性,则需要被局限于使用最新的TLS版本和最强大的密码组。

    Specific security vs. connectivity decisions are implemented by ConnectionSpec. OkHttp includes three built-in connection specs:

    特定安全性与连接性决定由ConnectionSpec实现。OkHttp包括三个内置连接规范:

    • MODERN_TLS is a secure configuration that connects to modern HTTPS servers. MODERN_TLS 是一个连接到现代HTTPS服务器的安全配置。
    • COMPATIBLE_TLS is a secure configuration that connects to secure–but not current–HTTPS servers. COMPATIBLE_TLS 是一个连接到安全但非最新的HTTPS服务器的安全配置。
    • CLEARTEXT is an insecure configuration that is used for http:// URLs. CLEARTEXT 是一个用于http:// URL的不安全配置。

    By default, OkHttp will attempt a MODERN_TLS connection, and fall back to COMPATIBLE_TLS connection if the modern configuration fails.

    OkHttp默认会尝试使用MODERN_TLS连接,如果配置失败则会回滚使用COMPATIBLE_TLS连接。

    The TLS versions and cipher suites in each spec can change with each release. For example, in OkHttp 2.2 we dropped support for SSL 3.0 in response to the POODLE attack. And in OkHttp 2.3 we dropped support for RC4. As with your desktop web browser, staying up-to-date with OkHttp is the best way to stay secure.

    每个规范中的TLS版本和密码组可以在每个发布版本中进行更改。例如,在OkHttp2.2中针对POODLE的攻击,放弃了对SSL3.0的支持。在OkHttp2.3中放弃了对RC4的支持。与桌面WEB浏览器一样,保持最新版本的OkHttp是保持安全的最佳方式。

    You can build your own connection spec with a custom set of TLS versions and cipher suites. For example, this configuration is limited to three highly-regarded cipher suites. Its drawback is that it requires Android 5.0+ and a similarly current webserver.

    用户可以使用一个自定义的TLS版本和密码组来构建你自己的连接规范。例如,下面代码中的配置仅限于三个高度重视的密码组。它的缺点就是,它需要Android5.0+以上的版本和一个类似目前的网络服务器。

    ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)//MODERN_TLS 是一个连接到现代HTTPS服务器的安全配置
            .tlsVersions(TlsVersion.TLS_1_2)//OkHttp需要知道需要提供哪个TLS版本和密码组
            .cipherSuites(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,//limited to three highly-regarded cipher suites
                    CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
                    CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
            .build();
    
    OkHttpClient client = new OkHttpClient.Builder()
            .connectionSpecs(Collections.singletonList(spec))
            .build();

    Certificate Pinning 证书固定

    By default, OkHttp trusts the certificate authorities of the host platform. This strategy maximizes connectivity, but it is subject to容易遭受、受…管制 certificate authority attacks such as the 2011 DigiNotar attack. It also assumes your HTTPS servers' certificates are signed by a certificate authority.

    默认情况下,OkHttp信任主机平台的证书颁发机构。这种策略最大程度地保持了连接性,但是它容易受到诸如2011年DigiNotar攻击,等认证机构的攻击。它还假设您的HTTPS服务器的证书由证书颁发机构签署。

    Use CertificatePinner to restrict which certificates and certificate authorities are trusted. CertificatePinner increases security, but limits your server team's abilities to update their TLS certificates. Do not use certificate pinning without the blessing of your server's TLS administrator!

    使用CertificatePinner来限制哪些证书和证书颁发机构是受信任的。CertificatePinner提高了安全性,但是服务器团队被受限去更新它们的TLS证书。当你的服务器TLS管理员没有同意时,不要使用CertificatePinner。

    CertificatePinner certificatePinner = new CertificatePinner.Builder()//使用CertificatePinner来限制哪些证书和证书颁发机构是受信任的
            .add("publicobject.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=")
            .build();
    
    OkHttpClient client = new OkHttpClient.Builder()
            .certificatePinner(certificatePinner)//使用CertificatePinner来限制哪些证书和证书颁发机构是受信任的
            .build();
    
    Request request = new Request.Builder().url("https://publicobject.com/robots.txt").build();
    Response response = client.newCall(request).execute();
    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
    
    for (java.security.cert.Certificate certificate : response.handshake().peerCertificates()) {//受信任的证书和证书颁发机构
        System.out.println("【证书固定】" + CertificatePinner.pin(certificate));
    }

    omizing Trusted Certificates 定制受信任的证书

    The full code sample shows how to replace the host platform’s certificate authorities with your own set. As above, do not use custom certificates without the blessing of your server’s TLS administrator!

    下面例子中完整的代码示例,展示了怎么使用自己的设置,来替换主机平台的证书颁发机构。和上面一样,当服务器TLS管理员没有同意时,不要使用自定义证书。

    OkHttpClient client = new OkHttpClient.Builder()
        .sslSocketFactory(sslSocketFactory, trustManager)//使用自己的设置来替换主机平台的证书颁发机构
        .build();

    2017-06-20

  • 相关阅读:
    js获取数组中的值显示[object HTMLInputElement]
    IntelliJ Idea 常用快捷键
    MySQL查询本周、上周、本月、上个月份数据的sql代码
    表的基本
    字符串类型
    备份数据库
    增加标 和增加其内容
    数据库的基本
    jq做的简单的变色表格
    jq做的简单的轮播
  • 原文地址:https://www.cnblogs.com/baiqiantao/p/7054055.html
Copyright © 2011-2022 走看看