TooSensitive - making comparison of hub and hub function names case insensitive

This commit is contained in:
moozzyk 2015-02-27 16:58:07 -08:00
Родитель 6ae3f6b52a
Коммит bc71c05d73
12 изменённых файлов: 110 добавлений и 14 удалений

Просмотреть файл

@ -38,6 +38,7 @@
<ClInclude Include="..\..\..\..\include\signalrclient\transport_type.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\web_exception.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\_exports.h" />
<ClInclude Include="..\..\case_insensitive_comparison_utils.h" />
<ClInclude Include="..\..\connection_impl.h" />
<ClInclude Include="..\..\constants.h" />
<ClInclude Include="..\..\default_websocket_client.h" />
@ -49,7 +50,7 @@
<ClInclude Include="..\..\negotiation_response.h" />
<ClInclude Include="..\..\request_sender.h" />
<ClInclude Include="..\..\stdafx.h" />
<ClInclude Include="..\..\trace_log_writer.h" />
<ClInclude Include="..\..\trace_log_writer.h" />
<ClInclude Include="..\..\transport.h" />
<ClInclude Include="..\..\transport_factory.h" />
<ClInclude Include="..\..\url_builder.h" />

Просмотреть файл

@ -105,6 +105,9 @@
<ClInclude Include="..\..\..\..\include\signalrclient\hub_proxy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\case_insensitive_comparison_utils.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\stdafx.cpp">

Просмотреть файл

@ -0,0 +1,50 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <functional>
#include <cctype>
#include "cpprest\details\basic_types.h"
namespace signalr
{
// Note: These functions are not pretending to be all-purpose helpers for case insensitive string comparison. Rather
// we use them to compare hub and hub method names which are expected to be almost exclusively ASCII and this is the
// simplest thing that would work without having to take dependencies on third party libraries.
struct case_insensitive_equals : std::binary_function<utility::string_t, utility::string_t, bool>
{
bool operator()(const utility::string_t& s1, const utility::string_t& s2) const
{
if (s1.length() != s2.length())
{
return false;
}
for (auto s1_iterator = s1.begin(), s2_iterator = s2.begin(); s1_iterator != s1.end(); ++s1_iterator, ++s2_iterator)
{
if (std::toupper(*s1_iterator) != std::toupper(*s2_iterator))
{
return false;
}
}
return true;
}
};
struct case_insensitive_hash : std::unary_function<utility::string_t, std::size_t>
{
std::size_t operator()(const utility::string_t& s) const
{
size_t hash = 0;
std::hash<size_t> hasher;
for (const utility::char_t& c : s)
{
hash ^= hasher(std::toupper(c)) + (hash << 5) + (hash >> 2);
}
return hash;
}
};
}

Просмотреть файл

@ -8,6 +8,7 @@
#include "connection_impl.h"
#include "internal_hub_proxy.h"
#include "callback_manager.h"
#include "case_insensitive_comparison_utils.h"
namespace signalr
{
@ -54,7 +55,7 @@ namespace signalr
logger m_logger;
std::shared_ptr<connection_impl> m_connection;
std::unordered_map<utility::string_t, std::shared_ptr<internal_hub_proxy>> m_proxies;
std::unordered_map<utility::string_t, std::shared_ptr<internal_hub_proxy>, case_insensitive_hash, case_insensitive_equals> m_proxies;
callback_manager m_callback_manager;
void initialize();

Просмотреть файл

@ -6,6 +6,7 @@
#include "cpprest\details\basic_types.h"
#include "cpprest\json.h"
#include "logger.h"
#include "case_insensitive_comparison_utils.h"
using namespace web;
@ -36,6 +37,6 @@ namespace signalr
const utility::string_t m_hub_name;
logger m_logger;
std::unordered_map<utility::string_t, std::function<void(const json::value &)>> m_subscriptions;
std::unordered_map<utility::string_t, std::function<void(const json::value &)>, case_insensitive_hash, case_insensitive_equals> m_subscriptions;
};
}

Просмотреть файл

@ -38,6 +38,7 @@
<ClInclude Include="..\..\..\..\include\signalrclient\transport_type.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\web_exception.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\_exports.h" />
<ClInclude Include="..\..\..\signalrclient\case_insensitive_comparison_utils.h" />
<ClInclude Include="..\..\..\signalrclient\connection_impl.h" />
<ClInclude Include="..\..\..\signalrclient\constants.h" />
<ClInclude Include="..\..\..\signalrclient\default_websocket_client.h" />

Просмотреть файл

@ -45,9 +45,6 @@
<ClInclude Include="..\..\..\signalrclient\request_sender.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\signalrclient\trace_level.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\signalrclient\transport.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -87,9 +84,6 @@
<ClInclude Include="..\..\..\..\include\signalrclient\log_writer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\trace_log_writer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\transport_type.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -105,6 +99,15 @@
<ClInclude Include="..\..\..\..\include\signalrclient\hub_proxy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\trace_level.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\signalrclient\trace_log_writer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\signalrclient\case_insensitive_comparison_utils.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\dllmain.cpp">

