* filtering/set_url: allow changing Name and URL parameters

This commit is contained in:
Simon Zolin 2019-11-06 15:56:29 +03:00
parent 3f7e2f7241
commit 0b8cba7384
3 changed files with 90 additions and 25 deletions

View File

@ -1338,9 +1338,13 @@ Request:
POST /control/filtering/set_url POST /control/filtering/set_url
{ {
"url": "..."
"data": {
"name": "..."
"url": "..." "url": "..."
"enabled": true | false "enabled": true | false
} }
}
Response: Response:

View File

@ -137,12 +137,18 @@ func handleFilteringRemoveURL(w http.ResponseWriter, r *http.Request) {
} }
type filterURLJSON struct { type filterURLJSON struct {
Name string `json:"name"`
URL string `json:"url"` URL string `json:"url"`
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
} }
type filterURLReq struct {
URL string `json:"url"`
Data filterURLJSON `json:"data"`
}
func handleFilteringSetURL(w http.ResponseWriter, r *http.Request) { func handleFilteringSetURL(w http.ResponseWriter, r *http.Request) {
fj := filterURLJSON{} fj := filterURLReq{}
err := json.NewDecoder(r.Body).Decode(&fj) err := json.NewDecoder(r.Body).Decode(&fj)
if err != nil { if err != nil {
httpError(w, http.StatusBadRequest, "json decode: %s", err) httpError(w, http.StatusBadRequest, "json decode: %s", err)
@ -154,14 +160,34 @@ func handleFilteringSetURL(w http.ResponseWriter, r *http.Request) {
return return
} }
found := filterEnable(fj.URL, fj.Enabled) f := filter{
if !found { Enabled: fj.Data.Enabled,
Name: fj.Data.Name,
URL: fj.Data.URL,
}
status := filterSetProperties(fj.URL, f)
if (status & statusFound) == 0 {
http.Error(w, "URL doesn't exist", http.StatusBadRequest) http.Error(w, "URL doesn't exist", http.StatusBadRequest)
return return
} }
if (status & statusURLExists) != 0 {
http.Error(w, "URL already exists", http.StatusBadRequest)
return
}
onConfigModified() onConfigModified()
enableFilters(true) if (status & statusURLChanged) != 0 {
if fj.Data.Enabled {
// download new filter and apply its rules
refreshStatus = 1
refreshLock.Lock()
_, _ = refreshFiltersIfNecessary(true)
refreshLock.Unlock()
}
} else if (status & statusEnabledChanged) != 0 {
enableFilters(true)
}
} }
func handleFilteringSetRules(w http.ResponseWriter, r *http.Request) { func handleFilteringSetRules(w http.ResponseWriter, r *http.Request) {

View File

@ -68,45 +68,80 @@ func userFilter() filter {
return f return f
} }
// Enable or disable a filter const (
func filterEnable(url string, enable bool) bool { statusFound = 1
r := false statusEnabledChanged = 2
statusURLChanged = 4
statusURLExists = 8
)
// Update properties for a filter specified by its URL
// Return status* flags.
func filterSetProperties(url string, newf filter) int {
r := 0
config.Lock() config.Lock()
defer config.Unlock()
for i := range config.Filters { for i := range config.Filters {
filter := &config.Filters[i] // otherwise we will be operating on a copy f := &config.Filters[i]
if filter.URL == url { if f.URL != url {
filter.Enabled = enable continue
if enable { }
e := filter.load()
if e != nil { log.Debug("filter: set properties: %s: {%s %s %v}",
// This isn't a fatal error, f.URL, newf.Name, newf.URL, newf.Enabled)
// because it may occur when someone removes the file from disk. f.Name = newf.Name
// In this case the periodic update task will try to download the file.
filter.LastUpdated = time.Time{} if f.URL != newf.URL {
log.Tracef("%s filter load: %v", url, e) r |= statusURLChanged
if filterExistsNoLock(newf.URL) {
return statusURLExists
}
f.URL = newf.URL
f.unload()
f.LastUpdated = time.Time{}
}
if f.Enabled != newf.Enabled {
r |= statusEnabledChanged
f.Enabled = newf.Enabled
if f.Enabled {
if (r & statusURLChanged) == 0 {
e := f.load()
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{}
}
} }
} else { } else {
filter.unload() f.unload()
} }
r = true
break
} }
return r | statusFound
} }
config.Unlock() return 0
return r
} }
// Return TRUE if a filter with this URL exists // Return TRUE if a filter with this URL exists
func filterExists(url string) bool { func filterExists(url string) bool {
r := false
config.RLock() config.RLock()
r := filterExistsNoLock(url)
config.RUnlock()
return r
}
// Return TRUE if a filter with this URL exists
func filterExistsNoLock(url string) bool {
r := false
for i := range config.Filters { for i := range config.Filters {
if config.Filters[i].URL == url { if config.Filters[i].URL == url {
r = true r = true
break break
} }
} }
config.RUnlock()
return r return r
} }