36 namespace discord_core_internal {
43 Unset = std::numeric_limits<uint64_t>::max(),
57 DCA_INLINE
static unordered_map<https_response_codes, jsonifier::string> outputErrorValues{
59 {
static_cast<https_response_codes>(204),
"The request completed successfully but returned no content" },
61 {
static_cast<https_response_codes>(400),
"The request was improperly formatted, or the server couldn't understand it" },
63 {
static_cast<https_response_codes>(403),
"The authorization token you passed did not have permission to the resource" },
64 {
static_cast<https_response_codes>(404),
"The resource at the location specified doesn't exist" },
65 {
static_cast<https_response_codes>(405),
"The https method used is not valid for the location specified" },
67 {
static_cast<https_response_codes>(502),
"There was not a gateway available to process your request.wait a bit and retry" },
68 {
static_cast<https_response_codes>(500),
"The server had an error processing your request(these are rare)" }
73 DCA_INLINE https_response_code() =
default;
75 DCA_INLINE https_response_code& operator=(uint64_t valueNew) {
80 DCA_INLINE https_response_code(uint64_t value) {
84 DCA_INLINE
operator jsonifier::string() {
85 return jsonifier::string{
"Code: " + jsonifier::toString(
static_cast<uint32_t
>(value)) + jsonifier::string{
", message: " } +
86 static_cast<jsonifier::string
>(https_response_code::outputErrorValues[value]) };
89 DCA_INLINE
operator uint64_t() {
90 return static_cast<uint64_t
>(value);
95 struct rate_limit_data;
97 enum class https_state { Collecting_Headers = 0, Collecting_Contents = 1, Collecting_Chunked_Contents = 2, complete = 3 };
99 class https_error :
public dca_exception {
101 https_response_code errorCode{};
102 DCA_INLINE https_error(
const jsonifier::string_view& message, std::source_location location = std::source_location::current()) :
dca_exception{ message, location } {};
105 struct DiscordCoreAPI_Dll https_response_data {
106 friend class https_rnr_builder;
107 friend class https_connection;
108 friend class https_client;
110 https_response_code responseCode{ std::numeric_limits<uint32_t>::max() };
111 unordered_map<jsonifier::string, jsonifier::string> responseHeaders{};
112 https_state currentState{ https_state::Collecting_Headers };
113 jsonifier::string responseData{};
114 uint64_t contentLength{};
120 class DiscordCoreAPI_Dll https_rnr_builder {
122 friend class https_client;
124 https_rnr_builder() =
default;
126 https_response_data finalizeReturnValues(rate_limit_data& rateLimitData);
128 jsonifier::string buildRequest(
const https_workload_data& workload);
130 void updateRateLimitData(rate_limit_data& rateLimitData);
134 virtual ~https_rnr_builder() =
default;
137 bool parseContents();
142 class DiscordCoreAPI_Dll https_connection :
public https_rnr_builder,
public tcp_connection<https_connection> {
144 template<
typename value_type>
friend class https_tcp_connection;
146 rate_limit_data* currentRateLimitData{};
147 const int32_t maxReconnectTries{ 3 };
148 jsonifier::string inputBufferReal{};
149 jsonifier::string currentBaseUrl{};
150 int32_t currentReconnectTries{};
151 https_workload_data workload{};
152 https_response_data data{};
154 https_connection() =
default;
156 https_connection(
const jsonifier::string& baseUrlNew,
const uint16_t portNew);
158 void resetValues(https_workload_data&& workloadNew, rate_limit_data* newRateLimitData);
160 void handleBuffer()
override;
162 bool areWeConnected();
166 virtual ~https_connection() =
default;
173 friend class https_client;
175 https_connection_manager() =
default;
177 https_connection_manager(rate_limit_queue*);
179 https_connection& getConnection(https_workload_type workloadType);
181 rate_limit_queue& getRateLimitQueue();
184 unordered_map<https_workload_type, unique_ptr<https_connection>> httpsConnections{};
185 rate_limit_queue* rateLimitQueue{};
186 std::mutex accessMutex{};
189 class DiscordCoreAPI_Dll https_connection_stack_holder {
191 https_connection_stack_holder(https_connection_manager& connectionManager, https_workload_data&& workload);
193 https_connection& getConnection();
195 ~https_connection_stack_holder();
198 rate_limit_queue* rateLimitQueue{};
199 https_connection* connection{};
202 class DiscordCoreAPI_Dll https_client_core {
204 https_client_core(jsonifier::string_view botTokenNew);
206 DCA_INLINE https_response_data submitWorkloadAndGetResult(https_workload_data&& workloadNew) {
207 https_connection connection{};
208 rate_limit_data rateLimitData{};
209 connection.resetValues(std::move(workloadNew), &rateLimitData);
210 auto returnData = httpsRequestInternal(connection);
211 if (returnData.responseCode != 200 && returnData.responseCode != 204 && returnData.responseCode != 201) {
212 jsonifier::string errorMessage{};
213 if (connection.workload.callStack !=
"") {
214 errorMessage += connection.workload.callStack +
" ";
216 errorMessage +=
"Https error: " + returnData.responseCode.operator jsonifier::string() +
"\nThe request: base url: " + connection.workload.baseUrl +
"\n";
217 if (!connection.workload.relativePath.empty()) {
218 errorMessage +=
"Relative Url: " + connection.workload.relativePath +
"\n";
220 if (!connection.workload.content.empty()) {
221 errorMessage +=
"Content: " + connection.workload.content +
"\n";
223 if (!returnData.responseData.empty()) {
224 errorMessage +=
"The Response: " +
static_cast<jsonifier::string
>(returnData.responseData);
226 https_error theError{ errorMessage };
227 theError.errorCode = returnData.responseCode;
233 jsonifier::string botToken{};
235 https_response_data httpsRequestInternal(https_connection& connection);
237 https_response_data recoverFromError(https_connection& connection);
239 https_response_data getResponse(https_connection& connection);
251 https_client(jsonifier::string_view botTokenNew);
253 template<
typename value_type,
typename string_type>
void getParseErrors(jsonifier::jsonifier_core<false>& parser, value_type& value, string_type& stringNew) {
254 parser.parseJson(value, parser.minifyJson(parser.prettifyJson(stringNew)));
255 if (
auto result = parser.getErrors(); result.size() > 0) {
256 for (
auto& valueNew: result) {
257 message_printer::printError<print_message_type::websocket>(valueNew.reportError());
262 template<
typename workload_type,
typename... args>
void submitWorkloadAndGetResult(workload_type&& workload, args&... argsNew) {
263 https_connection_stack_holder stackHolder{ connectionManager, std::move(workload) };
264 https_response_data returnData = httpsRequest(stackHolder.getConnection());
265 if (
static_cast<uint32_t
>(returnData.responseCode) != 200 &&
static_cast<uint32_t
>(returnData.responseCode) != 204 &&
266 static_cast<uint32_t
>(returnData.responseCode) != 201) {
267 jsonifier::string errorMessage{};
268 if (stackHolder.getConnection().workload.callStack !=
"") {
269 errorMessage += stackHolder.getConnection().workload.callStack +
" ";
272 "Https error: " + returnData.responseCode.operator jsonifier::string() +
"\nThe request: base url: " + stackHolder.getConnection().workload.baseUrl +
"\n";
273 if (!stackHolder.getConnection().workload.relativePath.empty()) {
274 errorMessage +=
"Relative Url: " + stackHolder.getConnection().workload.relativePath +
"\n";
276 if (!stackHolder.getConnection().workload.content.empty()) {
277 errorMessage +=
"Content: " + stackHolder.getConnection().workload.content +
"\n";
279 if (!returnData.responseData.empty()) {
280 errorMessage +=
"The Response: " +
static_cast<jsonifier::string
>(returnData.responseData);
282 https_error theError{ errorMessage };
283 theError.errorCode = returnData.responseCode;
286 if constexpr ((( !std::is_void_v<args> ) || ...)) {
287 if (returnData.responseData.size() > 0) {
288 (getParseErrors(parser, argsNew, returnData.responseData), ...);
294 https_connection_manager connectionManager{};
295 rate_limit_queue rateLimitQueue{};
297 https_response_data executeByRateLimitData(https_connection& connection);
299 https_response_data httpsRequest(https_connection& connection);
For sending Https requests.
For managing the collection of Https connections.
Voice websocket close codes.
https_response_codes
Voice websocket close codes.
@ No_Content
The request completed successfully but returned no content.
@ Gateway_Unavailable
There was not a gateway available to process your request. wait a bit and retry.
@ forbidden
The authorization token you passed did not have permission to the resource.
@ unauthorized
The authorization header was missing or invalid.
@ Too_Many_Requests
You are being rate limited, see rate limits.
@ ok
The request completed successfully.
@ Not_Modifies
The entity was not modified (no action was taken).
@ Not_Found
The resource at the location specified doesn't exist.
@ created
The entity was created successfully.
@ Bad_Request
The request was improperly formatted, or the server couldn't understand it.
@ Method_Not_Allowed
The https method used is not valid for the location specified.
The main namespace for the forward-facing interfaces.
DCA_INLINE dca_exception(jsonifier::string_view error, std::source_location location=std::source_location::current())
Constructor to create a dca_exception with an error message and optional source location.