예제 #1
0
func (hl *handlerLoader) setupHandler(prefix string) {
	h, ok := hl.config[prefix]
	if !ok {
		exitFailure("invalid reference to undefined handler %q", prefix)
	}
	if h.setupDone {
		// Already setup by something else reference it and forcing it to be
		// setup before the bottom loop got to it.
		return
	}
	hl.prefixStack = append(hl.prefixStack, prefix)
	if h.settingUp {
		buf := make([]byte, 1024)
		buf = buf[:runtime.Stack(buf, false)]
		exitFailure("loop in configuration graph; %q tried to load itself indirectly: %q\nStack:\n%s",
			prefix, hl.prefixStack, buf)
	}
	h.settingUp = true
	defer func() {
		// log.Printf("Configured handler %q", prefix)
		h.setupDone = true
		hl.prefixStack = hl.prefixStack[:len(hl.prefixStack)-1]
		r := recover()
		if r == nil {
			if hl.handler[prefix] == nil {
				panic(fmt.Sprintf("setupHandler for %q didn't install a handler", prefix))
			}
		} else {
			panic(r)
		}
	}()

	hl.curPrefix = prefix

	if strings.HasPrefix(h.htype, "storage-") {
		stype := strings.TrimPrefix(h.htype, "storage-")
		// Assume a storage interface
		pstorage, err := blobserver.CreateStorage(stype, hl, h.conf)
		if err != nil {
			exitFailure("error instantiating storage for prefix %q, type %q: %v",
				h.prefix, stype, err)
		}
		if ix, ok := pstorage.(*index.Index); ok && hl.reindex {
			log.Printf("Reindexing %s ...", h.prefix)
			if err := ix.Reindex(); err != nil {
				exitFailure("Error reindexing %s: %v", h.prefix, err)
			}
		}
		hl.handler[h.prefix] = pstorage
		if h.internal {
			hl.installer.Handle(prefix, unauthorizedHandler{})
		} else {
			hl.installer.Handle(prefix+"camli/", makeCamliHandler(prefix, hl.baseURL, pstorage, hl))
		}
		if cl, ok := pstorage.(blobserver.ShutdownStorage); ok {
			hl.closers = append(hl.closers, cl)
		}
		return
	}

	var hh http.Handler
	if h.htype == "app" {
		ap, err := app.NewHandler(h.conf, hl.baseURL+"/", prefix)
		if err != nil {
			exitFailure("error setting up app for prefix %q: %v", h.prefix, err)
		}
		hh = ap
		auth.AddMode(ap.AuthMode())
		if ap.ProgramName() == "publisher" {
			if err := hl.initPublisherRootNode(ap); err != nil {
				exitFailure("Error looking/setting up root node for publisher on %v: %v", h.prefix, err)
			}
		}
	} else {
		var err error
		hh, err = blobserver.CreateHandler(h.htype, hl, h.conf)
		if err != nil {
			exitFailure("error instantiating handler for prefix %q, type %q: %v",
				h.prefix, h.htype, err)
		}
	}

	hl.handler[prefix] = hh
	var wrappedHandler http.Handler
	if h.internal {
		wrappedHandler = unauthorizedHandler{}
	} else {
		wrappedHandler = &httputil.PrefixHandler{prefix, hh}
		if handlerTypeWantsAuth(h.htype) {
			wrappedHandler = auth.Handler{wrappedHandler}
		}
	}
	hl.installer.Handle(prefix, wrappedHandler)
}
예제 #2
0
func (hl *handlerLoader) setupHandler(prefix string) {
	h, ok := hl.config[prefix]
	if !ok {
		exitFailure("invalid reference to undefined handler %q", prefix)
	}
	if h.setupDone {
		// Already setup by something else reference it and forcing it to be
		// setup before the bottom loop got to it.
		return
	}
	hl.prefixStack = append(hl.prefixStack, prefix)
	if h.settingUp {
		buf := make([]byte, 1024)
		buf = buf[:runtime.Stack(buf, false)]
		exitFailure("loop in configuration graph; %q tried to load itself indirectly: %q\nStack:\n%s",
			prefix, hl.prefixStack, buf)
	}
	h.settingUp = true
	defer func() {
		// log.Printf("Configured handler %q", prefix)
		h.setupDone = true
		hl.prefixStack = hl.prefixStack[:len(hl.prefixStack)-1]
		r := recover()
		if r == nil {
			if hl.handler[prefix] == nil {
				panic(fmt.Sprintf("setupHandler for %q didn't install a handler", prefix))
			}
		} else {
			panic(r)
		}
	}()

	hl.curPrefix = prefix

	if strings.HasPrefix(h.htype, "storage-") {
		stype := strings.TrimPrefix(h.htype, "storage-")
		// Assume a storage interface
		pstorage, err := blobserver.CreateStorage(stype, hl, h.conf)
		if err != nil {
			exitFailure("error instantiating storage for prefix %q, type %q: %v",
				h.prefix, stype, err)
		}
		if ix, ok := pstorage.(*index.Index); ok && hl.reindex {
			log.Printf("Reindexing %s ...", h.prefix)
			if err := ix.Reindex(); err != nil {
				exitFailure("Error reindexing %s: %v", h.prefix, err)
			}
		}
		hl.handler[h.prefix] = pstorage
		if h.internal {
			hl.installer.Handle(prefix, unauthorizedHandler{})
		} else {
			hl.installer.Handle(prefix+"camli/", makeCamliHandler(prefix, hl.baseURL, pstorage, hl))
		}
		if cl, ok := pstorage.(blobserver.ShutdownStorage); ok {
			hl.closers = append(hl.closers, cl)
		}
		return
	}

	var hh http.Handler
	if h.htype == "app" {
		// h.conf might already contain the server's baseURL, but
		// camlistored.go derives (if needed) a more useful hl.baseURL,
		// after h.conf was generated, so we provide it as well to
		// FromJSONConfig so NewHandler can benefit from it.
		hc, err := app.FromJSONConfig(h.conf, hl.baseURL)
		if err != nil {
			exitFailure("error setting up app config for prefix %q: %v", h.prefix, err)
		}
		ap, err := app.NewHandler(hc)
		if err != nil {
			exitFailure("error setting up app for prefix %q: %v", h.prefix, err)
		}
		hh = ap
		auth.AddMode(ap.AuthMode())
		// TODO(mpl): this check is weak, as the user could very well
		// use another binary name for the publisher app. We should
		// introduce/use another identifier.
		if ap.ProgramName() == "publisher" {
			if err := hl.initPublisherRootNode(ap); err != nil {
				exitFailure("Error looking/setting up root node for publisher on %v: %v", h.prefix, err)
			}
		}
	} else {
		var err error
		hh, err = blobserver.CreateHandler(h.htype, hl, h.conf)
		if err != nil {
			exitFailure("error instantiating handler for prefix %q, type %q: %v",
				h.prefix, h.htype, err)
		}
	}

	hl.handler[prefix] = hh
	var wrappedHandler http.Handler
	if h.internal {
		wrappedHandler = unauthorizedHandler{}
	} else {
		wrappedHandler = &httputil.PrefixHandler{Prefix: prefix, Handler: hh}
		if handlerTypeWantsAuth(h.htype) {
			wrappedHandler = auth.Handler{Handler: wrappedHandler}
		}
	}
	hl.installer.Handle(prefix, wrappedHandler)
}