Add 405 handler for redfish

Redfish has specific error messages for OperationNotSupported in the
Base registry.  This commit allows bmcweb to return both the correct
return code (405) and the correct error message, while not effecting the
rest of the tree.

We didn't have the equivalent call in error_messages, so this adds the
required call.

Tested:
GET /redfish/v1 returns ServiceRoot
GET /redfish/v1/foo Returns 404
PATCH /redfish/v1 returns 405 OperationNotSupported
POST /redfish/v1/Chassis returns 405 OperationNotSupported
DELETE /redfish/v1/Chassis returns 405 ResourceCannotBeDeleted
POST /redfish/v1/foo/bar Returns 404

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I6f980af7307af602344b65a12a2b7589cc9ec959
Signed-off-by: Carson Labrado <clabrado@google.com>
diff --git a/redfish-core/lib/redfish_v1.hpp b/redfish-core/lib/redfish_v1.hpp
index 6aa3ee6..8907709 100644
--- a/redfish-core/lib/redfish_v1.hpp
+++ b/redfish-core/lib/redfish_v1.hpp
@@ -46,6 +46,29 @@
     messages::resourceNotFound(asyncResp->res, "", nameStr);
 }
 
+inline void redfish405(App& app, const crow::Request& req,
+                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                       const std::string& path)
+{
+    // If we fall to this route, we didn't have a more specific route, so return
+    // 405
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+
+    BMCWEB_LOG_ERROR << "405 on path " << path;
+    asyncResp->res.result(boost::beast::http::status::method_not_allowed);
+    if (req.method() == boost::beast::http::verb::delete_)
+    {
+        messages::resourceCannotBeDeleted(asyncResp->res);
+    }
+    else
+    {
+        messages::operationNotAllowed(asyncResp->res);
+    }
+}
+
 inline void
     jsonSchemaIndexGet(App& app, const crow::Request& req,
                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
@@ -138,6 +161,9 @@
     // Note, this route must always be registered last
     BMCWEB_ROUTE(app, "/redfish/<path>")
         .notFound()(std::bind_front(redfish404, std::ref(app)));
+
+    BMCWEB_ROUTE(app, "/redfish/<path>")
+        .methodNotAllowed()(std::bind_front(redfish405, std::ref(app)));
 }
 
 } // namespace redfish