Skip to content

Commit 84837fc

Browse files
authored
Merge pull request #199 from c-jimenez/develop
v1.5.1
2 parents 78a853e + 94ceef7 commit 84837fc

File tree

7 files changed

+45
-72
lines changed

7 files changed

+45
-72
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
cmake_minimum_required(VERSION 3.13)
66

77
project(OpenOCPP DESCRIPTION "Open Source C++ implementation of the OCPP 1.6 protocol"
8-
VERSION 1.5.0
8+
VERSION 1.5.1
99
)
1010

1111
# Definitions for Version.h file

src/chargepoint/ChargePoint.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ along with OpenOCPP. If not, see <http://www.gnu.org/licenses/>.
3535
#include "TimerPool.h"
3636
#include "TransactionManager.h"
3737
#include "TriggerMessageManager.h"
38+
#include "Url.h"
3839
#include "Version.h"
3940
#include "WebsocketFactory.h"
4041
#include "WorkerThreadPool.h"
@@ -1142,7 +1143,7 @@ bool ChargePoint::doConnect()
11421143
{
11431144
connection_url += "/";
11441145
}
1145-
connection_url += m_stack_config.chargePointIdentifier();
1146+
connection_url += ocpp::websockets::Url::encode(m_stack_config.chargePointIdentifier());
11461147

11471148
// Check if URL has changed since last connection
11481149
std::string last_url;
@@ -1166,7 +1167,7 @@ bool ChargePoint::doConnect()
11661167
{
11671168
auto authentication_key = ocpp::helpers::fromHexString(authorization_key);
11681169
credentials.user = m_stack_config.chargePointIdentifier();
1169-
credentials.password = std::string(reinterpret_cast<const char*>(authentication_key.data()), authorization_key.size());
1170+
credentials.password = std::string(reinterpret_cast<const char*>(authentication_key.data()), authentication_key.size());
11701171
credentials.password.resize(authentication_key.size());
11711172
}
11721173
if (security_profile != 1)

src/chargepoint/reservation/ReservationManager.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,8 @@ bool ReservationManager::handleMessage(const ocpp::messages::ReserveNowReq& requ
185185
if (connector)
186186
{
187187
// Check if reservation is allowed on connector
188-
if ((request.connectorId != 0) || ((request.connectorId == 0) && m_ocpp_config.reserveConnectorZeroSupported()))
188+
if (((request.connectorId != 0) || ((request.connectorId == 0) && m_ocpp_config.reserveConnectorZeroSupported()))
189+
&&( m_ocpp_config.supportedFeatureProfiles().find("Reservation")!= std::string::npos) )
189190
{
190191
std::lock_guard<std::mutex> lock(connector->mutex);
191192

src/localcontroller/centralsystem/CentralSystemProxy.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ along with OpenOCPP. If not, see <http://www.gnu.org/licenses/>.
1818

1919
#include "CentralSystemProxy.h"
2020
#include "ILocalControllerConfig.h"
21+
#include "Url.h"
2122
#include "WebsocketFactory.h"
2223

2324
#include <sstream>
@@ -86,7 +87,7 @@ bool CentralSystemProxy::connect(const std::string&
8687
{
8788
full_url << "/";
8889
}
89-
full_url << m_identifier;
90+
full_url << ocpp::websockets::Url::encode(m_identifier);
9091

9192
// Connect
9293
ret = m_rpc.start(full_url.str(), credentials, connect_timeout, retry_interval, ping_interval);

src/websockets/Url.cpp

+28-34
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@ Url::Url(const std::string& url)
4848

4949
// Convert path
5050
m_path = match[10].str();
51-
if (!m_path.empty())
52-
{
53-
m_path = encode(m_path);
54-
}
5551

5652
// Convert port
5753
std::string sport = match[9].str();
@@ -70,55 +66,53 @@ Url::Url(const std::string& url)
7066
m_is_valid = false;
7167
}
7268
}
73-
74-
// Rebuild URL
75-
if (m_is_valid)
76-
{
77-
std::stringstream encoded_url;
78-
encoded_url << m_protocol << "://";
79-
if (!m_username.empty() || !m_password.empty())
80-
{
81-
encoded_url << m_username;
82-
if (!m_password.empty())
83-
{
84-
encoded_url << ":" << m_password;
85-
}
86-
encoded_url << "@";
87-
}
88-
encoded_url << m_address;
89-
if (m_port != 0)
90-
{
91-
encoded_url << ":" << m_port;
92-
}
93-
encoded_url << m_path;
94-
m_url = encoded_url.str();
95-
}
9669
}
9770
}
9871

9972
/** @brief Destructor */
10073
Url::~Url() { }
10174

