-
Notifications
You must be signed in to change notification settings - Fork 0
/
rot_cipher.cc
90 lines (70 loc) · 2.81 KB
/
rot_cipher.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <string>
#include "rot_cipher.h"
namespace Envoy {
namespace Http {
// A completely inefficient function for rotating letters. It was like 2am
std::string RotCipherFilter::rotateText(std::string text) {
for (size_t i = 0; i < text.size(); i++) {
int j = text[i];
int new_letter = j;
if (j >= 65 && j <= 90) {
new_letter = j + rot_value_;
if (new_letter > 90) {
new_letter -= 26;
}
} else if (j >= 97 && j <= 122) {
new_letter = j + rot_value_;
if (new_letter > 122) {
new_letter -= 26;
}
}
text[i] = char(new_letter);
}
return text;
}
///////////////// constructors /////////////////////////////////////////////
RotCipherFilter::RotCipherFilter(int rot_value, const std::string& rot_header) :
rot_value_(rot_value), rot_header_(rot_header) {}
///////////////////////////////////////////////////////////////////////////////
RotCipherFilter::~RotCipherFilter() {}
void RotCipherFilter::onDestroy() {}
/**
* Here's where the magic happens. Envoy works in ordered filter chains, based
* on the order in the configuration file. When it's this filter's turn to
* process the request (going upstream), we get this call for the headers
*/
FilterHeadersStatus RotCipherFilter::decodeHeaders(RequestHeaderMap& headers, bool) {
// static b/c it's the same everytime, so once it's initialized let's just
// keep it around
static LowerCaseString header_key(rot_header_);
// extract the header
const HeaderMap::GetResult header_result = headers.get(header_key);
// if it's `nullptr`, then the header value isn't defined. If we don't have
// this check, then Envoy will segfault if the request doesn't have the header
if (!header_result.empty()) {
const HeaderEntry* header_entry = header_result[0];
std::string thingy(header_entry->value().getStringView());
std::string new_value = rotateText(thingy);
// we have to remove the header, otherwise we'll end up with duplicate
// headers, as adding a header with the same name only appends, doesn't
// replace.
headers.remove(header_key);
headers.addCopy(header_key, new_value);
}
return FilterHeadersStatus::Continue;
}
////////////// these functions are required by the abstract class but we don't
////////////// use them, so just `Continue` along
FilterDataStatus RotCipherFilter::decodeData(Buffer::Instance&, bool) {
return FilterDataStatus::Continue;
}
FilterTrailersStatus RotCipherFilter::decodeTrailers(RequestTrailerMap&) {
return FilterTrailersStatus::Continue;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void RotCipherFilter::setDecoderFilterCallbacks(StreamDecoderFilterCallbacks& callbacks) {
decoder_callbacks_ = &callbacks;
}
} // Http
} // Envoy