1*5d92fffcSrohitpai // SPDX-License-Identifier: Apache-2.0 2*5d92fffcSrohitpai // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3*5d92fffcSrohitpai #pragma once 4*5d92fffcSrohitpai 5*5d92fffcSrohitpai #include "error_message_utils.hpp" 6*5d92fffcSrohitpai #include "http_response.hpp" 7*5d92fffcSrohitpai 8*5d92fffcSrohitpai #include <algorithm> 9*5d92fffcSrohitpai #include <array> 10*5d92fffcSrohitpai #include <cstddef> 11*5d92fffcSrohitpai #include <limits> 12*5d92fffcSrohitpai 13*5d92fffcSrohitpai namespace redfish 14*5d92fffcSrohitpai { 15*5d92fffcSrohitpai // Propagates the worst error code to the final response. 16*5d92fffcSrohitpai // The order of error code is (from high to low) 17*5d92fffcSrohitpai // 500 Internal Server Error 18*5d92fffcSrohitpai // 511 Network Authentication Required 19*5d92fffcSrohitpai // 510 Not Extended 20*5d92fffcSrohitpai // 508 Loop Detected 21*5d92fffcSrohitpai // 507 Insufficient Storage 22*5d92fffcSrohitpai // 506 Variant Also Negotiates 23*5d92fffcSrohitpai // 505 HTTP Version Not Supported 24*5d92fffcSrohitpai // 504 Gateway Timeout 25*5d92fffcSrohitpai // 503 Service Unavailable 26*5d92fffcSrohitpai // 502 Bad Gateway 27*5d92fffcSrohitpai // 501 Not Implemented 28*5d92fffcSrohitpai // 401 Unauthorized 29*5d92fffcSrohitpai // 451 - 409 Error codes (not listed explicitly) 30*5d92fffcSrohitpai // 408 Request Timeout 31*5d92fffcSrohitpai // 407 Proxy Authentication Required 32*5d92fffcSrohitpai // 406 Not Acceptable 33*5d92fffcSrohitpai // 405 Method Not Allowed 34*5d92fffcSrohitpai // 404 Not Found 35*5d92fffcSrohitpai // 403 Forbidden 36*5d92fffcSrohitpai // 402 Payment Required 37*5d92fffcSrohitpai // 400 Bad Request 38*5d92fffcSrohitpai inline unsigned propogateErrorCode(unsigned finalCode, unsigned subResponseCode) 39*5d92fffcSrohitpai { 40*5d92fffcSrohitpai // We keep a explicit list for error codes that this project often uses 41*5d92fffcSrohitpai // Higher priority codes are in lower indexes 42*5d92fffcSrohitpai constexpr std::array<unsigned, 13> orderedCodes = { 43*5d92fffcSrohitpai 500, 507, 503, 502, 501, 401, 412, 409, 406, 405, 404, 403, 400}; 44*5d92fffcSrohitpai size_t finalCodeIndex = std::numeric_limits<size_t>::max(); 45*5d92fffcSrohitpai size_t subResponseCodeIndex = std::numeric_limits<size_t>::max(); 46*5d92fffcSrohitpai for (size_t i = 0; i < orderedCodes.size(); ++i) 47*5d92fffcSrohitpai { 48*5d92fffcSrohitpai if (orderedCodes[i] == finalCode) 49*5d92fffcSrohitpai { 50*5d92fffcSrohitpai finalCodeIndex = i; 51*5d92fffcSrohitpai } 52*5d92fffcSrohitpai if (orderedCodes[i] == subResponseCode) 53*5d92fffcSrohitpai { 54*5d92fffcSrohitpai subResponseCodeIndex = i; 55*5d92fffcSrohitpai } 56*5d92fffcSrohitpai } 57*5d92fffcSrohitpai if (finalCodeIndex != std::numeric_limits<size_t>::max() && 58*5d92fffcSrohitpai subResponseCodeIndex != std::numeric_limits<size_t>::max()) 59*5d92fffcSrohitpai { 60*5d92fffcSrohitpai return finalCodeIndex <= subResponseCodeIndex 61*5d92fffcSrohitpai ? finalCode 62*5d92fffcSrohitpai : subResponseCode; 63*5d92fffcSrohitpai } 64*5d92fffcSrohitpai if (subResponseCode == 500 || finalCode == 500) 65*5d92fffcSrohitpai { 66*5d92fffcSrohitpai return 500; 67*5d92fffcSrohitpai } 68*5d92fffcSrohitpai if (subResponseCode > 500 || finalCode > 500) 69*5d92fffcSrohitpai { 70*5d92fffcSrohitpai return std::max(finalCode, subResponseCode); 71*5d92fffcSrohitpai } 72*5d92fffcSrohitpai if (subResponseCode == 401) 73*5d92fffcSrohitpai { 74*5d92fffcSrohitpai return subResponseCode; 75*5d92fffcSrohitpai } 76*5d92fffcSrohitpai return std::max(finalCode, subResponseCode); 77*5d92fffcSrohitpai } 78*5d92fffcSrohitpai 79*5d92fffcSrohitpai // Propagates all error messages into |finalResponse| 80*5d92fffcSrohitpai inline void propogateError(crow::Response& finalResponse, 81*5d92fffcSrohitpai crow::Response& subResponse) 82*5d92fffcSrohitpai { 83*5d92fffcSrohitpai // no errors 84*5d92fffcSrohitpai if (subResponse.resultInt() >= 200 && subResponse.resultInt() < 400) 85*5d92fffcSrohitpai { 86*5d92fffcSrohitpai return; 87*5d92fffcSrohitpai } 88*5d92fffcSrohitpai messages::moveErrorsToErrorJson(finalResponse.jsonValue, 89*5d92fffcSrohitpai subResponse.jsonValue); 90*5d92fffcSrohitpai finalResponse.result( 91*5d92fffcSrohitpai propogateErrorCode(finalResponse.resultInt(), subResponse.resultInt())); 92*5d92fffcSrohitpai } 93*5d92fffcSrohitpai 94*5d92fffcSrohitpai } // namespace redfish 95