Merge lp:~marcustomlinson/unity-scopes-api/switch-to-net-cpp into lp:unity-scopes-api

Proposed by Marcus Tomlinson
Status: Merged
Approved by: Paweł Stołowski
Approved revision: 195
Merged at revision: 282
Proposed branch: lp:~marcustomlinson/unity-scopes-api/switch-to-net-cpp
Merge into: lp:unity-scopes-api
Prerequisite: lp:~saviq/unity-scopes-api/fix-cross-wrap
Diff against target: 1370 lines (+357/-698)
19 files modified
CMakeLists.txt (+27/-47)
debian/control (+1/-1)
include/unity/scopes/OnlineAccountClient.h (+1/-1)
include/unity/scopes/internal/smartscopes/HttpClientInterface.h (+1/-1)
include/unity/scopes/internal/smartscopes/HttpClientNetCpp.h (+78/-0)
include/unity/scopes/internal/smartscopes/HttpClientQt.h (+0/-91)
include/unity/scopes/internal/smartscopes/HttpClientQtThread.h (+0/-100)
src/scopes/internal/JsonCppNode.cpp (+4/-4)
src/scopes/internal/RegistryObject.cpp (+1/-1)
src/scopes/internal/smartscopes/CMakeLists.txt (+2/-31)
src/scopes/internal/smartscopes/HttpClientNetCpp.cpp (+189/-0)
src/scopes/internal/smartscopes/HttpClientQt.cpp (+0/-151)
src/scopes/internal/smartscopes/HttpClientQtThread.cpp (+0/-186)
src/scopes/internal/smartscopes/SSRegistryObject.cpp (+2/-2)
src/scopes/internal/smartscopes/SmartScopesClient.cpp (+41/-30)
test/gtest/scopes/internal/smartscopes/HttpClient/HttpClient_test.cpp (+3/-3)
test/gtest/scopes/internal/smartscopes/SmartScopesClient/FakeSss.py (+4/-1)
test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp (+3/-2)
valgrind-suppress (+0/-46)
To merge this branch: bzr merge lp:~marcustomlinson/unity-scopes-api/switch-to-net-cpp
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Michi Henning Pending
Review via email: mp+246982@code.launchpad.net

This proposal supersedes a proposal from 2015-01-15.

Commit message

Switch from QNetwork to net-cpp

Description of the change

Switch from QNetwork to net-cpp

This change has been on our backlog for some time now (Bug #1326816), but due to a recent issue we started experiencing with QNetwork (Bug #1409995) we are taking the opportunity now to make the switch over to net-cpp.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Michi Henning (michihenning) wrote : Posted in a previous version of this proposal

Looks good, thanks!

A few minor quibbles:

Please don't use uint anywhere. It's not a C++ type, and whether it works or not depends on whether some random header happens to drag in sys/types.h. Use unsigned int instead. (uint also causes warnings from doxygen when building the developer doc because it ends up not being able to match the signature in some cases.)

And, as an aside, try to not use unsigneds at all. They are evil. (See John Lakos for a really good explanation.)

76 + explicit HttpClientNetCpp(uint no_reply_timeout);
86 + void cancel_get(uint session_id) override;
88 + uint no_reply_timeout;
416 + std::pair<uint, std::shared_ptr<Cancelable>> add()
424 + uint add(const std::shared_ptr<Cancelable>& cancelable)
428 + uint result{++request_id};
435 + void cancel_and_remove_for_id(uint id)
448 + uint request_id{0};
450 + std::unordered_map<uint, std::shared_ptr<Cancelable>> store;
454 +HttpClientNetCpp::HttpClientNetCpp(uint no_reply_timeout)
529 +void HttpClientNetCpp::cancel_get(uint id)
923 HttpClientTest(uint no_reply_timeout = 20000)

It would be good to ditch the static library for smartscopes, I don't think we need it anymore.

While you are working on this anyway, would you mind making the lineData lambda thread-safe? At the moment, it appends to the string from a different thread without a lock.

Also, the lineData param should be called line_data instead.

Minor style issue here:

506 + } else
507 + {

And here (missing curlies):

465 + if (worker.joinable())
466 + worker.join();

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Michi Henning (michihenning) wrote : Posted in a previous version of this proposal

Thanks for that!

One request (please forgive me for being anal):

10 +find_library(ZMQPPLIB zmqpp)
11 +if(NOT ZMQPPLIB)
12 + message(FATAL_ERROR "Zmqpp lib not found.")
13 +endif()

I think this is nice. Without this, cmake says:

CMake Error at CMakeLists.txt:122 (message):
   Capnp compiler not found.

But it would be a *lot* nicer if it actually told me the package name instead of "Zmqpp lib not found".

I can't count the number of times where some sort of install script told me that command "foo" or library "libxyz" couldn't be found, and then I have to spend five minutes trying to figure out which package bloody "foo" or "libxyz" can be found in.

So, I'd change the error messages to actually spell out the package name "package capnproto not found". That way, I can just copy and paste: "apt-get install capnproto" and Bob's my uncle :-)

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote : Posted in a previous version of this proposal

> Thanks for that!
>
> One request (please forgive me for being anal):
>
> 10 +find_library(ZMQPPLIB zmqpp)
> 11 +if(NOT ZMQPPLIB)
> 12 + message(FATAL_ERROR "Zmqpp lib not found.")
> 13 +endif()
>
> I think this is nice. Without this, cmake says:
>
> CMake Error at CMakeLists.txt:122 (message):
> Capnp compiler not found.
>
> But it would be a *lot* nicer if it actually told me the package name instead
> of "Zmqpp lib not found".
>
> I can't count the number of times where some sort of install script told me
> that command "foo" or library "libxyz" couldn't be found, and then I have to
> spend five minutes trying to figure out which package bloody "foo" or "libxyz"
> can be found in.
>
> So, I'd change the error messages to actually spell out the package name
> "package capnproto not found". That way, I can just copy and paste: "apt-get
> install capnproto" and Bob's my uncle :-)

k, done

Revision history for this message
Michi Henning (michihenning) wrote : Posted in a previous version of this proposal

Thanks for that, and thanks for your diligence!

review: Approve
Revision history for this message
Michi Henning (michihenning) wrote : Posted in a previous version of this proposal

Not sure what was broken with Jenkins last time around. Top-approving to see what happens.

Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote : Posted in a previous version of this proposal

Fixed some small stupid mistakes (191 and 192), top approving again

195. By Marcus Tomlinson