Просмотреть файл

@ -38,6 +38,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\callback_manager_tests.cpp" />
<ClCompile Include="..\..\case_insensitive_comparison_utils_tests.cpp" />
<ClCompile Include="..\..\connection_impl_tests.cpp" />
<ClCompile Include="..\..\http_sender_tests.cpp" />
<ClCompile Include="..\..\hub_connection_impl_tests.cpp" />

Просмотреть файл

@ -98,6 +98,9 @@
<ClCompile Include="..\..\hub_exception_tests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\case_insensitive_comparison_utils_tests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

Просмотреть файл

@ -0,0 +1,30 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "case_insensitive_comparison_utils.h"
using namespace signalr;
TEST(case_insensitive_equals_functor, basic_comparison_tests)
{
case_insensitive_equals case_insensitive_compare;
ASSERT_TRUE(case_insensitive_compare(_XPLATSTR(""), _XPLATSTR("")));
ASSERT_TRUE(case_insensitive_compare(_XPLATSTR("abc"), _XPLATSTR("ABC")));
ASSERT_TRUE(case_insensitive_compare(_XPLATSTR("abc123!@"), _XPLATSTR("ABC123!@")));
ASSERT_FALSE(case_insensitive_compare(_XPLATSTR("abc"), _XPLATSTR("ABCD")));
ASSERT_FALSE(case_insensitive_compare(_XPLATSTR("abce"), _XPLATSTR("ABCD")));
}
TEST(case_insensitive_hash_functor, basic_hash_tests)
{
case_insensitive_hash case_insensitive_hasher;
ASSERT_EQ(0, case_insensitive_hasher(_XPLATSTR("")));
ASSERT_EQ(case_insensitive_hasher(_XPLATSTR("abc")), case_insensitive_hasher(_XPLATSTR("ABC")));
ASSERT_EQ(case_insensitive_hasher(_XPLATSTR("abc123!@")), case_insensitive_hasher(_XPLATSTR("ABC123!@")));
ASSERT_NE(case_insensitive_hasher(_XPLATSTR("abcd")), case_insensitive_hasher(_XPLATSTR("ABC")));
}

Просмотреть файл

@ -85,8 +85,10 @@ TEST(create_hub_proxy, create_hub_proxy_returns_existing_proxies_if_possible)
auto hub_connection = create_hub_connection();
auto hub_proxy_1 = hub_connection->create_hub_proxy(_XPLATSTR("my_hub_proxy"));
auto hub_proxy_2 = hub_connection->create_hub_proxy(_XPLATSTR("my_hub_proxy"));
auto hub_proxy_3 = hub_connection->create_hub_proxy(_XPLATSTR("My_Hub_Proxy"));
ASSERT_EQ(hub_proxy_1.get(), hub_proxy_2.get());
ASSERT_EQ(hub_proxy_2.get(), hub_proxy_3.get());
}
TEST(create_hub_proxy, cannot_create_proxy_with_empty_name)
@ -319,7 +321,7 @@ TEST(hub_invocation, hub_connection_invokes_users_code_on_hub_invocations)
std::string responses[]
{
"{ \"C\":\"x\", \"S\":1, \"M\":[] }",
"{ \"C\":\"d- F430FB19\", \"M\" : [{\"H\":\"my_hub\", \"M\":\"broadcast\", \"A\" : [\"message\", 1]}] }",
"{ \"C\":\"d- F430FB19\", \"M\" : [{\"H\":\"my_HUB\", \"M\":\"BROADcast\", \"A\" : [\"message\", 1]}] }",
"{}"
};
@ -329,11 +331,11 @@ TEST(hub_invocation, hub_connection_invokes_users_code_on_hub_invocations)
});
auto hub_connection = create_hub_connection(websocket_client);
auto hub_proxy = hub_connection->create_hub_proxy(_XPLATSTR("my_hub"));
auto hub_proxy = hub_connection->create_hub_proxy(_XPLATSTR("MY_hub"));
auto payload = std::make_shared<utility::string_t>();
auto on_broadcast_event = std::make_shared<pplx::event>();
hub_proxy->on(_XPLATSTR("broadcast"), [on_broadcast_event, payload](const json::value& message)
hub_proxy->on(_XPLATSTR("broadCAST"), [on_broadcast_event, payload](const json::value& message)
{
*payload = message.serialize();
on_broadcast_event->set();

Просмотреть файл

@ -337,7 +337,7 @@ TEST(websocket_transport_disconnect, exceptions_from_outstanding_receive_task_ob
receive_event->set();
}
template<class T>
template<typename T>
void receive_loop_logs_exception_runner(const T& e, const utility::string_t& expected_message, trace_level trace_level);
TEST(websocket_transport_receive_loop, receive_loop_logs_websocket_exceptions)
@ -364,7 +364,7 @@ TEST(websocket_transport_receive_loop, receive_loop_logs_std_exception)
trace_level::errors);
}
template<class T>
template<typename T>
void receive_loop_logs_exception_runner(const T& e, const utility::string_t& expected_message, trace_level trace_level)
{
pplx::event receive_event;