You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
3.6 KiB
147 lines
3.6 KiB
package cmd |
|
|
|
import ( |
|
"context" |
|
"encoding/json" |
|
"fmt" |
|
"net/http" |
|
"net/http/httputil" |
|
"os" |
|
"os/signal" |
|
"syscall" |
|
"time" |
|
|
|
"github.com/gorilla/mux" |
|
|
|
log "github.com/sirupsen/logrus" |
|
"github.com/spf13/cobra" |
|
) |
|
|
|
var scheme, key, cert string |
|
var returnStatusCode, port int |
|
|
|
type responseYesSir struct { |
|
Message string `json:"message,omitempty"` |
|
Status int `json:"status,omitempty"` |
|
} |
|
|
|
// runCmd represents the run command |
|
var runCmd = &cobra.Command{ |
|
Use: "run", |
|
Short: "Run the mock API server", |
|
Long: `Start serving!`, |
|
Run: func(cmd *cobra.Command, args []string) { |
|
|
|
log.SetFormatter(&log.TextFormatter{ |
|
DisableColors: false, |
|
FullTimestamp: true, |
|
}) |
|
log.SetOutput(os.Stdout) |
|
|
|
//Capture signals to correctly close channels and connections |
|
sigc := make(chan os.Signal, 1) |
|
var srv http.Server |
|
|
|
signal.Notify(sigc, |
|
syscall.SIGHUP, |
|
syscall.SIGINT, |
|
syscall.SIGTERM, |
|
syscall.SIGQUIT) |
|
|
|
go func() { |
|
s := <-sigc |
|
switch s { |
|
case os.Interrupt: |
|
log.Debug("Interrupt received. Closing connections...") |
|
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second) |
|
srv.Shutdown(ctx) |
|
os.Exit(0) |
|
|
|
case syscall.SIGTERM: |
|
log.Debug("Termination received. Closing connections...") |
|
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second) |
|
srv.Shutdown(ctx) |
|
os.Exit(-1) |
|
default: |
|
log.Debug("Closing connections...") |
|
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second) |
|
srv.Shutdown(ctx) |
|
os.Exit(-2) |
|
} |
|
}() |
|
|
|
//Create Router for REST interface |
|
muxRouter := mux.NewRouter() |
|
muxRouter.PathPrefix("/").HandlerFunc(getInfo) |
|
|
|
//Starting up server |
|
log.Info("Starting up " + ApplicationName + " on port " + fmt.Sprintf("%v", port)) |
|
|
|
if scheme == "https" { |
|
log.Error(http.ListenAndServeTLS(fmt.Sprintf(":%v", port), cert, key, muxRouter)) |
|
} else { |
|
srv.Addr = fmt.Sprintf(":%v", port) |
|
srv.Handler = muxRouter |
|
if err := srv.ListenAndServe(); err != nil { |
|
log.Error("%s\n" + fmt.Sprintf("%v", err)) |
|
} |
|
} |
|
}, |
|
} |
|
|
|
func init() { |
|
rootCmd.AddCommand(runCmd) |
|
runCmd.Flags().StringVarP(&scheme, "scheme", "s", "http", "Scheme http|https") |
|
runCmd.Flags().IntVarP(&returnStatusCode, "return", "r", 200, "HTTP return code (200,404,500)") |
|
runCmd.Flags().IntVarP(&port, "port", "p", 8888, "Port to listen on") |
|
runCmd.Flags().StringVarP(&cert, "cert", "c", "", "Path to the server TLS certificate file (only for https)") |
|
runCmd.Flags().StringVarP(&key, "key", "k", "", "Path to the server TLS certificate key file (only for https)") |
|
|
|
if scheme != "https" && scheme != "http" { |
|
log.Error("Scheme needs to be http or https") |
|
os.Exit(-1) |
|
} |
|
|
|
if scheme == "https" && (cert == "" || key == "") { |
|
log.Error("Need a certificate and a key for https!") |
|
os.Exit(-1) |
|
} |
|
} |
|
|
|
func getInfo(w http.ResponseWriter, r *http.Request) { |
|
w.Header().Set("Content-Type", "application/json") |
|
w.Header().Set("Access-Control-Allow-Origin", "*") |
|
|
|
connData := fmt.Sprintf("%v:%v %v", r.RemoteAddr, r.RequestURI, r.Method) |
|
callback := r.URL.Query().Get("callback") |
|
|
|
log.Info("Request from " + connData) |
|
req, _ := httputil.DumpRequest(r, true) |
|
log.Info(fmt.Sprintf("%s", req)) |
|
|
|
//Send them over the connection |
|
switch returnStatusCode { |
|
case 200: |
|
w.WriteHeader(http.StatusOK) |
|
case 500: |
|
w.WriteHeader(http.StatusInternalServerError) |
|
case 404: |
|
w.WriteHeader(http.StatusNotFound) |
|
default: |
|
w.WriteHeader(http.StatusOK) |
|
returnStatusCode = 200 |
|
} |
|
|
|
stat := responseYesSir{ |
|
Message: fmt.Sprintf("%s", req), |
|
Status: returnStatusCode, |
|
} |
|
|
|
resp, _ := json.Marshal(stat) |
|
|
|
if callback != "" { |
|
fmt.Fprintf(w, "%s(%s)", callback, resp) |
|
} else { |
|
w.Write(resp) |
|
} |
|
}
|
|
|