View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.hc.client5.http.impl;
28  
29  import java.util.Iterator;
30  
31  import org.apache.hc.core5.annotation.Internal;
32  import org.apache.hc.core5.http.HttpHeaders;
33  import org.apache.hc.core5.http.HttpMessage;
34  import org.apache.hc.core5.http.ParseException;
35  import org.apache.hc.core5.http.ProtocolException;
36  import org.apache.hc.core5.http.ProtocolVersion;
37  import org.apache.hc.core5.http.message.MessageSupport;
38  import org.apache.hc.core5.http.ssl.TLS;
39  
40  /**
41   * Protocol switch handler.
42   *
43   * @since 5.4
44   */
45  @Internal
46  public final class ProtocolSwitchStrategy {
47  
48      enum ProtocolSwitch { FAILURE, TLS }
49  
50      public ProtocolVersion switchProtocol(final HttpMessage response) throws ProtocolException  {
51          final Iterator<String> it = MessageSupport.iterateTokens(response, HttpHeaders.UPGRADE);
52  
53          ProtocolVersion tlsUpgrade = null;
54          while (it.hasNext()) {
55              final String token = it.next();
56              if (token.startsWith("TLS")) {
57                  // TODO: Improve handling of HTTP protocol token once HttpVersion has a #parse method
58                  try {
59                      tlsUpgrade = token.length() == 3 ? TLS.V_1_2.getVersion() : TLS.parse(token.replace("TLS/", "TLSv"));
60                  } catch (final ParseException ex) {
61                      throw new ProtocolException("Invalid protocol: " + token);
62                  }
63              } else if (token.equals("HTTP/1.1")) {
64                  // TODO: Improve handling of HTTP protocol token once HttpVersion has a #parse method
65              } else {
66                  throw new ProtocolException("Unsupported protocol: " + token);
67              }
68          }
69          if (tlsUpgrade == null) {
70              throw new ProtocolException("Invalid protocol switch response");
71          }
72          return tlsUpgrade;
73      }
74  
75  }