proxygen
HTTPTransactionIngressSM.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
11 
12 #include <folly/Indestructible.h>
13 
14 namespace proxygen {
15 
16 // +--> ChunkHeaderReceived -> ChunkBodyReceived
17 // | ^ v
18 // | | ChunkCompleted -> TrailersReceived
19 // | |_______________| | |
20 // | v v
21 // Start -> HeadersReceived ---------------> EOMQueued ---> ReceivingDone
22 // | | ^ ^
23 // | +-----> RegularBodyReceived --+ |
24 // | |
25 // +---------> UpgradeComplete --------+
26 
27 std::pair<HTTPTransactionIngressSMData::State, bool>
32  using TransitionTable = std::map<std::pair<State, Event>, State>;
33 
34  static const folly::Indestructible<TransitionTable> transitions{
35  TransitionTable{
37 
38  // For HTTP receiving 100 response, then a regular response
39  {{State::HeadersReceived, Event::onHeaders}, State::HeadersReceived},
40 
44  // special case - 0 byte body with trailers
48 
49  {{State::RegularBodyReceived, Event::onBody}, State::RegularBodyReceived},
50  // HTTP2 supports trailers and doesn't handle body as chunked events
51  {{State::RegularBodyReceived, Event::onTrailers}, State::TrailersReceived},
52  {{State::RegularBodyReceived, Event::onEOM}, State::EOMQueued},
53 
55 
56  {{State::ChunkBodyReceived, Event::onBody}, State::ChunkBodyReceived},
58 
59  {{State::ChunkCompleted, Event::onChunkHeader}, State::ChunkHeaderReceived},
60  // TODO: "trailers" may be received at any time due to the SPDY HEADERS
61  // frame coming at any time. We might want to have a
62  // TransactionStateMachineFactory that takes a codec and generates the
63  // appropriate transaction state machine from that.
64  {{State::ChunkCompleted, Event::onTrailers}, State::TrailersReceived},
65  {{State::ChunkCompleted, Event::onEOM}, State::EOMQueued},
66 
67  {{State::TrailersReceived, Event::onEOM}, State::EOMQueued},
68 
69  {{State::UpgradeComplete, Event::onBody}, State::UpgradeComplete},
70  {{State::UpgradeComplete, Event::onEOM}, State::EOMQueued},
71 
73  }
74  };
75 
76  auto const &it = transitions->find(std::make_pair(s, e));
77  if (it == transitions->end()) {
78  return std::make_pair(s, false);
79  }
80 
81  return std::make_pair(it->second, true);
82 }
83 
84 std::ostream& operator<<(std::ostream& os,
86  switch (s) {
88  os << "Start";
89  break;
91  os << "HeadersReceived";
92  break;
94  os << "RegularBodyReceived";
95  break;
97  os << "ChunkHeaderReceived";
98  break;
100  os << "ChunkBodyReceived";
101  break;
103  os << "ChunkCompleted";
104  break;
106  os << "TrailersReceived";
107  break;
109  os << "UpgradeComplete";
110  break;
112  os << "EOMQueued";
113  break;
115  os << "ReceivingDone";
116  break;
117  }
118 
119  return os;
120 }
121 
122 std::ostream& operator<<(std::ostream& os,
124  switch (e) {
126  os << "onHeaders";
127  break;
129  os << "onBody";
130  break;
132  os << "onChunkHeader";
133  break;
135  os << "onChunkComplete";
136  break;
138  os << "onTrailers";
139  break;
141  os << "onUpgrade";
142  break;
144  os << "onEOM";
145  break;
147  os << "eomFlushed";
148  break;
149  }
150 
151  return os;
152 }
153 
154 }
std::ostream & operator<<(std::ostream &os, const HeaderTable &table)
static std::pair< State, bool > find(State s, Event e)
static set< string > s