Skip to content

Instantly share code, notes, and snippets.

@iolalla
Created December 17, 2018 17:01
Show Gist options
  • Select an option

  • Save iolalla/cf7b3a65d1b2de9286066efe4114f26b to your computer and use it in GitHub Desktop.

Select an option

Save iolalla/cf7b3a65d1b2de9286066efe4114f26b to your computer and use it in GitHub Desktop.
Minimal go server with logging and all the headers visible.
package main
/**
* Minimal go server with logging and all the headers visible.
*
* To build it simply
* '$go build ms.go'
*
* # To lear how to use it simply:
* $ ms --help
* Usage of ms:
* -dir string
* dir to serve the content (default "src")
* -port string
* server listen address (default ":8080")
* # This command will start a server in the 8080 and serve content from src dir
* $ms
* # This will start in port 8181 and dir public
* $ms --port :8181 --dir public
*
*/
import (
"flag"
"fmt"
"log"
"net/http"
"os"
"strings"
"time"
)
type key int
var (
listenAddr string
healthy int32
)
func main() {
// This is to manage parameters or flags for the program
var port, dir string
flag.StringVar(&port, "port", ":8080", "server listen address")
flag.StringVar(&dir, "dir", "src", "dir to serve the content")
flag.Parse()
// This is the line to configure the logger, simply to print in the console
logger := log.New(os.Stdout, "http: ", log.LstdFlags)
logger.Println("Server is starting...")
router := http.NewServeMux()
router.Handle("/", http.FileServer(http.Dir(dir)))
server := &http.Server{
Addr: port,
Handler: logging(logger)(router),
ErrorLog: logger,
ReadTimeout: 5 * time.Second, // Allways is better to have TO
WriteTimeout: 10 * time.Second,
IdleTimeout: 15 * time.Second,
}
logger.Fatal(server.ListenAndServe())
}
// Manages the logger and adds an anonymous function to wrap the handler
func logging(logger *log.Logger) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
logger.Println(r.Method, r.URL.Path, r.RemoteAddr, r.UserAgent(), "\n")
logger.Println(formatRequest(r))
}()
next.ServeHTTP(w, r)
})
}
}
// formatRequest shows all the headers of a request
func formatRequest(r *http.Request) string {
// Create return string
var request []string
// Add the request string
url := fmt.Sprintf("%v %v %v", r.Method, r.URL, r.Proto)
request = append(request, url)
// Add the host
request = append(request, fmt.Sprintf("Host: %v", r.Host))
// Loop through headers
for name, headers := range r.Header {
name = strings.ToLower(name)
for _, h := range headers {
request = append(request, fmt.Sprintf("%v: %v", name, h))
}
}
// If this is a POST, add post data
if r.Method == "POST" {
r.ParseForm()
request = append(request, "\n")
request = append(request, r.Form.Encode())
}
// Return the request as a string
return strings.Join(request, "\n")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment