Skip to content

Commit

Permalink
Separate http handlers from main
Browse files Browse the repository at this point in the history
  • Loading branch information
xtrafrancyz committed Dec 15, 2017
1 parent 727330b commit f9a6fbd
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 148 deletions.
2 changes: 1 addition & 1 deletion backend/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import (
"encoding/json"
"errors"
"io/ioutil"
"log"
"os"
pathpkg "path"
"sync"
"time"
"log"
)

type File struct {
Expand Down
156 changes: 9 additions & 147 deletions server.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package main

import (
"encoding/json"
"flag"
"fmt"
"log"
"math/rand"
"strings"
"time"

"github.com/GeertJohan/go.rice"
"github.com/qiangxue/fasthttp-routing"
"github.com/valyala/fasthttp"
"github.com/vharitonsky/iniflags"
bk "github.com/xtrafrancyz/golish/backend"
"github.com/xtrafrancyz/golish/backend"
)

var Config struct {
Expand All @@ -35,9 +30,6 @@ var Config struct {
filePath string
}

var backend bk.Backend
var adminFiles *rice.Box

func main() {
rand.Seed(time.Now().UTC().UnixNano())

Expand All @@ -55,11 +47,12 @@ func main() {

iniflags.Parse()

var err error
var err error = nil
var storage backend.Backend = nil
if Config.backend == "mysql" {
backend, err = bk.NewMysql(Config.slugLength, Config.mysqlHost, Config.mysqlUser, Config.mysqlPassword, Config.mysqlDatabase)
storage, err = backend.NewMysql(Config.slugLength, Config.mysqlHost, Config.mysqlUser, Config.mysqlPassword, Config.mysqlDatabase)
} else if Config.backend == "file" {
backend, err = bk.NewFile(Config.slugLength, Config.filePath)
storage, err = backend.NewFile(Config.slugLength, Config.filePath)
} else {
log.Fatalf("backend must be 'mysql' or 'file'")
return
Expand All @@ -69,140 +62,9 @@ func main() {
return
}

adminFiles = rice.MustFindBox("admin")
adminFiles.HTTPBox()

router := routing.New()
router.Get("/", handleRoot)
router.Get("/<slug:[a-zA-Z0-9]+>", handleSlug)
adminGroup := router.Group("/@"+Config.adminPath, addACAO)
adminGroup.Get("/list", handleList)
adminGroup.Post("/create", handleCreate)
adminGroup.Post("/delete", handleDelete)
adminGroup.Post("/edit", handleEdit)
adminGroup.Get("/<file:.*>", handleAdminRoot)

server := &fasthttp.Server{
Handler: router.HandleRequest,
ReduceMemoryUsage: true,
}

log.Printf("Starting server on http://%s:%d", Config.host, Config.port)
err = server.ListenAndServe(fmt.Sprintf("%s:%d", Config.host, Config.port))

if err != nil {
log.Fatalf("error in fasthttp server: %s", err)
web := &web{
backend: storage,
adminFiles: rice.MustFindBox("admin"),
}
}

func addACAO(c *routing.Context) error {
c.Response.Header.Set("Access-Control-Allow-Origin", "*")
return nil
}

func handleRoot(c *routing.Context) error {
if Config.defaultRedirect != "" {
c.Redirect(Config.defaultRedirect, fasthttp.StatusFound)
} else {
c.NotFound()
}
return nil
}

func handleSlug(c *routing.Context) error {
log.Print(string(c.URI().Path()))
full := backend.TryClickLink(c.Param("slug"))

if full != nil {
c.Redirect(full.Url, fasthttp.StatusFound)
} else {
c.NotFound()
}

return nil
}

func handleAdminRoot(c *routing.Context) error {
path := "/" + c.Param("file")
if path == "/" {
path = "/index.html"
}
log.Print("{admin}" + path)
bytes, err := adminFiles.Bytes(path)
if err != nil {
c.NotFound()
} else {
if strings.HasSuffix(path, ".html") {
c.Response.Header.Set("Content-Type", "text/html")
} else if strings.HasSuffix(path, ".css") {
c.Response.Header.Set("Content-Type", "text/css")
} else if strings.HasSuffix(path, ".js") {
c.Response.Header.Set("Content-Type", "application/javascript")
} else if strings.HasSuffix(path, ".png") {
c.Response.Header.Set("Content-Type", "image/png")
}
c.SetStatusCode(fasthttp.StatusOK)
c.Write(bytes)
}
return nil
}

func handleList(c *routing.Context) error {
log.Print("{admin}/list")
links := backend.GetAllLinks()
marshaled, _ := json.Marshal(links)
c.Response.Header.Set("Content-Type", "application/json")
c.Write(marshaled)
return nil
}

func handleCreate(c *routing.Context) error {
url := c.PostArgs().Peek("url")
log.Printf("{admin}/create (url=%s)", url)
if len(url) == 0 {
c.SetStatusCode(fasthttp.StatusBadRequest)
} else {
var link *bk.Link
var err error
slug := c.PostArgs().Peek("slug")
if len(slug) == 0 {
link, err = backend.Create(string(url))
} else {
link, err = backend.CreateCustom(string(slug), string(url))
}
var marshaled []byte
if err != nil {
marshaled, _ = json.Marshal(OperationError{
Error: true,
Message: err.Error(),
})
} else {
marshaled, _ = json.Marshal(link)
}
c.Response.Header.Set("Content-Type", "application/json")
c.Write(marshaled)
}
return nil
}

func handleDelete(c *routing.Context) error {
slug := c.PostArgs().Peek("slug")
log.Printf("{admin}/delete (slug=%s)", slug)
backend.Delete(string(slug))
c.SetStatusCode(fasthttp.StatusOK)
return nil
}

func handleEdit(c *routing.Context) error {
slug := c.PostArgs().Peek("slug")
url := c.PostArgs().Peek("url")
log.Printf("{admin}/edit (slug=%s, url=%s)", slug, url)
backend.Edit(string(slug), string(url))
c.SetStatusCode(fasthttp.StatusOK)
return nil
}

type OperationError struct {
Error bool `json:"error"`
Message string `json:"message"`
web.run()
}
154 changes: 154 additions & 0 deletions web.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package main

import (
"encoding/json"
"fmt"
"log"
"strings"

"github.com/GeertJohan/go.rice"
"github.com/qiangxue/fasthttp-routing"
"github.com/valyala/fasthttp"
"github.com/xtrafrancyz/golish/backend"
)

type web struct {
backend backend.Backend
adminFiles *rice.Box
}

func (w *web) run() {
router := routing.New()
router.Get("/", w.handleRoot)
router.Get("/<slug:[a-zA-Z0-9]+>", w.handleSlug)
adminGroup := router.Group("/@"+Config.adminPath, w.addACAO)
adminGroup.Get("/list", w.handleList)
adminGroup.Post("/create", w.handleCreate)
adminGroup.Post("/delete", w.handleDelete)
adminGroup.Post("/edit", w.handleEdit)
adminGroup.Get("/<file:.*>", w.handleAdminRoot)

server := &fasthttp.Server{
Handler: router.HandleRequest,
ReduceMemoryUsage: true,
}

log.Printf("Starting server on http://%s:%d", Config.host, Config.port)
err := server.ListenAndServe(fmt.Sprintf("%s:%d", Config.host, Config.port))

if err != nil {
log.Fatalf("error in fasthttp server: %s", err)
}
}

func (w *web) addACAO(c *routing.Context) error {
c.Response.Header.Set("Access-Control-Allow-Origin", "*")
return nil
}

func (w *web) handleRoot(c *routing.Context) error {
if Config.defaultRedirect != "" {
c.Redirect(Config.defaultRedirect, fasthttp.StatusFound)
} else {
c.NotFound()
}
return nil
}

func (w *web) handleSlug(c *routing.Context) error {
log.Print(string(c.URI().Path()))
full := w.backend.TryClickLink(c.Param("slug"))

if full != nil {
c.Redirect(full.Url, fasthttp.StatusFound)
} else {
c.NotFound()
}

return nil
}

func (w *web) handleAdminRoot(c *routing.Context) error {
path := "/" + c.Param("file")
if path == "/" {
path = "/index.html"
}
log.Print("{admin}" + path)
bytes, err := w.adminFiles.Bytes(path)
if err != nil {
c.NotFound()
} else {
if strings.HasSuffix(path, ".html") {
c.Response.Header.Set("Content-Type", "text/html")
} else if strings.HasSuffix(path, ".css") {
c.Response.Header.Set("Content-Type", "text/css")
} else if strings.HasSuffix(path, ".js") {
c.Response.Header.Set("Content-Type", "application/javascript")
} else if strings.HasSuffix(path, ".png") {
c.Response.Header.Set("Content-Type", "image/png")
}
c.SetStatusCode(fasthttp.StatusOK)
c.Write(bytes)
}
return nil
}

func (w *web) handleList(c *routing.Context) error {
log.Print("{admin}/list")
links := w.backend.GetAllLinks()
marshaled, _ := json.Marshal(links)
c.Response.Header.Set("Content-Type", "application/json")
c.Write(marshaled)
return nil
}

func (w *web) handleCreate(c *routing.Context) error {
url := c.PostArgs().Peek("url")
log.Printf("{admin}/create (url=%s)", url)
if len(url) == 0 {
c.SetStatusCode(fasthttp.StatusBadRequest)
} else {
var link *backend.Link = nil
var err error = nil
slug := c.PostArgs().Peek("slug")
if len(slug) == 0 {
link, err = w.backend.Create(string(url))
} else {
link, err = w.backend.CreateCustom(string(slug), string(url))
}
var marshaled []byte
if err != nil {
marshaled, _ = json.Marshal(OperationError{
Error: true,
Message: err.Error(),
})
} else {
marshaled, _ = json.Marshal(link)
}
c.Response.Header.Set("Content-Type", "application/json")
c.Write(marshaled)
}
return nil
}

func (w *web) handleDelete(c *routing.Context) error {
slug := c.PostArgs().Peek("slug")
log.Printf("{admin}/delete (slug=%s)", slug)
w.backend.Delete(string(slug))
c.SetStatusCode(fasthttp.StatusOK)
return nil
}

func (w *web) handleEdit(c *routing.Context) error {
slug := c.PostArgs().Peek("slug")
url := c.PostArgs().Peek("url")
log.Printf("{admin}/edit (slug=%s, url=%s)", slug, url)
w.backend.Edit(string(slug), string(url))
c.SetStatusCode(fasthttp.StatusOK)
return nil
}

type OperationError struct {
Error bool `json:"error"`
Message string `json:"message"`
}

0 comments on commit f9a6fbd

Please sign in to comment.