How to write a simple custom HTTP server in Go?
in order to work properly, myHandler
should be an object that satisfy the Handler Interface, in other words myHandler
should have method called ServeHTTP
.
For example, let's say that myHandler
is custom handler for showing the current time. The code should be like this
package main
import (
"fmt"
"net/http"
"time"
)
type timeHandler struct {
zone *time.Location
}
func (th *timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
tm := time.Now().In(th.zone).Format(time.RFC1123)
w.Write([]byte("The time is: " + tm))
}
func newTimeHandler(name string) *timeHandler {
return &timeHandler{zone: time.FixedZone(name, 0)}
}
func main() {
myHandler := newTimeHandler("EST")
//Custom http server
s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
err := s.ListenAndServe()
if err != nil {
fmt.Printf("Server failed: ", err.Error())
}
}
run this code and access http://localhost:8080/
in your browser. you should see formatted text like this
The time is: Sat, 30 Aug 2014 18:19:46 EST
(you should see different time.)
hope this help,
Further more reading
A Recap of Request Handling in Go
You either use a struct and define ServeHTTP
on it or simply wrap your function in a HandlerFunc
s := &http.Server{
Addr: ":8080",
Handler: http.HandlerFunc(myHandler),
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
You could also define a mux and add handlers to it before assigning it to the server like below.
func myHandler(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "hello, world!\n")
}
func main(){
// define a serveMux to handle routes
mux := http.NewServeMux()
// assign a route/todo to a handler myHandler
mux.HandleFunc("/todo", myHandler)
// assign a route/todo/notes to an anonymous func
mux.HandleFunc("/todo/notes", func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("Hello again."))
})
s := &http.Server{
Addr: ":8080",
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
if err := s.ListenAndServe(); err != nil {
log.Fatalf("server failed to start with error %v", err.Error())
}
}