1 /*
2  * Copyright (C) 2014 Square, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 /*
17  * Forked from OkHttp 2.5.0
18  */
19 
20 package io.grpc.okhttp.internal;
21 
22 import java.io.IOException;
23 
24 /**
25  * Protocols that OkHttp implements for <a
26  * href="http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg">ALPN</a>
27  * selection.
28  *
29  * <h3>Protocol vs Scheme</h3>
30  * Despite its name, {@link java.net.URL#getProtocol()} returns the
31  * {@linkplain java.net.URI#getScheme() scheme} (http, https, etc.) of the URL, not
32  * the protocol (http/1.1, spdy/3.1, etc.). OkHttp uses the word <i>protocol</i>
33  * to identify how HTTP messages are framed.
34  */
35 public enum Protocol {
36   /**
37    * An obsolete plaintext framing that does not use persistent sockets by
38    * default.
39    */
40   HTTP_1_0("http/1.0"),
41 
42   /**
43    * A plaintext framing that includes persistent connections.
44    *
45    * <p>This version of OkHttp implements <a
46    * href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</a>, and tracks
47    * revisions to that spec.
48    */
49   HTTP_1_1("http/1.1"),
50 
51   /**
52    * Chromium's binary-framed protocol that includes header compression,
53    * multiplexing multiple requests on the same socket, and server-push.
54    * HTTP/1.1 semantics are layered on SPDY/3.
55    *
56    * <p>This version of OkHttp implements SPDY 3 <a
57    * href="http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1">draft
58    * 3.1</a>. Future releases of OkHttp may use this identifier for a newer draft
59    * of the SPDY spec.
60    */
61   SPDY_3("spdy/3.1"),
62 
63   /**
64    * The IETF's binary-framed protocol that includes header compression,
65    * multiplexing multiple requests on the same socket, and server-push.
66    * HTTP/1.1 semantics are layered on HTTP/2.
67    *
68    * <p>HTTP/2 requires deployments of HTTP/2 that use TLS 1.2 support
69    * {@linkplain CipherSuite#TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
70    * , present in Java 8+ and Android 5+. Servers that enforce this may send an
71    * exception message including the string {@code INADEQUATE_SECURITY}.
72    */
73   HTTP_2("h2"),
74 
75   /**
76    * The experimental "grpc-exp" string identifies gRPC (and by implication
77    * HTTP/2) when used over TLS. This indicates to the server that the client
78    * will only send gRPC traffic on the h2 connection and is negotiated in
79    * preference to h2 when the client and server support it, but is not
80    * standardized. Support for this may be removed at any time.
81    */
82   GRPC_EXP("grpc-exp");
83 
84   private final String protocol;
85 
Protocol(String protocol)86   Protocol(String protocol) {
87     this.protocol = protocol;
88   }
89 
90   /**
91    * Returns the protocol identified by {@code protocol}.
92    * @throws IOException if {@code protocol} is unknown.
93    */
get(String protocol)94   public static Protocol get(String protocol) throws IOException {
95     // Unroll the loop over values() to save an allocation.
96     if (protocol.equals(HTTP_1_0.protocol)) return HTTP_1_0;
97     if (protocol.equals(HTTP_1_1.protocol)) return HTTP_1_1;
98     if (protocol.equals(HTTP_2.protocol)) return HTTP_2;
99     if (protocol.equals(GRPC_EXP.protocol)) return GRPC_EXP;
100     if (protocol.equals(SPDY_3.protocol)) return SPDY_3;
101     throw new IOException("Unexpected protocol: " + protocol);
102   }
103 
104   /**
105    * Returns the string used to identify this protocol for ALPN, like
106    * "http/1.1", "spdy/3.1" or "h2".
107    */
toString()108   @Override public String toString() {
109     return protocol;
110   }
111 }
112