1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
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.
7  */
8 
9 #include <proxygen/lib/http/codec/SPDYConstants.h>
10 
11 namespace proxygen { namespace spdy {
12 
errorCodeToGoaway(ErrorCode code)13 GoawayStatusCode errorCodeToGoaway(ErrorCode code) {
14   switch (code) {
15     case ErrorCode::NO_ERROR:
16       return GOAWAY_OK;
17     case ErrorCode::INTERNAL_ERROR:
18       return GOAWAY_INTERNAL_ERROR;
19     case ErrorCode::FLOW_CONTROL_ERROR:
20       return GOAWAY_FLOW_CONTROL_ERROR;
21     case ErrorCode::PROTOCOL_ERROR:
22       break;
23     case ErrorCode::SETTINGS_TIMEOUT:
24       break;
25     case ErrorCode::STREAM_CLOSED:
26       break;
27     case ErrorCode::FRAME_SIZE_ERROR:
28       break;
29     case ErrorCode::REFUSED_STREAM:
30       break;
31     case ErrorCode::CANCEL:
32       break;
33     case ErrorCode::COMPRESSION_ERROR:
34       break;
35     case ErrorCode::CONNECT_ERROR:
36       break;
37     case ErrorCode::ENHANCE_YOUR_CALM:
38       break;
39     case ErrorCode::INADEQUATE_SECURITY:
40       break;
41     case ErrorCode::HTTP_1_1_REQUIRED:
42       break;
43   }
44   return GOAWAY_PROTOCOL_ERROR;
45 }
46 
errorCodeToReset(ErrorCode code)47 ResetStatusCode errorCodeToReset(ErrorCode code) {
48   switch (code) {
49     case ErrorCode::NO_ERROR:
50       break;
51     case ErrorCode::INTERNAL_ERROR:
52       return RST_INTERNAL_ERROR;
53     case ErrorCode::FLOW_CONTROL_ERROR:
54       return RST_FLOW_CONTROL_ERROR;
55     case ErrorCode::PROTOCOL_ERROR:
56       return RST_PROTOCOL_ERROR;
57     case ErrorCode::SETTINGS_TIMEOUT:
58       break;
59     case ErrorCode::STREAM_CLOSED:
60       // Invalid stream comes through here
61       return RST_STREAM_ALREADY_CLOSED;
62     case ErrorCode::FRAME_SIZE_ERROR:
63       return RST_FRAME_TOO_LARGE;
64     case ErrorCode::REFUSED_STREAM:
65       return RST_REFUSED_STREAM;
66     case ErrorCode::CANCEL:
67       return RST_CANCEL;
68     case ErrorCode::COMPRESSION_ERROR:
69       return RST_INTERNAL_ERROR;
70     case ErrorCode::CONNECT_ERROR:
71       break;
72     case ErrorCode::ENHANCE_YOUR_CALM:
73       break;
74     case ErrorCode::INADEQUATE_SECURITY:
75       return RST_INVALID_CREDENTIALS;
76     case ErrorCode::HTTP_1_1_REQUIRED:
77       break;
78   }
79   return RST_PROTOCOL_ERROR;
80 }
81 
goawayToErrorCode(GoawayStatusCode code)82 ErrorCode goawayToErrorCode(GoawayStatusCode code) {
83   switch (code) {
84     case GOAWAY_OK:
85       return ErrorCode::NO_ERROR;
86     case GOAWAY_PROTOCOL_ERROR:
87       return ErrorCode::PROTOCOL_ERROR;
88     case GOAWAY_INTERNAL_ERROR:
89       return ErrorCode::INTERNAL_ERROR;
90     case GOAWAY_FLOW_CONTROL_ERROR:
91       return ErrorCode::FLOW_CONTROL_ERROR;
92   }
93   return ErrorCode::PROTOCOL_ERROR;
94 }
95 
rstToErrorCode(uint32_t code)96 ErrorCode rstToErrorCode(uint32_t code) {
97   switch (code) {
98     case RST_PROTOCOL_ERROR:
99       break;
100     case RST_INVALID_STREAM:
101       return ErrorCode::STREAM_CLOSED;
102     case RST_REFUSED_STREAM:
103       return ErrorCode::REFUSED_STREAM;
104     case RST_UNSUPPORTED_VERSION:
105       break; // not used anyway
106     case RST_CANCEL:
107       return ErrorCode::CANCEL;
108     case RST_INTERNAL_ERROR:
109       return ErrorCode::INTERNAL_ERROR;
110     case RST_FLOW_CONTROL_ERROR:
111       return ErrorCode::FLOW_CONTROL_ERROR;
112     case RST_STREAM_IN_USE:
113       return ErrorCode::FLOW_CONTROL_ERROR;
114     case RST_STREAM_ALREADY_CLOSED:
115       return ErrorCode::STREAM_CLOSED;
116     case RST_INVALID_CREDENTIALS:
117       return ErrorCode::INADEQUATE_SECURITY;
118     case RST_FRAME_TOO_LARGE:
119       return ErrorCode::FRAME_SIZE_ERROR;
120   }
121   return ErrorCode::PROTOCOL_ERROR;
122 }
123 
httpToSpdySettingsId(proxygen::SettingsId id)124 folly::Optional<proxygen::spdy::SettingsId> httpToSpdySettingsId(
125     proxygen::SettingsId id) {
126   switch (id) {
127     // no mapping
128     case proxygen::SettingsId::HEADER_TABLE_SIZE:
129     case proxygen::SettingsId::ENABLE_PUSH:
130     case proxygen::SettingsId::MAX_FRAME_SIZE:
131     case proxygen::SettingsId::MAX_HEADER_LIST_SIZE:
132       return folly::none;
133     case proxygen::SettingsId::ENABLE_EX_HEADERS:
134       return folly::none;
135     case proxygen::SettingsId::MAX_CONCURRENT_STREAMS:
136       return SETTINGS_MAX_CONCURRENT_STREAMS;
137     case proxygen::SettingsId::INITIAL_WINDOW_SIZE:
138       return SETTINGS_INITIAL_WINDOW_SIZE;
139     case proxygen::SettingsId::_SPDY_UPLOAD_BANDWIDTH:
140       return SETTINGS_UPLOAD_BANDWIDTH;
141     case proxygen::SettingsId::_SPDY_DOWNLOAD_BANDWIDTH:
142       return SETTINGS_DOWNLOAD_BANDWIDTH;
143     case proxygen::SettingsId::_SPDY_ROUND_TRIP_TIME:
144       return SETTINGS_ROUND_TRIP_TIME;
145     case proxygen::SettingsId::_SPDY_CURRENT_CWND:
146       return SETTINGS_CURRENT_CWND;
147     case proxygen::SettingsId::_SPDY_DOWNLOAD_RETRANS_RATE:
148       return SETTINGS_DOWNLOAD_RETRANS_RATE;
149     case proxygen::SettingsId::_SPDY_CLIENT_CERTIFICATE_VECTOR_SIZE:
150       return SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE;
151     case proxygen::SettingsId::ENABLE_CONNECT_PROTOCOL:
152       return folly::none;
153     case proxygen::SettingsId::THRIFT_CHANNEL_ID_DEPRECATED:
154     case proxygen::SettingsId::THRIFT_CHANNEL_ID:
155       return folly::none;
156     case proxygen::SettingsId::_HQ_QPACK_BLOCKED_STREAMS:
157     case proxygen::SettingsId::_HQ_DATAGRAM:
158     case proxygen::SettingsId::SETTINGS_HTTP_CERT_AUTH:
159       return folly::none;
160   }
161   return folly::none;
162 }
163 
spdyToHttpSettingsId(proxygen::spdy::SettingsId id)164 folly::Optional<proxygen::SettingsId> spdyToHttpSettingsId(
165     proxygen::spdy::SettingsId id) {
166   switch (id) {
167     case SETTINGS_UPLOAD_BANDWIDTH:
168     case SETTINGS_DOWNLOAD_BANDWIDTH:
169     case SETTINGS_ROUND_TRIP_TIME:
170     case SETTINGS_CURRENT_CWND:
171     case SETTINGS_DOWNLOAD_RETRANS_RATE:
172     case SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE:
173       // These mappings are possible, but not needed right now
174       return folly::none;
175     case SETTINGS_MAX_CONCURRENT_STREAMS:
176       return proxygen::SettingsId::MAX_CONCURRENT_STREAMS;
177     case SETTINGS_INITIAL_WINDOW_SIZE:
178       return proxygen::SettingsId::INITIAL_WINDOW_SIZE;
179   }
180   return folly::none;
181 }
182 
183 const uint32_t kInitialWindow = 65536;
184 const uint32_t kMaxConcurrentStreams = 100;
185 const uint32_t kMaxFrameLength = (1 << 24) - 1;
186 
187 const std::string kSessionProtoNameSPDY3("spdy/3");
188 
189 const std::string httpVersion("HTTP/1.1");
190 const std::string kNameVersionv2("version");
191 const std::string kNameVersionv3(":version");
192 const std::string kNameStatusv2("status");
193 const std::string kNameStatusv3(":status");
194 const std::string kNameMethodv2("method");
195 const std::string kNameMethodv3(":method");
196 const std::string kNamePathv2("url");
197 const std::string kNamePathv3(":path");
198 const std::string kNameSchemev2("scheme");
199 const std::string kNameSchemev3(":scheme");
200 const std::string kNameHostv3(":host"); // SPDY v3 only
201 
202 const std::string kVersionStrv2("spdy/2");
203 const std::string kVersionStrv3("spdy/3");
204 const std::string kVersionStrv31("spdy/3.1");
205 
206 // In the future, we may be shifting the SPDY wire priority
207 // by this much so we can easily use the lower bits to do our
208 // own priority queueing within the bands defined by the SPDY
209 // protocol...
210 //
211 // so far:
212 //
213 // lower 2 LSB: used to randomly approximate some fairness within
214 // priority bands, relying on the poisson events of extracting or
215 // appending a frame to gather "entropy".
216 const size_t SPDY_PRIO_SHIFT_FACTOR = 2; // up to 60
217 
218 }} // namespace proxygen::spdy
219