Merge: * control: refactor: all handlers are registered via httpRegister()

* commit '452a668a5ba66efa265621104fe3be17ae156ed5':
  * control: refactor: all handlers are registered via httpRegister()
This commit is contained in:
Simon Zolin 2019-08-23 14:09:22 +03:00
commit 307b934cf1
11 changed files with 301 additions and 348 deletions

View File

@ -73,8 +73,6 @@ func ApplyBlockedServices(setts *dnsfilter.RequestFilteringSettings, list []stri
} }
func handleBlockedServicesList(w http.ResponseWriter, r *http.Request) { func handleBlockedServicesList(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.RLock() config.RLock()
list := config.DNS.BlockedServices list := config.DNS.BlockedServices
config.RUnlock() config.RUnlock()
@ -88,8 +86,6 @@ func handleBlockedServicesList(w http.ResponseWriter, r *http.Request) {
} }
func handleBlockedServicesSet(w http.ResponseWriter, r *http.Request) { func handleBlockedServicesSet(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
list := []string{} list := []string{}
err := json.NewDecoder(r.Body).Decode(&list) err := json.NewDecoder(r.Body).Decode(&list)
if err != nil { if err != nil {
@ -114,6 +110,6 @@ func handleBlockedServicesSet(w http.ResponseWriter, r *http.Request) {
// RegisterBlockedServicesHandlers - register HTTP handlers // RegisterBlockedServicesHandlers - register HTTP handlers
func RegisterBlockedServicesHandlers() { func RegisterBlockedServicesHandlers() {
http.HandleFunc("/control/blocked_services/list", postInstall(optionalAuth(ensureGET(handleBlockedServicesList)))) httpRegister(http.MethodGet, "/control/blocked_services/list", handleBlockedServicesList)
http.HandleFunc("/control/blocked_services/set", postInstall(optionalAuth(ensurePOST(handleBlockedServicesSet)))) httpRegister(http.MethodPost, "/control/blocked_services/set", handleBlockedServicesSet)
} }

View File

@ -382,8 +382,6 @@ type clientListJSON struct {
// respond with information about configured clients // respond with information about configured clients
func handleGetClients(w http.ResponseWriter, r *http.Request) { func handleGetClients(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
data := clientListJSON{} data := clientListJSON{}
config.clients.lock.Lock() config.clients.lock.Lock()
@ -456,7 +454,6 @@ func jsonToClient(cj clientJSON) (*Client, error) {
// Add a new client // Add a new client
func handleAddClient(w http.ResponseWriter, r *http.Request) { func handleAddClient(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
httpError(w, http.StatusBadRequest, "failed to read request body: %s", err) httpError(w, http.StatusBadRequest, "failed to read request body: %s", err)
@ -491,7 +488,6 @@ func handleAddClient(w http.ResponseWriter, r *http.Request) {
// Remove client // Remove client
func handleDelClient(w http.ResponseWriter, r *http.Request) { func handleDelClient(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
httpError(w, http.StatusBadRequest, "failed to read request body: %s", err) httpError(w, http.StatusBadRequest, "failed to read request body: %s", err)
@ -521,7 +517,6 @@ type updateJSON struct {
// Update client's properties // Update client's properties
func handleUpdateClient(w http.ResponseWriter, r *http.Request) { func handleUpdateClient(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
httpError(w, http.StatusBadRequest, "failed to read request body: %s", err) httpError(w, http.StatusBadRequest, "failed to read request body: %s", err)
@ -557,8 +552,8 @@ func handleUpdateClient(w http.ResponseWriter, r *http.Request) {
// RegisterClientsHandlers registers HTTP handlers // RegisterClientsHandlers registers HTTP handlers
func RegisterClientsHandlers() { func RegisterClientsHandlers() {
http.HandleFunc("/control/clients", postInstall(optionalAuth(ensureGET(handleGetClients)))) httpRegister(http.MethodGet, "/control/clients", handleGetClients)
http.HandleFunc("/control/clients/add", postInstall(optionalAuth(ensurePOST(handleAddClient)))) httpRegister(http.MethodPost, "/control/clients/add", handleAddClient)
http.HandleFunc("/control/clients/delete", postInstall(optionalAuth(ensurePOST(handleDelClient)))) httpRegister(http.MethodPost, "/control/clients/delete", handleDelClient)
http.HandleFunc("/control/clients/update", postInstall(optionalAuth(ensurePOST(handleUpdateClient)))) httpRegister(http.MethodPost, "/control/clients/update", handleUpdateClient)
} }

View File

@ -4,10 +4,8 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil"
"net" "net"
"net/http" "net/http"
"os"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@ -19,7 +17,6 @@ import (
"github.com/AdguardTeam/golibs/utils" "github.com/AdguardTeam/golibs/utils"
"github.com/NYTimes/gziphandler" "github.com/NYTimes/gziphandler"
"github.com/miekg/dns" "github.com/miekg/dns"
govalidator "gopkg.in/asaskevich/govalidator.v4"
) )
const updatePeriod = time.Hour * 24 const updatePeriod = time.Hour * 24
@ -114,8 +111,6 @@ func getDNSAddresses() []string {
} }
func handleStatus(w http.ResponseWriter, r *http.Request) { func handleStatus(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
data := map[string]interface{}{ data := map[string]interface{}{
"dns_addresses": getDNSAddresses(), "dns_addresses": getDNSAddresses(),
"http_port": config.BindPort, "http_port": config.BindPort,
@ -144,13 +139,11 @@ func handleStatus(w http.ResponseWriter, r *http.Request) {
} }
func handleProtectionEnable(w http.ResponseWriter, r *http.Request) { func handleProtectionEnable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.DNS.ProtectionEnabled = true config.DNS.ProtectionEnabled = true
httpUpdateConfigReloadDNSReturnOK(w, r) httpUpdateConfigReloadDNSReturnOK(w, r)
} }
func handleProtectionDisable(w http.ResponseWriter, r *http.Request) { func handleProtectionDisable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.DNS.ProtectionEnabled = false config.DNS.ProtectionEnabled = false
httpUpdateConfigReloadDNSReturnOK(w, r) httpUpdateConfigReloadDNSReturnOK(w, r)
} }
@ -159,19 +152,16 @@ func handleProtectionDisable(w http.ResponseWriter, r *http.Request) {
// stats // stats
// ----- // -----
func handleQueryLogEnable(w http.ResponseWriter, r *http.Request) { func handleQueryLogEnable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.DNS.QueryLogEnabled = true config.DNS.QueryLogEnabled = true
httpUpdateConfigReloadDNSReturnOK(w, r) httpUpdateConfigReloadDNSReturnOK(w, r)
} }
func handleQueryLogDisable(w http.ResponseWriter, r *http.Request) { func handleQueryLogDisable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.DNS.QueryLogEnabled = false config.DNS.QueryLogEnabled = false
httpUpdateConfigReloadDNSReturnOK(w, r) httpUpdateConfigReloadDNSReturnOK(w, r)
} }
func handleQueryLog(w http.ResponseWriter, r *http.Request) { func handleQueryLog(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
data := config.dnsServer.GetQueryLog() data := config.dnsServer.GetQueryLog()
jsonVal, err := json.Marshal(data) jsonVal, err := json.Marshal(data)
@ -188,7 +178,6 @@ func handleQueryLog(w http.ResponseWriter, r *http.Request) {
} }
func handleStatsTop(w http.ResponseWriter, r *http.Request) { func handleStatsTop(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
s := config.dnsServer.GetStatsTop() s := config.dnsServer.GetStatsTop()
// use manual json marshalling because we want maps to be sorted by value // use manual json marshalling because we want maps to be sorted by value
@ -235,7 +224,6 @@ func handleStatsTop(w http.ResponseWriter, r *http.Request) {
// handleStatsReset resets the stats caches // handleStatsReset resets the stats caches
func handleStatsReset(w http.ResponseWriter, r *http.Request) { func handleStatsReset(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.dnsServer.PurgeStats() config.dnsServer.PurgeStats()
_, err := fmt.Fprintf(w, "OK\n") _, err := fmt.Fprintf(w, "OK\n")
if err != nil { if err != nil {
@ -245,7 +233,6 @@ func handleStatsReset(w http.ResponseWriter, r *http.Request) {
// handleStats returns aggregated stats data for the 24 hours // handleStats returns aggregated stats data for the 24 hours
func handleStats(w http.ResponseWriter, r *http.Request) { func handleStats(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
summed := config.dnsServer.GetAggregatedStats() summed := config.dnsServer.GetAggregatedStats()
statsJSON, err := json.Marshal(summed) statsJSON, err := json.Marshal(summed)
@ -263,7 +250,6 @@ func handleStats(w http.ResponseWriter, r *http.Request) {
// HandleStatsHistory returns historical stats data for the 24 hours // HandleStatsHistory returns historical stats data for the 24 hours
func handleStatsHistory(w http.ResponseWriter, r *http.Request) { func handleStatsHistory(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
// handle time unit and prepare our time window size // handle time unit and prepare our time window size
timeUnitString := r.URL.Query().Get("time_unit") timeUnitString := r.URL.Query().Get("time_unit")
var timeUnit time.Duration var timeUnit time.Duration
@ -346,7 +332,6 @@ type upstreamConfig struct {
} }
func handleSetUpstreamConfig(w http.ResponseWriter, r *http.Request) { func handleSetUpstreamConfig(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
newconfig := upstreamConfig{} newconfig := upstreamConfig{}
err := json.NewDecoder(r.Body).Decode(&newconfig) err := json.NewDecoder(r.Body).Decode(&newconfig)
if err != nil { if err != nil {
@ -484,7 +469,6 @@ func checkPlainDNS(upstream string) error {
} }
func handleTestUpstreamDNS(w http.ResponseWriter, r *http.Request) { func handleTestUpstreamDNS(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
upstreamConfig := upstreamConfig{} upstreamConfig := upstreamConfig{}
err := json.NewDecoder(r.Body).Decode(&upstreamConfig) err := json.NewDecoder(r.Body).Decode(&upstreamConfig)
if err != nil { if err != nil {
@ -571,261 +555,21 @@ func checkDNS(input string, bootstrap []string) error {
return nil return nil
} }
// ---------
// filtering
// ---------
func handleFilteringEnable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.DNS.FilteringEnabled = true
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringDisable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.DNS.FilteringEnabled = false
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringStatus(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
data := map[string]interface{}{
"enabled": config.DNS.FilteringEnabled,
}
config.RLock()
data["filters"] = config.Filters
data["user_rules"] = config.UserRules
jsonVal, err := json.Marshal(data)
config.RUnlock()
if err != nil {
httpError(w, http.StatusInternalServerError, "Unable to marshal status json: %s", err)
return
}
w.Header().Set("Content-Type", "application/json")
_, err = w.Write(jsonVal)
if err != nil {
httpError(w, http.StatusInternalServerError, "Unable to write response json: %s", err)
return
}
}
func handleFilteringAddURL(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
f := filter{}
err := json.NewDecoder(r.Body).Decode(&f)
if err != nil {
httpError(w, http.StatusBadRequest, "Failed to parse request body json: %s", err)
return
}
if len(f.URL) == 0 {
http.Error(w, "URL parameter was not specified", http.StatusBadRequest)
return
}
if valid := govalidator.IsRequestURL(f.URL); !valid {
http.Error(w, "URL parameter is not valid request URL", http.StatusBadRequest)
return
}
// Check for duplicates
if filterExists(f.URL) {
httpError(w, http.StatusBadRequest, "Filter URL already added -- %s", f.URL)
return
}
// Set necessary properties
f.ID = assignUniqueFilterID()
f.Enabled = true
// Download the filter contents
ok, err := f.update()
if err != nil {
httpError(w, http.StatusBadRequest, "Couldn't fetch filter from url %s: %s", f.URL, err)
return
}
if f.RulesCount == 0 {
httpError(w, http.StatusBadRequest, "Filter at the url %s has no rules (maybe it points to blank page?)", f.URL)
return
}
if !ok {
httpError(w, http.StatusBadRequest, "Filter at the url %s is invalid (maybe it points to blank page?)", f.URL)
return
}
// Save the filter contents
err = f.save()
if err != nil {
httpError(w, http.StatusBadRequest, "Failed to save filter %d due to %s", f.ID, err)
return
}
// URL is deemed valid, append it to filters, update config, write new filter file and tell dns to reload it
// TODO: since we directly feed filters in-memory, revisit if writing configs is always necessary
if !filterAdd(f) {
httpError(w, http.StatusBadRequest, "Filter URL already added -- %s", f.URL)
return
}
err = writeAllConfigs()
if err != nil {
httpError(w, http.StatusInternalServerError, "Couldn't write config file: %s", err)
return
}
err = reconfigureDNSServer()
if err != nil {
httpError(w, http.StatusInternalServerError, "Couldn't reconfigure the DNS server: %s", err)
return
}
_, err = fmt.Fprintf(w, "OK %d rules\n", f.RulesCount)
if err != nil {
httpError(w, http.StatusInternalServerError, "Couldn't write body: %s", err)
}
}
func handleFilteringRemoveURL(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
type request struct {
URL string `json:"url"`
}
req := request{}
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
httpError(w, http.StatusBadRequest, "Failed to parse request body json: %s", err)
return
}
if valid := govalidator.IsRequestURL(req.URL); !valid {
http.Error(w, "URL parameter is not valid request URL", http.StatusBadRequest)
return
}
// Stop DNS server:
// we close urlfilter object which in turn closes file descriptors to filter files.
// Otherwise, Windows won't allow us to remove the file which is being currently used.
_ = config.dnsServer.Stop()
// go through each element and delete if url matches
config.Lock()
newFilters := config.Filters[:0]
for _, filter := range config.Filters {
if filter.URL != req.URL {
newFilters = append(newFilters, filter)
} else {
// Remove the filter file
err := os.Remove(filter.Path())
if err != nil && !os.IsNotExist(err) {
config.Unlock()
httpError(w, http.StatusInternalServerError, "Couldn't remove the filter file: %s", err)
return
}
log.Debug("os.Remove(%s)", filter.Path())
}
}
// Update the configuration after removing filter files
config.Filters = newFilters
config.Unlock()
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringEnableURL(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
parameters, err := parseParametersFromBody(r.Body)
if err != nil {
httpError(w, http.StatusBadRequest, "failed to parse parameters from body: %s", err)
return
}
url, ok := parameters["url"]
if !ok {
http.Error(w, "URL parameter was not specified", http.StatusBadRequest)
return
}
if valid := govalidator.IsRequestURL(url); !valid {
http.Error(w, "URL parameter is not valid request URL", http.StatusBadRequest)
return
}
found := filterEnable(url, true)
if !found {
http.Error(w, "URL parameter was not previously added", http.StatusBadRequest)
return
}
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringDisableURL(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
parameters, err := parseParametersFromBody(r.Body)
if err != nil {
httpError(w, http.StatusBadRequest, "failed to parse parameters from body: %s", err)
return
}
url, ok := parameters["url"]
if !ok {
http.Error(w, "URL parameter was not specified", http.StatusBadRequest)
return
}
if valid := govalidator.IsRequestURL(url); !valid {
http.Error(w, "URL parameter is not valid request URL", http.StatusBadRequest)
return
}
found := filterEnable(url, false)
if !found {
http.Error(w, "URL parameter was not previously added", http.StatusBadRequest)
return
}
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringSetRules(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
body, err := ioutil.ReadAll(r.Body)
if err != nil {
httpError(w, http.StatusBadRequest, "Failed to read request body: %s", err)
return
}
config.UserRules = strings.Split(string(body), "\n")
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringRefresh(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
updated := refreshFiltersIfNecessary(true)
fmt.Fprintf(w, "OK %d filters updated\n", updated)
}
// ------------ // ------------
// safebrowsing // safebrowsing
// ------------ // ------------
func handleSafeBrowsingEnable(w http.ResponseWriter, r *http.Request) { func handleSafeBrowsingEnable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.DNS.SafeBrowsingEnabled = true config.DNS.SafeBrowsingEnabled = true
httpUpdateConfigReloadDNSReturnOK(w, r) httpUpdateConfigReloadDNSReturnOK(w, r)
} }
func handleSafeBrowsingDisable(w http.ResponseWriter, r *http.Request) { func handleSafeBrowsingDisable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.DNS.SafeBrowsingEnabled = false config.DNS.SafeBrowsingEnabled = false
httpUpdateConfigReloadDNSReturnOK(w, r) httpUpdateConfigReloadDNSReturnOK(w, r)
} }
func handleSafeBrowsingStatus(w http.ResponseWriter, r *http.Request) { func handleSafeBrowsingStatus(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
data := map[string]interface{}{ data := map[string]interface{}{
"enabled": config.DNS.SafeBrowsingEnabled, "enabled": config.DNS.SafeBrowsingEnabled,
} }
@ -846,7 +590,6 @@ func handleSafeBrowsingStatus(w http.ResponseWriter, r *http.Request) {
// parental // parental
// -------- // --------
func handleParentalEnable(w http.ResponseWriter, r *http.Request) { func handleParentalEnable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
parameters, err := parseParametersFromBody(r.Body) parameters, err := parseParametersFromBody(r.Body)
if err != nil { if err != nil {
httpError(w, http.StatusBadRequest, "failed to parse parameters from body: %s", err) httpError(w, http.StatusBadRequest, "failed to parse parameters from body: %s", err)
@ -891,13 +634,11 @@ func handleParentalEnable(w http.ResponseWriter, r *http.Request) {
} }
func handleParentalDisable(w http.ResponseWriter, r *http.Request) { func handleParentalDisable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.DNS.ParentalEnabled = false config.DNS.ParentalEnabled = false
httpUpdateConfigReloadDNSReturnOK(w, r) httpUpdateConfigReloadDNSReturnOK(w, r)
} }
func handleParentalStatus(w http.ResponseWriter, r *http.Request) { func handleParentalStatus(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
data := map[string]interface{}{ data := map[string]interface{}{
"enabled": config.DNS.ParentalEnabled, "enabled": config.DNS.ParentalEnabled,
} }
@ -923,19 +664,16 @@ func handleParentalStatus(w http.ResponseWriter, r *http.Request) {
// ------------ // ------------
func handleSafeSearchEnable(w http.ResponseWriter, r *http.Request) { func handleSafeSearchEnable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.DNS.SafeSearchEnabled = true config.DNS.SafeSearchEnabled = true
httpUpdateConfigReloadDNSReturnOK(w, r) httpUpdateConfigReloadDNSReturnOK(w, r)
} }
func handleSafeSearchDisable(w http.ResponseWriter, r *http.Request) { func handleSafeSearchDisable(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.DNS.SafeSearchEnabled = false config.DNS.SafeSearchEnabled = false
httpUpdateConfigReloadDNSReturnOK(w, r) httpUpdateConfigReloadDNSReturnOK(w, r)
} }
func handleSafeSearchStatus(w http.ResponseWriter, r *http.Request) { func handleSafeSearchStatus(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
data := map[string]interface{}{ data := map[string]interface{}{
"enabled": config.DNS.SafeSearchEnabled, "enabled": config.DNS.SafeSearchEnabled,
} }
@ -957,7 +695,6 @@ func handleSafeSearchStatus(w http.ResponseWriter, r *http.Request) {
// DNS-over-HTTPS // DNS-over-HTTPS
// -------------- // --------------
func handleDOH(w http.ResponseWriter, r *http.Request) { func handleDOH(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
if r.TLS == nil { if r.TLS == nil {
httpError(w, http.StatusNotFound, "Not Found") httpError(w, http.StatusNotFound, "Not Found")
return return
@ -975,49 +712,49 @@ func handleDOH(w http.ResponseWriter, r *http.Request) {
// registration of handlers // registration of handlers
// ------------------------ // ------------------------
func registerControlHandlers() { func registerControlHandlers() {
http.HandleFunc("/control/status", postInstall(optionalAuth(ensureGET(handleStatus)))) httpRegister(http.MethodGet, "/control/status", handleStatus)
http.HandleFunc("/control/enable_protection", postInstall(optionalAuth(ensurePOST(handleProtectionEnable)))) httpRegister(http.MethodPost, "/control/enable_protection", handleProtectionEnable)
http.HandleFunc("/control/disable_protection", postInstall(optionalAuth(ensurePOST(handleProtectionDisable)))) httpRegister(http.MethodPost, "/control/disable_protection", handleProtectionDisable)
http.Handle("/control/querylog", postInstallHandler(optionalAuthHandler(gziphandler.GzipHandler(ensureGETHandler(handleQueryLog))))) httpRegister(http.MethodGet, "/control/querylog", handleQueryLog)
http.HandleFunc("/control/querylog_enable", postInstall(optionalAuth(ensurePOST(handleQueryLogEnable)))) httpRegister(http.MethodPost, "/control/querylog_enable", handleQueryLogEnable)
http.HandleFunc("/control/querylog_disable", postInstall(optionalAuth(ensurePOST(handleQueryLogDisable)))) httpRegister(http.MethodPost, "/control/querylog_disable", handleQueryLogDisable)
http.HandleFunc("/control/set_upstreams_config", postInstall(optionalAuth(ensurePOST(handleSetUpstreamConfig)))) httpRegister(http.MethodPost, "/control/set_upstreams_config", handleSetUpstreamConfig)
http.HandleFunc("/control/test_upstream_dns", postInstall(optionalAuth(ensurePOST(handleTestUpstreamDNS)))) httpRegister(http.MethodPost, "/control/test_upstream_dns", handleTestUpstreamDNS)
http.HandleFunc("/control/i18n/change_language", postInstall(optionalAuth(ensurePOST(handleI18nChangeLanguage)))) httpRegister(http.MethodPost, "/control/i18n/change_language", handleI18nChangeLanguage)
http.HandleFunc("/control/i18n/current_language", postInstall(optionalAuth(ensureGET(handleI18nCurrentLanguage)))) httpRegister(http.MethodGet, "/control/i18n/current_language", handleI18nCurrentLanguage)
http.HandleFunc("/control/stats_top", postInstall(optionalAuth(ensureGET(handleStatsTop)))) httpRegister(http.MethodGet, "/control/stats_top", handleStatsTop)
http.HandleFunc("/control/stats", postInstall(optionalAuth(ensureGET(handleStats)))) httpRegister(http.MethodGet, "/control/stats", handleStats)
http.HandleFunc("/control/stats_history", postInstall(optionalAuth(ensureGET(handleStatsHistory)))) httpRegister(http.MethodGet, "/control/stats_history", handleStatsHistory)
http.HandleFunc("/control/stats_reset", postInstall(optionalAuth(ensurePOST(handleStatsReset)))) httpRegister(http.MethodPost, "/control/stats_reset", handleStatsReset)
http.HandleFunc("/control/version.json", postInstall(optionalAuth(handleGetVersionJSON))) http.HandleFunc("/control/version.json", postInstall(optionalAuth(handleGetVersionJSON)))
http.HandleFunc("/control/update", postInstall(optionalAuth(ensurePOST(handleUpdate)))) httpRegister(http.MethodPost, "/control/update", handleUpdate)
http.HandleFunc("/control/filtering/enable", postInstall(optionalAuth(ensurePOST(handleFilteringEnable)))) httpRegister(http.MethodPost, "/control/filtering/enable", handleFilteringEnable)
http.HandleFunc("/control/filtering/disable", postInstall(optionalAuth(ensurePOST(handleFilteringDisable)))) httpRegister(http.MethodPost, "/control/filtering/disable", handleFilteringDisable)
http.HandleFunc("/control/filtering/add_url", postInstall(optionalAuth(ensurePOST(handleFilteringAddURL)))) httpRegister(http.MethodPost, "/control/filtering/add_url", handleFilteringAddURL)
http.HandleFunc("/control/filtering/remove_url", postInstall(optionalAuth(ensurePOST(handleFilteringRemoveURL)))) httpRegister(http.MethodPost, "/control/filtering/remove_url", handleFilteringRemoveURL)
http.HandleFunc("/control/filtering/enable_url", postInstall(optionalAuth(ensurePOST(handleFilteringEnableURL)))) httpRegister(http.MethodPost, "/control/filtering/enable_url", handleFilteringEnableURL)
http.HandleFunc("/control/filtering/disable_url", postInstall(optionalAuth(ensurePOST(handleFilteringDisableURL)))) httpRegister(http.MethodPost, "/control/filtering/disable_url", handleFilteringDisableURL)
http.HandleFunc("/control/filtering/refresh", postInstall(optionalAuth(ensurePOST(handleFilteringRefresh)))) httpRegister(http.MethodPost, "/control/filtering/refresh", handleFilteringRefresh)
http.HandleFunc("/control/filtering/status", postInstall(optionalAuth(ensureGET(handleFilteringStatus)))) httpRegister(http.MethodGet, "/control/filtering/status", handleFilteringStatus)
http.HandleFunc("/control/filtering/set_rules", postInstall(optionalAuth(ensurePOST(handleFilteringSetRules)))) httpRegister(http.MethodPost, "/control/filtering/set_rules", handleFilteringSetRules)
http.HandleFunc("/control/safebrowsing/enable", postInstall(optionalAuth(ensurePOST(handleSafeBrowsingEnable)))) httpRegister(http.MethodPost, "/control/safebrowsing/enable", handleSafeBrowsingEnable)
http.HandleFunc("/control/safebrowsing/disable", postInstall(optionalAuth(ensurePOST(handleSafeBrowsingDisable)))) httpRegister(http.MethodPost, "/control/safebrowsing/disable", handleSafeBrowsingDisable)
http.HandleFunc("/control/safebrowsing/status", postInstall(optionalAuth(ensureGET(handleSafeBrowsingStatus)))) httpRegister(http.MethodGet, "/control/safebrowsing/status", handleSafeBrowsingStatus)
http.HandleFunc("/control/parental/enable", postInstall(optionalAuth(ensurePOST(handleParentalEnable)))) httpRegister(http.MethodPost, "/control/parental/enable", handleParentalEnable)
http.HandleFunc("/control/parental/disable", postInstall(optionalAuth(ensurePOST(handleParentalDisable)))) httpRegister(http.MethodPost, "/control/parental/disable", handleParentalDisable)
http.HandleFunc("/control/parental/status", postInstall(optionalAuth(ensureGET(handleParentalStatus)))) httpRegister(http.MethodGet, "/control/parental/status", handleParentalStatus)
http.HandleFunc("/control/safesearch/enable", postInstall(optionalAuth(ensurePOST(handleSafeSearchEnable)))) httpRegister(http.MethodPost, "/control/safesearch/enable", handleSafeSearchEnable)
http.HandleFunc("/control/safesearch/disable", postInstall(optionalAuth(ensurePOST(handleSafeSearchDisable)))) httpRegister(http.MethodPost, "/control/safesearch/disable", handleSafeSearchDisable)
http.HandleFunc("/control/safesearch/status", postInstall(optionalAuth(ensureGET(handleSafeSearchStatus)))) httpRegister(http.MethodGet, "/control/safesearch/status", handleSafeSearchStatus)
http.HandleFunc("/control/dhcp/status", postInstall(optionalAuth(ensureGET(handleDHCPStatus)))) httpRegister(http.MethodGet, "/control/dhcp/status", handleDHCPStatus)
http.HandleFunc("/control/dhcp/interfaces", postInstall(optionalAuth(ensureGET(handleDHCPInterfaces)))) httpRegister(http.MethodGet, "/control/dhcp/interfaces", handleDHCPInterfaces)
http.HandleFunc("/control/dhcp/set_config", postInstall(optionalAuth(ensurePOST(handleDHCPSetConfig)))) httpRegister(http.MethodPost, "/control/dhcp/set_config", handleDHCPSetConfig)
http.HandleFunc("/control/dhcp/find_active_dhcp", postInstall(optionalAuth(ensurePOST(handleDHCPFindActiveServer)))) httpRegister(http.MethodPost, "/control/dhcp/find_active_dhcp", handleDHCPFindActiveServer)
http.HandleFunc("/control/dhcp/add_static_lease", postInstall(optionalAuth(ensurePOST(handleDHCPAddStaticLease)))) httpRegister(http.MethodPost, "/control/dhcp/add_static_lease", handleDHCPAddStaticLease)
http.HandleFunc("/control/dhcp/remove_static_lease", postInstall(optionalAuth(ensurePOST(handleDHCPRemoveStaticLease)))) httpRegister(http.MethodPost, "/control/dhcp/remove_static_lease", handleDHCPRemoveStaticLease)
http.HandleFunc("/control/access/list", postInstall(optionalAuth(ensureGET(handleAccessList)))) httpRegister(http.MethodGet, "/control/access/list", handleAccessList)
http.HandleFunc("/control/access/set", postInstall(optionalAuth(ensurePOST(handleAccessSet)))) httpRegister(http.MethodPost, "/control/access/set", handleAccessSet)
RegisterTLSHandlers() RegisterTLSHandlers()
RegisterClientsHandlers() RegisterClientsHandlers()
@ -1026,3 +763,9 @@ func registerControlHandlers() {
http.HandleFunc("/dns-query", postInstall(handleDOH)) http.HandleFunc("/dns-query", postInstall(handleDOH))
} }
type httpHandlerType func(http.ResponseWriter, *http.Request)
func httpRegister(method string, url string, handler httpHandlerType) {
http.Handle(url, postInstallHandler(optionalAuthHandler(gziphandler.GzipHandler(ensureHandler(method, handler)))))
}

View File

@ -15,8 +15,6 @@ type accessListJSON struct {
} }
func handleAccessList(w http.ResponseWriter, r *http.Request) { func handleAccessList(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
config.controlLock.Lock() config.controlLock.Lock()
j := accessListJSON{ j := accessListJSON{
AllowedClients: config.DNS.AllowedClients, AllowedClients: config.DNS.AllowedClients,
@ -50,7 +48,6 @@ func checkIPCIDRArray(src []string) error {
} }
func handleAccessSet(w http.ResponseWriter, r *http.Request) { func handleAccessSet(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
j := accessListJSON{} j := accessListJSON{}
err := json.NewDecoder(r.Body).Decode(&j) err := json.NewDecoder(r.Body).Decode(&j)

237
home/control_filtering.go Normal file
View File

@ -0,0 +1,237 @@
package home
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
"github.com/AdguardTeam/golibs/log"
"github.com/asaskevich/govalidator"
)
func handleFilteringEnable(w http.ResponseWriter, r *http.Request) {
config.DNS.FilteringEnabled = true
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringDisable(w http.ResponseWriter, r *http.Request) {
config.DNS.FilteringEnabled = false
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringStatus(w http.ResponseWriter, r *http.Request) {
data := map[string]interface{}{
"enabled": config.DNS.FilteringEnabled,
}
config.RLock()
data["filters"] = config.Filters
data["user_rules"] = config.UserRules
jsonVal, err := json.Marshal(data)
config.RUnlock()
if err != nil {
httpError(w, http.StatusInternalServerError, "Unable to marshal status json: %s", err)
return
}
w.Header().Set("Content-Type", "application/json")
_, err = w.Write(jsonVal)
if err != nil {
httpError(w, http.StatusInternalServerError, "Unable to write response json: %s", err)
return
}
}
func handleFilteringAddURL(w http.ResponseWriter, r *http.Request) {
f := filter{}
err := json.NewDecoder(r.Body).Decode(&f)
if err != nil {
httpError(w, http.StatusBadRequest, "Failed to parse request body json: %s", err)
return
}
if len(f.URL) == 0 {
http.Error(w, "URL parameter was not specified", http.StatusBadRequest)
return
}
if valid := govalidator.IsRequestURL(f.URL); !valid {
http.Error(w, "URL parameter is not valid request URL", http.StatusBadRequest)
return
}
// Check for duplicates
if filterExists(f.URL) {
httpError(w, http.StatusBadRequest, "Filter URL already added -- %s", f.URL)
return
}
// Set necessary properties
f.ID = assignUniqueFilterID()
f.Enabled = true
// Download the filter contents
ok, err := f.update()
if err != nil {
httpError(w, http.StatusBadRequest, "Couldn't fetch filter from url %s: %s", f.URL, err)
return
}
if f.RulesCount == 0 {
httpError(w, http.StatusBadRequest, "Filter at the url %s has no rules (maybe it points to blank page?)", f.URL)
return
}
if !ok {
httpError(w, http.StatusBadRequest, "Filter at the url %s is invalid (maybe it points to blank page?)", f.URL)
return
}
// Save the filter contents
err = f.save()
if err != nil {
httpError(w, http.StatusBadRequest, "Failed to save filter %d due to %s", f.ID, err)
return
}
// URL is deemed valid, append it to filters, update config, write new filter file and tell dns to reload it
// TODO: since we directly feed filters in-memory, revisit if writing configs is always necessary
if !filterAdd(f) {
httpError(w, http.StatusBadRequest, "Filter URL already added -- %s", f.URL)
return
}
err = writeAllConfigs()
if err != nil {
httpError(w, http.StatusInternalServerError, "Couldn't write config file: %s", err)
return
}
err = reconfigureDNSServer()
if err != nil {
httpError(w, http.StatusInternalServerError, "Couldn't reconfigure the DNS server: %s", err)
return
}
_, err = fmt.Fprintf(w, "OK %d rules\n", f.RulesCount)
if err != nil {
httpError(w, http.StatusInternalServerError, "Couldn't write body: %s", err)
}
}
func handleFilteringRemoveURL(w http.ResponseWriter, r *http.Request) {
type request struct {
URL string `json:"url"`
}
req := request{}
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
httpError(w, http.StatusBadRequest, "Failed to parse request body json: %s", err)
return
}
if valid := govalidator.IsRequestURL(req.URL); !valid {
http.Error(w, "URL parameter is not valid request URL", http.StatusBadRequest)
return
}
// Stop DNS server:
// we close urlfilter object which in turn closes file descriptors to filter files.
// Otherwise, Windows won't allow us to remove the file which is being currently used.
_ = config.dnsServer.Stop()
// go through each element and delete if url matches
config.Lock()
newFilters := config.Filters[:0]
for _, filter := range config.Filters {
if filter.URL != req.URL {
newFilters = append(newFilters, filter)
} else {
// Remove the filter file
err := os.Remove(filter.Path())
if err != nil && !os.IsNotExist(err) {
config.Unlock()
httpError(w, http.StatusInternalServerError, "Couldn't remove the filter file: %s", err)
return
}
log.Debug("os.Remove(%s)", filter.Path())
}
}
// Update the configuration after removing filter files
config.Filters = newFilters
config.Unlock()
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringEnableURL(w http.ResponseWriter, r *http.Request) {
parameters, err := parseParametersFromBody(r.Body)
if err != nil {
httpError(w, http.StatusBadRequest, "failed to parse parameters from body: %s", err)
return
}
url, ok := parameters["url"]
if !ok {
http.Error(w, "URL parameter was not specified", http.StatusBadRequest)
return
}
if valid := govalidator.IsRequestURL(url); !valid {
http.Error(w, "URL parameter is not valid request URL", http.StatusBadRequest)
return
}
found := filterEnable(url, true)
if !found {
http.Error(w, "URL parameter was not previously added", http.StatusBadRequest)
return
}
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringDisableURL(w http.ResponseWriter, r *http.Request) {
parameters, err := parseParametersFromBody(r.Body)
if err != nil {
httpError(w, http.StatusBadRequest, "failed to parse parameters from body: %s", err)
return
}
url, ok := parameters["url"]
if !ok {
http.Error(w, "URL parameter was not specified", http.StatusBadRequest)
return
}
if valid := govalidator.IsRequestURL(url); !valid {
http.Error(w, "URL parameter is not valid request URL", http.StatusBadRequest)
return
}
found := filterEnable(url, false)
if !found {
http.Error(w, "URL parameter was not previously added", http.StatusBadRequest)
return
}
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringSetRules(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
httpError(w, http.StatusBadRequest, "Failed to read request body: %s", err)
return
}
config.UserRules = strings.Split(string(body), "\n")
httpUpdateConfigReloadDNSReturnOK(w, r)
}
func handleFilteringRefresh(w http.ResponseWriter, r *http.Request) {
updated := refreshFiltersIfNecessary(true)
fmt.Fprintf(w, "OK %d filters updated\n", updated)
}

View File

@ -20,7 +20,6 @@ type firstRunData struct {
// Get initial installation settings // Get initial installation settings
func handleInstallGetAddresses(w http.ResponseWriter, r *http.Request) { func handleInstallGetAddresses(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
data := firstRunData{} data := firstRunData{}
data.WebPort = 80 data.WebPort = 80
data.DNSPort = 53 data.DNSPort = 53
@ -65,7 +64,6 @@ type checkConfigResp struct {
// Check if ports are available, respond with results // Check if ports are available, respond with results
func handleInstallCheckConfig(w http.ResponseWriter, r *http.Request) { func handleInstallCheckConfig(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
reqData := checkConfigReq{} reqData := checkConfigReq{}
respData := checkConfigResp{} respData := checkConfigResp{}
err := json.NewDecoder(r.Body).Decode(&reqData) err := json.NewDecoder(r.Body).Decode(&reqData)
@ -190,7 +188,6 @@ func copyInstallSettings(dst *configuration, src *configuration) {
// Apply new configuration, start DNS server, restart Web server // Apply new configuration, start DNS server, restart Web server
func handleInstallConfigure(w http.ResponseWriter, r *http.Request) { func handleInstallConfigure(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
newSettings := applyConfigReq{} newSettings := applyConfigReq{}
err := json.NewDecoder(r.Body).Decode(&newSettings) err := json.NewDecoder(r.Body).Decode(&newSettings)
if err != nil { if err != nil {

View File

@ -25,18 +25,16 @@ import (
// RegisterTLSHandlers registers HTTP handlers for TLS configuration // RegisterTLSHandlers registers HTTP handlers for TLS configuration
func RegisterTLSHandlers() { func RegisterTLSHandlers() {
http.HandleFunc("/control/tls/status", postInstall(optionalAuth(ensureGET(handleTLSStatus)))) httpRegister(http.MethodGet, "/control/tls/status", handleTLSStatus)
http.HandleFunc("/control/tls/configure", postInstall(optionalAuth(ensurePOST(handleTLSConfigure)))) httpRegister(http.MethodPost, "/control/tls/configure", handleTLSConfigure)
http.HandleFunc("/control/tls/validate", postInstall(optionalAuth(ensurePOST(handleTLSValidate)))) httpRegister(http.MethodPost, "/control/tls/validate", handleTLSValidate)
} }
func handleTLSStatus(w http.ResponseWriter, r *http.Request) { func handleTLSStatus(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
marshalTLS(w, config.TLS) marshalTLS(w, config.TLS)
} }
func handleTLSValidate(w http.ResponseWriter, r *http.Request) { func handleTLSValidate(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
data, err := unmarshalTLS(r) data, err := unmarshalTLS(r)
if err != nil { if err != nil {
httpError(w, http.StatusBadRequest, "Failed to unmarshal TLS config: %s", err) httpError(w, http.StatusBadRequest, "Failed to unmarshal TLS config: %s", err)
@ -62,7 +60,6 @@ func handleTLSValidate(w http.ResponseWriter, r *http.Request) {
} }
func handleTLSConfigure(w http.ResponseWriter, r *http.Request) { func handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
data, err := unmarshalTLS(r) data, err := unmarshalTLS(r)
if err != nil { if err != nil {
httpError(w, http.StatusBadRequest, "Failed to unmarshal TLS config: %s", err) httpError(w, http.StatusBadRequest, "Failed to unmarshal TLS config: %s", err)

View File

@ -57,10 +57,9 @@ type getVersionJSONRequest struct {
// Get the latest available version from the Internet // Get the latest available version from the Internet
func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) { func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
if config.disableUpdate { if config.disableUpdate {
log.Tracef("New app version check is disabled by user") httpError(w, http.StatusInternalServerError, "New app version check is disabled by user")
return return
} }
@ -499,7 +498,6 @@ func finishUpdate(u *updateInfo) {
// Perform an update procedure to the latest available version // Perform an update procedure to the latest available version
func handleUpdate(w http.ResponseWriter, r *http.Request) { func handleUpdate(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
if len(config.versionCheckJSON) == 0 { if len(config.versionCheckJSON) == 0 {
httpError(w, http.StatusBadRequest, "/update request isn't allowed now") httpError(w, http.StatusBadRequest, "/update request isn't allowed now")

View File

@ -38,7 +38,6 @@ func convertLeases(inputLeases []dhcpd.Lease, includeExpires bool) []map[string]
} }
func handleDHCPStatus(w http.ResponseWriter, r *http.Request) { func handleDHCPStatus(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
leases := convertLeases(config.dhcpServer.Leases(), true) leases := convertLeases(config.dhcpServer.Leases(), true)
staticLeases := convertLeases(config.dhcpServer.StaticLeases(), false) staticLeases := convertLeases(config.dhcpServer.StaticLeases(), false)
status := map[string]interface{}{ status := map[string]interface{}{
@ -67,7 +66,6 @@ type dhcpServerConfigJSON struct {
} }
func handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) { func handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
newconfig := dhcpServerConfigJSON{} newconfig := dhcpServerConfigJSON{}
err := json.NewDecoder(r.Body).Decode(&newconfig) err := json.NewDecoder(r.Body).Decode(&newconfig)
if err != nil { if err != nil {
@ -116,7 +114,6 @@ func handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
} }
func handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) { func handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
response := map[string]interface{}{} response := map[string]interface{}{}
ifaces, err := getValidNetInterfaces() ifaces, err := getValidNetInterfaces()
@ -181,7 +178,6 @@ func handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) {
// . Check if a static IP is configured for the network interface // . Check if a static IP is configured for the network interface
// Respond with results // Respond with results
func handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Request) { func handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
errorText := fmt.Sprintf("failed to read request body: %s", err) errorText := fmt.Sprintf("failed to read request body: %s", err)
@ -366,7 +362,6 @@ func setStaticIP(ifaceName string) error {
} }
func handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request) { func handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
lj := leaseJSON{} lj := leaseJSON{}
err := json.NewDecoder(r.Body).Decode(&lj) err := json.NewDecoder(r.Body).Decode(&lj)
@ -397,7 +392,6 @@ func handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request) {
} }
func handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Request) { func handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
lj := leaseJSON{} lj := leaseJSON{}
err := json.NewDecoder(r.Body).Decode(&lj) err := json.NewDecoder(r.Body).Decode(&lj)

View File

@ -14,7 +14,6 @@ type rewriteEntryJSON struct {
} }
func handleRewriteList(w http.ResponseWriter, r *http.Request) { func handleRewriteList(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
arr := []*rewriteEntryJSON{} arr := []*rewriteEntryJSON{}
@ -37,7 +36,6 @@ func handleRewriteList(w http.ResponseWriter, r *http.Request) {
} }
func handleRewriteAdd(w http.ResponseWriter, r *http.Request) { func handleRewriteAdd(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
jsent := rewriteEntryJSON{} jsent := rewriteEntryJSON{}
err := json.NewDecoder(r.Body).Decode(&jsent) err := json.NewDecoder(r.Body).Decode(&jsent)
@ -66,7 +64,6 @@ func handleRewriteAdd(w http.ResponseWriter, r *http.Request) {
} }
func handleRewriteDelete(w http.ResponseWriter, r *http.Request) { func handleRewriteDelete(w http.ResponseWriter, r *http.Request) {
log.Tracef("%s %v", r.Method, r.URL)
jsent := rewriteEntryJSON{} jsent := rewriteEntryJSON{}
err := json.NewDecoder(r.Body).Decode(&jsent) err := json.NewDecoder(r.Body).Decode(&jsent)
@ -101,7 +98,7 @@ func handleRewriteDelete(w http.ResponseWriter, r *http.Request) {
} }
func registerRewritesHandlers() { func registerRewritesHandlers() {
http.HandleFunc("/control/rewrite/list", postInstall(optionalAuth(ensureGET(handleRewriteList)))) httpRegister(http.MethodGet, "/control/rewrite/list", handleRewriteList)
http.HandleFunc("/control/rewrite/add", postInstall(optionalAuth(ensurePOST(handleRewriteAdd)))) httpRegister(http.MethodPost, "/control/rewrite/add", handleRewriteAdd)
http.HandleFunc("/control/rewrite/delete", postInstall(optionalAuth(ensurePOST(handleRewriteDelete)))) httpRegister(http.MethodPost, "/control/rewrite/delete", handleRewriteDelete)
} }

View File

@ -29,6 +29,8 @@ import (
// ---------------------------------- // ----------------------------------
func ensure(method string, handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) { func ensure(method string, handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
log.Debug("%s %v", r.Method, r.URL)
if r.Method != method { if r.Method != method {
http.Error(w, "This request must be "+method, http.StatusMethodNotAllowed) http.Error(w, "This request must be "+method, http.StatusMethodNotAllowed)
return return
@ -60,9 +62,9 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.handler(w, r) h.handler(w, r)
} }
func ensureGETHandler(handler func(http.ResponseWriter, *http.Request)) http.Handler { func ensureHandler(method string, handler func(http.ResponseWriter, *http.Request)) http.Handler {
h := httpHandler{} h := httpHandler{}
h.handler = ensure("GET", handler) h.handler = ensure(method, handler)
return &h return &h
} }