Merge lp:~mhr3/unity-lens-shopping/secure-connection into lp:unity-lens-shopping

Proposed by Michal Hruby
Status: Merged
Approved by: Paweł Stołowski
Approved revision: 23
Merged at revision: 22
Proposed branch: lp:~mhr3/unity-lens-shopping/secure-connection
Merge into: lp:unity-lens-shopping
Diff against target: 309 lines (+141/-68)
5 files modified
configure.ac (+2/-0)
src/Makefile.am (+3/-0)
src/scope.vala (+123/-68)
vapi/Makefile.am (+5/-0)
vapi/libsoup-gnome-2.4.vapi (+8/-0)
To merge this branch: bzr merge lp:~mhr3/unity-lens-shopping/secure-connection
Reviewer Review Type Date Requested Status
Paweł Stołowski (community) Approve
Review via email: mp+126396@code.launchpad.net

Commit message

Use secure connection to the server

Description of the change

Use secure connection to the server.

To post a comment you must log in.
22. By Michal Hruby

Use strict certificate checking

23. By Michal Hruby

Merge trunk, add more error reporting

Revision history for this message
Paweł Stołowski (stolowski) wrote :

Cool, we have SSL now! Looks good and works fine!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'configure.ac'
--- configure.ac 2012-07-25 15:18:43 +0000
+++ configure.ac 2012-09-26 11:13:24 +0000
@@ -62,6 +62,7 @@
62 gio-unix-2.0 >= $GLIB_REQUIRED62 gio-unix-2.0 >= $GLIB_REQUIRED
63 dee-1.0 >= 1.0.763 dee-1.0 >= 1.0.7
64 gee-1.064 gee-1.0
65 libsoup-gnome-2.4
65 json-glib-1.066 json-glib-1.0
66 unity >= 5.93.0)67 unity >= 5.93.0)
6768
@@ -118,6 +119,7 @@
118 data/Makefile119 data/Makefile
119 src/Makefile120 src/Makefile
120 src/config.vala121 src/config.vala
122 vapi/Makefile
121 po/Makefile.in123 po/Makefile.in
122])124])
123AC_OUTPUT125AC_OUTPUT
124126
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2012-09-24 16:17:01 +0000
+++ src/Makefile.am 2012-09-26 11:13:24 +0000
@@ -28,7 +28,10 @@
28 --pkg gio-unix-2.0 \28 --pkg gio-unix-2.0 \
29 --pkg glib-2.0 \29 --pkg glib-2.0 \
30 --pkg json-glib-1.0 \30 --pkg json-glib-1.0 \
31 --pkg libsoup-2.4 \
31 --vapidir $(srcdir) \32 --vapidir $(srcdir) \
33 --vapidir $(top_srcdir)/vapi \
34 --pkg libsoup-gnome-2.4 \
32 --target-glib=2.26 \35 --target-glib=2.26 \
33 $(MAINTAINER_VALAFLAGS) \36 $(MAINTAINER_VALAFLAGS) \
34 $(NULL)37 $(NULL)
3538
=== modified file 'src/scope.vala'
--- src/scope.vala 2012-09-25 10:05:54 +0000
+++ src/scope.vala 2012-09-26 11:13:24 +0000
@@ -23,10 +23,11 @@
23{23{
24 public class ShoppingScope : Unity.Scope24 public class ShoppingScope : Unity.Scope
25 {25 {
26 private const string OFFERS_BASE_URI = "http://productsearch.ubuntu.com";26 private const string OFFERS_BASE_URI = "https://productsearch.ubuntu.com";
2727
28 private HashTable<string, string> results_details_map;28 private HashTable<string, string> results_details_map;
29 private HashTable<string, string> global_results_details_map;29 private HashTable<string, string> global_results_details_map;
30 private Soup.Session session;
30 private PreviewPlayerHandler player;31 private PreviewPlayerHandler player;
3132
32 public ShoppingScope ()33 public ShoppingScope ()
@@ -36,6 +37,12 @@
3637
37 protected override void constructed ()38 protected override void constructed ()
38 {39 {
40 session = new Soup.SessionAsync ();
41 session.ssl_use_system_ca_file = true;
42 session.ssl_strict = true;
43 session.user_agent = "Unity Shopping Lens " + Config.VERSION;
44 session.add_feature_by_type (typeof (SoupGNOME.ProxyResolverGNOME));
45
39 /* Listen for filter changes */46 /* Listen for filter changes */
40 filters_changed.connect (() => {47 filters_changed.connect (() => {
41 queue_search_changed (SearchType.DEFAULT);48 queue_search_changed (SearchType.DEFAULT);
@@ -94,6 +101,7 @@
94 process_search_reply_json (parser, Category.TREAT_YOURSELF,101 process_search_reply_json (parser, Category.TREAT_YOURSELF,
95 search.results_model);102 search.results_model);
96 }103 }
104 catch (IOError.CANCELLED canc_err) { /* ignore */ }
97 catch (Error err)105 catch (Error err)
98 {106 {
99 warning ("Error: %s", err.message);107 warning ("Error: %s", err.message);
@@ -122,6 +130,62 @@
122 }130 }
123 }131 }
124132
133 private async Preview? process_preview_request (string details_uri)
134 {
135 Json.Parser parser;
136 try
137 {
138 parser = yield get_json_reply_async (details_uri, null);
139 }
140 catch (Error err)
141 {
142 return new GenericPreview (Path.get_basename (details_uri),
143 err.message, null);
144 }
145
146 if (U1MSPreviewFactory.is_u1ms_details (parser))
147 {
148 var u1mspf = new U1MSPreviewFactory ();
149 var preview = u1mspf.create_preview (parser);
150 u1mspf.add_download_action (preview); // download will be handled by normal activation
151 if (player == null)
152 player = new PreviewPlayerHandler ();
153 player.music_preview = preview;
154 return preview;
155 }
156 else
157 {
158 var root = parser.get_root ().get_object ();
159 unowned string title = root.get_string_member ("title");
160 unowned string description = root.get_string_member ("description_html");
161
162 unowned string price = null;
163 if (root.has_member ("formatted_price"))
164 price = root.get_string_member ("formatted_price");
165 else if (root.has_member ("price"))
166 price = root.get_string_member ("price");
167
168 var img_obj = root.get_object_member ("images");
169 string image_uri = extract_image_uri (img_obj, int.MAX);
170
171 Icon? image = null;
172 if (image_uri != "")
173 {
174 image = new FileIcon (File.new_for_uri (image_uri));
175 }
176
177 var preview = new GenericPreview (title, MarkupCleaner.html_to_pango_markup (description), image);
178 var icon_dir = File.new_for_path (ICON_PATH);
179 var icon = new FileIcon (icon_dir.get_child ("service-amazon.svg"));
180 var buy_action = new PreviewAction ("buy", _("Buy"), icon);
181 if (price != null) buy_action.extra_text = price;
182 /* Leaving the activation on unity for now */
183 // buy_action.activated.connect ((uri) => { });
184 preview.add_action (buy_action);
185 return preview;
186 }
187 }
188
125 private Preview? generate_preview_for_uri (string uri)189 private Preview? generate_preview_for_uri (string uri)
126 {190 {
127 string? details_uri =191 string? details_uri =
@@ -133,52 +197,13 @@
133 "No data available", null);197 "No data available", null);
134 }198 }
135199
136 try200 var preview = new AsyncPreview ();
137 {201 process_preview_request.begin (details_uri, (obj, res) =>
138 var parser = get_json_reply (details_uri, null);202 {
139203 var real_preview = process_preview_request.end (res);
140 if (U1MSPreviewFactory.is_u1ms_details (parser))204 preview.preview_ready (real_preview);
141 {205 });
142 var u1mspf = new U1MSPreviewFactory ();206 return preview;
143 var preview = u1mspf.create_preview (parser);
144 u1mspf.add_download_action (preview); // download will be handled by normal activation
145 if (player == null)
146 player = new PreviewPlayerHandler ();
147 player.music_preview = preview;
148 return preview;
149 }
150 else
151 {
152 var root = parser.get_root ().get_object ();
153 unowned string title = root.get_string_member ("title");
154 unowned string description = root.get_string_member ("description_html");
155 unowned string price = root.get_string_member ("formatted_price");
156 if (price == null) price = root.get_string_member ("price");
157
158 var img_obj = root.get_object_member ("images");
159 string image_uri = extract_image_uri (img_obj, int.MAX);
160
161 Icon? image = null;
162 if (image_uri != "")
163 {
164 image = new FileIcon (File.new_for_uri (image_uri));
165 }
166
167 var preview = new GenericPreview (title, MarkupCleaner.html_to_pango_markup (description), image);
168 var icon_dir = File.new_for_path (ICON_PATH);
169 var icon = new FileIcon (icon_dir.get_child ("service-amazon.svg"));
170 var buy_action = new PreviewAction ("buy", _("Buy"), icon);
171 if (price != null) buy_action.extra_text = price;
172 /* Leaving the activation on unity for now */
173 // buy_action.activated.connect ((uri) => { });
174 preview.add_action (buy_action);
175 return preview;
176 }
177 }
178 catch (Error err)
179 {
180 return new GenericPreview (Path.get_basename (uri), err.message, null);
181 }
182 }207 }
183208
184 private string build_search_uri (string query, SearchType search_type)209 private string build_search_uri (string query, SearchType search_type)
@@ -199,29 +224,55 @@
199 }224 }
200225
201 private async Json.Parser get_json_reply_async (string uri,226 private async Json.Parser get_json_reply_async (string uri,
202 Cancellable cancellable)227 Cancellable? cancellable)
203 throws Error228 throws Error
204 {229 {
205 message ("Sending request: %s", uri);230 message ("Sending request: %s", uri);
206231
207 var file = File.new_for_uri (uri);232 var msg = new Soup.Message ("GET", uri);
208 var stream = yield file.read_async (Priority.DEFAULT, cancellable);233 session.queue_message (msg, (session_, msg_) =>
209 var parser = new Json.Parser ();234 {
210 yield parser.load_from_stream_async (stream);235 msg = msg_;
211236 get_json_reply_async.callback ();
212 return parser;237 });
213 }238
214239 var cancelled = false;
215 private Json.Parser get_json_reply (string uri,240 ulong cancel_id = 0;
216 Cancellable? cancellable)241 if (cancellable != null)
217 throws Error242 {
218 {243 cancel_id = cancellable.connect (() =>
219 message ("Sending sync request: %s", uri);244 {
220245 cancelled = true;
221 var file = File.new_for_uri (uri);246 session.cancel_message (msg, Soup.KnownStatusCode.CANCELLED);
222 var stream = file.read (cancellable);247 });
223 var parser = new Json.Parser ();248 }
224 parser.load_from_stream (stream);249
250 yield;
251
252 if (cancelled)
253 {
254 // we can't disconnect right away, as that would deadlock (cause
255 // cancel_message doesn't return before invoking the callback)
256 Idle.add (get_json_reply_async.callback);
257 yield;
258 cancellable.disconnect (cancel_id);
259 throw new IOError.CANCELLED ("Cancelled");
260 }
261
262 if (msg.status_code < 100)
263 {
264 throw new IOError.FAILED ("Request failed with error %u", msg.status_code);
265 }
266 else if (msg.status_code != 200)
267 {
268 warning ("Request returned status code %u", msg.status_code);
269 }
270
271 if (msg.response_body.data == null)
272 throw new IOError.FAILED ("Request didn't return any content");
273
274 var parser = new Json.Parser ();
275 parser.load_from_data ((string) msg.response_body.data);
225276
226 return parser;277 return parser;
227 }278 }
@@ -308,8 +359,12 @@
308 var image_obj = result.get_object_member ("images");359 var image_obj = result.get_object_member ("images");
309 string image_uri = extract_image_uri (image_obj, 128*128);360 string image_uri = extract_image_uri (image_obj, 128*128);
310361
311 unowned string price = result.get_string_member ("formatted_price");362 unowned string price = null;
312 if (price == null) price = result.get_string_member ("price");363 if (result.has_member ("formatted_price"))
364 price = result.get_string_member ("formatted_price");
365 else if (result.has_member ("price"))
366 price = result.get_string_member ("price");
367
313 if (image_uri != "")368 if (image_uri != "")
314 {369 {
315 // TODO: what to do if we have price but no icon?370 // TODO: what to do if we have price but no icon?
316371
=== added directory 'vapi'
=== added file 'vapi/Makefile.am'
--- vapi/Makefile.am 1970-01-01 00:00:00 +0000
+++ vapi/Makefile.am 2012-09-26 11:13:24 +0000
@@ -0,0 +1,5 @@
1NULL =
2BUILT_SOURCES =
3CLEANFILES =
4EXTRA_DIST = libsoup-gnome-2.4.vapi
5
06
=== added file 'vapi/libsoup-gnome-2.4.vapi'
--- vapi/libsoup-gnome-2.4.vapi 1970-01-01 00:00:00 +0000
+++ vapi/libsoup-gnome-2.4.vapi 2012-09-26 11:13:24 +0000
@@ -0,0 +1,8 @@
1[CCode (cprefix = "Soup", gir_namespace = "SoupGNOME", gir_version = "2.4", lower_case_cprefix = "soup_")]
2namespace SoupGNOME {
3 [CCode (cheader_filename = "libsoup/soup-gnome.h", type_id = "soup_proxy_resolver_gnome_get_type ()")]
4 public class ProxyResolverGNOME : Soup.ProxyResolverDefault, Soup.ProxyURIResolver, Soup.SessionFeature {
5 [CCode (has_construct_function = false)]
6 protected ProxyResolverGNOME ();
7 }
8}

Subscribers

People subscribed via source and target branches

to all changes: