diff --git a/lib/go/camli/blobserver/registry.go b/lib/go/camli/blobserver/registry.go
index 3cf055d70..7761a4a56 100644
--- a/lib/go/camli/blobserver/registry.go
+++ b/lib/go/camli/blobserver/registry.go
@@ -31,6 +31,8 @@ type Loader interface {
// Returns either a Storage or an http.Handler
GetHandler(prefix string) (interface{}, os.Error)
+
+ FindHandlerByTypeIfLoaded(htype string) (prefix string, handler interface{}, err os.Error)
}
type StorageConstructor func(Loader, jsonconfig.Obj) (Storage, os.Error)
diff --git a/server/go/camlistored/camlistored.go b/server/go/camlistored/camlistored.go
index 83c2edd9c..23a10251e 100644
--- a/server/go/camlistored/camlistored.go
+++ b/server/go/camlistored/camlistored.go
@@ -226,6 +226,15 @@ func main() {
ws.Serve()
}
+func (hl *handlerLoader) FindHandlerByTypeIfLoaded(htype string) (prefix string, handler interface{}, err os.Error) {
+ for prefix, config := range hl.config {
+ if config.htype == htype {
+ return prefix, hl.handler[prefix], nil
+ }
+ }
+ return "", nil, os.ENOENT
+}
+
func (hl *handlerLoader) setupAll() {
for prefix := range hl.config {
hl.setupHandler(prefix)
diff --git a/server/go/camlistored/publish.go b/server/go/camlistored/publish.go
index d1786e656..4096d9354 100644
--- a/server/go/camlistored/publish.go
+++ b/server/go/camlistored/publish.go
@@ -46,6 +46,7 @@ type PublishHandler struct {
JSFiles, CSSFiles []string
+ bsLoader blobserver.Loader
staticHandler http.Handler
}
@@ -54,7 +55,9 @@ func init() {
}
func newPublishFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Handler, err os.Error) {
- ph := &PublishHandler{}
+ ph := &PublishHandler{
+ bsLoader: ld,
+ }
ph.RootName = conf.RequiredString("rootName")
ph.JSFiles = conf.OptionalList("js")
ph.CSSFiles = conf.OptionalList("css")
@@ -138,7 +141,29 @@ func (ph *PublishHandler) lookupPathTarget(root *blobref.BlobRef, suffix string)
return path.Target, nil
}
+func (ph *PublishHandler) serveDiscovery(rw http.ResponseWriter, req *http.Request) {
+ if !ph.ViewerIsOwner(req) {
+ discoveryHelper(rw, req, map[string]interface{}{
+ "error": "viewer isn't owner",
+ })
+ return
+ }
+ _, handler, err := ph.bsLoader.FindHandlerByTypeIfLoaded("ui")
+ if err != nil {
+ discoveryHelper(rw, req, map[string]interface{}{
+ "error": "no admin handler running",
+ })
+ return
+ }
+ ui := handler.(*UIHandler)
+ ui.serveDiscovery(rw, req)
+}
+
func (ph *PublishHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+ if req.URL.Query().Get("camli.mode") == "config" {
+ ph.serveDiscovery(rw, req)
+ return
+ }
preq := ph.NewRequest(rw, req)
preq.serveHTTP()
}
@@ -184,6 +209,16 @@ func (ph *PublishHandler) NewRequest(rw http.ResponseWriter, req *http.Request)
}
}
+func (ph *PublishHandler) ViewerIsOwner(req *http.Request) bool {
+ // TODO: better check later
+ return strings.HasPrefix(req.RemoteAddr, "127.") ||
+ strings.HasPrefix(req.RemoteAddr, "localhost:")
+}
+
+func (pr *publishRequest) ViewerIsOwner() bool {
+ return pr.ph.ViewerIsOwner(pr.req)
+}
+
func (pr *publishRequest) Debug() bool {
return pr.req.FormValue("debug") == "1"
}
@@ -359,8 +394,12 @@ func (pr *publishRequest) serveSubject() {
}
for _, filename := range pr.ph.JSFiles {
pr.pf(" \n", pr.staticPath(filename))
+ if filename == "camli.js" && pr.ViewerIsOwner() {
+ pr.pf(" \n", pr.base+"?camli.mode=config&cb=onConfiguration")
+ }
}
pr.pf("