Browse Source

Merge pull request #1110 from bcwaldon/proxy-readonly

Readonly proxy mode
Brian Waldon 11 years ago
parent
commit
6449387ccb
3 changed files with 64 additions and 2 deletions
  1. 9 2
      main.go
  2. 16 0
      proxy/proxy.go
  3. 39 0
      proxy/proxy_test.go

+ 9 - 2
main.go

@@ -25,8 +25,9 @@ const (
 	// the owner can make/remove files inside the directory
 	// the owner can make/remove files inside the directory
 	privateDirMode = 0700
 	privateDirMode = 0700
 
 
-	proxyFlagValueOff = "off"
-	proxyFlagValueOn  = "on"
+	proxyFlagValueOff      = "off"
+	proxyFlagValueReadonly = "readonly"
+	proxyFlagValueOn       = "on"
 )
 )
 
 
 var (
 var (
@@ -42,6 +43,7 @@ var (
 
 
 	proxyFlagValues = []string{
 	proxyFlagValues = []string{
 		proxyFlagValueOff,
 		proxyFlagValueOff,
+		proxyFlagValueReadonly,
 		proxyFlagValueOn,
 		proxyFlagValueOn,
 	}
 	}
 )
 )
@@ -178,6 +180,11 @@ func startProxy() {
 	if err != nil {
 	if err != nil {
 		log.Fatal(err)
 		log.Fatal(err)
 	}
 	}
+
+	if string(*proxyFlag) == proxyFlagValueReadonly {
+		ph = proxy.NewReadonlyHandler(ph)
+	}
+
 	// Start a proxy server goroutine for each listen address
 	// Start a proxy server goroutine for each listen address
 	for _, addr := range *addrs {
 	for _, addr := range *addrs {
 		addr := addr
 		addr := addr

+ 16 - 0
proxy/proxy.go

@@ -31,3 +31,19 @@ func NewHandler(endpoints []string) (http.Handler, error) {
 
 
 	return &rp, nil
 	return &rp, nil
 }
 }
+
+func readonlyHandlerFunc(next http.Handler) func(http.ResponseWriter, *http.Request) {
+	return func(w http.ResponseWriter, req *http.Request) {
+		if req.Method != "GET" {
+			w.WriteHeader(http.StatusNotImplemented)
+			return
+		}
+
+		next.ServeHTTP(w, req)
+	}
+}
+
+func NewReadonlyHandler(hdlr http.Handler) http.Handler {
+	readonly := readonlyHandlerFunc(hdlr)
+	return http.HandlerFunc(readonly)
+}

+ 39 - 0
proxy/proxy_test.go

@@ -0,0 +1,39 @@
+package proxy
+
+import (
+	"net/http"
+	"net/http/httptest"
+	"testing"
+)
+
+func TestReadonlyHandler(t *testing.T) {
+	fixture := func(w http.ResponseWriter, req *http.Request) {
+		w.WriteHeader(http.StatusOK)
+	}
+	hdlrFunc := readonlyHandlerFunc(http.HandlerFunc(fixture))
+
+	tests := []struct {
+		method string
+		want   int
+	}{
+		// GET is only passing method
+		{"GET", http.StatusOK},
+
+		// everything but GET is StatusNotImplemented
+		{"POST", http.StatusNotImplemented},
+		{"PUT", http.StatusNotImplemented},
+		{"PATCH", http.StatusNotImplemented},
+		{"DELETE", http.StatusNotImplemented},
+		{"FOO", http.StatusNotImplemented},
+	}
+
+	for i, tt := range tests {
+		req, _ := http.NewRequest(tt.method, "http://example.com", nil)
+		rr := httptest.NewRecorder()
+		hdlrFunc(rr, req)
+
+		if tt.want != rr.Code {
+			t.Errorf("#%d: incorrect HTTP status code: method=%s want=%d got=%d", i, tt.method, tt.want, rr.Code)
+		}
+	}
+}