Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added check for cookie update and support for HTTP Basic authentication #18

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 54 additions & 8 deletions include/abb_librws/rws_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,21 +272,67 @@ class RWSClient : public POCOClient
*/
std::vector<SubscriptionResource> resources_;
};

/**
* \brief A constructor.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a tad too general. Do you think we could describe this better?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are quite a few such general descriptions. I have opened an issue to improve this, see #25

*
* \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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we start using C++11, we could use delegating constructors here.

(and for all the other ctor variants below)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will keep that in mind.

{}

/**
* \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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the LAN address, or can it be any address?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have only tested with LAN addresses, but I guess it could be any address as long as it is possible to establish a network connection.

The argument is passed down to a constructor for a POCO C++ HTTPClientSession.

* \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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this lose the Poco::UInt16 type spec?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... I don't remember... possibly a case of "copy-and-paste".

const std::string username,
const std::string password)
:
POCOClient(ip_address, port, user, password) {}
POCOClient(ip_address,
port,
username,
password)
{}

/**
* \brief A destructor.
Expand Down
7 changes: 6 additions & 1 deletion include/abb_librws/rws_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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).
*/
Expand Down
57 changes: 55 additions & 2 deletions include/abb_librws/rws_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about the delegating constructors here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will keep it in mind.

{}

/**
* \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.
*
Expand Down
15 changes: 8 additions & 7 deletions include/abb_librws/rws_poco_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer only Digest auth, or has the default changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the default is still Digest for RWS. However, the POCOClient implementation don't know that it is used for RWS at all, and since the HTTPCredentials can handle both it is more general this way (compared to the previous HTTPDigestCredentials).

* \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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should for be removed here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment for all other places that for is used in this way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have thought about improving the parameter descriptions, but I haven't had time yet. I have opened an issue to improve this, see #26

*/
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));
Expand Down Expand Up @@ -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.
*/
Expand Down
61 changes: 55 additions & 6 deletions include/abb_librws/rws_simple_state_machine_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delegating constructors again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will keep it in mind.


/**
* \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.
*
Expand Down
25 changes: 13 additions & 12 deletions src/rws_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably change some of this to constexprs (but that would need C++11 again).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will keep it in mind.


const std::string SystemConstants::IOSignals::HAND_ACTUAL_POSITION_L = "hand_ActualPosition_L";
const std::string SystemConstants::IOSignals::HAND_ACTUAL_POSITION_R = "hand_ActualPosition_R";
Expand Down
8 changes: 0 additions & 8 deletions src/rws_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
31 changes: 28 additions & 3 deletions src/rws_poco_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTTPCookie> 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);
Expand Down Expand Up @@ -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);
Expand Down