From c858e99d06397eace6d07c581c407729153bc295 Mon Sep 17 00:00:00 2001 From: Alexandre Tuleu Date: Mon, 25 Jan 2016 14:23:20 +0100 Subject: [PATCH] Uses narco with logging We have a finner control of what we serve --- .gitignore | 1 + main.go | 5 +++ router.go | 118 ++++++++++++++++++++++++++++++++++------------------- 3 files changed, 81 insertions(+), 43 deletions(-) diff --git a/.gitignore b/.gitignore index a5d0e1f..29f3380 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ _testmain.go /cover.out *.bar.satellite/ +tmp/ diff --git a/main.go b/main.go index 40575af..658ec7b 100644 --- a/main.go +++ b/main.go @@ -50,6 +50,11 @@ func newAppData(opts Options) (*appData, error) { return nil, err } + err = os.MkdirAll(filepath.Join("tmp", "log"), 0755) + if err != nil { + return nil, err + } + res := &appData{ opts: opts, errors: make(chan error, 10), diff --git a/router.go b/router.go index 0ed1a56..7750208 100644 --- a/router.go +++ b/router.go @@ -3,76 +3,108 @@ package main import ( "encoding/json" "fmt" + "io" "net/http" + "os" "path" + "path/filepath" "regexp" "strconv" "strings" + "ponyo.epfl.ch/gitlab/alexandre.tuleu/narco" + bleve_http "github.com/blevesearch/bleve/http" - "github.com/gorilla/mux" + "github.com/codemodus/chain" + "github.com/julienschmidt/httprouter" + "golang.org/x/net/context" ) var rxExt = regexp.MustCompile(`[0-9]+`) func (a *appData) buildRouter() http.Handler { - router := mux.NewRouter() + router := httprouter.New() + + logger := narco.NewLogger() + f, err := os.Create(filepath.Join("tmp", "log", "access.log")) + if err != nil { + panic(err.Error()) + } + logger.SetOutput(f) + recoverer := narco.NewRecoverer() + ctx := narco.WithErrorFormatter(context.Background(), narco.BasicHTMLErrorFormatter) + ch := chain.New(logger.Wrap(), recoverer.Wrap()).SetContext(ctx) bleve_http.RegisterIndexName("album", a.index) searchHandler := bleve_http.NewSearchHandler("album") - router.Handle("/api/search", searchHandler).Methods("POST") + router.POST("/api/search", narco.EndChain(ch, + narco.HandlerFunc(func(_ context.Context, w http.ResponseWriter, req *http.Request, _ httprouter.Params) { + searchHandler.ServeHTTP(w, req) + }))) - router.Handle("/api/recents", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - albums, err := a.db.ByPurchaseDate() + router.GET("/api/recents", narco.EndChain(ch, + narco.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + albums, err := a.db.ByPurchaseDate() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } + if err != nil { + narco.Error(ctx, w, err, http.StatusInternalServerError) + return + } - enc := json.NewEncoder(w) - err = enc.Encode(albums) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } - })).Methods("GET") + enc := json.NewEncoder(w) + err = enc.Encode(albums) + if err != nil { + narco.Error(ctx, w, err, http.StatusInternalServerError) + } + }))) - router.Handle("/api/albums/{id:[0-9]+}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - var id uint64 - var err error - var idStr string - var ok bool - if len(vars) != 0 { - idStr, ok = vars["id"] - if ok == true { + router.GET("/api/albums/:id", narco.EndChain(ch, + narco.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + var id uint64 + var err error + idStr := ps.ByName("id") + if len(idStr) > 0 { id, err = strconv.ParseUint(idStr, 10, 64) } - } - if ok == false || err != nil { - http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) - return - } + if len(idStr) == 0 || err != nil { + narco.Error(ctx, w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + return + } - albumUnsafe, err := a.db.Get(AlbumID(id)) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } + albumUnsafe, err := a.db.Get(AlbumID(id)) + if err != nil { + narco.Error(ctx, w, err, http.StatusInternalServerError) + } - album := *albumUnsafe - ext := path.Ext(album.CoverURL) - ext = strings.ToLower(rxExt.ReplaceAllString(ext, "")) - album.CoverURL = fmt.Sprintf("/covers/%d%s", album.ID, ext) + album := *albumUnsafe + ext := path.Ext(album.CoverURL) + ext = strings.ToLower(rxExt.ReplaceAllString(ext, "")) + album.CoverURL = fmt.Sprintf("/covers/%d%s", album.ID, ext) - enc := json.NewEncoder(w) - if err := enc.Encode(album); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } - })).Methods("GET") + enc := json.NewEncoder(w) + if err := enc.Encode(album); err != nil { + narco.Error(ctx, w, err, http.StatusInternalServerError) + } + }))) - router.PathPrefix("/").Handler(http.FileServer(http.Dir("static"))) + dirs := []string{"css", "js", "img"} + for _, d := range dirs { + router.ServeFiles(path.Join("/", d, "/*filepath"), http.Dir(filepath.Join("static", d))) + } + + router.GET("/", narco.EndChain(ch, narco.HandlerFunc( + func(ctx context.Context, w http.ResponseWriter, req *http.Request, _ httprouter.Params) { + f, err := os.Open(filepath.Join("static", "index.html")) + if err != nil { + narco.Error(ctx, w, err, http.StatusInternalServerError) + return + } + defer closeOrPanic(f, filepath.Join("static", "index.html")) + + io.Copy(w, f) + }))) return router }