Title Text
Golang HTTP server for pro
Thomas Perez
@scullwm
Meetup Golang Marseille
Thomas Perez
Lead dev backend
Go|PHP
twitter.com/scullwm
PepperReport.io 🌶
github.com/scullwm
HTTP Server for pro
HTTP Server for pro
import "net/http"
Server
ServeMux
Transport
Client
Response
Request
TLS
Flusher
HTTP2
Proxy
Push
package main
import (
"io"
"net/http"
)
func main() {
http.HandleFunc("/", helloWorldHandler)
http.ListenAndServe(":80", nil)
}
func helloWorldHandler(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello world!")
}
HTTP Server for pro
Let's start
THE END!
HTTP Server for pro
HTTP Server for pro
Log ?
Advanced routing ?
Security ?
Error ?
Who need a
"hello world" application ?
HTTP Server for pro
Advanced routing
HTTP Server for pro
package main
import (
"io"
"net/http"
"gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/products/{key}", ProductHandler).Name("product").Methods("GET")
r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
http.Handle("/", r)
}
https://github.com/gorilla/mux
HTTP Server for pro
func(http.Handler) http.Handler
Middleware
HTTP Server for pro
func doingThings(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("I'm doing things here, really!")
next.ServeHTTP(w, r)
})
}
HTTP Server for pro
func loggerHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
h.ServeHTTP(w, r)
log.Printf("<< %s %s %v", r.Method, r.URL.Path, time.Since(start))
})
}
Let's log response time
HTTP Server for pro
What about security?
HTTP Server for pro
There's a middleware for that
func checkAuth(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if ReadCookieHandler(r) {
h.ServeHTTP(w, r)
} else {
log.Printf("Not authorized %s", 401)
}
h.ServeHTTP(w, r)
})
}
HTTP Server for pro
const cookieName = "mycookiename"
var hashKey = []byte(securecookie.GenerateRandomKey(32))
var blockKey = []byte(securecookie.GenerateRandomKey(32))
var sc = securecookie.New(hashKey, blockKey)
func ReadCookie(r *http.Request) bool {
if cookie, err := r.Cookie(cookieName); err == nil {
value := make(map[string]string)
if err = sc.Decode(cookieName, cookie.Value, &value); err == nil {
return true
}
}
return false
}
using securecookie and bcrypt
https://github.com/gorilla/securecookie
HTTP Server for pro
Organize theses middlewares
HTTP Server for pro
HTTP Server for pro
Before
After
Middleware1(Middleware2(Middleware3(App)))
alice.New(Middleware1, Middleware2, Middleware3).Then(App)
HTTP Server for pro
publicChain := alice.New(loggerHandler, recoverHandler)
privateChain := alice.New(loggerHandler, recoverHandler, authHandler)
apiChain := alice.New(loggerHandler, recoverHandler, rateLimitHandler, jsonHandler)
r := mux.NewRouter()
r.HandleFunc("/products/{key}", ProductHandler)
r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
http.Handle("/", publicChain.then(r))
http.Handle("/api", apiChain.Then(r))
http.Handle("/cart", privateChain.Then(r))
r.PathPrefix("/").Handler(http.FileServer(http.Dir("./static/")))
Chain them
HTTP Server for pro
HTTPS ?
With let's encrypt!
HTTP Server for pro
package main
import (
"crypto/tls"
"golang.org/x/crypto/acme/autocert"
"io"
"log"
"net/http"
)
func main() {
s := &http.Server{
Addr: ":443",
}
m := autocert.Manager{
Prompt: autocert.AcceptTOS,
Cache: autocert.DirCache("/tmp/acme/"),
HostPolicy: autocert.HostWhitelist("secure.500peppers.com"),
}
// Configure extra tcp/80 server for http-01 challenge:
// https://godoc.org/golang.org/x/crypto/acme/autocert#Manager.HTTPHandler
httpServer := &http.Server{
Handler: m.HTTPHandler(nil),
Addr: ":80",
}
go httpServer.ListenAndServe()
http.HandleFunc("/", helloWorldHandler)
s.TLSConfig = &tls.Config{GetCertificate: m.GetCertificate}
log.Fatal(s.ListenAndServeTLS("", ""))
}
HTTP Server for pro
HTTP Server for pro
Ready ?
Questions ?
Golang http server for pro
By Thomas Perez
Golang http server for pro
Meetup Golang #3
- 1,152