Commit 201e1d3e by Torkel Ödegaard

Macaron rewrite

parent 2c72831b
...@@ -4,6 +4,7 @@ watch_all = true ...@@ -4,6 +4,7 @@ watch_all = true
watch_dirs = [ watch_dirs = [
"$WORKDIR/pkg", "$WORKDIR/pkg",
"$WORKDIR/views", "$WORKDIR/views",
"$WORKDIR/conf",
] ]
watch_exts = [".go", ".ini"] watch_exts = [".go", ".ini"]
build_delay = 1500 build_delay = 1500
......
...@@ -8,7 +8,31 @@ root_url = %(protocol)s://%(domain)s:%(http_port)s/ ...@@ -8,7 +8,31 @@ root_url = %(protocol)s://%(domain)s:%(http_port)s/
http_addr = http_addr =
http_port = 3000 http_port = 3000
ssh_port = 22 ssh_port = 22
route_log = true router_logging = false
[session]
; Either "memory", "file", default is "memory"
provider = file
; Provider config options
; memory: not have any config yet
; file: session file path, e.g. `data/sessions`
; redis: config like redis server addr, poolSize, password, e.g. `127.0.0.1:6379,100,gogs`
; mysql: go-sql-driver/mysql dsn config string, e.g. `root:password@/session_table`
provider_config = data/sessions
; Session cookie name
cookie_name = grafana_pro_sess
; If you use session in https only, default is false
cookie_secure = false
; Enable set cookie, default is true
enable_set_cookie = true
; Session GC time interval, default is 86400
gc_time_interval = 86400
; Session life time, default is 86400
session_life_time = 86400
; session id hash func, Either "sha1", "sha256" or "md5" default is sha1
session_id_hashfunc = sha1
; Session hash key, default is use random string
session_id_hashkey =
[log] [log]
root_path = root_path =
......
No preview for this file type
// Copyright 2014 Unknwon
// Copyright 2014 Torkel Ödegaard
package cmd package cmd
import ( import (
"time" "fmt"
"net/http"
"path"
"github.com/Unknwon/macaron"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/siddontang/go-log/log"
"github.com/torkelo/grafana-pro/pkg/configuration" "github.com/torkelo/grafana-pro/pkg/log"
"github.com/torkelo/grafana-pro/pkg/server" "github.com/torkelo/grafana-pro/pkg/middleware"
"github.com/torkelo/grafana-pro/pkg/routes"
"github.com/torkelo/grafana-pro/pkg/setting" "github.com/torkelo/grafana-pro/pkg/setting"
) )
...@@ -18,23 +25,66 @@ var CmdWeb = cli.Command{ ...@@ -18,23 +25,66 @@ var CmdWeb = cli.Command{
Flags: []cli.Flag{}, Flags: []cli.Flag{},
} }
func newMacaron() *macaron.Macaron {
m := macaron.New()
m.Use(middleware.Logger())
m.Use(macaron.Recovery())
m.Use(macaron.Static(
path.Join(setting.StaticRootPath, "public"),
macaron.StaticOptions{
SkipLogging: true,
Prefix: "public",
},
))
m.Use(macaron.Static(
path.Join(setting.StaticRootPath, "public/app"),
macaron.StaticOptions{
SkipLogging: true,
Prefix: "app",
},
))
m.Use(macaron.Static(
path.Join(setting.StaticRootPath, "public/img"),
macaron.StaticOptions{
SkipLogging: true,
Prefix: "img",
},
))
m.Use(macaron.Renderer(macaron.RenderOptions{
Directory: path.Join(setting.StaticRootPath, "views"),
IndentJSON: macaron.Env != macaron.PROD,
Delims: macaron.Delims{Left: "[[", Right: "]]"},
}))
m.Use(middleware.GetContextHandler())
return m
}
func runWeb(*cli.Context) { func runWeb(*cli.Context) {
setting.NewConfigContext()
setting.InitServices()
log.Info("Starting Grafana-Pro v.1-alpha") log.Info("Starting Grafana-Pro v.1-alpha")
setting.NewConfigContext() m := newMacaron()
cfg := configuration.NewCfg(setting.HttpPort) // index
server, err := server.NewServer(cfg) m.Get("/", routes.Index)
if err != nil {
time.Sleep(time.Second) var err error
panic(err) listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort)
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubUrl)
switch setting.Protocol {
case setting.HTTP:
err = http.ListenAndServe(listenAddr, m)
case setting.HTTPS:
err = http.ListenAndServeTLS(listenAddr, setting.CertFile, setting.KeyFile, m)
default:
log.Fatal(4, "Invalid protocol: %s", setting.Protocol)
} }
err = server.ListenAndServe()
if err != nil { if err != nil {
log.Error("ListenAndServe failed: ", err) log.Fatal(4, "Fail to start server: %v", err)
} }
time.Sleep(time.Millisecond * 2000)
} }
// Copyright 2013 Martini Authors
// Copyright 2014 Unknwon
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package middleware
import (
"fmt"
"net/http"
"runtime"
"time"
"github.com/Unknwon/macaron"
"github.com/torkelo/grafana-pro/pkg/log"
)
var isWindows bool
func init() {
isWindows = runtime.GOOS == "windows"
}
// Logger returns a middleware handler that logs the request as it goes in and the response as it goes out.
func Logger() macaron.Handler {
return func(res http.ResponseWriter, req *http.Request, c *macaron.Context) {
start := time.Now()
rw := res.(macaron.ResponseWriter)
c.Next()
content := fmt.Sprintf("Completed %s %v %s in %v", req.URL.Path, rw.Status(), http.StatusText(rw.Status()), time.Since(start))
if !isWindows {
switch rw.Status() {
case 200:
content = fmt.Sprintf("\033[1;32m%s\033[0m", content)
case 304:
return
content = fmt.Sprintf("\033[1;33m%s\033[0m", content)
case 404:
content = fmt.Sprintf("\033[1;31m%s\033[0m", content)
case 500:
content = fmt.Sprintf("\033[1;36m%s\033[0m", content)
}
}
log.Info(content)
}
}
package middleware
import (
"time"
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/session"
"github.com/torkelo/grafana-pro/pkg/log"
"github.com/torkelo/grafana-pro/pkg/models"
)
type Context struct {
*macaron.Context
Session session.Store
Account *models.Account
UserAccount *models.Account
IsSigned bool
}
func GetContextHandler() macaron.Handler {
return func(c *macaron.Context) {
ctx := &Context{
Context: c,
}
ctx.Data["PageStartTime"] = time.Now()
c.Map(ctx)
}
}
// Handle handles and logs error by given status.
func (ctx *Context) Handle(status int, title string, err error) {
if err != nil {
log.Error(4, "%s: %v", title, err)
if macaron.Env != macaron.PROD {
ctx.Data["ErrorMsg"] = err
}
}
switch status {
case 404:
ctx.Data["Title"] = "Page Not Found"
case 500:
ctx.Data["Title"] = "Internal Server Error"
}
ctx.HTML(status, "index")
}
package routes
import "github.com/torkelo/grafana-pro/pkg/middleware"
func Index(ctx *middleware.Context) {
ctx.HTML(200, "index")
}
func NotFound(ctx *middleware.Context) {
ctx.Data["Title"] = "Page Not Found"
ctx.Handle(404, "index", nil)
}
package routes
import "github.com/torkelo/grafana-pro/pkg/setting"
func GlobalInit() {
setting.NewConfigContext()
}
// Copyright 2014 Unknwon
// Copyright 2014 Torkel Ödegaard
package setting package setting
import ( import (
...@@ -11,6 +14,8 @@ import ( ...@@ -11,6 +14,8 @@ import (
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/Unknwon/goconfig" "github.com/Unknwon/goconfig"
"github.com/macaron-contrib/session"
"github.com/torkelo/grafana-pro/pkg/log" "github.com/torkelo/grafana-pro/pkg/log"
) )
...@@ -39,7 +44,12 @@ var ( ...@@ -39,7 +44,12 @@ var (
HttpAddr, HttpPort string HttpAddr, HttpPort string
SshPort int SshPort int
CertFile, KeyFile string CertFile, KeyFile string
DisableRouterLog bool RouterLogging bool
StaticRootPath string
// Session settings.
SessionProvider string
SessionConfig *session.Config
// Global setting objects. // Global setting objects.
Cfg *goconfig.ConfigFile Cfg *goconfig.ConfigFile
...@@ -127,4 +137,33 @@ func NewConfigContext() { ...@@ -127,4 +137,33 @@ func NewConfigContext() {
if port != "" { if port != "" {
HttpPort = port HttpPort = port
} }
StaticRootPath = Cfg.MustValue("server", "static_root_path", workDir)
RouterLogging = Cfg.MustBool("server", "router_logging", false)
}
func initSessionService() {
SessionProvider = Cfg.MustValueRange("session", "provider", "memory", []string{"memory", "file"})
SessionConfig = new(session.Config)
SessionConfig.ProviderConfig = strings.Trim(Cfg.MustValue("session", "provider_config"), "\" ")
SessionConfig.CookieName = Cfg.MustValue("session", "cookie_name", "grafana_pro_sess")
SessionConfig.CookiePath = AppSubUrl
SessionConfig.Secure = Cfg.MustBool("session", "cookie_secure")
SessionConfig.EnableSetCookie = Cfg.MustBool("session", "enable_set_cookie", true)
SessionConfig.Gclifetime = Cfg.MustInt64("session", "gc_interval_time", 86400)
SessionConfig.Maxlifetime = Cfg.MustInt64("session", "session_life_time", 86400)
SessionConfig.SessionIDHashFunc = Cfg.MustValueRange("session", "session_id_hashfunc",
"sha1", []string{"sha1", "sha256", "md5"})
SessionConfig.SessionIDHashKey = Cfg.MustValue("session", "session_id_hashkey", string(com.RandomCreateBytes(16)))
if SessionProvider == "file" {
os.MkdirAll(path.Dir(SessionConfig.ProviderConfig), os.ModePerm)
}
log.Info("Session Service Enabled")
}
func InitServices() {
initSessionService()
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment