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  }