blob: 2b84db8a334f953aadfa0d5cb5008d9eace824ee [file] [log] [blame]
Ed Tanousc3ee5222018-05-01 12:58:27 -07001#pragma once
2
Ed Tanousc3ee5222018-05-01 12:58:27 -07003#include <crow/app.h>
Ed Tanous1abe55e2018-09-05 08:30:59 -07004
Ed Tanousc3ee5222018-05-01 12:58:27 -07005#include <boost/uuid/uuid.hpp>
6#include <boost/uuid/uuid_generators.hpp>
7#include <boost/uuid/uuid_io.hpp>
Ed Tanous1abe55e2018-09-05 08:30:59 -07008#include <cstdio>
9#include <dbus_singleton.hpp>
10#include <fstream>
11#include <memory>
Ed Tanousc3ee5222018-05-01 12:58:27 -070012
Ed Tanous1abe55e2018-09-05 08:30:59 -070013namespace crow
14{
15namespace image_upload
16{
Ed Tanousc3ee5222018-05-01 12:58:27 -070017
18std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatcher;
19
Ed Tanous55c7b7a2018-05-22 15:27:24 -070020inline void uploadImageHandler(const crow::Request& req, crow::Response& res,
Ed Tanous1abe55e2018-09-05 08:30:59 -070021 const std::string& filename)
22{
23 // Only allow one FW update at a time
24 if (fwUpdateMatcher != nullptr)
25 {
26 res.addHeader("Retry-After", "30");
27 res.result(boost::beast::http::status::service_unavailable);
Ed Tanousc3ee5222018-05-01 12:58:27 -070028 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -070029 return;
30 }
31 // Make this const static so it survives outside this method
32 static boost::asio::deadline_timer timeout(*req.ioService,
33 boost::posix_time::seconds(5));
34
35 timeout.expires_from_now(boost::posix_time::seconds(5));
36
37 timeout.async_wait([&res](const boost::system::error_code& ec) {
Ed Tanousc3ee5222018-05-01 12:58:27 -070038 fwUpdateMatcher = nullptr;
Ed Tanous1abe55e2018-09-05 08:30:59 -070039 if (ec == asio::error::operation_aborted)
40 {
41 // expected, we were canceled before the timer completed.
42 return;
43 }
44 BMCWEB_LOG_ERROR << "Timed out waiting for log event";
Ed Tanousc3ee5222018-05-01 12:58:27 -070045
Ed Tanous1abe55e2018-09-05 08:30:59 -070046 if (ec)
47 {
48 BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
49 return;
50 }
51
52 res.result(boost::beast::http::status::internal_server_error);
53 res.end();
54 });
55
56 std::function<void(sdbusplus::message::message&)> callback =
57 [&res](sdbusplus::message::message& m) {
58 BMCWEB_LOG_DEBUG << "Match fired";
59 boost::system::error_code ec;
60 timeout.cancel(ec);
61 if (ec)
62 {
63 BMCWEB_LOG_ERROR << "error canceling timer " << ec;
64 }
65 std::string versionInfo;
66 m.read(
67 versionInfo); // Read in the object path that was just created
68
69 std::size_t index = versionInfo.rfind('/');
70 if (index != std::string::npos)
71 {
72 versionInfo.erase(0, index);
73 }
74 res.jsonValue = {{"data", std::move(versionInfo)},
75 {"message", "200 OK"},
76 {"status", "ok"}};
77 BMCWEB_LOG_DEBUG << "ending response";
78 res.end();
79 fwUpdateMatcher = nullptr;
80 };
81 fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
82 *crow::connections::systemBus,
83 "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
84 "member='InterfacesAdded',path='/xyz/openbmc_project/logging'",
85 callback);
86
87 std::string filepath(
88 "/tmp/images/" +
89 boost::uuids::to_string(boost::uuids::random_generator()()));
90 BMCWEB_LOG_DEBUG << "Writing file to " << filepath;
91 std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
92 std::ofstream::trunc);
93 out << req.body;
94 out.close();
Ed Tanousc3ee5222018-05-01 12:58:27 -070095}
96
Ed Tanous1abe55e2018-09-05 08:30:59 -070097template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app)
98{
99 BMCWEB_ROUTE(app, "/upload/image/<str>")
100 .methods("POST"_method,
101 "PUT"_method)([](const crow::Request& req, crow::Response& res,
102 const std::string& filename) {
103 uploadImageHandler(req, res, filename);
104 });
Ed Tanousc3ee5222018-05-01 12:58:27 -0700105
Ed Tanous1abe55e2018-09-05 08:30:59 -0700106 BMCWEB_ROUTE(app, "/upload/image")
107 .methods("POST"_method, "PUT"_method)(
108 [](const crow::Request& req, crow::Response& res) {
109 uploadImageHandler(req, res, "");
110 });
Ed Tanousc3ee5222018-05-01 12:58:27 -0700111}
Ed Tanous1abe55e2018-09-05 08:30:59 -0700112} // namespace image_upload
113} // namespace crow