mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-19 01:05:37 +03:00
commit
a3127bed5f
5 changed files with 170 additions and 0 deletions
|
@ -62,6 +62,7 @@ var directiveOrder = []directive{
|
||||||
{"basicauth", setup.BasicAuth},
|
{"basicauth", setup.BasicAuth},
|
||||||
{"internal", setup.Internal},
|
{"internal", setup.Internal},
|
||||||
{"pprof", setup.PProf},
|
{"pprof", setup.PProf},
|
||||||
|
{"expvar", setup.ExpVar},
|
||||||
{"proxy", setup.Proxy},
|
{"proxy", setup.Proxy},
|
||||||
{"fastcgi", setup.FastCGI},
|
{"fastcgi", setup.FastCGI},
|
||||||
{"websocket", setup.WebSocket},
|
{"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 a new issue