Ejemplo n.º 1
0
func OnFormSubmitSaveModel(form *Form, formModel interface{}, ctx *Context) (msg string, url URL, err error) {
	err = formModel.(mongo.Document).Save()
	if err != nil {
		config.Logger.Println(err)
		debug.LogCallStack()
		msg = "An error occured while saving the form data"
		if Config.Debug.Mode {
			msg += ": " + err.Error()
		}
	}
	return msg, nil, err
}
Ejemplo n.º 2
0
func (self *Collection) logIdNotFoundError(id bson.ObjectId) {
	config.Logger.Printf("MongoDB document with id %s not found in collection %s", id.Hex(), self.Collection().Name)
	debug.LogCallStack()
}
Ejemplo n.º 3
0
// Pages and nil views will be registered with a trailing slash at their path
// and a permanent redirect from the path without trailing slash
// Nil views will be registered as NotFound404
// parentPath always ends with a slash
func (self *ViewPath) initAndRegisterViewsRecursive(parentPath string) {
	if parentPath == "" || parentPath[len(parentPath)-1] != '/' {
		panic("Parent path must end with a slash: " + parentPath)
	}
	if parentPath != "/" && self.Name == "" && self.Args == 0 {
		panic("Sub path of " + parentPath + " with no Name and Args")
	}
	if self.Name != "" && !PathFragmentRegexp.MatchString(self.Name) {
		panic("Invalid characters in view.ViewPath.Name: " + self.Name)
	}
	if self.View != nil && reflection.IsDeepNil(self.View) {
		panic("Nil value wrapped with non nil view.View under parentPath: " + parentPath)
	}

	addSlash := self.Args > 0
	if self.View == nil {
		addSlash = true
		self.View = &NotFoundView{Message: "Invalid URL"}
	} else if _, isPage := self.View.(*Page); isPage {
		addSlash = true
		if self.Auth != nil {
			if self.NoAuth == nil && Config.LoginSignupPage != nil && *Config.LoginSignupPage != nil {
				self.NoAuth = IndirectURL(Config.LoginSignupPage)
			}
		}
	}

	path := parentPath + self.Name
	if self.Args > 0 {
		if self.Name != "" {
			path += "/"
		}
		for i := 0; i < self.Args; i++ {
			path += PathFragmentPattern + "/"
		}
	}

	if addSlash {
		if path[len(path)-1] != '/' {
			path += "/"
		}
		if path != "/" {
			web.Get(path[:len(path)-1], func(webContext *web.Context, args ...string) string {
				webContext.Redirect(http.StatusMovedPermanently, webContext.Request.RequestURI+"/")
				return ""
			})
		}
	}

	if self.Args < 0 {
		panic("Negative Args at " + path)
	}
	if _, pathExists := viewsByPath[path]; pathExists {
		panic("View with path '" + path + "' already registered")
	}
	viewsByPath[path] = self.View

	if Config.Debug.LogPaths {
		log.Print(path)
	}

	//debug.Print(path)
	self.View.Init(self.View)
	if viewWithURL, ok := self.View.(ViewWithURL); ok {
		viewWithURL.SetPath(path)
	}

	htmlFunc := func(webContext *web.Context, args ...string) string {

		// See: http://groups.google.com/group/golang-nuts/browse_thread/thread/ab1971bb9459025d
		// Slows down the memory leak on 32 bit systems a little bit:
		defer func() {
			go runtime.GC()
		}()

		ctx := newContext(webContext, self.View, args)

		for _, subdomain := range Config.RedirectSubdomains {
			if len(subdomain) > 0 {
				if subdomain[len(subdomain)-1] != '.' {
					subdomain += "."
				}
				host := ctx.Request.Host
				if strings.Index(host, subdomain) == 0 {
					host = host[len(subdomain):]
					url := "http://" + host + ctx.Request.URL.Path
					ctx.Response.RedirectPermanently301(url)
					return ""
				}
			}
		}

		handleErr := func(err error) string {
			switch err.(type) {
			case NotFound:
				ctx.Response.NotFound404(err.Error())
			case Redirect:
				if Config.Debug.LogRedirects {
					log.Printf("%d Redirect: %s\n", http.StatusFound, err.Error())
				}
				ctx.Response.RedirectTemporary302(err.Error())
			case PermanentRedirect:
				if Config.Debug.LogRedirects {
					log.Printf("%d Permanent Redirect: %s\n", http.StatusMovedPermanently, err.Error())
				}
				ctx.Response.RedirectPermanently301(err.Error())
			case Forbidden:
				ctx.Response.Forbidden403(err.Error())
			default:
				log.Println(err.Error())
				debug.LogCallStack()
				msg := err.Error()
				if Config.Debug.Mode {
					msg += debug.Stack()
				}
				ctx.Response.Abort(http.StatusInternalServerError, msg)
			}
			return ""
		}

		handleNoAuth := func(err error) string {
			switch {
			case err != nil:
				return handleErr(err)
			case self.NoAuth != nil:
				from := url.QueryEscape(ctx.Request.RequestURI)
				to := self.NoAuth.URL(ctx) + "?from=" + from
				return handleErr(Redirect(to))
			}
			return handleErr(Forbidden("403 Forbidden: authentication required"))
		}

		if Config.OnPreAuth != nil {
			if err := Config.OnPreAuth(ctx); err != nil {
				return handleErr(err)
			}
		}

		if Config.GlobalAuth != nil {
			if ok, err := Config.GlobalAuth.Authenticate(ctx); !ok {
				return handleNoAuth(err)
			}
		}

		if self.Auth == nil {
			self.Auth = Config.FallbackAuth
		}
		if self.Auth != nil {
			if ok, err := self.Auth.Authenticate(ctx); !ok {
				return handleNoAuth(err)
			}
		}

		//		numMiddlewares := len(Config.Middlewares)
		//		for i := 0; i < numMiddlewares; i++ {
		//			if abort := Config.Middlewares[i].PreRender(context); abort {
		//				return ""
		//			}
		//		}

		err := self.View.Render(ctx)

		//		for i := numMiddlewares - 1; i >= 0; i-- {
		//			html, err = Config.Middlewares[i].PostRender(context, html, err)
		//		}

		if err != nil {
			return handleErr(err)
		}
		return ctx.Response.String()
	}

	web.Get(path, htmlFunc)
	web.Post(path, htmlFunc)

	for i := range self.Sub {
		self.Sub[i].initAndRegisterViewsRecursive(path)
	}
}