Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/extensions/filters/network/thrift_proxy/auto_protocol_impl.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/extensions/filters/network/thrift_proxy/auto_protocol_impl.h"
2
3
#include <algorithm>
4
5
#include "envoy/common/exception.h"
6
7
#include "source/common/common/assert.h"
8
#include "source/common/common/byte_order.h"
9
#include "source/common/common/macros.h"
10
#include "source/extensions/filters/network/thrift_proxy/binary_protocol_impl.h"
11
#include "source/extensions/filters/network/thrift_proxy/buffer_helper.h"
12
#include "source/extensions/filters/network/thrift_proxy/compact_protocol_impl.h"
13
#include "source/extensions/filters/network/thrift_proxy/twitter_protocol_impl.h"
14
15
namespace Envoy {
16
namespace Extensions {
17
namespace NetworkFilters {
18
namespace ThriftProxy {
19
20
0
void AutoProtocolImpl::setType(ProtocolType type) {
21
0
  if (!protocol_) {
22
0
    switch (type) {
23
0
    case ProtocolType::Binary:
24
0
      setProtocol(std::make_unique<BinaryProtocolImpl>());
25
0
      break;
26
0
    case ProtocolType::Compact:
27
0
      setProtocol(std::make_unique<CompactProtocolImpl>());
28
0
      break;
29
0
    case ProtocolType::Twitter:
30
0
      setProtocol(std::make_unique<TwitterProtocolImpl>());
31
0
      break;
32
0
    default:
33
      // Ignored: attempt protocol detection.
34
0
      break;
35
0
    }
36
0
  }
37
0
}
38
39
0
bool AutoProtocolImpl::readMessageBegin(Buffer::Instance& buffer, MessageMetadata& metadata) {
40
0
  if (protocol_ == nullptr) {
41
0
    if (buffer.length() < 2) {
42
0
      return false;
43
0
    }
44
45
0
    uint16_t version = buffer.peekBEInt<uint16_t>();
46
0
    if (BinaryProtocolImpl::isMagic(version)) {
47
      // 12 bytes is the minimum length for message-begin in the binary protocol.
48
0
      if (buffer.length() < BinaryProtocolImpl::MinMessageBeginLength) {
49
0
        return false;
50
0
      }
51
52
      // The first message in the twitter protocol is always an upgrade request, so we use as
53
      // much of the buffer as possible to detect the upgrade message. If we guess wrong,
54
      // TwitterProtocolImpl will still fall back to binary protocol.
55
0
      if (TwitterProtocolImpl::isUpgradePrefix(buffer)) {
56
0
        setType(ProtocolType::Twitter);
57
0
      } else {
58
0
        setType(ProtocolType::Binary);
59
0
      }
60
0
    } else if (CompactProtocolImpl::isMagic(version)) {
61
0
      setType(ProtocolType::Compact);
62
0
    }
63
64
0
    if (!protocol_) {
65
0
      throw EnvoyException(
66
0
          fmt::format("unknown thrift auto protocol message start {:04x}", version));
67
0
    }
68
0
  }
69
70
0
  return protocol_->readMessageBegin(buffer, metadata);
71
0
}
72
73
0
bool AutoProtocolImpl::readMessageEnd(Buffer::Instance& buffer) {
74
0
  RELEASE_ASSERT(protocol_ != nullptr, "");
75
0
  return protocol_->readMessageEnd(buffer);
76
0
}
77
78
class AutoProtocolConfigFactory : public ProtocolFactoryBase<AutoProtocolImpl> {
79
public:
80
4
  AutoProtocolConfigFactory() : ProtocolFactoryBase(ProtocolNames::get().AUTO) {}
81
};
82
83
/**
84
 * Static registration for the auto protocol. @see RegisterFactory.
85
 */
86
REGISTER_FACTORY(AutoProtocolConfigFactory, NamedProtocolConfigFactory);
87
88
} // namespace ThriftProxy
89
} // namespace NetworkFilters
90
} // namespace Extensions
91
} // namespace Envoy