summaryrefslogtreecommitdiff
path: root/http/http_connection.hpp
diff options
context:
space:
mode:
authorEd Tanous <edtanous@google.com>2023-01-24 02:57:41 +0300
committerEd Tanous <ed@tanous.net>2023-03-03 18:58:24 +0300
commit7d243eb7d1fafef191372146249ddafc5cadb4e8 (patch)
treecf7b367d2777e6854b6f42537150d3cc33eae22f /http/http_connection.hpp
parenta4eb761a4537a95f445d2980c43d79e55573507b (diff)
downloadbmcweb-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.hpp55
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<