Return td_api::error for incorrect requests in JSON interface.
GitOrigin-RevId: 1c3e3f6c2b7a9828930bdfc185f332f6190467d1
This commit is contained in:
parent
8ae3ac91a4
commit
a5a7e30ec5
@ -18,11 +18,29 @@ int main() {
|
||||
void *client = td_json_client_create();
|
||||
// somehow share the client with other threads, which will be able to send requests via td_json_client_send
|
||||
|
||||
const bool test_incorrect_queries = true;
|
||||
if (test_incorrect_queries) {
|
||||
td_json_client_execute(nullptr, "{\"@type\":\"setLogVerbosityLevel\", \"new_verbosity_level\":3}");
|
||||
td_json_client_execute(nullptr, "");
|
||||
td_json_client_execute(nullptr, "test");
|
||||
td_json_client_execute(nullptr, "\"test\"");
|
||||
td_json_client_execute(nullptr, "{\"@type\":\"test\", \"@extra\":1}");
|
||||
|
||||
td_json_client_send(client, "{\"@type\":\"getFileMimeType\"}");
|
||||
td_json_client_send(client, "{\"@type\":\"getFileMimeType\", \"@extra\":1}");
|
||||
td_json_client_send(client, "{\"@type\":\"getFileMimeType\", \"@extra\":null}");
|
||||
td_json_client_send(client, "{\"@type\":\"test\"}");
|
||||
td_json_client_send(client, "[]");
|
||||
td_json_client_send(client, "{\"@type\":\"test\", \"@extra\":1}");
|
||||
td_json_client_send(client, "{\"@type\":\"sendMessage\", \"chat_id\":true, \"@extra\":1}");
|
||||
td_json_client_send(client, "test");
|
||||
}
|
||||
|
||||
const double WAIT_TIMEOUT = 10.0; // seconds
|
||||
while (true) {
|
||||
const char *result = td_json_client_receive(client, WAIT_TIMEOUT);
|
||||
if (result != nullptr) {
|
||||
// parse the result as JSON object and process it as an incoming update or an answer to a previously sent request
|
||||
// parse the result as a JSON object and process it as an incoming update or an answer to a previously sent request
|
||||
|
||||
// if (result is UpdateAuthorizationState with authorizationStateClosed) {
|
||||
// break;
|
||||
|
@ -4010,5 +4010,5 @@ testProxy server:string port:int32 type:ProxyType = Ok;
|
||||
testGetDifference = Ok;
|
||||
//@description Does nothing and ensures that the Update object is used; for testing only. This is an offline method. Can be called before authorization
|
||||
testUseUpdate = Update;
|
||||
//@description Returns the specified error and ensures that the Error object is used; for testing only. This is an offline method. Can be called before authorization @error The error to be returned
|
||||
//@description Returns the specified error and ensures that the Error object is used; for testing only. This is an offline method. Can be called before authorization. Can be called synchronously @error The error to be returned
|
||||
testReturnError error:error = Error;
|
||||
|
@ -151,7 +151,7 @@ void gen_tl_constructor_from_string(StringBuilder &sb, Slice name, const Vec &ve
|
||||
sb << "\n };\n";
|
||||
sb << " auto it = m.find(str);\n";
|
||||
sb << " if (it == m.end()) {\n"
|
||||
<< " return Status::Error(\"Unknown class\");\n"
|
||||
<< " return Status::Error(PSLICE() << \"Unknown class \\\"\" << str << \"\\\"\");\n"
|
||||
<< " }\n"
|
||||
<< " return it->second;\n";
|
||||
sb << "}\n";
|
||||
|
@ -22,11 +22,22 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
static Result<std::pair<td_api::object_ptr<td_api::Function>, string>> to_request(Slice request) {
|
||||
static td_api::object_ptr<td_api::Function> get_return_error_function(Slice error_message) {
|
||||
auto error = td_api::make_object<td_api::error>(400, error_message.str());
|
||||
return td_api::make_object<td_api::testReturnError>(std::move(error));
|
||||
}
|
||||
|
||||
static std::pair<td_api::object_ptr<td_api::Function>, string> to_request(Slice request) {
|
||||
auto request_str = request.str();
|
||||
TRY_RESULT(json_value, json_decode(request_str));
|
||||
auto r_json_value = json_decode(request_str);
|
||||
if (r_json_value.is_error()) {
|
||||
return {get_return_error_function(PSLICE()
|
||||
<< "Failed to parse request as JSON object: " << r_json_value.error().message()),
|
||||
string()};
|
||||
}
|
||||
auto json_value = r_json_value.move_as_ok();
|
||||
if (json_value.type() != JsonValue::Type::Object) {
|
||||
return Status::Error("Expected an Object");
|
||||
return {get_return_error_function("Expected a JSON object"), string()};
|
||||
}
|
||||
|
||||
string extra;
|
||||
@ -36,8 +47,13 @@ static Result<std::pair<td_api::object_ptr<td_api::Function>, string>> to_reques
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::Function> func;
|
||||
TRY_STATUS(from_json(func, json_value));
|
||||
return std::make_pair(std::move(func), extra);
|
||||
auto status = from_json(func, json_value);
|
||||
if (status.is_error()) {
|
||||
return {get_return_error_function(PSLICE()
|
||||
<< "Failed to parse JSON object as TDLib request: " << status.error().message()),
|
||||
std::move(extra)};
|
||||
}
|
||||
return std::make_pair(std::move(func), std::move(extra));
|
||||
}
|
||||
|
||||
static std::string from_response(const td_api::Object &object, const string &extra) {
|
||||
@ -62,18 +78,13 @@ static CSlice store_string(std::string str) {
|
||||
}
|
||||
|
||||
void ClientJson::send(Slice request) {
|
||||
auto r_request = to_request(request);
|
||||
if (r_request.is_error()) {
|
||||
LOG(ERROR) << "Failed to parse " << tag("request", format::escaped(request)) << " " << r_request.error();
|
||||
return;
|
||||
}
|
||||
|
||||
auto parsed_request = to_request(request);
|
||||
std::uint64_t extra_id = extra_id_.fetch_add(1, std::memory_order_relaxed);
|
||||
if (!r_request.ok_ref().second.empty()) {
|
||||
if (!parsed_request.second.empty()) {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
extra_[extra_id] = std::move(r_request.ok_ref().second);
|
||||
extra_[extra_id] = std::move(parsed_request.second);
|
||||
}
|
||||
client_.send(Client::Request{extra_id, std::move(r_request.ok_ref().first)});
|
||||
client_.send(Client::Request{extra_id, std::move(parsed_request.first)});
|
||||
}
|
||||
|
||||
CSlice ClientJson::receive(double timeout) {
|
||||
@ -95,14 +106,9 @@ CSlice ClientJson::receive(double timeout) {
|
||||
}
|
||||
|
||||
CSlice ClientJson::execute(Slice request) {
|
||||
auto r_request = to_request(request);
|
||||
if (r_request.is_error()) {
|
||||
LOG(ERROR) << "Failed to parse " << tag("request", format::escaped(request)) << " " << r_request.error();
|
||||
return {};
|
||||
}
|
||||
|
||||
return store_string(from_response(*Client::execute(Client::Request{0, std::move(r_request.ok_ref().first)}).object,
|
||||
r_request.ok().second));
|
||||
auto parsed_request = to_request(request);
|
||||
return store_string(from_response(*Client::execute(Client::Request{0, std::move(parsed_request.first)}).object,
|
||||
parsed_request.second));
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -3422,6 +3422,7 @@ bool Td::is_synchronous_request(int32 id) {
|
||||
case td_api::setLogTagVerbosityLevel::ID:
|
||||
case td_api::getLogTagVerbosityLevel::ID:
|
||||
case td_api::addLogMessage::ID:
|
||||
case td_api::testReturnError::ID:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -3433,7 +3434,6 @@ bool Td::is_preinitialization_request(int32 id) {
|
||||
case td_api::getCurrentState::ID:
|
||||
case td_api::setAlarm::ID:
|
||||
case td_api::testUseUpdate::ID:
|
||||
case td_api::testReturnError::ID:
|
||||
case td_api::testCallEmpty::ID:
|
||||
case td_api::testSquareInt::ID:
|
||||
case td_api::testCallString::ID:
|
||||
@ -3632,6 +3632,7 @@ td_api::object_ptr<td_api::Object> Td::static_request(td_api::object_ptr<td_api:
|
||||
case td_api::cleanFileName::ID:
|
||||
case td_api::getJsonValue::ID:
|
||||
case td_api::getJsonString::ID:
|
||||
case td_api::testReturnError::ID:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -7664,8 +7665,16 @@ td_api::object_ptr<td_api::Object> Td::do_static_request(const td_api::addLogMes
|
||||
return td_api::make_object<td_api::ok>();
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::Object> Td::do_static_request(td_api::testReturnError &request) {
|
||||
if (request.error_ == nullptr) {
|
||||
return td_api::make_object<td_api::error>(404, "Not Found");
|
||||
}
|
||||
|
||||
return std::move(request.error_);
|
||||
}
|
||||
|
||||
// test
|
||||
void Td::on_request(uint64 id, td_api::testNetwork &request) {
|
||||
void Td::on_request(uint64 id, const td_api::testNetwork &request) {
|
||||
create_handler<TestQuery>(id)->send();
|
||||
}
|
||||
|
||||
@ -7677,24 +7686,24 @@ void Td::on_request(uint64 id, td_api::testProxy &request) {
|
||||
CREATE_REQUEST(TestProxyRequest, r_proxy.move_as_ok());
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::testGetDifference &request) {
|
||||
void Td::on_request(uint64 id, const td_api::testGetDifference &request) {
|
||||
updates_manager_->get_difference("testGetDifference");
|
||||
send_closure(actor_id(this), &Td::send_result, id, make_tl_object<td_api::ok>());
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::testUseUpdate &request) {
|
||||
void Td::on_request(uint64 id, const td_api::testUseUpdate &request) {
|
||||
send_closure(actor_id(this), &Td::send_result, id, nullptr);
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::testReturnError &request) {
|
||||
send_closure(actor_id(this), &Td::send_result, id, std::move(request.error_));
|
||||
void Td::on_request(uint64 id, const td_api::testReturnError &request) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::testCallEmpty &request) {
|
||||
void Td::on_request(uint64 id, const td_api::testCallEmpty &request) {
|
||||
send_closure(actor_id(this), &Td::send_result, id, make_tl_object<td_api::ok>());
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::testSquareInt &request) {
|
||||
void Td::on_request(uint64 id, const td_api::testSquareInt &request) {
|
||||
send_closure(actor_id(this), &Td::send_result, id, make_tl_object<td_api::testInt>(request.x_ * request.x_));
|
||||
}
|
||||
|
||||
|
@ -1023,13 +1023,13 @@ class Td final : public NetQueryCallback {
|
||||
void on_request(uint64 id, const td_api::addLogMessage &request);
|
||||
|
||||
// test
|
||||
void on_request(uint64 id, td_api::testNetwork &request);
|
||||
void on_request(uint64 id, const td_api::testNetwork &request);
|
||||
void on_request(uint64 id, td_api::testProxy &request);
|
||||
void on_request(uint64 id, td_api::testGetDifference &request);
|
||||
void on_request(uint64 id, td_api::testUseUpdate &request);
|
||||
void on_request(uint64 id, td_api::testReturnError &request);
|
||||
void on_request(uint64 id, td_api::testCallEmpty &request);
|
||||
void on_request(uint64 id, td_api::testSquareInt &request);
|
||||
void on_request(uint64 id, const td_api::testGetDifference &request);
|
||||
void on_request(uint64 id, const td_api::testUseUpdate &request);
|
||||
void on_request(uint64 id, const td_api::testReturnError &request);
|
||||
void on_request(uint64 id, const td_api::testCallEmpty &request);
|
||||
void on_request(uint64 id, const td_api::testSquareInt &request);
|
||||
void on_request(uint64 id, td_api::testCallString &request);
|
||||
void on_request(uint64 id, td_api::testCallBytes &request);
|
||||
void on_request(uint64 id, td_api::testCallVectorInt &request);
|
||||
@ -1058,6 +1058,7 @@ class Td final : public NetQueryCallback {
|
||||
static td_api::object_ptr<td_api::Object> do_static_request(const td_api::setLogTagVerbosityLevel &request);
|
||||
static td_api::object_ptr<td_api::Object> do_static_request(const td_api::getLogTagVerbosityLevel &request);
|
||||
static td_api::object_ptr<td_api::Object> do_static_request(const td_api::addLogMessage &request);
|
||||
static td_api::object_ptr<td_api::Object> do_static_request(td_api::testReturnError &request);
|
||||
|
||||
static DbKey as_db_key(string key);
|
||||
Status init(DbKey key) TD_WARN_UNUSED_RESULT;
|
||||
|
Reference in New Issue
Block a user