aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md10
-rw-r--r--http/http.go10
-rw-r--r--http/http_test.go32
3 files changed, 48 insertions, 4 deletions
diff --git a/README.md b/README.md
index fc2ae51..4aeb9d6 100644
--- a/README.md
+++ b/README.md
@@ -69,6 +69,7 @@ served by the built-in web server, which can be enabled in `zdnsrc`.
### Examples
+Read the log:
```shell
$ curl -s 'http://127.0.0.1:8053/log/v1/?n=1' | jq .
[
@@ -86,6 +87,7 @@ $ curl -s 'http://127.0.0.1:8053/log/v1/?n=1' | jq .
]
```
+Read the cache:
```shell
$ curl -s 'http://127.0.0.1:8053/cache/v1/?n=1' | jq .
[
@@ -109,6 +111,14 @@ $ curl -s 'http://127.0.0.1:8053/cache/v1/?n=1' | jq .
]
```
+Clear the cache:
+```shell
+$ curl -s -XDELETE 'http://127.0.0.1:8053/cache/v1/' | jq .
+{
+ "message": "Cleared cache"
+}
+```
+
## Port redirection
Most operating systems expect to find their DNS resolver on UDP port 53.
diff --git a/http/http.go b/http/http.go
index 98e6616..8ab4101 100644
--- a/http/http.go
+++ b/http/http.go
@@ -53,6 +53,7 @@ func (s *Server) handler() http.Handler {
r := newRouter()
r.route("GET", "/cache/v1/", s.cacheHandler)
r.route("GET", "/log/v1/", s.logHandler)
+ r.route("DELETE", "/cache/v1/", s.cacheResetHandler)
return r.handler()
}
@@ -82,6 +83,15 @@ func (s *Server) cacheHandler(w http.ResponseWriter, r *http.Request) (interface
return entries, nil
}
+func (s *Server) cacheResetHandler(w http.ResponseWriter, r *http.Request) (interface{}, *httpError) {
+ s.cache.Reset()
+ return struct {
+ Message string `json:"message"`
+ }{
+ "Cleared cache",
+ }, nil
+}
+
func (s *Server) logHandler(w http.ResponseWriter, r *http.Request) (interface{}, *httpError) {
logEntries, err := s.logger.Get(listCountFrom(r))
if err != nil {
diff --git a/http/http_test.go b/http/http_test.go
index bdeb213..2c1a6ae 100644
--- a/http/http_test.go
+++ b/http/http_test.go
@@ -52,6 +52,27 @@ func httpGet(url string) (*http.Response, string, error) {
return res, string(data), nil
}
+func httpRequest(method, url, body string) (*http.Response, string, error) {
+ r, err := http.NewRequest(method, url, strings.NewReader(body))
+ if err != nil {
+ return nil, "", err
+ }
+ res, err := http.DefaultClient.Do(r)
+ if err != nil {
+ return nil, "", err
+ }
+ defer res.Body.Close()
+ data, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, "", err
+ }
+ return res, string(data), nil
+}
+
+func httpDelete(url, body string) (*http.Response, string, error) {
+ return httpRequest(http.MethodDelete, url, body)
+}
+
func TestRequests(t *testing.T) {
httpSrv, srv := testServer()
defer httpSrv.Close()
@@ -80,28 +101,31 @@ func TestRequests(t *testing.T) {
{http.MethodGet, "/cache/v1/", cr1, 200},
{http.MethodGet, "/cache/v1/?n=foo", cr1, 200},
{http.MethodGet, "/cache/v1/?n=1", cr2, 200},
+ {http.MethodDelete, "/cache/v1/", `{"message":"Cleared cache"}`, 200},
}
for i, tt := range tests {
var (
- resp *http.Response
+ res *http.Response
data string
err error
)
switch tt.method {
case http.MethodGet:
- resp, data, err = httpGet(httpSrv.URL + tt.url)
+ res, data, err = httpGet(httpSrv.URL + tt.url)
+ case http.MethodDelete:
+ res, data, err = httpDelete(httpSrv.URL+tt.url, "")
default:
t.Fatalf("#%d: invalid method: %s", i, tt.method)
}
if err != nil {
t.Fatal(err)
}
- if got := resp.StatusCode; got != tt.status {
+ if got := res.StatusCode; got != tt.status {
t.Errorf("#%d: %s %s returned status %d, want %d", i, tt.method, tt.url, got, tt.status)
}
- if got, want := resp.Header.Get("Content-Type"), "application/json"; got != want {
+ if got, want := res.Header.Get("Content-Type"), "application/json"; got != want {
t.Errorf("#%d: got Content-Type %q, want %q", i, got, want)
}