From b600d7b09d3f11b9f1635af67e0e7388cf62189c Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Wed, 11 Mar 2020 19:17:46 +0300 Subject: [PATCH] Merge: - filters: 'enable/disable filter' didn't work Squashed commit of the following: commit c4c616162b66f2e89932ac44253ff6bedb8692eb Merge: 800740da 579177fc Author: Simon Zolin Date: Wed Mar 11 19:14:27 2020 +0300 Merge remote-tracking branch 'origin/master' into apply-disable-filter commit 800740dace018dbe58abc579c06f7c494cdd1c15 Author: Simon Zolin Date: Wed Mar 11 18:40:38 2020 +0300 improve logic commit 2aab4fbe658de09cd4c1d0badc178e0ce9e60251 Author: Simon Zolin Date: Wed Mar 11 18:23:14 2020 +0300 - filters: 'disable filter' didn't work --- home/control_filtering.go | 28 +++++++++++++++++++++++++--- home/filter.go | 18 ++++++++++-------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/home/control_filtering.go b/home/control_filtering.go index 73bd9ca8..d78badf6 100644 --- a/home/control_filtering.go +++ b/home/control_filtering.go @@ -185,9 +185,27 @@ func handleFilteringSetURL(w http.ResponseWriter, r *http.Request) { } onConfigModified() - if (status&(statusURLChanged|statusEnabledChanged)) != 0 && fj.Data.Enabled { + restart := false + if (status & statusEnabledChanged) != 0 { + // we must add or remove filter rules + restart = true + } + if (status&statusUpdateRequired) != 0 && fj.Data.Enabled { // download new filter and apply its rules - _, _ = refreshFilters(fj.Whitelist, true) + flags := FilterRefreshBlocklists + if fj.Whitelist { + flags = FilterRefreshAllowlists + } + nUpdated, _ := refreshFilters(flags, true) + // if at least 1 filter has been updated, refreshFilters() restarts the filtering automatically + // if not - we restart the filtering ourselves + restart = false + if nUpdated == 0 { + restart = true + } + } + if restart { + enableFilters(true) } } @@ -226,7 +244,11 @@ func handleFilteringRefresh(w http.ResponseWriter, r *http.Request) { } Context.controlLock.Unlock() - resp.Updated, err = refreshFilters(req.White, false) + flags := FilterRefreshBlocklists + if req.White { + flags = FilterRefreshAllowlists + } + resp.Updated, err = refreshFilters(flags|FilterRefreshForce, false) Context.controlLock.Lock() if err != nil { httpError(w, http.StatusInternalServerError, "%s", err) diff --git a/home/filter.go b/home/filter.go index d5791ef3..f9770ca3 100644 --- a/home/filter.go +++ b/home/filter.go @@ -78,6 +78,7 @@ const ( statusEnabledChanged = 2 statusURLChanged = 4 statusURLExists = 8 + statusUpdateRequired = 0x10 ) // Update properties for a filter specified by its URL @@ -103,13 +104,15 @@ func filterSetProperties(url string, newf filter, whitelist bool) int { f.Name = newf.Name if f.URL != newf.URL { - r |= statusURLChanged + r |= statusURLChanged | statusUpdateRequired if filterExistsNoLock(newf.URL) { return statusURLExists } f.URL = newf.URL f.unload() f.LastUpdated = time.Time{} + f.checksum = 0 + f.RulesCount = 0 } if f.Enabled != newf.Enabled { @@ -121,8 +124,10 @@ func filterSetProperties(url string, newf filter, whitelist bool) int { if e != nil { // This isn't a fatal error, // because it may occur when someone removes the file from disk. - // In this case the periodic update task will try to download the file. f.LastUpdated = time.Time{} + f.checksum = 0 + f.RulesCount = 0 + r |= statusUpdateRequired } } } else { @@ -257,20 +262,17 @@ func periodicallyRefreshFilters() { } // Refresh filters +// flags: FilterRefresh* // important: // TRUE: ignore the fact that we're currently updating the filters -func refreshFilters(whitelist bool, important bool) (int, error) { +func refreshFilters(flags int, important bool) (int, error) { set := atomic.CompareAndSwapUint32(&refreshStatus, 0, 1) if !important && !set { return 0, fmt.Errorf("Filters update procedure is already running") } refreshLock.Lock() - flags := FilterRefreshBlocklists - if whitelist { - flags = FilterRefreshAllowlists - } - nUpdated, _ := refreshFiltersIfNecessary(flags | FilterRefreshForce) + nUpdated, _ := refreshFiltersIfNecessary(flags) refreshLock.Unlock() refreshStatus = 0 return nUpdated, nil