summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--_www/index.html67
-rw-r--r--_www/rescached.js30
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--httpd.go41
5 files changed, 128 insertions, 16 deletions
diff --git a/_www/index.html b/_www/index.html
index 3403751..aea85e5 100644
--- a/_www/index.html
+++ b/_www/index.html
@@ -12,6 +12,18 @@
padding: 1em 0px;
border-bottom: 1px solid silver;
}
+ #summary {
+ margin: 1em 0;
+ }
+ #caches {
+ height: 20em;
+ overflow: auto;
+ font-family: monospace;
+ }
+ .QType {
+ width: 3em;
+ display: inline-block;
+ }
.rr {
margin-left: 1em;
width: 100%;
@@ -37,7 +49,7 @@
}
</style>
</head>
- <body>
+ <body onload="main()">
<nav class="menu">
<a href="/" class="active"> rescached </a>
/
@@ -57,10 +69,42 @@
<div id="result"></div>
<div id="notif"></div>
+ <div id="summary"></div>
+ <div id="caches"></div>
+
<script src="/index.js"></script>
<script src="/rescached.js"></script>
<script>
- const resc = new Rescached("")
+ let resc = null
+ let cachePoller = null
+ let dateFmt = new Intl.DateTimeFormat(undefined, {
+ year: "numeric",
+ month: "numeric",
+ day: "numeric",
+ hour: "numeric",
+ minute: "numeric",
+ second: "numeric",
+ })
+
+ async function main() {
+ resc = new Rescached("")
+ const res = await resc.Caches()
+ if (res.code != 200) {
+ notifError(`doSearch ${query}: ${res.message}`)
+ return
+ }
+ renderCaches(res.data)
+ cachePoller = setInterval(pollCaches, 10000)
+ }
+
+ async function pollCaches() {
+ const res = await resc.Caches()
+ if (res.code != 200) {
+ notifError(`doSearch ${query}: ${res.message}`)
+ return
+ }
+ renderCaches(res.data)
+ }
async function doSearch() {
const query = document.getElementsByName("query")[0].value
@@ -110,6 +154,25 @@
}
}
+ function renderCaches(answers) {
+ document.getElementById("summary").innerHTML = `
+ Total caches: ${answers.length}
+ `
+ let w = document.getElementById("caches")
+ let out = `
+ `
+ for (let x = answers.length - 1; x >= 0; x--) {
+ let answer = answers[x]
+ out += `
+ <div class="cache">
+ <span class="AccessedAt">${dateFmt.format(new Date(answer.AccessedAt * 1000))}</span>
+ <span class="QType">${resc.GetRRTypeName(answer.QType)}</span>
+ <span class="QName">${answer.QName}</span>
+ </div>`
+ }
+ w.innerHTML = out
+ }
+
function renderRR(listRR, title) {
let innerHTML = ""
diff --git a/_www/rescached.js b/_www/rescached.js
index 5610e4e..1b76331 100644
--- a/_www/rescached.js
+++ b/_www/rescached.js
@@ -30,6 +30,8 @@ function getRRTypeName(k) {
class Rescached {
static nanoSeconds = 1000000000
+ static apiCaches = "/api/caches"
+ static apiCachesSearch = "/api/caches/search"
static apiHostsd = "/api/hosts.d/"
static apiZoned = "/api/zone.d/"
@@ -38,6 +40,26 @@ class Rescached {
this.env = {}
}
+ async Caches() {
+ const res = await fetch(this.server + Rescached.apiCaches, {
+ headers: {
+ Connection: "keep-alive",
+ },
+ })
+ return await res.json()
+ }
+
+ async Search(query) {
+ console.log("Search: ", query)
+ const res = await fetch(
+ this.server +
+ Rescached.apiCachesSearch +
+ "?query=" +
+ query,
+ )
+ return await res.json()
+ }
+
async HostsFileCreate(name) {
const httpRes = await fetch(
this.server + Rescached.apiHostsd + name,
@@ -55,14 +77,6 @@ class Rescached {
return res
}
- async Search(query) {
- console.log("Search: ", query)
- const res = await fetch(
- this.server + "/api/caches" + "?query=" + query,
- )
- return await res.json()
- }
-
async getEnvironment() {
const httpRes = await fetch(this.server + "/api/environment")
const res = await httpRes.json()
diff --git a/go.mod b/go.mod
index 2c383a0..669d368 100644
--- a/go.mod
+++ b/go.mod
@@ -2,6 +2,6 @@ module github.com/shuLhan/rescached-go/v3
go 1.14
-require github.com/shuLhan/share v0.22.1-0.20210119183627-da9256c28c9c
+require github.com/shuLhan/share v0.22.1-0.20210121194620-62d4a5af43bb
//replace github.com/shuLhan/share => ../share
diff --git a/go.sum b/go.sum
index 4bebf00..91e46fe 100644
--- a/go.sum
+++ b/go.sum
@@ -6,8 +6,8 @@ github.com/shuLhan/share v0.20.2-0.20201122173411-e8b3bf5ee6e9/go.mod h1:oBv+CGH
github.com/shuLhan/share v0.20.2-0.20201205202022-66069b9e49fe/go.mod h1:oBv+CGHG6u4Sa71+nJJJji8mCgPAadywjsB3I3k/b0o=
github.com/shuLhan/share v0.22.1-0.20210109185915-0490a19341d9 h1:Kqmfgkwq5dn68epHLBmPVkkLRDk3XFftqO/o3X84Mqg=
github.com/shuLhan/share v0.22.1-0.20210109185915-0490a19341d9/go.mod h1:u9caerexlcxmPVDttj7PnkxCBDY6yBRTZ+gGR+1tO98=
-github.com/shuLhan/share v0.22.1-0.20210119183627-da9256c28c9c h1:LrwXdGkzOKcszqS+IX9SQ94l8p6eAzcaml5ZFfW/Mz4=
-github.com/shuLhan/share v0.22.1-0.20210119183627-da9256c28c9c/go.mod h1:y4+p5vUmKNNhMMhU6yGgE6QxTgJxA4nv6OOq+cIf7wU=
+github.com/shuLhan/share v0.22.1-0.20210121194620-62d4a5af43bb h1:XNl502ViCu+DzO6lAONT/bJDCe1Qik3DrRVW8PHcYVM=
+github.com/shuLhan/share v0.22.1-0.20210121194620-62d4a5af43bb/go.mod h1:y4+p5vUmKNNhMMhU6yGgE6QxTgJxA4nv6OOq+cIf7wU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
diff --git a/httpd.go b/httpd.go
index 149326f..2c2b85e 100644
--- a/httpd.go
+++ b/httpd.go
@@ -33,6 +33,7 @@ const (
paramNameType = "type"
paramNameValue = "value"
apiCaches = "/api/caches"
+ apiCachesSearch = "/api/caches/search"
apiEnvironment = "/api/environment"
apiHostsBlock = "/api/hosts_block"
apiHostsDir = "/api/hosts.d/:name"
@@ -60,7 +61,7 @@ func (srv *Server) httpdInit() (err error) {
`.*\.js`,
`.*\.png`,
},
- Development: srv.env.Debug >= 3,
+ Development: srv.env.Debug >= 2,
},
Memfs: memFS,
Address: srv.env.WUIListen,
@@ -91,11 +92,23 @@ func (srv *Server) httpdRegisterEndpoints() (err error) {
Path: apiCaches,
RequestType: libhttp.RequestTypeQuery,
ResponseType: libhttp.ResponseTypeJSON,
- Call: srv.httpdAPIGetCaches,
+ Call: srv.apiCaches,
})
if err != nil {
return err
}
+
+ err = srv.httpd.RegisterEndpoint(&libhttp.Endpoint{
+ Method: libhttp.RequestMethodGet,
+ Path: apiCachesSearch,
+ RequestType: libhttp.RequestTypeQuery,
+ ResponseType: libhttp.ResponseTypeJSON,
+ Call: srv.apiCachesSearch,
+ })
+ if err != nil {
+ return err
+ }
+
err = srv.httpd.RegisterEndpoint(&libhttp.Endpoint{
Method: libhttp.RequestMethodDelete,
Path: apiCaches,
@@ -262,7 +275,23 @@ func (srv *Server) httpdRun() {
}
}
-func (srv *Server) httpdAPIGetCaches(
+func (srv *Server) apiCaches(
+ _ http.ResponseWriter, req *http.Request, _ []byte,
+) (
+ resBody []byte, err error,
+) {
+ res := response{}
+ res.Code = http.StatusOK
+ answers := srv.dns.CachesLRU()
+ if len(answers) == 0 {
+ res.Data = make([]struct{}, 0, 1)
+ } else {
+ res.Data = answers
+ }
+ return json.Marshal(res)
+}
+
+func (srv *Server) apiCachesSearch(
_ http.ResponseWriter, req *http.Request, _ []byte,
) (
resBody []byte, err error,
@@ -275,6 +304,12 @@ func (srv *Server) httpdAPIGetCaches(
q := req.Form.Get(paramNameQuery)
+ if len(q) == 0 {
+ res.Code = http.StatusOK
+ res.Data = make([]struct{}, 0, 1)
+ return json.Marshal(res)
+ }
+
re, err := regexp.Compile(q)
if err != nil {
res.Message = err.Error()