1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4//
5// HttpAlternateProtocols is an in-memory data structure used for keeping track
6// of which HTTP HostPortPairs have an alternate protocol that can be used
7// instead of HTTP on a different port.
8
9#ifndef NET_HTTP_HTTP_ALTERNATE_PROTOCOLS_H_
10#define NET_HTTP_HTTP_ALTERNATE_PROTOCOLS_H_
11#pragma once
12
13#include <map>
14#include <string>
15#include <utility>
16
17#include "base/basictypes.h"
18#include "net/base/host_port_pair.h"
19
20namespace net {
21
22class HttpAlternateProtocols {
23 public:
24  enum Protocol {
25    NPN_SPDY_1,
26    NPN_SPDY_2,
27    NUM_ALTERNATE_PROTOCOLS,
28    BROKEN,  // The alternate protocol is known to be broken.
29    UNINITIALIZED,
30  };
31
32  struct PortProtocolPair {
33    bool Equals(const PortProtocolPair& other) const {
34      return port == other.port && protocol == other.protocol;
35    }
36
37    std::string ToString() const;
38
39    uint16 port;
40    Protocol protocol;
41  };
42
43  typedef std::map<HostPortPair, PortProtocolPair> ProtocolMap;
44
45  static const char kHeader[];
46  static const char* const kProtocolStrings[NUM_ALTERNATE_PROTOCOLS];
47
48  HttpAlternateProtocols();
49  ~HttpAlternateProtocols();
50
51  // Reports whether or not we have received Alternate-Protocol for
52  // |http_host_port_pair|.
53  bool HasAlternateProtocolFor(const HostPortPair& http_host_port_pair) const;
54  bool HasAlternateProtocolFor(const std::string& host, uint16 port) const;
55
56  PortProtocolPair GetAlternateProtocolFor(
57      const HostPortPair& http_host_port_pair) const;
58  PortProtocolPair GetAlternateProtocolFor(
59      const std::string& host, uint16 port) const;
60
61  // SetAlternateProtocolFor() will ignore the request if the alternate protocol
62  // has already been marked broken via MarkBrokenAlternateProtocolFor().
63  void SetAlternateProtocolFor(const HostPortPair& http_host_port_pair,
64                               uint16 alternate_port,
65                               Protocol alternate_protocol);
66
67  // Marks the alternate protocol as broken.  Once marked broken, any further
68  // attempts to set the alternate protocol for |http_host_port_pair| will fail.
69  void MarkBrokenAlternateProtocolFor(const HostPortPair& http_host_port_pair);
70
71  const ProtocolMap& protocol_map() const { return protocol_map_; }
72
73  // Debugging to simulate presence of an AlternateProtocol.
74  // If we don't have an alternate protocol in the map for any given host/port
75  // pair, force this ProtocolPortPair.
76  static void ForceAlternateProtocol(const PortProtocolPair& pair);
77  static void DisableForcedAlternateProtocol();
78
79 private:
80  ProtocolMap protocol_map_;
81
82  static const char* ProtocolToString(Protocol protocol);
83
84  // The forced alternate protocol.  If not-null, there is a protocol being
85  // forced.
86  static PortProtocolPair* forced_alternate_protocol_;
87
88  DISALLOW_COPY_AND_ASSIGN(HttpAlternateProtocols);
89};
90
91}  // namespace net
92
93#endif  // NET_HTTP_HTTP_ALTERNATE_PROTOCOLS_H_
94