diff options
author | Ed Tanous <edtanous@google.com> | 2023-01-24 02:57:41 +0300 |
---|---|---|
committer | Ed Tanous <ed@tanous.net> | 2023-03-03 18:58:24 +0300 |
commit | 7d243eb7d1fafef191372146249ddafc5cadb4e8 (patch) | |
tree | cf7b367d2777e6854b6f42537150d3cc33eae22f /http/http_connection.hpp | |
parent | a4eb761a4537a95f445d2980c43d79e55573507b (diff) | |
download | bmcweb-7d243eb7d1fafef191372146249ddafc5cadb4e8.tar.xz |
Allow logged in users to upload incrementally
There are use cases where logged in users might want to upload a large
file over a slow connection, and would exceed the 60 second timeout that
bmcweb has. This commit would theoretically allow the user timer to be
per-segment, allowing very long timeouts in the case of slow
connections, so long as some progress was made within the 15 second
window, which seems reasonable.
If user authentication is disabled then there is no user session active
in this case timer will be refreshed as long as progress was made.
This seems like a better alternative compared to setting a very long
(5-20 minute) timeout.
Testing:
- Loaded image on the system
$ curl -k -H 'X-Auth-Token: <token>' -H 'Content-Type: application/octet-stream' -X POST -T ./obmc-phosphor-image-p10bmc.ext4.mmc.tar https://${bmc}:443/redfish/v1/UpdateService/update
{
"@odata.id": "/redfish/v1/TaskService/Tasks/0",
"@odata.type": "#Task.v1_4_3.Task",
"Id": "0",
"TaskState": "Running",
"TaskStatus": "OK"
}
- Tested image load using disable authentication and insecure http
connections.
- Ran few querries and those are fine.
* curl -s -k https://${bmc}:443/redfish/v1/Managers
* curl -s -k https://${bmc}:443/redfish/v1/Managers/bmc
* curl -s -k https://${bmc}:443/redfish/v1/AccountService/Accounts
* curl -s -k https://${bmc}:443/redfish/v1/Systems/system
* curl -s -k https://${bmc}:443/redfish/v1/Chassis/chassis
* curl -s -k https://${bmc}:443/redfish/v1/AccountService/LDAP/Certificates
* curl -k -X POST https://${bmc}:443/redfish/v1/AccountService/Accounts -d '{"UserName": "user99", "Password": "pass123", "RoleId": "Administrator"}'
* curl -k https://${bmc}:443/redfish/v1/AccountService/Accounts/user99
* curl -k -X DELETE https://${bmc}:443/redfish/v1/AccountService/Accounts/user99
* curl -k -H 'Content-Type: application/json' -X POST https://${bmc}:443/login -d '{"username" : "admin", "password" : "newpas1"}'
* curl -k -H 'X-Auth-Token: ' -X PATCH https://${bmc}:443/redfish/v1/AccountService/Accounts/admin -d '{"Password":"newpas2"}'
* curl -k -H 'X-Auth-Token: ' -X POST https://${bmc}:443/logout
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I579c86defdd199c140891a986d70ae2eca63b2aa
Signed-off-by: Ninad Palsule <ninadpalsule@us.ibm.com>
Diffstat (limited to 'http/http_connection.hpp')
-rw-r--r-- | http/http_connection.hpp | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/http/http_connection.hpp b/http/http_connection.hpp index 2c921b50f5..0daf6650d4 100644 --- a/http/http_connection.hpp +++ b/http/http_connection.hpp @@ -490,6 +490,12 @@ class Connection : } #endif // BMCWEB_INSECURE_DISABLE_AUTHX + if (parser->is_done()) + { + handle(); + return; + } + doRead(); }); } @@ -498,13 +504,14 @@ class Connection : { BMCWEB_LOG_DEBUG << this << " doRead"; startDeadline(); - boost::beast::http::async_read(adaptor, buffer, *parser, - [this, self(shared_from_this())]( - const boost::system::error_code& ec, - std::size_t bytesTransferred) { - BMCWEB_LOG_DEBUG << this << " async_read " << bytesTransferred + boost::beast::http::async_read_some( + adaptor, buffer, *parser, + [this, + self(shared_from_this())](const boost::system::error_code& ec, + std::size_t bytesTransferred) { + BMCWEB_LOG_DEBUG << this << " async_read_some " << bytesTransferred << " Bytes"; - cancelDeadlineTimer(); + if (ec) { BMCWEB_LOG_ERROR << this @@ -513,8 +520,23 @@ class Connection : BMCWEB_LOG_DEBUG << this << " from read(1)"; return; } + + // If the user is logged in, allow them to send files incrementally + // one piece at a time. If authentication is disabled then there is + // no user session hence always allow to send one piece at a time. + if (userSession != nullptr) + { + cancelDeadlineTimer(); + } + if (!parser->is_done()) + { + doRead(); + return; + } + + cancelDeadlineTimer(); handle(); - }); + }); } void doWrite(crow::Response& thisRes) @@ -567,22 +589,19 @@ class Connection : void startDeadline() { - cancelDeadlineTimer(); - - std::chrono::seconds timeout(15); - // allow slow uploads for logged in users - bool loggedIn = userSession != nullptr; - if (loggedIn) + // Timer is already started so no further action is required. + if (timerStarted) { - timeout = std::chrono::seconds(60); + return; } + std::chrono::seconds timeout(15); + std::weak_ptr<Connection<Adaptor, Handler>> weakSelf = weak_from_this(); timer.expires_after(timeout); timer.async_wait([weakSelf](const boost::system::error_code ec) { // Note, we are ignoring other types of errors here; If the timer // failed for any reason, we should still close the connection - std::shared_ptr<Connection<Adaptor, Handler>> self = weakSelf.lock(); if (!self) @@ -590,6 +609,9 @@ class Connection : BMCWEB_LOG_CRITICAL << self << " Failed to capture connection"; return; } + + self->timerStarted = false; + if (ec == boost::asio::error::operation_aborted) { // Canceled wait means the path succeeeded. @@ -605,6 +627,7 @@ class Connection : self->close(); }); + timerStarted = true; BMCWEB_LOG_DEBUG << this << " timer started"; } @@ -632,6 +655,8 @@ class Connection : bool keepAlive = true; + bool timerStarted = false; + std::function<std::string()>& getCachedDateStr; using std::enable_shared_from_this< |