golang network programming Middleware

Posted by S_henry on Sat, 23 Nov 2019 19:07:21 +0100

golang_real.jpg

Share before
Gorang network programming (5) middleware
By learning to write two interceptors by ourselves, output log and simple permission verification. This is what we usually do in middleware. In fact, many times we don't need to do too much by ourselves. Do we still need to grow, bake and grind if we want to drink coffee? Directly McDonald's.

However, it is necessary for us to have a brief understanding of the middleware implementation principle. Let's take the log system for example. Usually our logs need to be saved as files, not output in the console.
We will use the third-party package "github.com/gorilla/handlers".

func index(w http.ResponseWriter, r *http.Request){
    log.Println("Execute index handler")
    fmt.Fprintf(w,"welcome")
}

func about(w http.ResponseWriter, r *http.Request){
    log.Println("Execute about handler")
    fmt.Fprintf(w,"about")
}

We first define two routers to output text in the browser.

logFile, err := os.OpenFile("server.log",os.O_WRONLY|os.O_CREATE|os.O_APPEND,0666)
    // logFile, err := os.OpenFile("server.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)

Here, the go language provides the os package to create a file server.log for saving logs

http.Handle("/", handlers.LoggingHandler(logFile, handlers.CompressHandler(indexHandler))) 
    http.Handle("/about", handlers.LoggingHandler(logFile, handlers.CompressHandler( aboutHandler)))

Here, the LoggingHandler and compressionhandler provided by handlers are used to compress the logs and input them into the logFile. Here, gzip or Deflate is used to compress the request return.

The complete code is as follows

package main

import(
    "fmt"
    "log"
    "net/http"
    "os"

    "github.com/gorilla/handlers"
)

func index(w http.ResponseWriter, r *http.Request){
    log.Println("Execute index handler")
    fmt.Fprintf(w,"welcome")
}

func about(w http.ResponseWriter, r *http.Request){
    log.Println("Execute about handler")
    fmt.Fprintf(w,"about")
}

func iconHandler(w http.ResponseWriter, r *http.Request) {
}

func main(){
    http.HandleFunc("/favicon.icon",iconHandler)

    indexHandler := http.HandlerFunc(index)
    aboutHandler := http.HandlerFunc(about)

    logFile, err := os.OpenFile("server.log",os.O_WRONLY|os.O_CREATE|os.O_APPEND,0666)
    // logFile, err := os.OpenFile("server.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
    if err != nil{
        panic(err)
    }

    http.Handle("/", handlers.LoggingHandler(logFile, handlers.CompressHandler(indexHandler))) 
    http.Handle("/about", handlers.LoggingHandler(logFile, handlers.CompressHandler( aboutHandler)))

    server := &http.Server{
        Addr: ":8080",
    }
    log.Println("Listening...")
    server.ListenAndServe()
}
::1 - - [24/Apr/2019:05:39:31 +0800] "GET / HTTP/1.1" 200 31
::1 - - [24/Apr/2019:05:39:31 +0800] "GET /favicon.ico HTTP/1.1" 200 31
::1 - - [24/Apr/2019:05:39:38 +0800] "GET /about HTTP/1.1" 200 31
::1 - - [24/Apr/2019:05:39:38 +0800] "GET /favicon.ico HTTP/1.1" 200 31

This time we introduced github.com/justinas/alice, a third-party package. The reason for using Alice is to make our code look more elegant.

commonHandlers := alice.New(loggingHandler, handlers.CompressHandler)

Integrate and encapsulate our logs.

package main

import(
    "io"
    "log"
    "net/http"
    "os"

    "github.com/justinas/alice"
    "github.com/gorilla/handlers"
)

func loggingHandler(next http.Handler) http.Handler{
    
    logFile, err := os.OpenFile("server.log",os.O_WRONLY|os.O_CREATE|os.O_APPEND,0666)

    if err != nil{
        panic(err)
    }

    return handlers.LoggingHandler(logFile,next)
}

func index(w http.ResponseWriter, r *http.Request){
    w.Header().Set(
        "Content-Type",
        "text/html",
    )
    io.WriteString(
        w,
        `<doctype html>
        <html>
            <head>
                <title>Index</title>
            </head>
            <body>
                Hello Zidea!
            </body>
        </html>`, )
}

func about(w http.ResponseWriter, r *http.Request){
    w.Header().Set(
        "Content-Type",
        "text/html",
    )
    io.WriteString(
        w,
        `<doctype html>
        <html>
            <head>
                <title>About</title>
            </head>
            <body>
                about HTTP Middleware
            </body>
        </html>`, )
}

func iconHandler(w http.ResponseWriter, r *http.Request) {
    // http.ServeFile(w, r, "./favicon.ico")
}

func main(){
    http.HandleFunc("/favicon.ico", iconHandler)
    indexHandler := http.HandlerFunc(index)
    aboutHandler := http.HandlerFunc(about)
    commonHandlers := alice.New(loggingHandler, handlers.CompressHandler)
    http.Handle("/", commonHandlers.ThenFunc(indexHandler))
    http.Handle("/about", commonHandlers.ThenFunc(aboutHandler))

    server := &http.Server{
        Addr: ":8080",
    }
    log.Println("Listening...")
    server.ListenAndServe()
}
::1 - - [24/Apr/2019:05:53:01 +0800] "GET /about HTTP/1.1" 200 110
::1 - - [24/Apr/2019:05:53:05 +0800] "GET /welcome HTTP/1.1" 200 103
th-9.jpeg

Topics: github network Programming Go