mirror of https://github.com/perkeep/perkeep.git
Merge "publish: find ui and closure resources similarly to ui handler"
This commit is contained in:
commit
8b4ebd59b7
|
@ -36,6 +36,7 @@ import (
|
|||
"camlistore.org/pkg/blobref"
|
||||
"camlistore.org/pkg/blobserver"
|
||||
"camlistore.org/pkg/client" // just for NewUploadHandleFromString. move elsewhere?
|
||||
"camlistore.org/pkg/fileembed"
|
||||
"camlistore.org/pkg/httputil"
|
||||
"camlistore.org/pkg/jsonconfig"
|
||||
"camlistore.org/pkg/jsonsign/signhandler"
|
||||
|
@ -56,8 +57,17 @@ type PublishHandler struct {
|
|||
|
||||
JSFiles, CSSFiles []string
|
||||
|
||||
handlerFinder blobserver.FindHandlerByTyper
|
||||
staticHandler http.Handler
|
||||
handlerFinder blobserver.FindHandlerByTyper
|
||||
|
||||
// sourceRoot optionally specifies the path to root of Camlistore's
|
||||
// source. If empty, the UI files must be compiled in to the
|
||||
// binary (with go run make.go). This comes from the "sourceRoot"
|
||||
// publish handler config option.
|
||||
sourceRoot string
|
||||
|
||||
uiDir string // if sourceRoot != "", this is sourceRoot+"/server/camlistored/ui"
|
||||
|
||||
// closureHandler serves the Closure JS files.
|
||||
closureHandler http.Handler
|
||||
}
|
||||
|
||||
|
@ -78,6 +88,7 @@ func newPublishFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Han
|
|||
scType := conf.OptionalString("scaledImage", "")
|
||||
bootstrapSignRoot := conf.OptionalString("devBootstrapPermanodeUsing", "")
|
||||
rootNode := conf.OptionalList("rootPermanode")
|
||||
ph.sourceRoot = conf.OptionalString("sourceRoot", "")
|
||||
if err = conf.Validate(); err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -148,20 +159,32 @@ func newPublishFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Han
|
|||
}
|
||||
}
|
||||
|
||||
camliRootPath, err := osutil.GoPackagePath("camlistore.org")
|
||||
if err != nil {
|
||||
error := "Package camlistore.org not found in $GOPATH (or $GOPATH not defined)." +
|
||||
" Needed to find closure dir."
|
||||
return nil, fmt.Errorf(error)
|
||||
if ph.sourceRoot == "" {
|
||||
ph.sourceRoot = os.Getenv("CAMLI_DEV_CAMLI_ROOT")
|
||||
}
|
||||
if ph.sourceRoot != "" {
|
||||
ph.uiDir = filepath.Join(ph.sourceRoot, filepath.FromSlash("server/camlistored/ui"))
|
||||
// Ignore any fileembed files:
|
||||
Files = &fileembed.Files{
|
||||
DirFallback: filepath.Join(ph.sourceRoot, filepath.FromSlash("pkg/server")),
|
||||
}
|
||||
uistatic.Files = &fileembed.Files{
|
||||
DirFallback: ph.uiDir,
|
||||
}
|
||||
}
|
||||
closureDir := filepath.Join(camliRootPath, "tmp", "closure-lib", "closure")
|
||||
ph.closureHandler = http.FileServer(http.Dir(closureDir))
|
||||
|
||||
ph.staticHandler = http.FileServer(uistatic.Files)
|
||||
ph.closureHandler, err = ph.makeClosureHandler(ph.sourceRoot)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(`Invalid "sourceRoot" value of %q: %v"`, ph.sourceRoot, err)
|
||||
}
|
||||
|
||||
return ph, nil
|
||||
}
|
||||
|
||||
func (ph *PublishHandler) makeClosureHandler(root string) (http.Handler, error) {
|
||||
return makeClosureHandler(root, "publish")
|
||||
}
|
||||
|
||||
func (ph *PublishHandler) rootPermanode() (*blobref.BlobRef, error) {
|
||||
// TODO: caching, but this can change over time (though
|
||||
// probably rare). might be worth a 5 second cache or
|
||||
|
@ -384,25 +407,26 @@ func (pr *publishRequest) serveHTTP() {
|
|||
pr.serveSubresImage()
|
||||
case "s": // static
|
||||
pr.req.URL.Path = pr.subres[len("/=s"):]
|
||||
if len(pr.req.URL.Path) > 1 {
|
||||
if m := closurePattern.FindStringSubmatch(pr.req.URL.Path[1:]); m != nil {
|
||||
pr.req.URL.Path = "/" + m[1]
|
||||
pr.ph.closureHandler.ServeHTTP(pr.rw, pr.req)
|
||||
return
|
||||
}
|
||||
if len(pr.req.URL.Path) <= 1 {
|
||||
http.Error(pr.rw, "Illegal URL.", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
file := pr.req.URL.Path[1:]
|
||||
if m := closurePattern.FindStringSubmatch(file); m != nil {
|
||||
pr.req.URL.Path = "/" + m[1]
|
||||
pr.ph.closureHandler.ServeHTTP(pr.rw, pr.req)
|
||||
return
|
||||
}
|
||||
// TODO: this assumes that deps.js either dev server, or that deps.js
|
||||
// is embedded in the binary. We want to NOT embed deps.js, but also
|
||||
// serve dynamic deps.js from other resources embedded in the server
|
||||
// when not in dev-server mode. So fix this later, when serveDepsJS
|
||||
// can work over embedded resources.
|
||||
if pr.req.URL.Path == "/deps.js" {
|
||||
if dir := os.Getenv("CAMLI_DEV_CAMLI_ROOT"); dir != "" {
|
||||
serveDepsJS(pr.rw, pr.req, dir+"/server/camlistored/ui")
|
||||
return
|
||||
}
|
||||
if file == "deps.js" && pr.ph.sourceRoot != "" {
|
||||
serveDepsJS(pr.rw, pr.req, pr.ph.uiDir)
|
||||
return
|
||||
}
|
||||
pr.ph.staticHandler.ServeHTTP(pr.rw, pr.req)
|
||||
serveStaticFile(pr.rw, pr.req, uistatic.Files, file)
|
||||
default:
|
||||
pr.rw.WriteHeader(400)
|
||||
pr.pf("<p>Invalid or unsupported resource request.</p>")
|
||||
|
|
|
@ -188,6 +188,10 @@ func uiFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Handler, er
|
|||
return ui, nil
|
||||
}
|
||||
|
||||
func (ui *UIHandler) makeClosureHandler(root string) (http.Handler, error) {
|
||||
return makeClosureHandler(root, "ui")
|
||||
}
|
||||
|
||||
// makeClosureHandler returns a handler to serve Closure files.
|
||||
// root is either:
|
||||
// 1) empty: use the Closure files compiled in to the binary (if
|
||||
|
@ -195,26 +199,26 @@ func uiFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Handler, er
|
|||
// 2) a URL prefix: base of Camlistore to get Closure to redirect to
|
||||
// 3) a path on disk to the root of camlistore's source (which
|
||||
// contains the necessary subset of Closure files)
|
||||
func (ui *UIHandler) makeClosureHandler(root string) (http.Handler, error) {
|
||||
func makeClosureHandler(root, handlerName string) (http.Handler, error) {
|
||||
// dev-server environment variable takes precendence:
|
||||
if d := os.Getenv("CAMLI_DEV_CLOSURE_DIR"); d != "" {
|
||||
log.Printf("ui: serving Closure from dev-server's $CAMLI_DEV_CLOSURE_DIR: %v", d)
|
||||
log.Printf("%v: serving Closure from dev-server's $CAMLI_DEV_CLOSURE_DIR: %v", handlerName, d)
|
||||
return http.FileServer(http.Dir(d)), nil
|
||||
}
|
||||
if root == "" {
|
||||
fs, err := closurestatic.FileSystem()
|
||||
if err == os.ErrNotExist {
|
||||
log.Printf("ui: no configured setting or embedded resources; serving Closure via %v", closureBaseURL)
|
||||
log.Printf("%v: no configured setting or embedded resources; serving Closure via %v", handlerName, closureBaseURL)
|
||||
return closureBaseURL, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error loading embedded Closure zip file: %v", err)
|
||||
}
|
||||
log.Printf("ui: serving Closure from embedded resources")
|
||||
log.Printf("%v: serving Closure from embedded resources", handlerName)
|
||||
return http.FileServer(fs), nil
|
||||
}
|
||||
if strings.HasPrefix(root, "http") {
|
||||
log.Printf("ui: serving Closure using redirects to %v", root)
|
||||
log.Printf("%v: serving Closure using redirects to %v", handlerName, root)
|
||||
return closureRedirector(root), nil
|
||||
}
|
||||
fi, err := os.Stat(root)
|
||||
|
@ -229,7 +233,7 @@ func (ui *UIHandler) makeClosureHandler(root string) (http.Handler, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("directory doesn't contain closure/goog/base.js; wrong directory?")
|
||||
}
|
||||
log.Printf("ui: serving Closure from disk: %v", closureRoot)
|
||||
log.Printf("%v: serving Closure from disk: %v", handlerName, closureRoot)
|
||||
return http.FileServer(http.Dir(closureRoot)), nil
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,9 @@ type configPrefixesParams struct {
|
|||
|
||||
var tempDir = os.TempDir
|
||||
|
||||
func addPublishedConfig(prefixes jsonconfig.Obj, published jsonconfig.Obj) ([]interface{}, error) {
|
||||
func addPublishedConfig(prefixes jsonconfig.Obj,
|
||||
published jsonconfig.Obj,
|
||||
sourceRoot string) ([]interface{}, error) {
|
||||
pubPrefixes := []interface{}{}
|
||||
for k, v := range published {
|
||||
p, ok := v.(map[string]interface{})
|
||||
|
@ -83,6 +85,9 @@ func addPublishedConfig(prefixes jsonconfig.Obj, published jsonconfig.Obj) ([]in
|
|||
"cache": "/cache/",
|
||||
"rootPermanode": []interface{}{"/sighelper/", rootPermanode},
|
||||
}
|
||||
if sourceRoot != "" {
|
||||
handlerArgs["sourceRoot"] = sourceRoot
|
||||
}
|
||||
switch template {
|
||||
case "gallery":
|
||||
if style == "" {
|
||||
|
@ -384,6 +389,7 @@ func genLowLevelConfig(conf *Config) (lowLevelConf *Config, err error) {
|
|||
// If non empty, the ui files will be expected at
|
||||
// sourceRoot + "/server/camlistored/ui" and the closure library at
|
||||
// sourceRoot + "/third_party/closure/lib"
|
||||
// Also used by the publish handler.
|
||||
sourceRoot = conf.OptionalString("sourceRoot", "")
|
||||
|
||||
ownerName = conf.OptionalString("ownerName", "")
|
||||
|
@ -490,7 +496,7 @@ func genLowLevelConfig(conf *Config) (lowLevelConf *Config, err error) {
|
|||
if !runIndex {
|
||||
return nil, fmt.Errorf("publishing requires an index")
|
||||
}
|
||||
published, err = addPublishedConfig(prefixes, publish)
|
||||
published, err = addPublishedConfig(prefixes, publish, sourceRoot)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not generate config for published: %v", err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue