openappsec/core/rest/rest.cc
2024-11-28 10:41:59 +00:00

142 lines
3.7 KiB
C++

// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
// Licensed under the Apache License, Version 2.0 (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 "rest.h"
using namespace std;
ostream &
RestHelper::printIndent(ostream &os, uint indent)
{
for (uint i = 0; i < indent; i++) os << " ";
return os;
}
void
RestHelper::reportError(std::string const &err)
{
throw JsonError(err);
}
Maybe<string>
ServerRest::performRestCall(istream &in)
{
try {
try {
int firstChar = in.peek();
if (firstChar != EOF) {
// array as root is not supported in JSONInputArchive format
// but this struct is in bulk invalidations requirements
// we will change the format here
if (firstChar == '[') {
std::string content((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
std::string modifiedContent = "{\"" + BULK_ARRAY_NAME + "\": " + content + "}";
std::istringstream* modifiedStream = new std::istringstream(modifiedContent);
in.rdbuf(modifiedStream->rdbuf());
}
}
cereal::JSONInputArchive in_ar(in);
load(in_ar);
} catch (cereal::Exception &e) {
throw JsonError(string("JSON parsing failed: ") + e.what());
}
doCall();
stringstream out;
{
cereal::JSONOutputArchive out_ar(out);
save(out_ar);
}
return out.str();
} catch (const JsonError &e) {
return genError(e.getMsg());
}
}
void
BasicRest::performOutputingSchema(ostream &out, int level)
{
RestHelper::printIndent(out, level) << "{\n";
RestHelper::printIndent(out, level + 1) << "\"properties\": {";
outputSchema(out, level + 2);
out << "\n";
RestHelper::printIndent(out, level + 1) << "},\n";
RestHelper::printIndent(out, level + 1) << "\"required\": [";
outputRequired(out, level + 2);
out << "\n";
RestHelper::printIndent(out, level+1) << "]\n";
RestHelper::printIndent(out, level) << "}";
}
void
BasicRest::outputSchema(ostream &os, int level)
{
bool first = true;
for (auto it : schema_func) {
if (!first) os << ',';
os << '\n';
it(os, level);
first = false;
}
}
void
BasicRest::outputRequired(ostream &os, int level)
{
bool first = true;
for (auto it : required) {
if (!first) os << ',';
os << '\n';
RestHelper::printIndent(os, level) << "\"" << it << '"';
first = false;
}
}
Maybe<string>
ClientRest::genJson() const
{
try {
stringstream out;
{
cereal::JSONOutputArchive out_ar(out);
save(out_ar);
}
return out.str();
} catch (const JsonError &e) {
return genError(e.getMsg());
}
}
bool
ClientRest::loadJson(const string &json)
{
try
{
stringstream in;
in.str(json);
try {
cereal::JSONInputArchive in_ar(in);
load(in_ar);
} catch (cereal::Exception &e) {
throw JsonError(string("JSON parsing failed: ") + e.what());
}
return true;
}
catch (const JsonError &j)
{
return false;
}
}