MCPcopy Create free account
hub / github.com/apache/trafficserver / handle_upgrade_request

Method handle_upgrade_request

src/proxy/http/HttpTransact.cc:1249–1341  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1247}
1248
1249bool
1250HttpTransact::handle_upgrade_request(State *s)
1251{
1252 HTTPHdr &request = s->hdr_info.client_request;
1253 s->method = request.method_get_wksidx();
1254
1255 // Quickest way to determine that this is defintely not an upgrade.
1256 /* RFC 6455 The method of the request MUST be GET, and the HTTP version MUST
1257 be at least 1.1. */
1258 if (!s->hdr_info.client_request.presence(MIME_PRESENCE_UPGRADE) ||
1259 !s->hdr_info.client_request.presence(MIME_PRESENCE_CONNECTION) || s->method != HTTP_WKSIDX_GET ||
1260 s->hdr_info.client_request.version_get() < HTTP_1_1) {
1261 return false;
1262 }
1263
1264 MIMEField *upgrade_hdr = s->hdr_info.client_request.field_find(MIME_FIELD_UPGRADE, MIME_LEN_UPGRADE);
1265 MIMEField *connection_hdr = s->hdr_info.client_request.field_find(MIME_FIELD_CONNECTION, MIME_LEN_CONNECTION);
1266
1267 StrList connection_hdr_vals;
1268 std::string_view upgrade_hdr_val;
1269
1270 if (!upgrade_hdr || !connection_hdr || connection_hdr->value_get_comma_list(&connection_hdr_vals) == 0 ||
1271 (upgrade_hdr_val = upgrade_hdr->value_get()).data() == nullptr) {
1272 TxnDbg(dbg_ctl_http_trans_upgrade, "Transaction wasn't a valid upgrade request, proceeding as a normal HTTP request.");
1273 return false;
1274 }
1275
1276 /*
1277 * In order for this request to be treated as a normal upgrade request we must have a Connection: Upgrade header
1278 * and a Upgrade: header, with a non-empty value, otherwise we just assume it's not an Upgrade Request, after
1279 * we've verified that, we will try to match this upgrade to a known upgrade type such as Websockets.
1280 */
1281 bool connection_contains_upgrade = false;
1282 // Next, let's validate that the Connection header contains an Upgrade key
1283 for (int i = 0; i < connection_hdr_vals.count; ++i) {
1284 Str *val = connection_hdr_vals.get_idx(i);
1285 if (ptr_len_casecmp(val->str, val->len, MIME_FIELD_UPGRADE, MIME_LEN_UPGRADE) == 0) {
1286 connection_contains_upgrade = true;
1287 break;
1288 }
1289 }
1290
1291 if (!connection_contains_upgrade) {
1292 TxnDbg(dbg_ctl_http_trans_upgrade,
1293 "Transaction wasn't a valid upgrade request, proceeding as a normal HTTP request, missing Connection upgrade header.");
1294 return false;
1295 }
1296
1297 // Mark this request as an upgrade request.
1298 s->is_upgrade_request = true;
1299
1300 /*
1301 RFC 6455
1302 The request MUST contain an |Upgrade| header field whose value
1303 MUST include the "websocket" keyword.
1304 The request MUST contain a |Connection| header field whose value
1305 MUST include the "Upgrade" token. // Checked Above
1306 The request MUST include a header field with the name

Callers

nothing calls this directly

Calls 12

ptr_len_casecmpFunction · 0.85
hdrtoken_tokenizeFunction · 0.85
method_get_wksidxMethod · 0.80
presenceMethod · 0.80
version_getMethod · 0.80
field_findMethod · 0.80
value_get_comma_listMethod · 0.80
get_idxMethod · 0.80
value_get_intMethod · 0.80
dataMethod · 0.45
value_getMethod · 0.45
lengthMethod · 0.45

Tested by

no test coverage detected