refactored totally, but now exits and doesn't serve for some reason
This commit is contained in:
		
							parent
							
								
									6c9b82a10c
								
							
						
					
					
						commit
						297b8f4e1a
					
				@ -1,13 +1,13 @@
 | 
			
		||||
//3456789112345676892123456789312345678941234567895123456789612345678971234567898
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import "time"
 | 
			
		||||
import "os"
 | 
			
		||||
import "sync"
 | 
			
		||||
import "time"
 | 
			
		||||
 | 
			
		||||
import "github.com/rs/zerolog"
 | 
			
		||||
import "github.com/rs/zerolog/log"
 | 
			
		||||
import "golang.org/x/crypto/ssh/terminal"
 | 
			
		||||
import "github.com/sneak/merp"
 | 
			
		||||
import "golang.org/x/crypto/ssh/terminal"
 | 
			
		||||
 | 
			
		||||
//revive:disable
 | 
			
		||||
var Version string
 | 
			
		||||
@ -21,7 +21,16 @@ var Appname string
 | 
			
		||||
func main() {
 | 
			
		||||
	initLogging()
 | 
			
		||||
	identify()
 | 
			
		||||
	merp.ServeForever()
 | 
			
		||||
	var wg sync.WaitGroup
 | 
			
		||||
 | 
			
		||||
	wg.Add(1)
 | 
			
		||||
	go func() {
 | 
			
		||||
		ms := merp.NewMerpServer()
 | 
			
		||||
		ms.ServeForever()
 | 
			
		||||
		wg.Done()
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func identify() {
 | 
			
		||||
 | 
			
		||||
@ -1,62 +1,48 @@
 | 
			
		||||
package models
 | 
			
		||||
package merp
 | 
			
		||||
 | 
			
		||||
import "os"
 | 
			
		||||
import "time"
 | 
			
		||||
import "github.com/astaxie/beego/orm"
 | 
			
		||||
import "github.com/sneak/merp/models"
 | 
			
		||||
import "github.com/rs/zerolog/log"
 | 
			
		||||
import _ "github.com/lib/pq" //revive:disable-line
 | 
			
		||||
 | 
			
		||||
var ormObject orm.Ormer
 | 
			
		||||
 | 
			
		||||
func initialize() {
 | 
			
		||||
func GetDB() orm.Ormer {
 | 
			
		||||
	if os.Getenv("DEBUG") != "" {
 | 
			
		||||
		orm.Debug = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	connectToDb()
 | 
			
		||||
	syncDB()
 | 
			
		||||
	o := connectDB()
 | 
			
		||||
	syncDB(o)
 | 
			
		||||
 | 
			
		||||
	return o
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ConnectToDb - Initializes the ORM and Connection to the postgres DB
 | 
			
		||||
func connectToDb() {
 | 
			
		||||
 | 
			
		||||
func connectDB() orm.Ormer {
 | 
			
		||||
	orm.DefaultTimeLoc = time.UTC
 | 
			
		||||
 | 
			
		||||
	dbURL := os.Getenv("POSTGRES_DB_URL")
 | 
			
		||||
 | 
			
		||||
	orm.RegisterDriver("postgres", orm.DRPostgres)
 | 
			
		||||
	orm.RegisterDataBase("default", "postgres", dbURL)
 | 
			
		||||
	orm.SetMaxIdleConns("default", 1)
 | 
			
		||||
	orm.SetMaxOpenConns("default", 5)
 | 
			
		||||
 | 
			
		||||
	orm.RegisterModel(new(Merp))
 | 
			
		||||
	ormObject = orm.NewOrm()
 | 
			
		||||
	ormObject.Using("default")
 | 
			
		||||
 | 
			
		||||
	orm.RegisterModel(new(models.Merp))
 | 
			
		||||
	o := orm.NewOrm()
 | 
			
		||||
	o.Using("default")
 | 
			
		||||
	return o
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SyncDB() is responsible for creating the schema in the database
 | 
			
		||||
func syncDB() {
 | 
			
		||||
func syncDB(o orm.Ormer) {
 | 
			
		||||
	// Database alias.
 | 
			
		||||
	name := "default"
 | 
			
		||||
 | 
			
		||||
	// Drop table and re-create.
 | 
			
		||||
	force := false
 | 
			
		||||
 | 
			
		||||
	// Print log.
 | 
			
		||||
	verbose := true
 | 
			
		||||
 | 
			
		||||
	// Error.
 | 
			
		||||
	err := orm.RunSyncdb(name, force, verbose)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal().Msg(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetOrmObject - Getter function for the ORM object with which we can query the database
 | 
			
		||||
func GetOrmObject() orm.Ormer {
 | 
			
		||||
	if ormObject == nil {
 | 
			
		||||
		initialize()
 | 
			
		||||
	}
 | 
			
		||||
	return ormObject
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								merp.go
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								merp.go
									
									
									
									
									
								
							@ -2,7 +2,6 @@ package merp
 | 
			
		||||
 | 
			
		||||
import "encoding/json"
 | 
			
		||||
import "net/http"
 | 
			
		||||
import "regexp"
 | 
			
		||||
import "time"
 | 
			
		||||
 | 
			
		||||
import "github.com/astaxie/beego/orm"
 | 
			
		||||
@ -11,34 +10,21 @@ import "github.com/google/uuid"
 | 
			
		||||
import "github.com/rs/zerolog/log"
 | 
			
		||||
import "github.com/sneak/merp/models"
 | 
			
		||||
 | 
			
		||||
func thingRegex() *regexp.Regexp {
 | 
			
		||||
	ThingRegex, e := regexp.Compile(`^[a-zA-Z0-9\_\-]+$`)
 | 
			
		||||
	if e != nil {
 | 
			
		||||
		panic(e)
 | 
			
		||||
	}
 | 
			
		||||
	return ThingRegex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decodeJSON(in []byte) interface{} {
 | 
			
		||||
func decodeJSON(in []byte) (interface{}, error) {
 | 
			
		||||
	var out interface{}
 | 
			
		||||
	err := json.Unmarshal(in, &out)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error().Msg("error decoding json")
 | 
			
		||||
		return nil
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return out
 | 
			
		||||
	return out, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getLatestMerps() gin.HandlerFunc {
 | 
			
		||||
	ThingRegex := thingRegex()
 | 
			
		||||
	o := models.GetOrmObject()
 | 
			
		||||
 | 
			
		||||
	h := func(c *gin.Context) {
 | 
			
		||||
 | 
			
		||||
func (ms *MerpServer) getLatestMerps() gin.HandlerFunc {
 | 
			
		||||
	return func(c *gin.Context) {
 | 
			
		||||
		thing := c.Param("thing")
 | 
			
		||||
 | 
			
		||||
		if thing != "" {
 | 
			
		||||
			if ThingRegex.MatchString(thing) == false {
 | 
			
		||||
			if ms.thingRegex.MatchString(thing) == false {
 | 
			
		||||
				c.JSON(http.StatusPreconditionFailed, gin.H{
 | 
			
		||||
					"this":    "failed",
 | 
			
		||||
					"status":  http.StatusPreconditionFailed,
 | 
			
		||||
@ -50,9 +36,9 @@ func getLatestMerps() gin.HandlerFunc {
 | 
			
		||||
 | 
			
		||||
		var qs orm.QuerySeter
 | 
			
		||||
		if thing == "" {
 | 
			
		||||
			qs = o.QueryTable("merp").OrderBy("-created").Limit(50)
 | 
			
		||||
			qs = ms.db.QueryTable("merp").OrderBy("-created").Limit(50)
 | 
			
		||||
		} else {
 | 
			
		||||
			qs = o.QueryTable("merp").Filter("thing", thing).OrderBy("-created").Limit(50)
 | 
			
		||||
			qs = ms.db.QueryTable("merp").Filter("thing", thing).OrderBy("-created").Limit(50)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var merps []*models.Merp
 | 
			
		||||
@ -62,8 +48,8 @@ func getLatestMerps() gin.HandlerFunc {
 | 
			
		||||
		for _, merp := range merps {
 | 
			
		||||
			outelem := make(map[string]interface{})
 | 
			
		||||
			outelem["thing"] = merp.Thing
 | 
			
		||||
			outjs := decodeJSON([]byte(merp.Content))
 | 
			
		||||
			if outjs == nil {
 | 
			
		||||
			outjs, err := decodeJSON([]byte(merp.Content))
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				outelem["content"] = gin.H{}
 | 
			
		||||
			} else {
 | 
			
		||||
				outelem["content"] = outjs
 | 
			
		||||
@ -79,40 +65,13 @@ func getLatestMerps() gin.HandlerFunc {
 | 
			
		||||
			"with": output,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	return h
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getLatestMerp() gin.HandlerFunc {
 | 
			
		||||
	ThingRegex := thingRegex()
 | 
			
		||||
 | 
			
		||||
	h := func(c *gin.Context) {
 | 
			
		||||
		thing := c.Param("thing")
 | 
			
		||||
		if ThingRegex.MatchString(thing) == false {
 | 
			
		||||
			c.JSON(http.StatusPreconditionFailed, gin.H{
 | 
			
		||||
				"this":    "failed",
 | 
			
		||||
				"status":  http.StatusPreconditionFailed,
 | 
			
		||||
				"because": "invalid thing format, try [a-zA-Z0-9-_]",
 | 
			
		||||
			})
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		c.JSON(http.StatusOK, gin.H{
 | 
			
		||||
			"this": "succeeded",
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	return h
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleNewMerp() gin.HandlerFunc {
 | 
			
		||||
	// server startup time
 | 
			
		||||
 | 
			
		||||
	ThingRegex := thingRegex()
 | 
			
		||||
	// establish db connection *first*, before requests
 | 
			
		||||
	orm := models.GetOrmObject()
 | 
			
		||||
 | 
			
		||||
	h := func(c *gin.Context) {
 | 
			
		||||
func (ms *MerpServer) handleNewMerp() gin.HandlerFunc {
 | 
			
		||||
	return func(c *gin.Context) {
 | 
			
		||||
		// request time
 | 
			
		||||
		thing := c.Param("thing")
 | 
			
		||||
		if ThingRegex.MatchString(thing) == false {
 | 
			
		||||
		if ms.thingRegex.MatchString(thing) == false {
 | 
			
		||||
			c.JSON(http.StatusPreconditionFailed, gin.H{
 | 
			
		||||
				"this":    "failed",
 | 
			
		||||
				"status":  http.StatusPreconditionFailed,
 | 
			
		||||
@ -159,7 +118,7 @@ func handleNewMerp() gin.HandlerFunc {
 | 
			
		||||
			UUID:    u.String(),
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		_, err := orm.Insert(&merp)
 | 
			
		||||
		_, err := ms.db.Insert(&merp)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			c.JSON(
 | 
			
		||||
@ -185,6 +144,4 @@ func handleNewMerp() gin.HandlerFunc {
 | 
			
		||||
			},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return h
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										122
									
								
								server.go
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								server.go
									
									
									
									
									
								
							@ -1,27 +1,78 @@
 | 
			
		||||
package merp
 | 
			
		||||
 | 
			
		||||
//3456789112345676892123456789312345678941234567895123456789612345678971234567898
 | 
			
		||||
 | 
			
		||||
import "encoding/json"
 | 
			
		||||
import "fmt"
 | 
			
		||||
import "net/http"
 | 
			
		||||
import "os"
 | 
			
		||||
import "regexp"
 | 
			
		||||
import "strconv"
 | 
			
		||||
import "time"
 | 
			
		||||
 | 
			
		||||
//import "github.com/rs/zerolog/log"
 | 
			
		||||
import "github.com/didip/tollbooth"
 | 
			
		||||
import "github.com/didip/tollbooth_gin"
 | 
			
		||||
import "github.com/gin-gonic/gin"
 | 
			
		||||
import "github.com/dn365/gin-zerolog"
 | 
			
		||||
import "github.com/thoas/stats"
 | 
			
		||||
 | 
			
		||||
// ServeForever causes merp to serve http forever
 | 
			
		||||
func ServeForever() {
 | 
			
		||||
	s := getServer()
 | 
			
		||||
	s.ListenAndServe()
 | 
			
		||||
import "github.com/astaxie/beego/orm"
 | 
			
		||||
import _ "github.com/lib/pq" //revive:disable-line
 | 
			
		||||
 | 
			
		||||
type MerpServer struct {
 | 
			
		||||
	db         orm.Ormer
 | 
			
		||||
	debug      bool
 | 
			
		||||
	gin        *gin.Engine
 | 
			
		||||
	port       uint
 | 
			
		||||
	server     *http.Server
 | 
			
		||||
	stats      *stats.Stats
 | 
			
		||||
	thingRegex *regexp.Regexp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getHealthCheckHandler() http.HandlerFunc {
 | 
			
		||||
func NewMerpServer() *MerpServer {
 | 
			
		||||
	ms := new(MerpServer)
 | 
			
		||||
	ms.init()
 | 
			
		||||
	return ms
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ms *MerpServer) init() {
 | 
			
		||||
 | 
			
		||||
	ms.thingRegex = regexp.MustCompile(`^[a-zA-Z0-9\_\-]+$`)
 | 
			
		||||
 | 
			
		||||
	if os.Getenv("DEBUG") != "" {
 | 
			
		||||
		ms.debug = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ms.port = 8080
 | 
			
		||||
	var s uint64
 | 
			
		||||
	var err error
 | 
			
		||||
	if os.Getenv("PORT") != "" {
 | 
			
		||||
		if s, err = strconv.ParseUint(os.Getenv("PORT"), 10, 64); err == nil {
 | 
			
		||||
		} else {
 | 
			
		||||
			panic("invalid PORT in environment")
 | 
			
		||||
		}
 | 
			
		||||
		ms.port = uint(s)
 | 
			
		||||
	}
 | 
			
		||||
	ms.connectDB()
 | 
			
		||||
	ms.setupRoutes()
 | 
			
		||||
 | 
			
		||||
	ms.server = &http.Server{
 | 
			
		||||
		Addr:           fmt.Sprintf(":%s", ms.port),
 | 
			
		||||
		Handler:        ms.gin,
 | 
			
		||||
		ReadTimeout:    10 * time.Second,
 | 
			
		||||
		WriteTimeout:   10 * time.Second,
 | 
			
		||||
		MaxHeaderBytes: 1 << 20,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ms *MerpServer) connectDB() {
 | 
			
		||||
	ms.db = GetDB()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ServeForever causes merp to serve http forever
 | 
			
		||||
func (ms *MerpServer) ServeForever() {
 | 
			
		||||
	ms.server.ListenAndServe()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ms *MerpServer) HealthCheckHandler() http.HandlerFunc {
 | 
			
		||||
	return func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		result := gin.H{
 | 
			
		||||
			"status": "ok",
 | 
			
		||||
@ -38,24 +89,23 @@ func getHealthCheckHandler() http.HandlerFunc {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getStatsHandler(middleware *stats.Stats) http.HandlerFunc {
 | 
			
		||||
func (ms *MerpServer) StatsHandler() http.HandlerFunc {
 | 
			
		||||
	return func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		w.Header().Set("Content-Type", "application/json")
 | 
			
		||||
		stats := middleware.Data()
 | 
			
		||||
		stats := ms.stats.Data()
 | 
			
		||||
		b, _ := json.Marshal(stats)
 | 
			
		||||
		w.Write(b)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getRouter() *gin.Engine {
 | 
			
		||||
 | 
			
		||||
	if os.Getenv("DEBUG") == "" {
 | 
			
		||||
func (ms *MerpServer) setupRoutes() {
 | 
			
		||||
	if !ms.debug {
 | 
			
		||||
		gin.SetMode(gin.ReleaseMode)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	limiter := tollbooth.NewLimiter(5, nil)
 | 
			
		||||
 | 
			
		||||
	statsMiddleware := stats.New()
 | 
			
		||||
	ms.stats = stats.New()
 | 
			
		||||
 | 
			
		||||
	// empty router
 | 
			
		||||
	r := gin.New()
 | 
			
		||||
@ -67,41 +117,19 @@ func getRouter() *gin.Engine {
 | 
			
		||||
	r.Use(ginzerolog.Logger("gin"))
 | 
			
		||||
 | 
			
		||||
	r.Use(func(c *gin.Context) {
 | 
			
		||||
		beginning, recorder := statsMiddleware.Begin(c.Writer)
 | 
			
		||||
		beginning, recorder := ms.stats.Begin(c.Writer)
 | 
			
		||||
		c.Next()
 | 
			
		||||
		statsMiddleware.End(beginning, stats.WithRecorder(recorder))
 | 
			
		||||
		ms.stats.End(beginning, stats.WithRecorder(recorder))
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	r.GET("/.well-known/healthcheck.json", gin.WrapF(getHealthCheckHandler()))
 | 
			
		||||
	r.GET("/admin/healthcheck.json", gin.WrapF(getHealthCheckHandler()))
 | 
			
		||||
	r.GET("/admin/stats.json", gin.WrapF(getStatsHandler(statsMiddleware)))
 | 
			
		||||
	r.GET("/admin/other.json", gin.WrapF(getStatsHandler(statsMiddleware)))
 | 
			
		||||
	r.GET("/.well-known/healthcheck.json", gin.WrapF(ms.HealthCheckHandler()))
 | 
			
		||||
	r.GET("/admin/healthcheck.json", gin.WrapF(ms.HealthCheckHandler()))
 | 
			
		||||
	r.GET("/admin/stats.json", gin.WrapF(ms.StatsHandler()))
 | 
			
		||||
	r.GET("/admin/other.json", gin.WrapF(ms.StatsHandler()))
 | 
			
		||||
	r.GET("/merp/for/:thing", tollbooth_gin.LimitHandler(limiter), ms.handleNewMerp())
 | 
			
		||||
	r.GET("/get/latest/merp/for/:thing", tollbooth_gin.LimitHandler(limiter), ms.getLatestMerps())
 | 
			
		||||
	r.GET("/get/latest/merps", tollbooth_gin.LimitHandler(limiter), ms.getLatestMerps())
 | 
			
		||||
	r.GET("/get/merps/for/:thing", tollbooth_gin.LimitHandler(limiter), ms.getLatestMerps())
 | 
			
		||||
 | 
			
		||||
	// call it, it returns the appropriate handler function
 | 
			
		||||
	// so we can execute some code at startup time
 | 
			
		||||
	// and not just request time
 | 
			
		||||
	r.GET("/merp/for/:thing", tollbooth_gin.LimitHandler(limiter), handleNewMerp())
 | 
			
		||||
	r.GET("/get/latest/merp/for/:thing", tollbooth_gin.LimitHandler(limiter), getLatestMerp())
 | 
			
		||||
	r.GET("/get/latest/merps", tollbooth_gin.LimitHandler(limiter), getLatestMerps())
 | 
			
		||||
	r.GET("/get/merps/for/:thing", tollbooth_gin.LimitHandler(limiter), getLatestMerps())
 | 
			
		||||
 | 
			
		||||
	return r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getServer() *http.Server {
 | 
			
		||||
	r := getRouter()
 | 
			
		||||
 | 
			
		||||
	port := "8080"
 | 
			
		||||
	if os.Getenv("PORT") != "" {
 | 
			
		||||
		port = os.Getenv("PORT")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s := &http.Server{
 | 
			
		||||
		Addr:           fmt.Sprintf(":%s", port),
 | 
			
		||||
		Handler:        r,
 | 
			
		||||
		ReadTimeout:    10 * time.Second,
 | 
			
		||||
		WriteTimeout:   10 * time.Second,
 | 
			
		||||
		MaxHeaderBytes: 1 << 20,
 | 
			
		||||
	}
 | 
			
		||||
	return s
 | 
			
		||||
	ms.gin = r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user