github.com/ckxng/wakeup@v0.0.0-20190105202853-90356a5f5a15/src/wakeup/server/server.go (about) 1 // Copyright (c) 2015 Cameron King. All rights reserved. 2 // License: BSD 2-clause. 3 // Website: https://github.com/ckxng/wakeup 4 5 package server 6 7 import ( 8 "log" 9 "os" 10 "runtime" 11 "fmt" 12 "time" 13 "net/http" 14 "encoding/json" 15 "github.com/gorilla/mux" 16 "github.com/codegangsta/negroni" 17 "wakeup/config" 18 ) 19 20 var logger *log.Logger = log.New(os.Stdout, "[server] ", log.Lshortfile) 21 22 // a specialized version of http.HandlerFunc that returns (interface{}, error) 23 // and is intended to be wrapped by JSONDecorator 24 type JSONHandlerFunc func(http.ResponseWriter, *http.Request) (interface{}, error) 25 26 func Go(cfg *config.Config, c chan int) { 27 logger.Println("router = mux.NewRouter") 28 router := mux.NewRouter().StrictSlash(false) 29 30 logger.Println("router: adding controllers") 31 router.HandleFunc("/hello", handler) 32 router.HandleFunc("/json", JSONDecorator(jsonHandler)) 33 // add additional controller routes 34 35 logger.Println("router: adding static file server") 36 router.PathPrefix("/").Handler(http.FileServer(http.Dir("./assets/"))) 37 38 logger.Println("stack = negroni.New") 39 stack := negroni.New() 40 41 logger.Println("stack: adding middleware") 42 // add additional middleware 43 44 logger.Println("stack.UseHandler router") 45 stack.UseHandler(router) 46 47 http.Handle("/", stack) 48 49 listen_at := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port) 50 logger.Printf("http.ListenAndServe %s\n", listen_at) 51 if err := http.ListenAndServe(listen_at, nil); err != nil { 52 logger.Printf("error %s\n", err) 53 c <- 1 54 return 55 } 56 57 logger.Println("shutdown") 58 c <- 0 59 } 60 61 func handler(w http.ResponseWriter, req *http.Request) { 62 logger.Println("serve") 63 w.Header().Set("Content-Type", "text/html; charset=utf-8") 64 fmt.Fprintf(w, "This is Go server talking.<br>") 65 fmt.Fprintf(w, "Time on the server: %v<br>", 66 time.Now().Format("Jan 2, 2006 at 3:04pm (MST)")) 67 fmt.Fprintf(w, "Go version: %v<br>", runtime.Version()) 68 fmt.Fprintf(w, "<br>") 69 fmt.Fprintf(w, "Try <a href=/json>/json</a><br>") 70 } 71 72 func jsonHandler(http.ResponseWriter, *http.Request) (interface{}, error) { 73 return "ok", nil 74 } 75 76 // wraps JSONHanderFunc functions and provide JSON Content-type, marshaling, 77 // and HTTP error code functionality 78 func JSONDecorator(handler JSONHandlerFunc) http.HandlerFunc { 79 return func(w http.ResponseWriter, r *http.Request) { 80 data, err := handler(w,r) 81 82 payload := struct{ 83 Data interface{} `json:"data"` 84 Err interface{} `json:"err"` 85 } { 86 Data: data, 87 Err: err, 88 } 89 90 if err != nil { 91 payload.Err = err.Error() 92 } 93 94 w.Header().Set("Content-Type", "application/json") 95 if bPayload, merr := json.MarshalIndent(payload, "", " "); merr == nil { 96 if err != nil { 97 w.WriteHeader(500) 98 } 99 fmt.Fprint(w, string(bPayload)) 100 } else { 101 w.WriteHeader(500) 102 fmt.Fprintf(w, "{\"data\":\"\",\"err\":\"Marshal error: %s\"}", err) 103 } 104 } 105 }