mirror of
https://github.com/caddyserver/caddy.git
synced 2024-11-26 02:09:47 +08:00
commit
a3127bed5f
|
@ -62,6 +62,7 @@ var directiveOrder = []directive{
|
|||
{"basicauth", setup.BasicAuth},
|
||||
{"internal", setup.Internal},
|
||||
{"pprof", setup.PProf},
|
||||
{"expvar", setup.ExpVar},
|
||||
{"proxy", setup.Proxy},
|
||||
{"fastcgi", setup.FastCGI},
|
||||
{"websocket", setup.WebSocket},
|
||||
|
|
41
caddy/setup/expvar.go
Normal file
41
caddy/setup/expvar.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package setup
|
||||
|
||||
import (
|
||||
_ "expvar"
|
||||
|
||||
"github.com/mholt/caddy/middleware"
|
||||
"github.com/mholt/caddy/middleware/expvar"
|
||||
)
|
||||
|
||||
// ExpVar configures a new ExpVar middleware instance.
|
||||
func ExpVar(c *Controller) (middleware.Middleware, error) {
|
||||
resource, err := expVarParse(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
expvar := expvar.ExpVar{Resource: resource}
|
||||
|
||||
return func(next middleware.Handler) middleware.Handler {
|
||||
expvar.Next = next
|
||||
return expvar
|
||||
}, nil
|
||||
}
|
||||
|
||||
func expVarParse(c *Controller) (expvar.Resource, error) {
|
||||
var resource expvar.Resource
|
||||
|
||||
var err error
|
||||
for c.Next() {
|
||||
args := c.RemainingArgs()
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
resource = expvar.Resource(args[0])
|
||||
default:
|
||||
return resource, c.ArgErr()
|
||||
}
|
||||
}
|
||||
|
||||
return resource, err
|
||||
}
|
36
caddy/setup/expvar_test.go
Normal file
36
caddy/setup/expvar_test.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package setup
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mholt/caddy/middleware/expvar"
|
||||
)
|
||||
|
||||
func TestExpvar(t *testing.T) {
|
||||
c := NewTestController(`expvar /d/v`)
|
||||
|
||||
mid, err := ExpVar(c)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no errors, got: %v", err)
|
||||
}
|
||||
|
||||
if mid == nil {
|
||||
t.Fatal("Expected middleware, was nil instead")
|
||||
}
|
||||
|
||||
handler := mid(EmptyNext)
|
||||
myHandler, ok := handler.(expvar.ExpVar)
|
||||
|
||||
if !ok {
|
||||
t.Fatalf("Expected handler to be type ExpVar, got: %#v", handler)
|
||||
}
|
||||
|
||||
if myHandler.Resource != "/d/v" {
|
||||
t.Errorf("Expected /d/v as expvar resource")
|
||||
}
|
||||
|
||||
if !SameNext(myHandler.Next, EmptyNext) {
|
||||
t.Error("'Next' field of handler was not set properly")
|
||||
}
|
||||
}
|
46
middleware/expvar/expvar.go
Normal file
46
middleware/expvar/expvar.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package expvar
|
||||
|
||||
import (
|
||||
"expvar"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/mholt/caddy/middleware"
|
||||
)
|
||||
|
||||
// ExpVar is a simple struct to hold expvar's configuration
|
||||
type ExpVar struct {
|
||||
Next middleware.Handler
|
||||
Resource Resource
|
||||
}
|
||||
|
||||
// ServeHTTP handles requests to expvar's configured entry point with
|
||||
// expvar, or passes all other requests up the chain.
|
||||
func (e ExpVar) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
if middleware.Path(r.URL.Path).Matches(string(e.Resource)) {
|
||||
expvarHandler(w, r)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return e.Next.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// expvarHandler returns a JSON object will all the published variables.
|
||||
//
|
||||
// This is lifted straight from the expvar package.
|
||||
func expvarHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
fmt.Fprintf(w, "{\n")
|
||||
first := true
|
||||
expvar.Do(func(kv expvar.KeyValue) {
|
||||
if !first {
|
||||
fmt.Fprintf(w, ",\n")
|
||||
}
|
||||
first = false
|
||||
fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value)
|
||||
})
|
||||
fmt.Fprintf(w, "\n}\n")
|
||||
}
|
||||
|
||||
// Resource contains the path to the expvar entry point
|
||||
type Resource string
|
46
middleware/expvar/expvar_test.go
Normal file
46
middleware/expvar/expvar_test.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package expvar
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/mholt/caddy/middleware"
|
||||
)
|
||||
|
||||
func TestExpVar(t *testing.T) {
|
||||
rw := ExpVar{
|
||||
Next: middleware.HandlerFunc(contentHandler),
|
||||
Resource: "/d/v",
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
from string
|
||||
result int
|
||||
}{
|
||||
{"/d/v", 0},
|
||||
{"/x/y", http.StatusOK},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
req, err := http.NewRequest("GET", test.from, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: Could not create HTTP request %v", i, err)
|
||||
}
|
||||
rec := httptest.NewRecorder()
|
||||
result, err := rw.ServeHTTP(rec, req)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: Could not ServeHTTP %v", i, err)
|
||||
}
|
||||
if result != test.result {
|
||||
t.Errorf("Test %d: Expected Header '%d' but was '%d'",
|
||||
i, test.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func contentHandler(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
fmt.Fprintf(w, r.URL.String())
|
||||
return http.StatusOK, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user