summaryrefslogtreecommitdiff
path: root/lib/safe-browsing/ephy-gsb-service.c
diff options
context:
space:
mode:
authorGabriel Ivascu <gabrielivascu@gnome.org>2017-09-19 15:31:02 +0300
committerGabriel Ivascu <gabrielivascu@gnome.org>2017-10-03 18:29:53 +0200
commit5e804a6e7e70c2c4c39da69cdd1d2892dac08136 (patch)
tree152183ff761360e43ba4d4de5ba093d4ed7d87a3 /lib/safe-browsing/ephy-gsb-service.c
parentc3a788a9c61a97bf6caa9b4c092673079dcb6efe (diff)
downloadepiphany-5e804a6e7e70c2c4c39da69cdd1d2892dac08136.tar.gz
gsb-service: Handle back-off mode
Diffstat (limited to 'lib/safe-browsing/ephy-gsb-service.c')
-rw-r--r--lib/safe-browsing/ephy-gsb-service.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/lib/safe-browsing/ephy-gsb-service.c b/lib/safe-browsing/ephy-gsb-service.c
index a4c7b7870..268412564 100644
--- a/lib/safe-browsing/ephy-gsb-service.c
+++ b/lib/safe-browsing/ephy-gsb-service.c
@@ -44,6 +44,8 @@ struct _EphyGSBService {
guint source_id;
gint64 next_full_hashes_request_time;
+ gint64 back_off_mode_exit_time;
+ gint64 num_fails;
SoupSession *session;
};
@@ -139,6 +141,38 @@ json_object_has_non_null_array_member (JsonObject *object,
return JSON_NODE_HOLDS_ARRAY (node);
}
+/*
+ * https://developers.google.com/safe-browsing/v4/request-frequency#back-off-mode
+ */
+static inline void
+ephy_gsb_service_update_back_off_mode (EphyGSBService *self)
+{
+ gint64 duration;
+
+ g_assert (EPHY_IS_GSB_SERVICE (self));
+
+ duration = (1 << self->num_fails++) * 15 * 60 * (g_random_double () + 1);
+ self->back_off_mode_exit_time = CURRENT_TIME + MIN (duration, 24 * 60 * 60);
+
+ LOG ("Set back-off mode for %ld seconds", duration);
+}
+
+static inline void
+ephy_gsb_service_reset_back_off_mode (EphyGSBService *self)
+{
+ g_assert (EPHY_IS_GSB_SERVICE (self));
+
+ self->num_fails = self->back_off_mode_exit_time = 0;
+}
+
+static inline gboolean
+ephy_gsb_service_is_back_off_mode (EphyGSBService *self)
+{
+ g_assert (EPHY_IS_GSB_SERVICE (self));
+
+ return self->num_fails > 0 && CURRENT_TIME < self->back_off_mode_exit_time;
+}
+
static void
ephy_gsb_service_schedule_update (EphyGSBService *self,
gint64 interval)
@@ -183,12 +217,17 @@ ephy_gsb_service_update_thread (GTask *task,
soup_message_set_request (msg, "application/json", SOUP_MEMORY_TAKE, body, strlen (body));
soup_session_send_message (self->session, msg);
+ /* Handle unsuccessful responses. */
if (msg->status_code != 200) {
- LOG ("Cannot update GSB threat lists. Server responded: %u, %s",
- msg->status_code, msg->response_body->data);
+ LOG ("Cannot update threat lists, got: %u, %s", msg->status_code, msg->response_body->data);
+ ephy_gsb_service_update_back_off_mode (self);
+ next_update_time = self->back_off_mode_exit_time;
goto out;
}
+ /* Successful response, reset back-off mode. */
+ ephy_gsb_service_reset_back_off_mode (self);
+
body_node = json_from_string (msg->response_body->data, NULL);
body_obj = json_node_get_object (body_node);
responses = json_object_get_array_member (body_obj, "listUpdateResponses");
@@ -459,12 +498,16 @@ ephy_gsb_service_find_full_hashes_cb (SoupSession *session,
const char *duration_str;
double duration;
+ /* Handle unsuccessful responses. */
if (msg->status_code != 200) {
- LOG ("Cannot update full hashes. Server responded: %u, %s",
- msg->status_code, msg->response_body->data);
+ LOG ("Cannot update full hashes, got: %u, %s", msg->status_code, msg->response_body->data);
+ ephy_gsb_service_update_back_off_mode (self);
goto out;
}
+ /* Successful response, reset back-off mode. */
+ ephy_gsb_service_reset_back_off_mode (self);
+
body_node = json_from_string (msg->response_body->data, NULL);
body_obj = json_node_get_object (body_node);
matches = json_object_get_array_member (body_obj, "matches");
@@ -558,6 +601,13 @@ ephy_gsb_service_find_full_hashes (EphyGSBService *self,
return;
}
+ if (ephy_gsb_service_is_back_off_mode (self)) {
+ LOG ("Cannot send fullHashes:find request. Back-off mode is enabled for %ld seconds",
+ self->back_off_mode_exit_time - CURRENT_TIME);
+ callback (threats, user_data);
+ return;
+ }
+
threat_lists = ephy_gsb_storage_get_threat_lists (self->storage);
if (!threat_lists) {
callback (threats, user_data);