/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include namespace apache { namespace thrift { LegacyHeaderRoutingHandler::LegacyHeaderRoutingHandler(ThriftServer&) {} LegacyHeaderRoutingHandler::~LegacyHeaderRoutingHandler() { stopListening(); } void LegacyHeaderRoutingHandler::stopListening() { listening_ = false; } // copied from THeader::compactFramed bool compactFramed(uint32_t magic) { int8_t protocolId = (magic >> 24); int8_t protocolVersion = (magic >> 16) & (uint32_t)protocol::TCompactProtocol::VERSION_MASK; return ( (protocolId == protocol::TCompactProtocol::PROTOCOL_ID) && (protocolVersion <= protocol::TCompactProtocol::VERSION_N) && (protocolVersion >= protocol::TCompactProtocol::VERSION_LOW)); } bool LegacyHeaderRoutingHandler::canAcceptConnection( const std::vector& bytes, const wangle::TransportInfo&) { if (!listening_) { return false; } uint32_t firstWord = bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]; // logic from THeader::analyzeFirst32bit if ((firstWord & protocol::TBinaryProtocol::VERSION_MASK) == static_cast(protocol::TBinaryProtocol::VERSION_1)) { // unframed return true; } else if (compactFramed(firstWord)) { // unframed compact return true; } else if ( firstWord == transport::THeader::HTTP_SERVER_MAGIC || firstWord == transport::THeader::HTTP_GET_CLIENT_MAGIC || firstWord == transport::THeader::HTTP_HEAD_CLIENT_MAGIC || firstWord == transport::THeader::HTTP_CLIENT_MAGIC) { // HTTP return true; } uint32_t secondWord = bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7]; // logic from THeader::analyzeSecond32bit if ((secondWord & protocol::TBinaryProtocol::VERSION_MASK) == static_cast(protocol::TBinaryProtocol::VERSION_1)) { // framed return true; } else if (compactFramed(secondWord)) { // framed compact return true; } else if ( (secondWord & transport::THeader::HEADER_MASK) == transport::THeader::HEADER_MAGIC) { // header return true; } return false; } bool LegacyHeaderRoutingHandler::canAcceptEncryptedConnection( const std::string& protocolName) { // for HTTP requests, the body is expected to be Thrift binary content return listening_ && (protocolName == "thrift" || protocolName == "http/1.1"); } void LegacyHeaderRoutingHandler::handleConnection( wangle::ConnectionManager* /* connectionManager */, folly::AsyncTransport::UniquePtr sock, const folly::SocketAddress* address, const wangle::TransportInfo& tinfo, std::shared_ptr worker) { if (!listening_) { return; } // send it back to the Cpp2Worker for handling worker->handleHeader(std::move(sock), address, tinfo); } } // namespace thrift } // namespace apache