Fixed formatting in control

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-01-19 08:08:55 +0000
3+++ CMakeLists.txt 2015-01-20 09:11:18 +0000
4@@ -67,9 +67,30 @@
5 pkg_check_modules(LTTNG_UST lttng-ust REQUIRED)
6 pkg_check_modules(LIBURCU_BP liburcu-bp REQUIRED)
7 pkg_check_modules(JSONCPP jsoncpp REQUIRED)
8-pkg_check_modules(LIBACCOUNTS REQUIRED libaccounts-glib)
9-pkg_check_modules(LIBSIGNON REQUIRED libsignon-glib)
10+pkg_check_modules(LIBACCOUNTS libaccounts-glib REQUIRED)
11+pkg_check_modules(LIBSIGNON libsignon-glib REQUIRED)
12 pkg_check_modules(ZMQLIB libzmq REQUIRED)
13+pkg_check_modules(NET_CPP net-cpp REQUIRED)
14+
15+find_library(ZMQPPLIB zmqpp)
16+if(NOT ZMQPPLIB)
17+ message(FATAL_ERROR "libzmqpp-dev not found.")
18+endif()
19+
20+find_library(CAPNPLIB capnp)
21+if(NOT CAPNPLIB)
22+ message(FATAL_ERROR "libcapnp-dev not found.")
23+endif()
24+
25+find_library(KJLIB kj)
26+if(NOT KJLIB)
27+ message(FATAL_ERROR "capnproto not found.")
28+endif()
29+
30+find_library(DLLIB dl)
31+if(NOT DLLIB)
32+ message(FATAL_ERROR "dl lib not found.")
33+endif()
34
35 find_program(LTTNG_EXECUTABLE lttng)
36 if (NOT LTTNG_EXECUTABLE)
37@@ -118,8 +139,10 @@
38
39 set(OTHER_INCLUDE_DIRS ${OTHER_INCLUDE_DIRS} ${UNITY_API_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
40 ${JSONCPP_INCLUDE_DIRS} ${PROCESS_CPP_INCLUDE_DIRS} ${APPARMOR_INCLUDE_DIRS}
41- ${LIBACCOUNTS_INCLUDE_DIRS} ${LIBSIGNON_INCLUDE_DIRS})
42-set(OTHER_LIBS ${OTHER_LIBS} ${UNITY_API_LDFLAGS} ${APPARMOR_LDFLAGS} ${LIBACCOUNTS_LIBRARIES} ${LIBSIGNON_LIBRARIES})
43+ ${LIBACCOUNTS_INCLUDE_DIRS} ${LIBSIGNON_INCLUDE_DIRS} ${NET_CPP_INCLUDE_DIRS})
44+set(OTHER_LIBS ${OTHER_LIBS} ${UNITY_API_LDFLAGS} ${APPARMOR_LDFLAGS} ${LIBACCOUNTS_LIBRARIES}
45+ ${LIBSIGNON_LIBRARIES} ${Boost_LIBRARIES} ${JSONCPP_LDFLAGS} ${PROCESS_CPP_LDFLAGS}
46+ ${ZMQPPLIB} ${ZMQLIB_LDFLAGS} ${CAPNPLIB} ${KJLIB} ${DLLIB} ${NET_CPP_LDFLAGS} pthread)
47
48 # Standard install paths
49 include(GNUInstallDirs)
50@@ -207,49 +230,6 @@
51 # Version for testing, with all symbols visible
52 set(UNITY_SCOPES_TEST_LIB ${UNITY_SCOPES_LIB}-test)
53
54-find_library(ZMQPPLIB zmqpp)
55-if(NOT ZMQPPLIB)
56- message(FATAL_ERROR "Zmqpp lib not found.")
57-endif()
58-
59-find_library(CAPNPLIB capnp)
60-if(NOT CAPNPLIB)
61- message(FATAL_ERROR "Cap'n Proto lib not found.")
62-endif()
63-
64-find_library(KJLIB kj)
65-if(NOT KJLIB)
66- message(FATAL_ERROR "Kj lib not found.")
67-endif()
68-
69-find_library(DLLIB dl)
70-if(NOT DLLIB)
71- message(FATAL_ERROR "Dl lib not found.")
72-endif()
73-
74-
75-# Stop complaints during the generation phase about executables depending
76-# on Qt5::Core and Qt5::Network. They are bogus because only
77-# only smartscopes uses these.
78-if(POLICY CMP0028)
79- cmake_policy(SET CMP0028 OLD)
80-endif()
81-
82-# Other libraries we depend on
83-set(OTHER_LIBS
84- ${OTHER_LIBS}
85- ${Boost_LIBRARIES}
86- ${JSONCPP_LDFLAGS}
87- ${PROCESS_CPP_LDFLAGS}
88- ${ZMQPPLIB}
89- ${ZMQLIB_LDFLAGS}
90- ${CAPNPLIB}
91- ${KJLIB}
92- ${DLLIB}
93- pthread
94- smartscopes
95-)
96-
97 # All the libraries we need to link a normal executable that uses Unity scopes
98 set(LIBS ${UNITY_SCOPES_LIB})
99
100
101=== modified file 'debian/control'
102--- debian/control 2015-01-20 09:11:18 +0000
103+++ debian/control 2015-01-20 09:11:18 +0000
104@@ -25,6 +25,7 @@
105 libdbustest1-dev,
106 libjsoncpp-dev,
107 liblttng-ust-dev,
108+ libnet-cpp-dev,
109 libprocess-cpp-dev (>= 1.0.1),
110 libsignon-glib-dev,
111 libunity-api-dev (>= 7.80.7~),
112@@ -33,7 +34,6 @@
113 lttng-tools,
114 pkg-config,
115 python3:any,
116- qtbase5-dev,
117 valgrind,
118 Standards-Version: 3.9.5
119 XS-Testsuite: autopkgtest
120
121=== modified file 'include/unity/scopes/OnlineAccountClient.h'
122--- include/unity/scopes/OnlineAccountClient.h 2014-11-03 05:31:30 +0000
123+++ include/unity/scopes/OnlineAccountClient.h 2015-01-20 09:11:18 +0000
124@@ -59,7 +59,7 @@
125 */
126 struct ServiceStatus
127 {
128- uint account_id; ///< A unique ID of the online account parenting this service.
129+ unsigned int account_id; ///< A unique ID of the online account parenting this service.
130 bool service_enabled; ///< True if this service is enabled.
131 bool service_authenticated; ///< True if this service is authenticated.
132 std::string client_id; ///< "ConsumerKey" / "ClientId" OAuth (1 / 2) parameter.
133
134=== modified file 'include/unity/scopes/internal/smartscopes/HttpClientInterface.h'
135--- include/unity/scopes/internal/smartscopes/HttpClientInterface.h 2014-11-03 05:31:30 +0000
136+++ include/unity/scopes/internal/smartscopes/HttpClientInterface.h 2015-01-20 09:11:18 +0000
137@@ -53,7 +53,7 @@
138 virtual ~HttpClientInterface() = default;
139
140 virtual std::shared_ptr<HttpResponseHandle> get(std::string const& request_url,
141- std::function<void(std::string const&)> const& lineData = [](std::string const&) {},
142+ std::function<void(std::string const&)> const& line_data = [](std::string const&) {},
143 HttpHeaders const& headers = HttpHeaders()) = 0;
144
145 virtual std::string to_percent_encoding(std::string const& string) = 0;
146
147=== added file 'include/unity/scopes/internal/smartscopes/HttpClientNetCpp.h'
148--- include/unity/scopes/internal/smartscopes/HttpClientNetCpp.h 1970-01-01 00:00:00 +0000
149+++ include/unity/scopes/internal/smartscopes/HttpClientNetCpp.h 2015-01-20 09:11:18 +0000
150@@ -0,0 +1,78 @@
151+/*
152+ * Copyright (C) 2013 Canonical Ltd
153+ *
154+ * This program is free software: you can redistribute it and/or modify
155+ * it under the terms of the GNU Lesser General Public License version 3 as
156+ * published by the Free Software Foundation.
157+ *
158+ * This program is distributed in the hope that it will be useful,
159+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
160+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
161+ * GNU Lesser General Public License for more details.
162+ *
163+ * You should have received a copy of the GNU Lesser General Public License
164+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
165+ *
166+ * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
167+ */
168+
169+#ifndef UNITY_SCOPES_INTERNAL_SMARTSCOPES_HTTPCLIENTNETCPP_H
170+#define UNITY_SCOPES_INTERNAL_SMARTSCOPES_HTTPCLIENTNETCPP_H
171+
172+#include <unity/scopes/internal/smartscopes/HttpClientInterface.h>
173+
174+#include <memory>
175+#include <thread>
176+
177+namespace core
178+{
179+namespace net
180+{
181+namespace http
182+{
183+class Client;
184+}
185+}
186+}
187+
188+namespace unity
189+{
190+
191+namespace scopes
192+{
193+
194+namespace internal
195+{
196+
197+namespace smartscopes
198+{
199+
200+class HttpClientNetCpp : public HttpClientInterface
201+{
202+public:
203+ explicit HttpClientNetCpp(unsigned int no_reply_timeout);
204+ ~HttpClientNetCpp();
205+
206+ HttpResponseHandle::SPtr get(std::string const& request_url,
207+ std::function<void(std::string const&)> const& line_data = [](std::string const&) {},
208+ HttpHeaders const& headers = HttpHeaders()) override;
209+
210+ std::string to_percent_encoding(std::string const& string) override;
211+
212+private:
213+ void cancel_get(unsigned int session_id) override;
214+
215+ unsigned int no_reply_timeout;
216+ std::shared_ptr<core::net::http::Client> client;
217+ std::thread worker;
218+};
219+
220+} // namespace smartscopes
221+
222+} // namespace internal
223+
224+} // namespace scopes
225+
226+} // namespace unity
227+
228+#endif // UNITY_SCOPES_INTERNAL_SMARTSCOPES_HTTPCLIENTNETCPP_H
229
230=== removed file 'include/unity/scopes/internal/smartscopes/HttpClientQt.h'
231--- include/unity/scopes/internal/smartscopes/HttpClientQt.h 2014-11-03 05:31:30 +0000
232+++ include/unity/scopes/internal/smartscopes/HttpClientQt.h 1970-01-01 00:00:00 +0000
233@@ -1,91 +0,0 @@
234-/*
235- * Copyright (C) 2013 Canonical Ltd
236- *
237- * This program is free software: you can redistribute it and/or modify
238- * it under the terms of the GNU Lesser General Public License version 3 as
239- * published by the Free Software Foundation.
240- *
241- * This program is distributed in the hope that it will be useful,
242- * but WITHOUT ANY WARRANTY; without even the implied warranty of
243- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
244- * GNU Lesser General Public License for more details.
245- *
246- * You should have received a copy of the GNU Lesser General Public License
247- * along with this program. If not, see <http://www.gnu.org/licenses/>.
248- *
249- * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
250- */
251-
252-#pragma once
253-
254-#include <unity/scopes/internal/smartscopes/HttpClientInterface.h>
255-#include <map>
256-
257-class QCoreApplication;
258-
259-namespace unity
260-{
261-
262-namespace scopes
263-{
264-
265-namespace internal
266-{
267-
268-namespace smartscopes
269-{
270-
271-class HttpClientQtThread;
272-
273-class HttpClientQt : public HttpClientInterface
274-{
275-public:
276- explicit HttpClientQt(unsigned int no_reply_timeout);
277- ~HttpClientQt();
278-
279- HttpResponseHandle::SPtr get(std::string const& request_url, std::function<void(std::string const&)> const& lineData = [](std::string const&) {},
280- HttpHeaders const& headers = HttpHeaders()) override;
281-
282- std::string to_percent_encoding(std::string const& string) override;
283-
284-private:
285- void cancel_get(unsigned int session_id) override;
286-
287-private:
288- class HttpSession
289- {
290- public:
291- HttpSession(std::string const& request_url, unsigned int timeout, std::function<void(std::string const&)> const& lineData, HttpHeaders const& headers =
292- HttpHeaders());
293- ~HttpSession();
294-
295- std::future<void> get_future();
296-
297- void cancel_session();
298- void wait_for_session();
299-
300- private:
301- std::promise<void> promise_;
302- std::thread get_thread_;
303- std::unique_ptr<HttpClientQtThread> qt_thread_;
304- std::mutex qt_thread_mutex_;
305- std::promise<void> qt_thread_ready_;
306- };
307-
308-private:
309- unsigned int session_index_;
310- std::map<unsigned int, std::shared_ptr<HttpSession>> sessions_;
311- std::mutex sessions_mutex_;
312-
313- unsigned int const no_reply_timeout_;
314-
315- std::unique_ptr<QCoreApplication> app_;
316-};
317-
318-} // namespace smartscopes
319-
320-} // namespace internal
321-
322-} // namespace scopes
323-
324-} // namespace unity
325
326=== removed file 'include/unity/scopes/internal/smartscopes/HttpClientQtThread.h'
327--- include/unity/scopes/internal/smartscopes/HttpClientQtThread.h 2014-11-03 05:31:30 +0000
328+++ include/unity/scopes/internal/smartscopes/HttpClientQtThread.h 1970-01-01 00:00:00 +0000
329@@ -1,100 +0,0 @@
330-/*
331- * Copyright (C) 2013 Canonical Ltd
332- *
333- * This program is free software: you can redistribute it and/or modify
334- * it under the terms of the GNU Lesser General Public License version 3 as
335- * published by the Free Software Foundation.
336- *
337- * This program is distributed in the hope that it will be useful,
338- * but WITHOUT ANY WARRANTY; without even the implied warranty of
339- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
340- * GNU Lesser General Public License for more details.
341- *
342- * You should have received a copy of the GNU Lesser General Public License
343- * along with this program. If not, see <http://www.gnu.org/licenses/>.
344- *
345- * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
346- */
347-
348-#pragma once
349-
350-// This hack allows unity-scopes-api to be built with
351-// clang-3.4+ and versions of Qt before v5.1.1.
352-#if QT_VERSION < 0x050101
353- #define register
354-
355- #include <QThread>
356-
357- #define qHash(x,y) qHash(const QUrl &url, unsigned int seed)
358- #include <QUrl>
359- #undef qHash
360-
361- #undef register
362-#else
363- #include <QThread>
364- #include <QUrl>
365-#endif
366-
367-#include <unity/scopes/internal/smartscopes/HttpClientInterface.h>
368-#include <unity/util/NonCopyable.h>
369-
370-#include <mutex>
371-
372-class QNetworkReply;
373-class QNetworkAccessManager;
374-
375-namespace unity
376-{
377-
378-namespace scopes
379-{
380-
381-namespace internal
382-{
383-
384-namespace smartscopes
385-{
386-
387-class Q_DECL_EXPORT HttpClientQtThread : public QThread
388-{
389- Q_OBJECT
390-
391-public:
392- NONCOPYABLE(HttpClientQtThread);
393-
394- HttpClientQtThread(const QUrl& url, unsigned int timeout, std::function<void(std::string const&)> const& lineData, const HttpHeaders& headers =
395- HttpHeaders());
396- ~HttpClientQtThread();
397-
398- bool get_reply(std::string& reply);
399-
400-private:
401- void run();
402-
403-public Q_SLOTS:
404- void cancel();
405- void timeout();
406- void got_reply(QNetworkReply* reply);
407- void dataReady();
408-
409-Q_SIGNALS:
410- void abort();
411-
412-private:
413- QUrl url_;
414- const std::function<void(std::string const&)> lineDataCallback_;
415- HttpHeaders headers_;
416- unsigned int timeout_;
417- std::mutex reply_mutex_;
418-
419- bool success_;
420- std::string reply_;
421-};
422-
423-} // namespace smartscopes
424-
425-} // namespace internal
426-
427-} // namespace scopes
428-
429-} // namespace unity
430
431=== modified file 'src/scopes/internal/JsonCppNode.cpp'
432--- src/scopes/internal/JsonCppNode.cpp 2015-01-13 09:12:06 +0000
433+++ src/scopes/internal/JsonCppNode.cpp 2015-01-20 09:11:18 +0000
434@@ -117,7 +117,7 @@
435 return Variant(value.asString());
436 case Json::ValueType::intValue:
437 case Json::ValueType::uintValue:
438- return Variant(value.asInt()); // this can throw std::runtime_error from jsoncpp if uint to int conversion is not possible
439+ return Variant(value.asInt()); // this can throw std::runtime_error from jsoncpp if unsigned int to int conversion is not possible
440 case Json::ValueType::realValue:
441 return Variant(value.asDouble());
442 case Json::ValueType::booleanValue:
443@@ -220,11 +220,11 @@
444 return root_.asInt();
445 }
446
447-uint JsonCppNode::as_uint() const
448+unsigned int JsonCppNode::as_uint() const
449 {
450 if (!root_.isConvertibleTo(Json::uintValue))
451 {
452- throw unity::LogicException("Node does not contain a uint value");
453+ throw unity::LogicException("Node does not contain a unsigned int value");
454 }
455
456 return root_.asUInt();
457@@ -281,7 +281,7 @@
458 return std::make_shared<JsonCppNode>(value_node);
459 }
460
461-JsonNodeInterface::SPtr JsonCppNode::get_node(uint node_index) const
462+JsonNodeInterface::SPtr JsonCppNode::get_node(unsigned int node_index) const
463 {
464 if (root_.type() != Json::arrayValue)
465 {
466
467=== modified file 'src/scopes/internal/RegistryObject.cpp'
468--- src/scopes/internal/RegistryObject.cpp 2015-01-05 01:48:35 +0000
469+++ src/scopes/internal/RegistryObject.cpp 2015-01-20 09:11:18 +0000
470@@ -766,7 +766,7 @@
471 util::ResourcePtr<wordexp_t*, decltype(&wordfree)> free_guard(&exp, wordfree);
472
473 command_args.push_back(exp.we_wordv[0]);
474- for (uint i = 1; i < exp.we_wordc; ++i)
475+ for (unsigned int i = 1; i < exp.we_wordc; ++i)
476 {
477 std::string arg = exp.we_wordv[i];
478 // Replace "%R" placeholders with the runtime config
479
480=== modified file 'src/scopes/internal/smartscopes/CMakeLists.txt'
481--- src/scopes/internal/smartscopes/CMakeLists.txt 2014-08-18 08:50:39 +0000
482+++ src/scopes/internal/smartscopes/CMakeLists.txt 2015-01-20 09:11:18 +0000
483@@ -1,5 +1,7 @@
484 set(SRC
485+ ${CMAKE_CURRENT_SOURCE_DIR}/HttpClientNetCpp.cpp
486 ${CMAKE_CURRENT_SOURCE_DIR}/SmartScope.cpp
487+ ${CMAKE_CURRENT_SOURCE_DIR}/SmartScopesClient.cpp
488 ${CMAKE_CURRENT_SOURCE_DIR}/SSConfig.cpp
489 ${CMAKE_CURRENT_SOURCE_DIR}/SSQueryCtrlObject.cpp
490 ${CMAKE_CURRENT_SOURCE_DIR}/SSQueryObject.cpp
491@@ -7,34 +9,3 @@
492 ${CMAKE_CURRENT_SOURCE_DIR}/SSScopeObject.cpp
493 )
494 set(UNITY_SCOPES_LIB_SRC ${UNITY_SCOPES_LIB_SRC} ${SRC} PARENT_SCOPE)
495-
496-# -- libsmartscopes --
497-
498-set(CMAKE_AUTOMOC ON)
499-set(CMAKE_INCLUDE_CURRENT_DIR ON)
500-
501-find_package(Qt5Core REQUIRED)
502-include_directories(${Qt5Core_INCLUDE_DIRS})
503-
504-add_library(
505- smartscopes STATIC
506-
507- HttpClientQt.cpp
508-
509- ${CMAKE_SOURCE_DIR}/include/unity/scopes/internal/smartscopes/HttpClientQtThread.h
510- HttpClientQtThread.cpp
511-
512- SmartScopesClient.cpp
513-)
514-
515-qt5_use_modules(
516- smartscopes
517-
518- Core
519- Network
520-)
521-
522-target_link_libraries(
523- smartscopes
524- ${UNITY_API_LDFLAGS}
525-)
526
527=== added file 'src/scopes/internal/smartscopes/HttpClientNetCpp.cpp'
528--- src/scopes/internal/smartscopes/HttpClientNetCpp.cpp 1970-01-01 00:00:00 +0000
529+++ src/scopes/internal/smartscopes/HttpClientNetCpp.cpp 2015-01-20 09:11:18 +0000
530@@ -0,0 +1,189 @@
531+/*
532+ * Copyright (C) 2013 Canonical Ltd
533+ *
534+ * This program is free software: you can redistribute it and/or modify
535+ * it under the terms of the GNU Lesser General Public License version 3 as
536+ * published by the Free Software Foundation.
537+ *
538+ * This program is distributed in the hope that it will be useful,
539+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
540+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
541+ * GNU Lesser General Public License for more details.
542+ *
543+ * You should have received a copy of the GNU Lesser General Public License
544+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
545+ *
546+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
547+ */
548+
549+#include <unity/scopes/internal/smartscopes/HttpClientNetCpp.h>
550+
551+#include <unity/UnityExceptions.h>
552+
553+#include <core/net/http/client.h>
554+#include <core/net/http/request.h>
555+#include <core/net/http/response.h>
556+#include <core/net/http/status.h>
557+
558+#include <iostream>
559+#include <unordered_map>
560+
561+namespace net = core::net;
562+namespace http = core::net::http;
563+
564+using namespace unity::scopes::internal::smartscopes;
565+
566+namespace
567+{
568+struct Cancelable
569+{
570+ Cancelable() = default;
571+ Cancelable(const Cancelable&) = delete;
572+ Cancelable& operator=(const Cancelable&) = delete;
573+
574+ void cancel()
575+ {
576+ cancelled.store(true);
577+ }
578+
579+ bool is_cancelled() const
580+ {
581+ return cancelled.load();
582+ }
583+
584+ std::atomic<bool> cancelled{false};
585+};
586+
587+struct CancellationRegistry
588+{
589+ static CancellationRegistry& instance()
590+ {
591+ static CancellationRegistry cr;
592+ return cr;
593+ }
594+
595+ std::pair<unsigned int, std::shared_ptr<Cancelable>> add()
596+ {
597+ auto cancelable = std::make_shared<Cancelable>();
598+ auto id = add(cancelable);
599+
600+ return std::make_pair(id, cancelable);
601+ }
602+
603+ unsigned int add(const std::shared_ptr<Cancelable>& cancelable)
604+ {
605+ std::lock_guard<std::mutex> lg(guard);
606+
607+ unsigned int result{++request_id};
608+
609+ store.insert(std::make_pair(result, cancelable));
610+
611+ return result;
612+ }
613+
614+ void cancel_and_remove_for_id(unsigned int id)
615+ {
616+ std::lock_guard<std::mutex> lg(guard);
617+
618+ auto it = store.find(id);
619+
620+ if (it != store.end())
621+ {
622+ it->second->cancel();
623+ store.erase(it);
624+ }
625+ }
626+
627+ unsigned int request_id{0};
628+ std::mutex guard;
629+ std::unordered_map<unsigned int, std::shared_ptr<Cancelable>> store;
630+};
631+}
632+
633+HttpClientNetCpp::HttpClientNetCpp(unsigned int no_reply_timeout)
634+ : no_reply_timeout{no_reply_timeout},
635+ client{http::make_client()},
636+ worker([this]() { client->run(); })
637+{
638+}
639+
640+HttpClientNetCpp::~HttpClientNetCpp()
641+{
642+ client->stop();
643+
644+ if (worker.joinable())
645+ {
646+ worker.join();
647+ }
648+}
649+
650+HttpResponseHandle::SPtr HttpClientNetCpp::get(std::string const& request_url,
651+ std::function<void(std::string const&)> const& line_data,
652+ HttpHeaders const& headers)
653+{
654+ auto http_config = http::Request::Configuration::from_uri_as_string(request_url);
655+ http::Header http_header;
656+ for (auto const& hdr: headers)
657+ {
658+ http_header.add(hdr.first, hdr.second);
659+ }
660+ http_config.header = http_header;
661+
662+ auto request = client->get(http_config);
663+ request->set_timeout(std::chrono::milliseconds{no_reply_timeout});
664+
665+ auto promise = std::make_shared<std::promise<void>>();
666+ std::shared_future<void> future(promise->get_future());
667+
668+ auto id_and_cancelable = CancellationRegistry::instance().add();
669+
670+ request->async_execute(
671+ http::Request::Handler()
672+ .on_progress([id_and_cancelable](const http::Request::Progress&)
673+ {
674+ return id_and_cancelable.second->is_cancelled() ?
675+ http::Request::Progress::Next::abort_operation :
676+ http::Request::Progress::Next::continue_operation;
677+ })
678+ .on_response([line_data, promise](const http::Response& response)
679+ {
680+ if (response.status != http::Status::ok)
681+ {
682+ std::ostringstream msg;
683+ msg << "HTTP request failed with: " << response.status << std::endl << response.body;
684+ unity::ResourceException e(msg.str());
685+
686+ promise->set_exception(std::make_exception_ptr(e));
687+ }
688+ else
689+ {
690+ std::istringstream in(response.body);
691+ std::string line;
692+ while (std::getline(in, line))
693+ {
694+ line_data(line);
695+ }
696+ promise->set_value();
697+ }
698+ })
699+ .on_error([promise](const net::Error& e)
700+ {
701+ unity::ResourceException re(e.what());
702+ promise->set_exception(std::make_exception_ptr(re));
703+ }));
704+
705+ return std::make_shared<HttpResponseHandle>(
706+ shared_from_this(),
707+ id_and_cancelable.first,
708+ future);
709+}
710+
711+void HttpClientNetCpp::cancel_get(unsigned int id)
712+{
713+ CancellationRegistry::instance().cancel_and_remove_for_id(id);
714+}
715+
716+std::string HttpClientNetCpp::to_percent_encoding(std::string const& string)
717+{
718+ return client->url_escape(string);
719+}
720
721=== removed file 'src/scopes/internal/smartscopes/HttpClientQt.cpp'
722--- src/scopes/internal/smartscopes/HttpClientQt.cpp 2014-12-02 02:00:57 +0000
723+++ src/scopes/internal/smartscopes/HttpClientQt.cpp 1970-01-01 00:00:00 +0000
724@@ -1,151 +0,0 @@
725-/*
726- * Copyright (C) 2013 Canonical Ltd
727- *
728- * This program is free software: you can redistribute it and/or modify
729- * it under the terms of the GNU Lesser General Public License version 3 as
730- * published by the Free Software Foundation.
731- *
732- * This program is distributed in the hope that it will be useful,
733- * but WITHOUT ANY WARRANTY; without even the implied warranty of
734- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
735- * GNU Lesser General Public License for more details.
736- *
737- * You should have received a copy of the GNU Lesser General Public License
738- * along with this program. If not, see <http://www.gnu.org/licenses/>.
739- *
740- * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
741- */
742-
743-#pragma GCC diagnostic push
744-#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
745-#pragma GCC diagnostic ignored "-Wswitch-default"
746-
747-#include <unity/scopes/internal/smartscopes/HttpClientQt.h>
748-#include <unity/scopes/internal/smartscopes/HttpClientQtThread.h>
749-#include <unity/UnityExceptions.h>
750-
751-#include <QCoreApplication>
752-#include <QEventLoop>
753-#include <QUrl>
754-#include <QNetworkRequest>
755-#include <QNetworkReply>
756-
757-#pragma GCC diagnostic pop
758-
759-using namespace unity::scopes::internal::smartscopes;
760-
761-//-- HttpClientQt
762-
763-HttpClientQt::HttpClientQt(uint no_reply_timeout)
764- : session_index_(0)
765- , no_reply_timeout_(no_reply_timeout)
766- , app_(nullptr)
767-{
768- if (!QCoreApplication::instance())
769- {
770- int argc = 0;
771- app_ = std::unique_ptr<QCoreApplication>(new QCoreApplication(argc, nullptr));
772- }
773-}
774-
775-HttpClientQt::~HttpClientQt()
776-{
777-}
778-
779-HttpResponseHandle::SPtr HttpClientQt::get(std::string const& request_url, std::function<void(std::string const&)> const& lineData,
780- HttpHeaders const& headers)
781-{
782- std::lock_guard<std::mutex> lock(sessions_mutex_);
783-
784- // start new session
785- auto session = std::make_shared<HttpSession>(request_url, no_reply_timeout_, lineData, headers);
786- sessions_[session_index_] = session;
787-
788- return std::make_shared<HttpResponseHandle>(shared_from_this(), session_index_++, session->get_future());
789-}
790-
791-void HttpClientQt::cancel_get(uint session_id)
792-{
793- std::lock_guard<std::mutex> lock(sessions_mutex_);
794-
795- // if session_id in map, cancel it
796- auto it = sessions_.find(session_id);
797- if (it != sessions_.end())
798- {
799- it->second->cancel_session();
800- sessions_.erase(it);
801- }
802-}
803-
804-std::string HttpClientQt::to_percent_encoding(std::string const& string)
805-{
806- return QUrl::toPercentEncoding(string.c_str()).constData();
807-}
808-
809-//-- HttpClientQt::HttpSession
810-
811-HttpClientQt::HttpSession::HttpSession(std::string const& request_url, uint timeout, std::function<void(std::string const&)> const& lineData,
812- HttpHeaders const& headers)
813- : qt_thread_(nullptr)
814-{
815- get_thread_ =
816- std::thread([this, request_url, headers, timeout, lineData]()
817- {
818- QUrl url(request_url.c_str());
819-
820- {
821- std::lock_guard<std::mutex> lock(qt_thread_mutex_);
822- qt_thread_ = std::unique_ptr<HttpClientQtThread>(new HttpClientQtThread(url, timeout, lineData, headers));
823- }
824-
825- QEventLoop loop;
826- QObject::connect(qt_thread_.get(), &HttpClientQtThread::finished, &loop, &QEventLoop::quit);
827-
828- qt_thread_->start();
829- qt_thread_ready_.set_value();
830- loop.exec();
831-
832- std::string reply;
833- bool success = qt_thread_->get_reply(reply);
834-
835- if (!success)
836- {
837- unity::ResourceException e(reply);
838- promise_.set_exception(e.self());
839- }
840- else
841- {
842- promise_.set_value();
843- }
844- });
845-
846- qt_thread_ready_.get_future().wait();
847-}
848-
849-HttpClientQt::HttpSession::~HttpSession()
850-{
851- cancel_session();
852-}
853-
854-std::future<void> HttpClientQt::HttpSession::get_future()
855-{
856- return promise_.get_future();
857-}
858-
859-void HttpClientQt::HttpSession::cancel_session()
860-{
861- {
862- std::lock_guard<std::mutex> lock(qt_thread_mutex_);
863- qt_thread_->cancel();
864- }
865-
866- wait_for_session();
867-}
868-
869-void HttpClientQt::HttpSession::wait_for_session()
870-{
871- if (get_thread_.joinable())
872- {
873- get_thread_.join();
874- }
875-}
876
877=== removed file 'src/scopes/internal/smartscopes/HttpClientQtThread.cpp'
878--- src/scopes/internal/smartscopes/HttpClientQtThread.cpp 2014-12-02 02:00:57 +0000
879+++ src/scopes/internal/smartscopes/HttpClientQtThread.cpp 1970-01-01 00:00:00 +0000
880@@ -1,186 +0,0 @@
881-/*
882- * Copyright (C) 2013 Canonical Ltd
883- *
884- * This program is free software: you can redistribute it and/or modify
885- * it under the terms of the GNU Lesser General Public License version 3 as
886- * published by the Free Software Foundation.
887- *
888- * This program is distributed in the hope that it will be useful,
889- * but WITHOUT ANY WARRANTY; without even the implied warranty of
890- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
891- * GNU Lesser General Public License for more details.
892- *
893- * You should have received a copy of the GNU Lesser General Public License
894- * along with this program. If not, see <http://www.gnu.org/licenses/>.
895- *
896- * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
897- * Pawel Stolowski <pawel.stolowski@canonical.com>
898- */
899-
900-#pragma GCC diagnostic push
901-#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
902-#pragma GCC diagnostic ignored "-Wswitch-default"
903-
904-#include "unity/scopes/internal/smartscopes/HttpClientQtThread.h"
905-
906-#include <QNetworkRequest>
907-#include <QNetworkAccessManager>
908-#include <QNetworkReply>
909-#include <QTimer>
910-
911-#pragma GCC diagnostic pop
912-
913-#include <cassert>
914-
915-namespace unity
916-{
917-
918-namespace scopes
919-{
920-
921-namespace internal
922-{
923-
924-namespace smartscopes
925-{
926-
927-HttpClientQtThread::HttpClientQtThread(const QUrl& url, uint timeout, std::function<void(std::string const&)> const& lineData, HttpHeaders const& headers)
928- : QThread()
929- , url_(url)
930- , lineDataCallback_(lineData)
931- , headers_(headers)
932- , timeout_(timeout)
933- , success_(false)
934-{
935-}
936-
937-HttpClientQtThread::~HttpClientQtThread()
938-{
939- cancel();
940-
941- wait();
942-}
943-
944-bool HttpClientQtThread::get_reply(std::string& reply)
945-{
946- std::lock_guard<std::mutex> lock(reply_mutex_);
947-
948- reply = reply_;
949- return success_;
950-}
951-
952-void HttpClientQtThread::run()
953-{
954- QNetworkAccessManager* manager = new QNetworkAccessManager();
955-
956- QNetworkRequest request(url_);
957- for (auto const& hdr: headers_)
958- {
959- request.setRawHeader(QString::fromStdString(hdr.first).toUtf8(), QString::fromStdString(hdr.second).toUtf8());
960- }
961-
962- QNetworkReply* reply = manager->get(request);
963- reply->setReadBufferSize(0); // unlimited buffer
964-
965- connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(got_reply(QNetworkReply *)));
966- connect(reply, SIGNAL(readyRead()), this, SLOT(dataReady()));
967- connect(this, &HttpClientQtThread::abort, reply, &QNetworkReply::abort);
968-
969- QTimer timeout;
970- timeout.singleShot(timeout_, this, SLOT(timeout()));
971- QThread::exec(); // enter event loop
972-
973- reply->deleteLater();
974- manager->deleteLater();
975-}
976-
977-void HttpClientQtThread::cancel()
978-{
979- std::lock_guard<std::mutex> lock(reply_mutex_);
980-
981- success_ = false;
982- reply_ = "Request cancelled: " + url_.url().toStdString();
983-
984- emit HttpClientQtThread::abort();
985- quit();
986-}
987-
988-void HttpClientQtThread::timeout()
989-{
990- std::lock_guard<std::mutex> lock(reply_mutex_);
991-
992- success_ = false;
993- reply_ = "Request timed out: " + url_.url().toStdString();
994-
995- emit HttpClientQtThread::abort();
996- quit();
997-}
998-
999-void HttpClientQtThread::dataReady()
1000-{
1001- QNetworkReply* net_reply = qobject_cast<QNetworkReply*>(sender());
1002- if (net_reply)
1003- {
1004- if (net_reply->canReadLine())
1005- {
1006- QByteArray data = net_reply->readLine();
1007- const std::string replyLine(data.constData(), data.size());
1008- lineDataCallback_(replyLine);
1009- }
1010- }
1011-}
1012-
1013-void HttpClientQtThread::got_reply(QNetworkReply* reply)
1014-{
1015- std::lock_guard<std::mutex> lock(reply_mutex_);
1016-
1017- if (!reply_.empty())
1018- {
1019- return;
1020- }
1021-
1022- if (!reply)
1023- {
1024- // no reply
1025- success_ = false;
1026- reply_ = "No reply from " + url_.url().toStdString();
1027- }
1028- else if (!reply->isFinished())
1029- {
1030- // incomplete reply
1031- success_ = false;
1032- reply_ = "Incomplete reply from " + url_.url().toStdString();
1033- }
1034- else if (reply->error() != QNetworkReply::NoError)
1035- {
1036- // communication error
1037- success_ = false;
1038- reply_ = reply->errorString().toStdString();
1039- }
1040- else
1041- {
1042- success_ = true;
1043- // read any remaining lines
1044- while (reply->canReadLine())
1045- {
1046- const QByteArray byte_array = reply->readLine();
1047- lineDataCallback_(std::string(byte_array.constData(), byte_array.size()));
1048- }
1049- // there may be data left which is not "\n" terminated
1050- if (reply->bytesAvailable())
1051- {
1052- const QByteArray byte_array = reply->readAll();
1053- lineDataCallback_(std::string(byte_array.constData(), byte_array.size()));
1054- }
1055- }
1056-
1057- quit();
1058-}
1059-
1060-} // namespace smartscopes
1061-
1062-} // namespace internal
1063-
1064-} // namespace scopes
1065-
1066-} // namespace unity
1067
1068=== modified file 'src/scopes/internal/smartscopes/SSRegistryObject.cpp'
1069--- src/scopes/internal/smartscopes/SSRegistryObject.cpp 2015-01-09 03:16:51 +0000
1070+++ src/scopes/internal/smartscopes/SSRegistryObject.cpp 2015-01-20 09:11:18 +0000
1071@@ -25,7 +25,7 @@
1072 #include <unity/scopes/internal/RuntimeImpl.h>
1073 #include <unity/scopes/internal/ScopeImpl.h>
1074 #include <unity/scopes/internal/ScopeMetadataImpl.h>
1075-#include <unity/scopes/internal/smartscopes/HttpClientQt.h>
1076+#include <unity/scopes/internal/smartscopes/HttpClientNetCpp.h>
1077 #include <unity/scopes/internal/Utils.h>
1078 #include <unity/scopes/ScopeExceptions.h>
1079 #include <unity/UnityExceptions.h>
1080@@ -48,7 +48,7 @@
1081 std::string const& sss_url,
1082 bool caching_enabled)
1083 : ssclient_(std::make_shared<SmartScopesClient>(
1084- std::make_shared<HttpClientQt>(ss_config.http_reply_timeout() * 1000), // need millisecs
1085+ std::make_shared<HttpClientNetCpp>(ss_config.http_reply_timeout() * 1000), // need millisecs
1086 std::make_shared<JsonCppNode>(),
1087 middleware->runtime(),
1088 sss_url))
1089
1090=== modified file 'src/scopes/internal/smartscopes/SmartScopesClient.cpp'
1091--- src/scopes/internal/smartscopes/SmartScopesClient.cpp 2015-01-09 03:16:51 +0000
1092+++ src/scopes/internal/smartscopes/SmartScopesClient.cpp 2015-01-20 09:11:18 +0000
1093@@ -63,7 +63,7 @@
1094
1095 //-- SearchHandle
1096
1097-SearchHandle::SearchHandle(uint search_id, SmartScopesClient::SPtr ssc)
1098+SearchHandle::SearchHandle(unsigned int search_id, SmartScopesClient::SPtr ssc)
1099 : search_id_(search_id)
1100 , ssc_(ssc)
1101 {
1102@@ -86,7 +86,7 @@
1103
1104 //-- PreviewHandle
1105
1106-PreviewHandle::PreviewHandle(uint preview_id, SmartScopesClient::SPtr ssc)
1107+PreviewHandle::PreviewHandle(unsigned int preview_id, SmartScopesClient::SPtr ssc)
1108 : preview_id_(preview_id)
1109 , ssc_(ssc)
1110 {
1111@@ -200,9 +200,13 @@
1112 BOOST_LOG_SEV(logger_, Logger::Error) << "SmartScopesClient.get_remote_scopes(): failed to read " << partner_file_ << ": " << e.what();
1113 }
1114
1115- HttpResponseHandle::SPtr response = http_client_->get(remote_scopes_uri.str(), [&response_str](std::string const& replyLine) {
1116- response_str += replyLine; // accumulate all reply lines
1117+ std::mutex reponse_mutex;
1118+ HttpResponseHandle::SPtr response = http_client_->get(remote_scopes_uri.str(), [&response_str, &reponse_mutex](std::string const& replyLine)
1119+ {
1120+ std::lock_guard<std::mutex> lock(reponse_mutex);
1121+ response_str += replyLine; // accumulate all reply lines
1122 }, headers);
1123+
1124 response->get();
1125
1126 BOOST_LOG_SEV(logger_, Logger::Info)
1127@@ -409,7 +413,7 @@
1128 std::string const& locale,
1129 LocationInfo const& location,
1130 std::string const& user_agent_hdr,
1131- uint limit)
1132+ unsigned int limit)
1133 {
1134 std::ostringstream search_uri;
1135 search_uri.imbue(std::locale::classic()); // so that doubles use one standard formatting wrt decimal point
1136@@ -458,7 +462,7 @@
1137 }
1138
1139 std::lock_guard<std::mutex> lock(query_results_mutex_);
1140- uint search_id = ++query_counter_;
1141+ unsigned int search_id = ++query_counter_;
1142
1143 BOOST_LOG_SEV(logger_, Logger::Info) << "SmartScopesClient.search(): GET " << search_uri.str();
1144
1145@@ -469,15 +473,18 @@
1146 headers.push_back(std::make_pair("User-Agent", user_agent_hdr));
1147 }
1148
1149- query_results_[search_id] = http_client_->get(search_uri.str(), [this, handler](std::string const& lineData) {
1150- try
1151- {
1152- parse_line(lineData, handler);
1153- }
1154- catch (std::exception const &e)
1155- {
1156- BOOST_LOG(logger_) << "SmartScopesClient.search(): Failed to parse: " << e.what();
1157- }
1158+ auto reponse_mutex = std::make_shared<std::mutex>();
1159+ query_results_[search_id] = http_client_->get(search_uri.str(), [this, handler, reponse_mutex](std::string const& line_data)
1160+ {
1161+ std::lock_guard<std::mutex> lock(*reponse_mutex);
1162+ try
1163+ {
1164+ parse_line(line_data, handler);
1165+ }
1166+ catch (std::exception const &e)
1167+ {
1168+ BOOST_LOG_SEV(logger_, Logger::Error) << "SmartScopesClient.search(): Failed to parse: " << e.what();
1169+ }
1170 }, headers);
1171
1172 return SearchHandle::UPtr(new SearchHandle(search_id, shared_from_this()));
1173@@ -488,7 +495,7 @@
1174 std::string const& result,
1175 std::string const& session_id,
1176 std::string const& platform,
1177- const uint widgets_api_version,
1178+ const unsigned int widgets_api_version,
1179 VariantMap const& settings,
1180 std::string const& locale,
1181 std::string const& country,
1182@@ -530,18 +537,22 @@
1183 }
1184
1185 std::lock_guard<std::mutex> lock(query_results_mutex_);
1186- uint preview_id = ++query_counter_;
1187+ unsigned int preview_id = ++query_counter_;
1188
1189 BOOST_LOG_SEV(logger_, Logger::Info) << "SmartScopesClient.preview(): GET " << preview_uri.str();
1190- query_results_[preview_id] = http_client_->get(preview_uri.str(), [this, handler](std::string const& lineData) {
1191- try
1192- {
1193- parse_line(lineData, handler);
1194- }
1195- catch (std::exception const &e)
1196- {
1197- BOOST_LOG(logger_) << "SmartScopesClient.preview(): Failed to parse: " << e.what();
1198- }
1199+
1200+ auto reponse_mutex = std::make_shared<std::mutex>();
1201+ query_results_[preview_id] = http_client_->get(preview_uri.str(), [this, handler, reponse_mutex](std::string const& line_data)
1202+ {
1203+ std::lock_guard<std::mutex> lock(*reponse_mutex);
1204+ try
1205+ {
1206+ parse_line(line_data, handler);
1207+ }
1208+ catch (std::exception const &e)
1209+ {
1210+ BOOST_LOG_SEV(logger_, Logger::Error) << "SmartScopesClient.preview(): Failed to parse: " << e.what();
1211+ }
1212 }, headers);
1213
1214 return PreviewHandle::UPtr(new PreviewHandle(preview_id, shared_from_this()));
1215@@ -675,7 +686,7 @@
1216 }
1217 }
1218
1219-void SmartScopesClient::wait_for_search(uint search_id)
1220+void SmartScopesClient::wait_for_search(unsigned int search_id)
1221 {
1222 try
1223 {
1224@@ -781,7 +792,7 @@
1225 return FilterStateImpl::deserialize(node->to_variant().get_dict());
1226 }
1227
1228-void SmartScopesClient::wait_for_preview(uint preview_id)
1229+void SmartScopesClient::wait_for_preview(unsigned int preview_id)
1230 {
1231 try
1232 {
1233@@ -817,7 +828,7 @@
1234 {
1235 std::vector<std::string> jsons;
1236
1237- uint start_pos = 0;
1238+ unsigned int start_pos = 0;
1239
1240 while (start_pos < json_stream.size())
1241 {
1242@@ -835,7 +846,7 @@
1243 return jsons;
1244 }
1245
1246-void SmartScopesClient::cancel_query(uint query_id)
1247+void SmartScopesClient::cancel_query(unsigned int query_id)
1248 {
1249 std::lock_guard<std::mutex> lock(query_results_mutex_);
1250
1251
1252=== modified file 'test/gtest/scopes/internal/smartscopes/HttpClient/HttpClient_test.cpp'
1253--- test/gtest/scopes/internal/smartscopes/HttpClient/HttpClient_test.cpp 2014-09-03 11:55:23 +0000
1254+++ test/gtest/scopes/internal/smartscopes/HttpClient/HttpClient_test.cpp 2015-01-20 09:11:18 +0000
1255@@ -16,7 +16,7 @@
1256 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
1257 */
1258
1259-#include <unity/scopes/internal/smartscopes/HttpClientQt.h>
1260+#include <unity/scopes/internal/smartscopes/HttpClientNetCpp.h>
1261 #include <unity/UnityExceptions.h>
1262
1263 #include "../RaiiServer.h"
1264@@ -37,8 +37,8 @@
1265 class HttpClientTest : public Test
1266 {
1267 public:
1268- HttpClientTest(uint no_reply_timeout = 20000)
1269- : http_client_(new HttpClientQt(no_reply_timeout)),
1270+ HttpClientTest(unsigned int no_reply_timeout = 20000)
1271+ : http_client_(new HttpClientNetCpp(no_reply_timeout)),
1272 server_(FAKE_SERVER_PATH)
1273 {
1274 test_url_ = c_test_url + ":" + std::to_string(server_.port_);
1275
1276=== modified file 'test/gtest/scopes/internal/smartscopes/SmartScopesClient/FakeSss.py'
1277--- test/gtest/scopes/internal/smartscopes/SmartScopesClient/FakeSss.py 2014-12-09 10:44:42 +0000
1278+++ test/gtest/scopes/internal/smartscopes/SmartScopesClient/FakeSss.py 2015-01-20 09:11:18 +0000
1279@@ -32,7 +32,10 @@
1280
1281 if outfile != '':
1282 f = open(outfile, 'a')
1283- f.writelines(["%s : %s\n" % (environ['PATH_INFO'], environ['HTTP_USER_AGENT'])])
1284+ if environ.has_key('HTTP_USER_AGENT'):
1285+ f.writelines(["%s : %s\n" % (environ['PATH_INFO'], environ['HTTP_USER_AGENT'])])
1286+ else:
1287+ f.writelines(["%s : \n" % (environ['PATH_INFO'])])
1288
1289 if environ['PATH_INFO'] == '/remote-scopes' and (environ['QUERY_STRING'] == '' or environ['QUERY_STRING'] == 'locale=test_TEST'):
1290 return [remote_scopes_response]
1291
1292=== modified file 'test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp'
1293--- test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp 2015-01-09 03:16:51 +0000
1294+++ test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp 2015-01-20 09:11:18 +0000
1295@@ -17,7 +17,8 @@
1296 */
1297
1298 #include <unity/scopes/internal/JsonCppNode.h>
1299-#include <unity/scopes/internal/smartscopes/HttpClientQt.h>
1300+#include <unity/scopes/internal/Logger.h>
1301+#include <unity/scopes/internal/smartscopes/HttpClientNetCpp.h>
1302 #include <unity/scopes/internal/smartscopes/SmartScopesClient.h>
1303 #include <unity/scopes/OptionSelectorFilter.h>
1304
1305@@ -45,7 +46,7 @@
1306 {
1307 public:
1308 SmartScopesClientTest()
1309- : http_client_(new HttpClientQt(20000)),
1310+ : http_client_(new HttpClientNetCpp(20000)),
1311 json_node_(new JsonCppNode()),
1312 server_(FAKE_SSS_PATH, FAKE_SSS_LOG)
1313 {
1314
1315=== modified file 'valgrind-suppress'
1316--- valgrind-suppress 2014-12-10 05:32:14 +0000
1317+++ valgrind-suppress 2015-01-20 09:11:18 +0000
1318@@ -63,52 +63,6 @@
1319 obj:/lib/x86_64-linux-gnu/ld-2.18.so
1320 }
1321
1322-# False positives for memory leaks in Qt
1323-
1324-{
1325- QNetworkConfigurationManager
1326- Memcheck:Leak
1327- fun:*alloc
1328- ...
1329- fun:_ZN35QNetworkConfigurationManagerPrivate20updateConfigurationsEv
1330- fun:_ZN35QNetworkConfigurationManagerPrivate10initializeEv
1331-}
1332-
1333-{
1334- QCoreApplication
1335- Memcheck:Leak
1336- fun:realloc
1337- ...
1338- fun:_ZN7QObject5eventEP6QEvent
1339- fun:_ZN16QCoreApplication6notifyEP7QObjectP6QEvent
1340-}
1341-
1342-{
1343- QNetworkAccessManager
1344- Memcheck:Leak
1345- ...
1346- fun:_ZN21QNetworkAccessManager13createRequestENS_9OperationERK15QNetworkRequestP9QIODevice
1347- fun:_ZN21QNetworkAccessManager3getERK15QNetworkRequest
1348-}
1349-
1350-{
1351- QNetworkConfigurationManager
1352- Memcheck:Leak
1353- match-leak-kinds: possible
1354- ...
1355- fun:_ZN7QThread5startENS_8PriorityE
1356- fun:_ZN35QNetworkConfigurationManagerPrivate10initializeEv
1357- fun:_Z35qNetworkConfigurationManagerPrivatev
1358-}
1359-
1360-{
1361- QFactoryLoader
1362- Memcheck:Leak
1363- fun:*alloc
1364- ...
1365- fun:_ZNK14QFactoryLoader8instanceEi
1366-}
1367-
1368 # Bogus "invalid read" reports for ::putenv and ::genenv
1369
1370 {

Subscribers

People subscribed via source and target branches

to all changes: