Pull request: imp-json-resp

Merge in DNS/adguard-home from imp-json-resp to master

Squashed commit of the following:

commit 44532b6fa551815e5ea876e7320ce0a73c32b6fb
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Sep 30 15:59:58 2022 +0300

    all: imp json resp
This commit is contained in:
Ainar Garipov 2022-10-04 14:35:10 +03:00
parent bf792b83f6
commit c26ab190e7
10 changed files with 35 additions and 140 deletions

View file

@ -62,9 +62,16 @@ func WriteTextPlainDeprecated(w http.ResponseWriter, r *http.Request) (isPlainTe
} }
// WriteJSONResponse sets the content-type header in w.Header() to // WriteJSONResponse sets the content-type header in w.Header() to
// "application/json", encodes resp to w, calls Error on any returned error, and // "application/json", writes a header with a "200 OK" status, encodes resp to
// returns it as well. // w, calls [Error] on any returned error, and returns it as well.
func WriteJSONResponse(w http.ResponseWriter, r *http.Request, resp any) (err error) { func WriteJSONResponse(w http.ResponseWriter, r *http.Request, resp any) (err error) {
return WriteJSONResponseCode(w, r, http.StatusOK, resp)
}
// WriteJSONResponseCode is like [WriteJSONResponse] but adds the ability to
// redefine the status code.
func WriteJSONResponseCode(w http.ResponseWriter, r *http.Request, code int, resp any) (err error) {
w.WriteHeader(code)
w.Header().Set(HdrNameContentType, HdrValApplicationJSON) w.Header().Set(HdrNameContentType, HdrValApplicationJSON)
err = json.NewEncoder(w).Encode(resp) err = json.NewEncoder(w).Encode(resp)
if err != nil { if err != nil {

View file

@ -78,18 +78,7 @@ func (s *server) handleDHCPStatus(w http.ResponseWriter, r *http.Request) {
status.Leases = s.Leases(LeasesDynamic) status.Leases = s.Leases(LeasesDynamic)
status.StaticLeases = s.Leases(LeasesStatic) status.StaticLeases = s.Leases(LeasesStatic)
w.Header().Set("Content-Type", "application/json") _ = aghhttp.WriteJSONResponse(w, r, status)
err := json.NewEncoder(w).Encode(status)
if err != nil {
aghhttp.Error(
r,
w,
http.StatusInternalServerError,
"Unable to marshal DHCP status json: %s",
err,
)
}
} }
func (s *server) enableDHCP(ifaceName string) (code int, err error) { func (s *server) enableDHCP(ifaceName string) (code int, err error) {

View file

@ -3,11 +3,10 @@
package dhcpd package dhcpd
import ( import (
"encoding/json"
"net/http" "net/http"
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
"github.com/AdguardTeam/AdGuardHome/internal/aghos" "github.com/AdguardTeam/AdGuardHome/internal/aghos"
"github.com/AdguardTeam/golibs/log"
) )
// jsonError is a generic JSON error response. // jsonError is a generic JSON error response.
@ -25,15 +24,9 @@ type jsonError struct {
// TODO(a.garipov): Either take the logger from the server after we've // TODO(a.garipov): Either take the logger from the server after we've
// refactored logging or make this not a method of *Server. // refactored logging or make this not a method of *Server.
func (s *server) notImplemented(w http.ResponseWriter, r *http.Request) { func (s *server) notImplemented(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") _ = aghhttp.WriteJSONResponseCode(w, r, http.StatusNotImplemented, &jsonError{
w.WriteHeader(http.StatusNotImplemented)
err := json.NewEncoder(w).Encode(&jsonError{
Message: aghos.Unsupported("dhcp").Error(), Message: aghos.Unsupported("dhcp").Error(),
}) })
if err != nil {
log.Debug("writing 501 json response: %s", err)
}
} }
// registerHandlers sets the handlers for DHCP HTTP API that always respond with // registerHandlers sets the handlers for DHCP HTTP API that always respond with

View file

@ -453,13 +453,7 @@ func (d *DNSFilter) ApplyBlockedServices(setts *Settings, list []string) {
} }
func (d *DNSFilter) handleBlockedServicesAvailableServices(w http.ResponseWriter, r *http.Request) { func (d *DNSFilter) handleBlockedServicesAvailableServices(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") _ = aghhttp.WriteJSONResponse(w, r, serviceIDs)
err := json.NewEncoder(w).Encode(serviceIDs)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "encoding available services: %s", err)
return
}
} }
func (d *DNSFilter) handleBlockedServicesList(w http.ResponseWriter, r *http.Request) { func (d *DNSFilter) handleBlockedServicesList(w http.ResponseWriter, r *http.Request) {
@ -467,13 +461,7 @@ func (d *DNSFilter) handleBlockedServicesList(w http.ResponseWriter, r *http.Req
list := d.Config.BlockedServices list := d.Config.BlockedServices
d.confLock.RUnlock() d.confLock.RUnlock()
w.Header().Set("Content-Type", "application/json") _ = aghhttp.WriteJSONResponse(w, r, list)
err := json.NewEncoder(w).Encode(list)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "encoding services: %s", err)
return
}
} }
func (d *DNSFilter) handleBlockedServicesSet(w http.ResponseWriter, r *http.Request) { func (d *DNSFilter) handleBlockedServicesSet(w http.ResponseWriter, r *http.Request) {

View file

@ -301,14 +301,7 @@ func (d *DNSFilter) handleFilteringRefresh(w http.ResponseWriter, r *http.Reques
return return
} }
w.Header().Set("Content-Type", "application/json") _ = aghhttp.WriteJSONResponse(w, r, resp)
err = json.NewEncoder(w).Encode(resp)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "json encode: %s", err)
return
}
} }
type filterJSON struct { type filterJSON struct {
@ -361,17 +354,7 @@ func (d *DNSFilter) handleFilteringStatus(w http.ResponseWriter, r *http.Request
resp.UserRules = d.UserRules resp.UserRules = d.UserRules
d.filtersMu.RUnlock() d.filtersMu.RUnlock()
jsonVal, err := json.Marshal(resp) _ = aghhttp.WriteJSONResponse(w, r, resp)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "json encode: %s", err)
return
}
w.Header().Set("Content-Type", "application/json")
_, err = w.Write(jsonVal)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "http write: %s", err)
}
} }
// Set filtering configuration // Set filtering configuration
@ -473,11 +456,7 @@ func (d *DNSFilter) handleCheckHost(w http.ResponseWriter, r *http.Request) {
} }
} }
w.Header().Set("Content-Type", "application/json") _ = aghhttp.WriteJSONResponse(w, r, resp)
err = json.NewEncoder(w).Encode(resp)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "encoding response: %s", err)
}
} }
// RegisterFilteringHandlers - register handlers // RegisterFilteringHandlers - register handlers

View file

@ -240,13 +240,7 @@ func (d *DNSFilter) handleRewriteList(w http.ResponseWriter, r *http.Request) {
} }
d.confLock.Unlock() d.confLock.Unlock()
w.Header().Set("Content-Type", "application/json") _ = aghhttp.WriteJSONResponse(w, r, arr)
err := json.NewEncoder(w).Encode(arr)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "json.Encode: %s", err)
return
}
} }
func (d *DNSFilter) handleRewriteAdd(w http.ResponseWriter, r *http.Request) { func (d *DNSFilter) handleRewriteAdd(w http.ResponseWriter, r *http.Request) {

View file

@ -5,7 +5,6 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"encoding/json"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
@ -381,17 +380,13 @@ func (d *DNSFilter) handleSafeBrowsingDisable(w http.ResponseWriter, r *http.Req
} }
func (d *DNSFilter) handleSafeBrowsingStatus(w http.ResponseWriter, r *http.Request) { func (d *DNSFilter) handleSafeBrowsingStatus(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") resp := &struct {
err := json.NewEncoder(w).Encode(&struct {
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
}{ }{
Enabled: d.Config.SafeBrowsingEnabled, Enabled: d.Config.SafeBrowsingEnabled,
})
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "Unable to write response json: %s", err)
return
} }
_ = aghhttp.WriteJSONResponse(w, r, resp)
} }
func (d *DNSFilter) handleParentalEnable(w http.ResponseWriter, r *http.Request) { func (d *DNSFilter) handleParentalEnable(w http.ResponseWriter, r *http.Request) {
@ -405,13 +400,11 @@ func (d *DNSFilter) handleParentalDisable(w http.ResponseWriter, r *http.Request
} }
func (d *DNSFilter) handleParentalStatus(w http.ResponseWriter, r *http.Request) { func (d *DNSFilter) handleParentalStatus(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") resp := &struct {
err := json.NewEncoder(w).Encode(&struct {
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
}{ }{
Enabled: d.Config.ParentalEnabled, Enabled: d.Config.ParentalEnabled,
})
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "Unable to write response json: %s", err)
} }
_ = aghhttp.WriteJSONResponse(w, r, resp)
} }

View file

@ -5,7 +5,6 @@ import (
"context" "context"
"encoding/binary" "encoding/binary"
"encoding/gob" "encoding/gob"
"encoding/json"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
@ -146,21 +145,13 @@ func (d *DNSFilter) handleSafeSearchDisable(w http.ResponseWriter, r *http.Reque
} }
func (d *DNSFilter) handleSafeSearchStatus(w http.ResponseWriter, r *http.Request) { func (d *DNSFilter) handleSafeSearchStatus(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") resp := &struct {
err := json.NewEncoder(w).Encode(&struct {
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
}{ }{
Enabled: d.Config.SafeSearchEnabled, Enabled: d.Config.SafeSearchEnabled,
})
if err != nil {
aghhttp.Error(
r,
w,
http.StatusInternalServerError,
"Unable to write response json: %s",
err,
)
} }
_ = aghhttp.WriteJSONResponse(w, r, resp)
} }
var safeSearchDomains = map[string]string{ var safeSearchDomains = map[string]string{

View file

@ -1,7 +1,6 @@
package querylog package querylog
import ( import (
"encoding/json"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
@ -48,24 +47,7 @@ func (l *queryLog) handleQueryLog(w http.ResponseWriter, r *http.Request) {
// convert log entries to JSON // convert log entries to JSON
data := l.entriesToJSON(entries, oldest) data := l.entriesToJSON(entries, oldest)
jsonVal, err := json.Marshal(data) _ = aghhttp.WriteJSONResponse(w, r, data)
if err != nil {
aghhttp.Error(
r,
w,
http.StatusInternalServerError,
"Couldn't marshal data into json: %s",
err,
)
return
}
w.Header().Set("Content-Type", "application/json")
_, err = w.Write(jsonVal)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "Unable to write response json: %s", err)
}
} }
func (l *queryLog) handleQueryLogClear(_ http.ResponseWriter, _ *http.Request) { func (l *queryLog) handleQueryLogClear(_ http.ResponseWriter, _ *http.Request) {
@ -74,23 +56,13 @@ func (l *queryLog) handleQueryLogClear(_ http.ResponseWriter, _ *http.Request) {
// Get configuration // Get configuration
func (l *queryLog) handleQueryLogInfo(w http.ResponseWriter, r *http.Request) { func (l *queryLog) handleQueryLogInfo(w http.ResponseWriter, r *http.Request) {
resp := qlogConfig{} resp := qlogConfig{
resp.Enabled = l.conf.Enabled Enabled: l.conf.Enabled,
resp.Interval = l.conf.RotationIvl.Hours() / 24 Interval: l.conf.RotationIvl.Hours() / 24,
resp.AnonymizeClientIP = l.conf.AnonymizeClientIP AnonymizeClientIP: l.conf.AnonymizeClientIP,
jsonVal, err := json.Marshal(resp)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "json encode: %s", err)
return
} }
w.Header().Set("Content-Type", "application/json") _ = aghhttp.WriteJSONResponse(w, r, resp)
_, err = w.Write(jsonVal)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "http write: %s", err)
}
} }
// AnonymizeIP masks ip to anonymize the client if the ip is a valid one. // AnonymizeIP masks ip to anonymize the client if the ip is a valid one.

View file

@ -55,12 +55,7 @@ func (s *StatsCtx) handleStats(w http.ResponseWriter, r *http.Request) {
return return
} }
w.Header().Set("Content-Type", "application/json") _ = aghhttp.WriteJSONResponse(w, r, resp)
err := json.NewEncoder(w).Encode(resp)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "json encode: %s", err)
}
} }
// configResp is the response to the GET /control/stats_info. // configResp is the response to the GET /control/stats_info.
@ -71,13 +66,7 @@ type configResp struct {
// handleStatsInfo handles requests to the GET /control/stats_info endpoint. // handleStatsInfo handles requests to the GET /control/stats_info endpoint.
func (s *StatsCtx) handleStatsInfo(w http.ResponseWriter, r *http.Request) { func (s *StatsCtx) handleStatsInfo(w http.ResponseWriter, r *http.Request) {
resp := configResp{IntervalDays: atomic.LoadUint32(&s.limitHours) / 24} resp := configResp{IntervalDays: atomic.LoadUint32(&s.limitHours) / 24}
_ = aghhttp.WriteJSONResponse(w, r, resp)
w.Header().Set("Content-Type", "application/json")
err := json.NewEncoder(w).Encode(resp)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "json encode: %s", err)
}
} }
// handleStatsConfig handles requests to the POST /control/stats_config // handleStatsConfig handles requests to the POST /control/stats_config