102-
/** @brief Encode an URL */
103-
std::string Url::encode(const std::string& url) const
75+
/** @brief Encode a part of an URL using RFC3986 percent encoding */
76+
std::string Url::encode(const std::string& url)
10477
{
78+
// RFC3986 : Un reserved chars which must not be encoded
79+
static const char unreserved_char[] = {'-', '_', '.', '~'};
80+
10581
std::stringstream encoded_url;
106-
encoded_url << std::hex;
82+
encoded_url << std::uppercase << std::hex;
10783

10884
for (const auto& c : url)
10985
{
110-
// Safe characters
111-
if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')) || (c == '/'))
86+
// RFC3986 : Only alphanumeric and unreserved chars may be used
87+
// unencoded within a URL
88+
bool encode = true;
89+
if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')))
11290
{
113-
// No encoding
114-
encoded_url << c;
91+
encode = false;
11592
}
11693
else
94+
{
95+
for (size_t i = 0; i < sizeof(unreserved_char) / sizeof(char); i++)
96+
{
97+
if (c == unreserved_char[i])
98+
{
99+
encode = false;
100+
break;
101+
}
102+
}
103+
}
104+
105+
if (encode)
117106
{
118107
// Percent encoding
119108
encoded_url << '%';
120109
encoded_url << std::setw(2) << std::setfill('0') << static_cast<int>(c);
121110
}
111+
else
112+
{
113+
// No encoding
114+
encoded_url << c;
115+
}
122116
}
123117

124118
return encoded_url.str();

src/websockets/Url.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ class Url
9696
*/
9797
const std::string& path() const { return m_path; }
9898

99+
/** @brief Encode a part of an URL using RFC3986 percent encoding */
100+
static std::string encode(const std::string& url);
101+
99102
private:
100103
/** @brief Full URL */
101104
std::string m_url;
@@ -113,9 +116,6 @@ class Url
113116
unsigned int m_port;
114117
/** @brief Path part of the URL */
115118
std::string m_path;
116-
117-
/** @brief Encode an URL */
118-
std::string encode(const std::string& url) const;
119119
};
120120

121121
} // namespace websockets

tests/websockets/test_websockets_url.cpp

+6-30
Original file line numberDiff line numberDiff line change
@@ -80,21 +80,6 @@ TEST_SUITE("Nominal - hostname as string")
8080
CHECK_EQ(url.path(), "/paf/pouf/");
8181
}
8282

83-
TEST_CASE("URL with port and encoded path")
84-
{
85-
Url url("ftp://pif.com:12345/paf [ pouf / + BIM_bam) = boum ] 10.11.12.13!");
86-
87-
CHECK(url.isValid());
88-
CHECK_EQ(url.url(),
89-
R"(ftp://pif.com:12345/paf%20%5b%20pouf%20/%20%20%2b%20BIM%5fbam%29%20%3d%20boum%20%5d%2010%2e11%2e12%2e13%21)");
90-
CHECK_EQ(url.protocol(), "ftp");
91-
CHECK_EQ(url.username(), "");
92-
CHECK_EQ(url.password(), "");
93-
CHECK_EQ(url.address(), "pif.com");
94-
CHECK_EQ(url.port(), 12345);
95-
CHECK_EQ(url.path(), R"(/paf%20%5b%20pouf%20/%20%20%2b%20BIM%5fbam%29%20%3d%20boum%20%5d%2010%2e11%2e12%2e13%21)");
96-
}
97-
9883
TEST_CASE("URL with username and port")
9984
{
10085
Url url("ftp://yip76-84@pif.com:12345");
@@ -228,21 +213,6 @@ TEST_SUITE("Nominal - hostname as IP address")
228213
CHECK_EQ(url.path(), "/paf/pouf/");
229214
}
230215

231-
TEST_CASE("URL with port and encoded path")
232-
{
233-
Url url("ftp://10.189.70.3:12345/paf [ pouf / + BIM_bam) = boum ] 10.11.12.13!");
234-
235-
CHECK(url.isValid());
236-
CHECK_EQ(url.url(),
237-
R"(ftp://10.189.70.3:12345/paf%20%5b%20pouf%20/%20%20%2b%20BIM%5fbam%29%20%3d%20boum%20%5d%2010%2e11%2e12%2e13%21)");
238-
CHECK_EQ(url.protocol(), "ftp");
239-
CHECK_EQ(url.username(), "");
240-
CHECK_EQ(url.password(), "");
241-
CHECK_EQ(url.address(), "10.189.70.3");
242-
CHECK_EQ(url.port(), 12345);
243-
CHECK_EQ(url.path(), R"(/paf%20%5b%20pouf%20/%20%20%2b%20BIM%5fbam%29%20%3d%20boum%20%5d%2010%2e11%2e12%2e13%21)");
244-
}
245-
246216
TEST_CASE("URL with username and port")
247217
{
248218
Url url("ftp://yip76-84@10.189.70.3:12345");
@@ -316,6 +286,12 @@ TEST_SUITE("Nominal - hostname as IP address")
316286
CHECK_EQ(url1.port(), url2.port());
317287
CHECK_EQ(url1.path(), url2.path());
318288
}
289+
290+
TEST_CASE("URL percent encoding")
291+
{
292+
std::string url("paf [ pouf / + BIM_bam) = boum ] 10.11.12.13!");
293+
CHECK_EQ(Url::encode(url), R"(paf%20%5B%20pouf%20%2F%20%20%2B%20BIM_bam%29%20%3D%20boum%20%5D%2010.11.12.13%21)");
294+
}
319295
}
320296

321297
TEST_SUITE("Errors")

0 commit comments

Comments
 (0)