| 424 | } |
| 425 | |
| 426 | bool WSLPeer::_verify_server_response() { |
| 427 | Vector<String> psa = String::ascii(Span((const char *)handshake_buffer->get_data_array().ptr(), handshake_buffer->get_position() - 4)).split("\r\n"); |
| 428 | int len = psa.size(); |
| 429 | ERR_FAIL_COND_V_MSG(len < 4, false, "Not enough response headers. Got: " + itos(len) + ", expected >= 4."); |
| 430 | |
| 431 | Vector<String> req = psa[0].split(" ", false); |
| 432 | ERR_FAIL_COND_V_MSG(req.size() < 2, false, "Invalid protocol or status code. Got '" + psa[0] + "', expected 'HTTP/1.1 101'."); |
| 433 | |
| 434 | // Wrong protocol |
| 435 | ERR_FAIL_COND_V_MSG(req[0] != "HTTP/1.1", false, "Invalid protocol. Got: '" + req[0] + "', expected 'HTTP/1.1'."); |
| 436 | ERR_FAIL_COND_V_MSG(req[1] != "101", false, "Invalid status code. Got: '" + req[1] + "', expected '101'."); |
| 437 | |
| 438 | HashMap<String, String> headers; |
| 439 | for (int i = 1; i < len; i++) { |
| 440 | Vector<String> header = psa[i].split(":", false, 1); |
| 441 | ERR_FAIL_COND_V_MSG(header.size() != 2, false, "Invalid header -> " + psa[i] + "."); |
| 442 | String name = header[0].to_lower(); |
| 443 | String value = header[1].strip_edges(); |
| 444 | if (headers.has(name)) { |
| 445 | headers[name] += "," + value; |
| 446 | } else { |
| 447 | headers[name] = value; |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | #define WSL_CHECK(NAME, VALUE) \ |
| 452 | ERR_FAIL_COND_V_MSG(!headers.has(NAME) || headers[NAME].to_lower() != VALUE, false, \ |
| 453 | "Missing or invalid header '" + String(NAME) + "'. Expected value '" + VALUE + "'."); |
| 454 | #define WSL_CHECK_NC(NAME, VALUE) \ |
| 455 | ERR_FAIL_COND_V_MSG(!headers.has(NAME) || headers[NAME] != VALUE, false, \ |
| 456 | "Missing or invalid header '" + String(NAME) + "'. Expected value '" + VALUE + "'."); |
| 457 | WSL_CHECK("connection", "upgrade"); |
| 458 | WSL_CHECK("upgrade", "websocket"); |
| 459 | WSL_CHECK_NC("sec-websocket-accept", _compute_key_response(session_key)); |
| 460 | #undef WSL_CHECK_NC |
| 461 | #undef WSL_CHECK |
| 462 | if (supported_protocols.is_empty()) { |
| 463 | // We didn't request a custom protocol |
| 464 | ERR_FAIL_COND_V_MSG(headers.has("sec-websocket-protocol"), false, "Received unrequested sub-protocol -> " + headers["sec-websocket-protocol"]); |
| 465 | } else { |
| 466 | // We requested at least one custom protocol but didn't receive one |
| 467 | ERR_FAIL_COND_V_MSG(!headers.has("sec-websocket-protocol"), false, "Requested sub-protocol(s) but received none."); |
| 468 | // Check received sub-protocol was one of those requested. |
| 469 | selected_protocol = headers["sec-websocket-protocol"]; |
| 470 | bool valid = false; |
| 471 | for (int i = 0; i < supported_protocols.size(); i++) { |
| 472 | if (supported_protocols[i] != selected_protocol) { |
| 473 | continue; |
| 474 | } |
| 475 | valid = true; |
| 476 | break; |
| 477 | } |
| 478 | if (!valid) { |
| 479 | ERR_FAIL_V_MSG(false, "Received unrequested sub-protocol -> " + selected_protocol); |
| 480 | } |
| 481 | } |
| 482 | return true; |
| 483 | } |
nothing calls this directly
no test coverage detected