From 1a35522dd1a02647cab21720e8414b92dbd3b384 Mon Sep 17 00:00:00 2001 From: jontje Date: Tue, 21 Aug 2018 15:38:49 +0200 Subject: [PATCH] Added check for cookie update and support for HTTP Basic authentication --- include/abb_librws/rws_client.h | 62 ++++++++++++++++--- include/abb_librws/rws_common.h | 7 ++- include/abb_librws/rws_interface.h | 57 ++++++++++++++++- include/abb_librws/rws_poco_client.h | 15 ++--- .../rws_simple_state_machine_interface.h | 61 ++++++++++++++++-- src/rws_common.cpp | 25 ++++---- src/rws_interface.cpp | 8 --- src/rws_poco_client.cpp | 31 +++++++++- 8 files changed, 219 insertions(+), 47 deletions(-) diff --git a/include/abb_librws/rws_client.h b/include/abb_librws/rws_client.h index 737dac0c..1e5e2bcb 100644 --- a/include/abb_librws/rws_client.h +++ b/include/abb_librws/rws_client.h @@ -272,21 +272,67 @@ class RWSClient : public POCOClient */ std::vector resources_; }; + + /** + * \brief A constructor. + * + * \param ip_address specifying the robot controller's IP address. + */ + RWSClient(const std::string ip_address) + : + POCOClient(ip_address, + SystemConstants::General::DEFAULT_PORT_NUMBER, + SystemConstants::General::DEFAULT_USERNAME, + SystemConstants::General::DEFAULT_PASSWORD) + {} + + /** + * \brief A constructor. + * + * \param ip_address specifying the robot controller's IP address. + * \param username for the username to the RWS authentication process. + * \param password for the password to the RWS authentication process. + */ + RWSClient(const std::string ip_address, const std::string username, const std::string password) + : + POCOClient(ip_address, + SystemConstants::General::DEFAULT_PORT_NUMBER, + username, + password) + {} + + /** + * \brief A constructor. + * + * \param ip_address specifying the robot controller's IP address. + * \param port for the port used by the RWS server. + */ + RWSClient(const std::string ip_address, const unsigned short port) + : + POCOClient(ip_address, + port, + SystemConstants::General::DEFAULT_USERNAME, + SystemConstants::General::DEFAULT_PASSWORD) + {} /** * \brief A constructor. * - * \param ip_address for the remote server's IP address. - * \param port for the remote server's port. - * \param user for the remote server's authentication (assumed to be Digest). - * \param password for the remote server's authentication (assumed to be Digest). + * \param ip_address specifying the robot controller's IP address. + * \param port for the port used by the RWS server. + * \param username for the username to the RWS authentication process. + * \param password for the password to the RWS authentication process. */ RWSClient(const std::string ip_address, - const Poco::UInt16 port = 80, - const std::string user = SystemConstants::General::DEFAULT_USERNAME, - const std::string password = SystemConstants::General::DEFAULT_PASSWORD) + const unsigned short port, + const std::string username, + const std::string password) : - POCOClient(ip_address, port, user, password) {} + POCOClient(ip_address, + port, + username, + password) + {} /** * \brief A destructor. diff --git a/include/abb_librws/rws_common.h b/include/abb_librws/rws_common.h index f5e6e4e0..51a9270b 100644 --- a/include/abb_librws/rws_common.h +++ b/include/abb_librws/rws_common.h @@ -163,11 +163,16 @@ struct SystemConstants */ static const std::string EXTERNAL_LOCATION; + /** + * \brief Default port number for RWS communication. + */ + static const unsigned short DEFAULT_PORT_NUMBER; + /** * \brief Default password (for unconfigured robot controller systems). */ static const std::string DEFAULT_PASSWORD; - + /** * \brief Default username (for unconfigured robot controller systems). */ diff --git a/include/abb_librws/rws_interface.h b/include/abb_librws/rws_interface.h index bda8c58d..a1bde1da 100644 --- a/include/abb_librws/rws_interface.h +++ b/include/abb_librws/rws_interface.h @@ -305,10 +305,63 @@ class RWSInterface * \brief A constructor. * * \param ip_address specifying the robot controller's IP address. - * \param port specifying the robot controller's RWS server's port number. */ - RWSInterface(const std::string ip_address, const unsigned short port = 80); + RWSInterface(const std::string ip_address) + : + rws_client_(ip_address, + SystemConstants::General::DEFAULT_PORT_NUMBER, + SystemConstants::General::DEFAULT_USERNAME, + SystemConstants::General::DEFAULT_PASSWORD) + {} + /** + * \brief A constructor. + * + * \param ip_address specifying the robot controller's IP address. + * \param username for the username to the RWS authentication process. + * \param password for the password to the RWS authentication process. + */ + RWSInterface(const std::string ip_address, const std::string username, const std::string password) + : + rws_client_(ip_address, + SystemConstants::General::DEFAULT_PORT_NUMBER, + username, + password) + {} + + /** + * \brief A constructor. + * + * \param ip_address specifying the robot controller's IP address. + * \param port for the port used by the RWS server. + */ + RWSInterface(const std::string ip_address, const unsigned short port) + : + rws_client_(ip_address, + port, + SystemConstants::General::DEFAULT_USERNAME, + SystemConstants::General::DEFAULT_PASSWORD) + {} + + /** + * \brief A constructor. + * + * \param ip_address specifying the robot controller's IP address. + * \param port for the port used by the RWS server. + * \param username for the username to the RWS authentication process. + * \param password for the password to the RWS authentication process. + */ + RWSInterface(const std::string ip_address, + const unsigned short port, + const std::string username, + const std::string password) + : + rws_client_(ip_address, + port, + username, + password) + {} + /** * \brief A method for collecting runtime information of the robot controller. * diff --git a/include/abb_librws/rws_poco_client.h b/include/abb_librws/rws_poco_client.h index dcbffd2f..0a58ef68 100644 --- a/include/abb_librws/rws_poco_client.h +++ b/include/abb_librws/rws_poco_client.h @@ -39,6 +39,7 @@ #include "Poco/Mutex.h" #include "Poco/Net/HTTPClientSession.h" +#include "Poco/Net/HTTPCredentials.h" #include "Poco/Net/HTTPResponse.h" #include "Poco/Net/WebSocket.h" #include "Poco/SharedPtr.h" @@ -246,16 +247,16 @@ class POCOClient * * \param ip_address for the remote server's IP address. * \param port for the remote server's port. - * \param user for the remote server's authentication (assumed to be Digest). - * \param password for the remote server's authentication (assumed to be Digest). + * \param username for the username to the remote server's authentication process. + * \param password for the password to the remote server's authentication process. */ POCOClient(const std::string ip_address, const Poco::UInt16 port, - const std::string user, + const std::string username, const std::string password) : client_session_(ip_address, port), - digest_credentials_(user, password) + http_credentials_(username, password) { client_session_.setKeepAlive(true); client_session_.setTimeout(Poco::Timespan(DEFAULT_TIMEOUT)); @@ -424,10 +425,10 @@ class POCOClient Poco::Mutex websocket_mutex_; /** - * \brief Digest authentication credentials. + * \brief HTTP credentials for the remote server's access authentication process. */ - Poco::Net::HTTPDigestCredentials digest_credentials_; - + Poco::Net::HTTPCredentials http_credentials_; + /** * \brief A container for cookies received from a server. */ diff --git a/include/abb_librws/rws_simple_state_machine_interface.h b/include/abb_librws/rws_simple_state_machine_interface.h index 9735eea0..09ad7d83 100644 --- a/include/abb_librws/rws_simple_state_machine_interface.h +++ b/include/abb_librws/rws_simple_state_machine_interface.h @@ -411,15 +411,64 @@ class RWSSimpleStateMachineInterface : public RWSInterface /** * \brief A constructor. * - * \param ip_address for the remote server's IP address. - * \param port for the remote server's port. + * \param ip_address specifying the robot controller's IP address. */ - RWSSimpleStateMachineInterface(const std::string ip_address, const unsigned short port = 80) + RWSSimpleStateMachineInterface(const std::string ip_address) : - RWSInterface(ip_address, port) - { - } + RWSInterface(ip_address, + SystemConstants::General::DEFAULT_PORT_NUMBER, + SystemConstants::General::DEFAULT_USERNAME, + SystemConstants::General::DEFAULT_PASSWORD) + {} + /** + * \brief A constructor. + * + * \param ip_address specifying the robot controller's IP address. + * \param username for the username to the RWS authentication process. + * \param password for the password to the RWS authentication process. + */ + RWSSimpleStateMachineInterface(const std::string ip_address, const std::string username, const std::string password) + : + RWSInterface(ip_address, + SystemConstants::General::DEFAULT_PORT_NUMBER, + username, + password) + {} + + /** + * \brief A constructor. + * + * \param ip_address specifying the robot controller's IP address. + * \param port for the port used by the RWS server. + */ + RWSSimpleStateMachineInterface(const std::string ip_address, const unsigned short port) + : + RWSInterface(ip_address, + port, + SystemConstants::General::DEFAULT_USERNAME, + SystemConstants::General::DEFAULT_PASSWORD) + {} + + /** + * \brief A constructor. + * + * \param ip_address specifying the robot controller's IP address. + * \param port for the port used by the RWS server. + * \param username for the username to the RWS authentication process. + * \param password for the password to the RWS authentication process. + */ + RWSSimpleStateMachineInterface(const std::string ip_address, + const unsigned short port, + const std::string username, + const std::string password) + : + RWSInterface(ip_address, + port, + username, + password) + {} + /** * \brief A method for retrieving the current jointtarget values of the robot. * diff --git a/src/rws_common.cpp b/src/rws_common.cpp index bd6f747b..bb6d7992 100644 --- a/src/rws_common.cpp +++ b/src/rws_common.cpp @@ -165,18 +165,19 @@ const std::string SystemConstants::ContollerStates::CONTROLLER_MOTOR_OFF = const std::string SystemConstants::ContollerStates::PANEL_OPERATION_MODE_AUTO = "AUTO"; const std::string SystemConstants::ContollerStates::RAPID_EXECUTION_RUNNING = "running"; -const std::string SystemConstants::General::EXTERNAL_APPLICATION = "ExternalApplication"; -const std::string SystemConstants::General::EXTERNAL_LOCATION = "ExternalLocation"; -const std::string SystemConstants::General::DEFAULT_PASSWORD = "robotics"; -const std::string SystemConstants::General::DEFAULT_USERNAME = "Default User"; -const std::string SystemConstants::General::LOCAL = "local"; -const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_1 = "ROB_1"; -const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_2 = "ROB_2"; -const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_3 = "ROB_3"; -const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_4 = "ROB_4"; -const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_L = "ROB_L"; -const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_R = "ROB_R"; -const std::string SystemConstants::General::REMOTE = "remote"; +const std::string SystemConstants::General::EXTERNAL_APPLICATION = "ExternalApplication"; +const std::string SystemConstants::General::EXTERNAL_LOCATION = "ExternalLocation"; +const unsigned short SystemConstants::General::DEFAULT_PORT_NUMBER = 80; +const std::string SystemConstants::General::DEFAULT_PASSWORD = "robotics"; +const std::string SystemConstants::General::DEFAULT_USERNAME = "Default User"; +const std::string SystemConstants::General::LOCAL = "local"; +const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_1 = "ROB_1"; +const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_2 = "ROB_2"; +const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_3 = "ROB_3"; +const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_4 = "ROB_4"; +const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_L = "ROB_L"; +const std::string SystemConstants::General::MECHANICAL_UNIT_ROB_R = "ROB_R"; +const std::string SystemConstants::General::REMOTE = "remote"; const std::string SystemConstants::IOSignals::HAND_ACTUAL_POSITION_L = "hand_ActualPosition_L"; const std::string SystemConstants::IOSignals::HAND_ACTUAL_POSITION_R = "hand_ActualPosition_R"; diff --git a/src/rws_interface.cpp b/src/rws_interface.cpp index ca661605..724d328c 100644 --- a/src/rws_interface.cpp +++ b/src/rws_interface.cpp @@ -57,14 +57,6 @@ typedef SystemConstants::RWS::XMLAttributes XMLAttributes; * Primary methods */ -RWSInterface::RWSInterface(const std::string ip_address, const unsigned short port) -: -rws_client_(ip_address, port) -{ - collectStaticInfo(); - collectRuntimeInfo(); -} - RWSInterface::RuntimeInfo RWSInterface::collectRuntimeInfo() { RuntimeInfo runtime_info; diff --git a/src/rws_poco_client.cpp b/src/rws_poco_client.cpp index d0b2aa14..21825aeb 100644 --- a/src/rws_poco_client.cpp +++ b/src/rws_poco_client.cpp @@ -258,7 +258,30 @@ POCOClient::POCOResult POCOClient::makeHTTPRequest(const std::string method, { sendAndReceive(result, request, response, content); - // Check if the request was approved, else add credentials. + // Check if the server has sent an update for the cookies. + std::vector temp_cookies; + response.getCookies(temp_cookies); + for (size_t i = 0; i < temp_cookies.size(); ++i) + { + if (cookies_.find(temp_cookies[i].getName()) != cookies_.end()) + { + cookies_.set(temp_cookies[i].getName(), temp_cookies[i].getValue()); + } + else + { + cookies_.add(temp_cookies[i].getName(), temp_cookies[i].getValue()); + } + } + + // Check if there was a server error, if so, make another attempt with a clean sheet. + if (response.getStatus() >= HTTPResponse::HTTP_INTERNAL_SERVER_ERROR) + { + client_session_.reset(); + request.erase(HTTPRequest::COOKIE); + sendAndReceive(result, request, response, content); + } + + // Check if the request was unauthorized, if so add credentials. if (response.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED) { authenticate(result, request, response, content); @@ -452,9 +475,11 @@ void POCOClient::authenticate(POCOResult& result, HTTPResponse& response, const std::string request_content) { - // Remove any old cookies and add credentials. + // Remove any old cookies. cookies_.clear(); - digest_credentials_.authenticate(request, response); + + // Authenticate with the provided credentials. + http_credentials_.authenticate(request, response); // Contact the server, and extract and store the received cookies. sendAndReceive(result, request, response, request_content);