diff options
| author | Mitchell Riedstra <mitch@riedstra.dev> | 2021-10-24 12:52:38 -0400 |
|---|---|---|
| committer | Mitchell Riedstra <mitch@riedstra.dev> | 2021-10-24 12:52:38 -0400 |
| commit | 268fcf7e6b671d4959a12111d5abf553bf0a201b (patch) | |
| tree | 6f5c46c9a765478eaae78d66f4b9aefc953bbd1a /cmd/server | |
| parent | d36b6a55c8fa4400cd39de717443e110e990a8a3 (diff) | |
| download | go-website-268fcf7e6b671d4959a12111d5abf553bf0a201b.tar.gz go-website-268fcf7e6b671d4959a12111d5abf553bf0a201b.tar.xz | |
Redis caching. Linter config and cleanup.
Diffstat (limited to 'cmd/server')
| -rw-r--r-- | cmd/server/app.go | 16 | ||||
| -rw-r--r-- | cmd/server/feed.go | 48 | ||||
| -rw-r--r-- | cmd/server/handlers.go | 17 | ||||
| -rw-r--r-- | cmd/server/main.go | 38 |
4 files changed, 93 insertions, 26 deletions
diff --git a/cmd/server/app.go b/cmd/server/app.go index 743a389..290b44a 100644 --- a/cmd/server/app.go +++ b/cmd/server/app.go @@ -1,8 +1,10 @@ package main import ( + "fmt" "os" + "github.com/gomodule/redigo/redis" "gopkg.in/yaml.v3" "riedstra.dev/mitch/go-website/page" ) @@ -10,6 +12,8 @@ import ( var FeedPrefixDefault = ".feeds" type App struct { + redisPool *redis.Pool + ReIndexPath string StaticDirectory string BaseTemplate string @@ -21,7 +25,7 @@ type App struct { Description string // aka, "subtitle" Author Author SiteURL string - FeedId string + FeedId string //nolint Updated page.PageTime FeedPrefix string } @@ -29,28 +33,34 @@ type App struct { func loadConf(fn string) (*App, error) { fh, err := os.Open(fn) if err != nil { - return nil, err + return nil, fmt.Errorf("loading config: %w", err) } + dec := yaml.NewDecoder(fh) app := &App{} + err = dec.Decode(app) if err != nil { - return nil, err + return nil, fmt.Errorf("decoding yaml: %w", err) } if app.StaticDirectory == "" { app.StaticDirectory = "static" } + if app.FeedPrefix == "" { app.FeedPrefix = FeedPrefixDefault } + if app.BaseTemplate != "" { page.BaseTemplate = app.BaseTemplate } + if app.DocumentSplit != "" { page.DocumentSplit = app.DocumentSplit } + if app.Suffix != "" { page.Suffix = app.Suffix } diff --git a/cmd/server/feed.go b/cmd/server/feed.go index c478365..880eeb4 100644 --- a/cmd/server/feed.go +++ b/cmd/server/feed.go @@ -16,8 +16,8 @@ import ( ) type Author struct { - Name string `xml:"name"` // Required - Uri string `xml:"uri,omitempty"` + Name string `xml:"name"` // Required + Uri string `xml:"uri,omitempty"` //nolint:golint,stylecheck Email string `xml:"email,omitempty"` } @@ -37,7 +37,7 @@ type Content struct { type Entry struct { // Spec requires this, autogenerated from Title and updated if otherwise // left empty - Id string `xml:"id"` + Id string `xml:"id"` //nolint:golint,stylecheck Title string `xml:"title"` // Required Updated *time.Time `xml:"updated"` // Required @@ -54,12 +54,13 @@ func (i Entry) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if i.Title == "" { errs = append(errs, "Title Cannot be empty") } + if i.Updated == nil { errs = append(errs, "Updated cannot be nil") } if len(errs) > 0 { - return errors.New(strings.Join(errs, ",")) + return errors.New(strings.Join(errs, ",")) //nolint:goerr113 } if i.Id == "" { @@ -71,6 +72,7 @@ func (i Entry) MarshalXML(e *xml.Encoder, start xml.StartElement) error { return e.EncodeElement(i2, start) } +//nolint:stylecheck,golint type Atom struct { Ns string `xml:"xmlns,attr"` Title string `xml:"title"` // Required @@ -87,18 +89,21 @@ func (a Atom) MarshalXML(e *xml.Encoder, start xml.StartElement) error { a.Ns = "http://www.w3.org/2005/Atom" errs := []string{} + if a.Id == "" { errs = append(errs, "ID Cannot be empty") } + if a.Author.Name == "" { errs = append(errs, "Author Name cannot be empty") } + if a.Updated == nil { errs = append(errs, "Updated cannot be empty") } if len(errs) > 0 { - return errors.New(strings.Join(errs, ",")) + return errors.New(strings.Join(errs, ",")) //nolint:goerr113 } start.Name = xml.Name{Local: "feed"} @@ -114,12 +119,15 @@ func (a Atom) MarshalXML(e *xml.Encoder, start xml.StartElement) error { // Relevant query parameters are: // // "content" if unset, or set to false content is omitted from the feed -// "limit=n" stop at "n" and return the feed +// "limit=n" stop at "n" and return the feed. // -func (a *App) FeedHandler(w http.ResponseWriter, r *http.Request) { +func (a *App) FeedHandler(w http.ResponseWriter, r *http.Request) { //nolint:funlen vars := mux.Vars(r) - var addContent bool - var limit int + + var ( + addContent bool + limit int + ) if _, ok := r.URL.Query()["content"]; ok { if r.URL.Query().Get("content") != "false" { @@ -137,20 +145,24 @@ func (a *App) FeedHandler(w http.ResponseWriter, r *http.Request) { tag, ok := vars["tag"] if !ok { http.Error(w, "Tag not found or supplied", http.StatusNotFound) + return } p := page.NewPage("index") + index, err := p.Index() if err != nil { log.Println(err) http.Error(w, "Internal server error", http.StatusInternalServerError) + return } pages, ok := index[tag] if !ok { http.Error(w, "Invalid tag", http.StatusNotFound) + return } @@ -158,6 +170,7 @@ func (a *App) FeedHandler(w http.ResponseWriter, r *http.Request) { for _, p := range dateless { log.Printf("Warning, page %s has no Date field. Skipping inclusion on feed", p) } + pages.SortDate() feed := &Atom{ @@ -180,22 +193,24 @@ func (a *App) FeedHandler(w http.ResponseWriter, r *http.Request) { } content := &bytes.Buffer{} + err := p.Render(content) if err != nil { log.Println(err) http.Error(w, "Internal server error", http.StatusInternalServerError) + return } entry := Entry{ Title: p.Title, Updated: &p.Date.Time, - Links: []Link{Link{Href: strings.Join([]string{a.SiteURL, p.Path()}, "/")}}, + Links: []Link{{Href: strings.Join([]string{a.SiteURL, p.Path()}, "/")}}, } if p.AuthorName != "" { entry.Author = &Author{ - Name: p.AuthorName, + Name: p.AuthorName, } if p.AuthorEmail != "" { entry.Author.Email = p.AuthorEmail @@ -207,13 +222,18 @@ func (a *App) FeedHandler(w http.ResponseWriter, r *http.Request) { } entries = append(entries, entry) - } feed.Entries = entries w.Header().Add("Content-type", "application/xml") - w.Write([]byte(xml.Header)) + + _, err = w.Write([]byte(xml.Header)) + if err != nil { + log.Println("Writing xml: ", err) + + return + } enc := xml.NewEncoder(w) enc.Indent("", " ") @@ -224,6 +244,4 @@ func (a *App) FeedHandler(w http.ResponseWriter, r *http.Request) { // Headers probably already sent, but we'll try anyway http.Error(w, "Internal server error", http.StatusInternalServerError) } - - return } diff --git a/cmd/server/handlers.go b/cmd/server/handlers.go index cb63774..869e5ba 100644 --- a/cmd/server/handlers.go +++ b/cmd/server/handlers.go @@ -7,14 +7,23 @@ import ( "github.com/gorilla/mux" "riedstra.dev/mitch/go-website/page" + "riedstra.dev/mitch/go-website/rediscache" ) func (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request) { rtr := mux.NewRouter() rtr.HandleFunc(a.ReIndexPath, a.RebuildIndexHandler) rtr.PathPrefix("/static/").Handler(a.StaticHandler()) - rtr.PathPrefix(fmt.Sprintf("/%s/{tag}", a.FeedPrefix)).HandlerFunc(a.FeedHandler) - rtr.PathPrefix("/").HandlerFunc(a.PageHandler) + rtr.PathPrefix(fmt.Sprintf("/%s/{tag}", a.FeedPrefix)).HandlerFunc( + a.FeedHandler) + + if a.redisPool != nil { + rtr.PathPrefix("/").Handler(rediscache.Handle( + a.redisPool, http.HandlerFunc(a.PageHandler))) + } else { + rtr.PathPrefix("/").Handler(http.HandlerFunc(a.PageHandler)) + } + rtr.ServeHTTP(w, r) } @@ -23,6 +32,7 @@ func (a *App) PageHandler(w http.ResponseWriter, r *http.Request) { if u == "/" { u = "/index" } + u = filepath.Join(".", u) page.RenderForPath(w, r, u) @@ -33,6 +43,7 @@ func (a *App) RebuildIndexHandler(w http.ResponseWriter, r *http.Request) { if u == "/" { u = "/index" } + u = filepath.Join(".", u) p := page.NewPage("index") @@ -44,7 +55,7 @@ func (a *App) RebuildIndexHandler(w http.ResponseWriter, r *http.Request) { } // StaticHandler simply returns a HTTP handler that looks at the current -// directory and exposes `static` via HTTP `/static` +// directory and exposes `static` via HTTP `/static`. func (a *App) StaticHandler() http.Handler { return http.StripPrefix("/static/", http.FileServer(http.Dir(a.StaticDirectory))) } diff --git a/cmd/server/main.go b/cmd/server/main.go index 00aecbf..d76f938 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -3,12 +3,13 @@ package main import ( "flag" "fmt" - "gopkg.in/yaml.v3" "log" "net/http" "os" "time" + "github.com/gomodule/redigo/redis" + "gopkg.in/yaml.v3" "riedstra.dev/mitch/go-website/page" ) @@ -19,17 +20,28 @@ func VersionPrint() { os.Exit(0) } -func main() { +func main() { //nolint:funlen fl := flag.NewFlagSet("Website", flag.ExitOnError) listen := fl.String("l", "0.0.0.0:8001", "Listening address") directory := fl.String("d", ".", "Directory to serve.") version := fl.Bool("v", false, "Print the version then exit") confFn := fl.String("c", "conf.yml", "Location for the config file") verbose := fl.Bool("V", false, "Be more verbose ( dump config, etc ) ") - fl.StringVar(&page.TimeFormat, "T", page.TimeFormat, "Set the page time format, be careful with this") + fl.StringVar(&page.TimeFormat, "T", page.TimeFormat, + "Set the page time format, be careful with this") + defaultIndexPath := "/reIndex" + indexPath := fl.String("i", defaultIndexPath, "Path in which, when called will rebuild the index and clear the cache") + redisAddr := fl.String("r", "127.0.0.1:6379", + "Redis server set to \"\" to disable") + + pageTimeout := fl.Int("timeout", 15, "Seconds until page timeout for read and write") + + fl.BoolVar(&page.CacheIndex, "cache-index", true, + "If set to false do not cache index") + _ = fl.Parse(os.Args[1:]) if *version { @@ -43,6 +55,7 @@ func main() { app, err := loadConf(*confFn) if err != nil { log.Println(err) + app = &App{} } @@ -50,6 +63,21 @@ func main() { app.ReIndexPath = *indexPath } + if *redisAddr != "" { + app.redisPool = &redis.Pool{ + MaxIdle: 80, //nolint:gomnd + MaxActive: 12000, //nolint:gomnd + Dial: func() (redis.Conn, error) { + c, err := redis.Dial("tcp", *redisAddr) + if err != nil { + log.Println("Redis dial error: ", err) + } + + return c, err //nolint + }, + } + } + if *verbose { b, _ := yaml.Marshal(app) os.Stderr.Write(b) @@ -58,8 +86,8 @@ func main() { srv := &http.Server{ Handler: app, Addr: *listen, - WriteTimeout: 15 * time.Second, - ReadTimeout: 15 * time.Second, + WriteTimeout: time.Duration(*pageTimeout) * time.Second, + ReadTimeout: time.Duration(*pageTimeout) * time.Second, } log.Fatal(srv.ListenAndServe()) } |
