mirror of https://github.com/grafana/grafana
parent
8bccbdafd2
commit
fad07f0d15
@ -0,0 +1,138 @@ |
|||||||
|
package api |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"net/http" |
||||||
|
"os" |
||||||
|
"path" |
||||||
|
|
||||||
|
macaron "gopkg.in/macaron.v1" |
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/api/live" |
||||||
|
httpstatic "github.com/grafana/grafana/pkg/api/static" |
||||||
|
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger" |
||||||
|
"github.com/grafana/grafana/pkg/log" |
||||||
|
"github.com/grafana/grafana/pkg/middleware" |
||||||
|
"github.com/grafana/grafana/pkg/plugins" |
||||||
|
"github.com/grafana/grafana/pkg/setting" |
||||||
|
) |
||||||
|
|
||||||
|
type HttpServer struct { |
||||||
|
log log.Logger |
||||||
|
macaron *macaron.Macaron |
||||||
|
context context.Context |
||||||
|
streamManager *live.StreamManager |
||||||
|
} |
||||||
|
|
||||||
|
func NewHttpServer() *HttpServer { |
||||||
|
return &HttpServer{ |
||||||
|
log: log.New("http.server"), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (hs *HttpServer) Start(ctx context.Context) error { |
||||||
|
var err error |
||||||
|
|
||||||
|
hs.context = ctx |
||||||
|
hs.streamManager = live.NewStreamManager() |
||||||
|
hs.macaron = hs.newMacaron() |
||||||
|
hs.registerRoutes() |
||||||
|
|
||||||
|
hs.streamManager.Run(ctx) |
||||||
|
|
||||||
|
listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort) |
||||||
|
hs.log.Info("Initializing HTTP Server", "address", listenAddr, "protocol", setting.Protocol, "subUrl", setting.AppSubUrl) |
||||||
|
|
||||||
|
switch setting.Protocol { |
||||||
|
case setting.HTTP: |
||||||
|
err = http.ListenAndServe(listenAddr, hs.macaron) |
||||||
|
case setting.HTTPS: |
||||||
|
err = hs.listenAndServeTLS(listenAddr, setting.CertFile, setting.KeyFile) |
||||||
|
default: |
||||||
|
hs.log.Error("Invalid protocol", "protocol", setting.Protocol) |
||||||
|
err = errors.New("Invalid Protocol") |
||||||
|
} |
||||||
|
|
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
func (hs *HttpServer) listenAndServeTLS(listenAddr, certfile, keyfile string) error { |
||||||
|
if certfile == "" { |
||||||
|
return fmt.Errorf("cert_file cannot be empty when using HTTPS") |
||||||
|
} |
||||||
|
|
||||||
|
if keyfile == "" { |
||||||
|
return fmt.Errorf("cert_key cannot be empty when using HTTPS") |
||||||
|
} |
||||||
|
|
||||||
|
if _, err := os.Stat(setting.CertFile); os.IsNotExist(err) { |
||||||
|
return fmt.Errorf(`Cannot find SSL cert_file at %v`, setting.CertFile) |
||||||
|
} |
||||||
|
|
||||||
|
if _, err := os.Stat(setting.KeyFile); os.IsNotExist(err) { |
||||||
|
return fmt.Errorf(`Cannot find SSL key_file at %v`, setting.KeyFile) |
||||||
|
} |
||||||
|
|
||||||
|
return http.ListenAndServeTLS(listenAddr, setting.CertFile, setting.KeyFile, hs.macaron) |
||||||
|
} |
||||||
|
|
||||||
|
func (hs *HttpServer) newMacaron() *macaron.Macaron { |
||||||
|
macaron.Env = setting.Env |
||||||
|
m := macaron.New() |
||||||
|
|
||||||
|
m.Use(middleware.Logger()) |
||||||
|
m.Use(middleware.Recovery()) |
||||||
|
|
||||||
|
if setting.EnableGzip { |
||||||
|
m.Use(middleware.Gziper()) |
||||||
|
} |
||||||
|
|
||||||
|
for _, route := range plugins.StaticRoutes { |
||||||
|
pluginRoute := path.Join("/public/plugins/", route.PluginId) |
||||||
|
logger.Debug("Plugins: Adding route", "route", pluginRoute, "dir", route.Directory) |
||||||
|
hs.mapStatic(m, route.Directory, "", pluginRoute) |
||||||
|
} |
||||||
|
|
||||||
|
hs.mapStatic(m, setting.StaticRootPath, "", "public") |
||||||
|
hs.mapStatic(m, setting.StaticRootPath, "robots.txt", "robots.txt") |
||||||
|
|
||||||
|
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()) |
||||||
|
m.Use(middleware.Sessioner(&setting.SessionOptions)) |
||||||
|
m.Use(middleware.RequestMetrics()) |
||||||
|
|
||||||
|
// needs to be after context handler
|
||||||
|
if setting.EnforceDomain { |
||||||
|
m.Use(middleware.ValidateHostHeader(setting.Domain)) |
||||||
|
} |
||||||
|
|
||||||
|
return m |
||||||
|
} |
||||||
|
|
||||||
|
func (hs *HttpServer) mapStatic(m *macaron.Macaron, rootDir string, dir string, prefix string) { |
||||||
|
headers := func(c *macaron.Context) { |
||||||
|
c.Resp.Header().Set("Cache-Control", "public, max-age=3600") |
||||||
|
} |
||||||
|
|
||||||
|
if setting.Env == setting.DEV { |
||||||
|
headers = func(c *macaron.Context) { |
||||||
|
c.Resp.Header().Set("Cache-Control", "max-age=0, must-revalidate, no-cache") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
m.Use(httpstatic.Static( |
||||||
|
path.Join(rootDir, dir), |
||||||
|
httpstatic.StaticOptions{ |
||||||
|
SkipLogging: true, |
||||||
|
Prefix: prefix, |
||||||
|
AddHeaders: headers, |
||||||
|
}, |
||||||
|
)) |
||||||
|
} |
@ -1,40 +0,0 @@ |
|||||||
package live |
|
||||||
|
|
||||||
import ( |
|
||||||
"net/http" |
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api/dtos" |
|
||||||
"github.com/grafana/grafana/pkg/log" |
|
||||||
"github.com/grafana/grafana/pkg/middleware" |
|
||||||
) |
|
||||||
|
|
||||||
type LiveConn struct { |
|
||||||
log log.Logger |
|
||||||
} |
|
||||||
|
|
||||||
func New() *LiveConn { |
|
||||||
go h.run() |
|
||||||
|
|
||||||
return &LiveConn{log: log.New("live.server")} |
|
||||||
} |
|
||||||
|
|
||||||
func (lc *LiveConn) Serve(w http.ResponseWriter, r *http.Request) { |
|
||||||
lc.log.Info("Upgrading to WebSocket") |
|
||||||
|
|
||||||
ws, err := upgrader.Upgrade(w, r, nil) |
|
||||||
if err != nil { |
|
||||||
log.Error(3, "Live: Failed to upgrade connection to WebSocket", err) |
|
||||||
return |
|
||||||
} |
|
||||||
|
|
||||||
c := newConnection(ws) |
|
||||||
h.register <- c |
|
||||||
|
|
||||||
go c.writePump() |
|
||||||
c.readPump() |
|
||||||
} |
|
||||||
|
|
||||||
func (lc *LiveConn) PushToStream(c *middleware.Context, message dtos.StreamMessage) { |
|
||||||
h.streamChannel <- &message |
|
||||||
c.JsonOK("Message recevived") |
|
||||||
} |
|
@ -1,107 +0,0 @@ |
|||||||
// Copyright 2014 Unknwon
|
|
||||||
// Copyright 2014 Torkel Ödegaard
|
|
||||||
|
|
||||||
package main |
|
||||||
|
|
||||||
import ( |
|
||||||
"fmt" |
|
||||||
"net/http" |
|
||||||
"path" |
|
||||||
|
|
||||||
"gopkg.in/macaron.v1" |
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api" |
|
||||||
"github.com/grafana/grafana/pkg/api/static" |
|
||||||
"github.com/grafana/grafana/pkg/log" |
|
||||||
"github.com/grafana/grafana/pkg/middleware" |
|
||||||
"github.com/grafana/grafana/pkg/plugins" |
|
||||||
"github.com/grafana/grafana/pkg/setting" |
|
||||||
) |
|
||||||
|
|
||||||
var logger log.Logger |
|
||||||
|
|
||||||
func newMacaron() *macaron.Macaron { |
|
||||||
macaron.Env = setting.Env |
|
||||||
m := macaron.New() |
|
||||||
|
|
||||||
m.Use(middleware.Logger()) |
|
||||||
m.Use(middleware.Recovery()) |
|
||||||
|
|
||||||
if setting.EnableGzip { |
|
||||||
m.Use(middleware.Gziper()) |
|
||||||
} |
|
||||||
|
|
||||||
for _, route := range plugins.StaticRoutes { |
|
||||||
pluginRoute := path.Join("/public/plugins/", route.PluginId) |
|
||||||
logger.Debug("Plugins: Adding route", "route", pluginRoute, "dir", route.Directory) |
|
||||||
mapStatic(m, route.Directory, "", pluginRoute) |
|
||||||
} |
|
||||||
|
|
||||||
mapStatic(m, setting.StaticRootPath, "", "public") |
|
||||||
mapStatic(m, setting.StaticRootPath, "robots.txt", "robots.txt") |
|
||||||
|
|
||||||
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()) |
|
||||||
m.Use(middleware.Sessioner(&setting.SessionOptions)) |
|
||||||
m.Use(middleware.RequestMetrics()) |
|
||||||
|
|
||||||
// needs to be after context handler
|
|
||||||
if setting.EnforceDomain { |
|
||||||
m.Use(middleware.ValidateHostHeader(setting.Domain)) |
|
||||||
} |
|
||||||
|
|
||||||
return m |
|
||||||
} |
|
||||||
|
|
||||||
func mapStatic(m *macaron.Macaron, rootDir string, dir string, prefix string) { |
|
||||||
headers := func(c *macaron.Context) { |
|
||||||
c.Resp.Header().Set("Cache-Control", "public, max-age=3600") |
|
||||||
} |
|
||||||
|
|
||||||
if setting.Env == setting.DEV { |
|
||||||
headers = func(c *macaron.Context) { |
|
||||||
c.Resp.Header().Set("Cache-Control", "max-age=0, must-revalidate, no-cache") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
m.Use(httpstatic.Static( |
|
||||||
path.Join(rootDir, dir), |
|
||||||
httpstatic.StaticOptions{ |
|
||||||
SkipLogging: true, |
|
||||||
Prefix: prefix, |
|
||||||
AddHeaders: headers, |
|
||||||
}, |
|
||||||
)) |
|
||||||
} |
|
||||||
|
|
||||||
func StartServer() int { |
|
||||||
logger = log.New("server") |
|
||||||
|
|
||||||
var err error |
|
||||||
m := newMacaron() |
|
||||||
api.Register(m) |
|
||||||
|
|
||||||
listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort) |
|
||||||
logger.Info("Server Listening", "address", listenAddr, "protocol", setting.Protocol, "subUrl", 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: |
|
||||||
logger.Error("Invalid protocol", "protocol", setting.Protocol) |
|
||||||
return 1 |
|
||||||
} |
|
||||||
|
|
||||||
if err != nil { |
|
||||||
logger.Error("Fail to start server", "error", err) |
|
||||||
return 1 |
|
||||||
} |
|
||||||
|
|
||||||
return 0 |
|
||||||
} |
|
Loading…
Reference in new issue