Go HTTP programming (3): HTTP/HTTPS request processing

Handling HTTP requests

Server-side implementation

Using   the  method provided by the net/http package  http.ListenAndServe(), you can start an HTTP server and listen to client requests on the specified IP address and port. The prototype of this method is as follows:

func ListenAndServe(addr string, handler Handler) error

This method has two parameters: the first parameter  addr represents the IP address and port number to be monitored; the second parameter represents the handler corresponding to the server, usually empty, which means that the call will  http.DefaultServeMux be processed, and the business logic written by the server The handler  http.Handle() or  http.HandleFunc() default will be injected into  http.DefaultServeMux it.

Let's implement a basic HTTP server according to the above ideas  server.go:

package main

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

func main() {
    http.HandleFunc("/hello", func(writer http.ResponseWriter, request *http.Request) {
        params := request.URL.Query();
        fmt.Fprintf(writer, "你好, %s", params.Get("name"))
    })
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatalf("启动 HTTP 服务器失败: %v", err)
    }
}

In this code, we http.HandleFunc define a /hello route and corresponding handler through the  method  , in this handler we will return a welcome string, which also references the request parameters passed by the client. Then http.ListenAndServe start the HTTP server through the  method and monitor the 8080 port of the local IP  . When the client requests the  http://127.0.0.1:8080/hello URL, the HTTP server will forward it to the default  http.DefaultServeMux processing, where http.HandleFunc the processor defined by the method will eventually be called to  process the request and return the response.

Client request

We  adjust the request address in the HTTP client sample code implemented in the  previous tutorialclient.go as follows:

req, err := http.NewRequest("GET", "http://127.0.0.1:8080/hello?name=学院君", nil)

Next, start the HTTP server:

go run server.go

Then open a new Terminal window to execute the client calling code:

HTTP request processing

The expected result is printed, indicating that the HTTP server can provide services normally.

Handling HTTPS requests

Server-side logic

The net/http  package also provides  http.ListenAndServeTLS() methods for handling HTTPS connection requests:

func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error

ListenAndServeTLS()ListenAndServe() The behavior of  and is  the same, the difference is that the former only processes HTTPS requests. To process HTTPS requests correctly, the SSL certificate and the matching private key file must exist on the server, such as the  certFile storage path of the corresponding SSL certificate file and the path of the keyFile corresponding certificate private key file. If the certificate is signed by a certificate authority, certFile the path specified by the parameter must be a CA-certified SSL certificate stored on the server.

Generate a self-signed certificate via OpenSSL

Here we demonstrate the processing of HTTPS requests locally, and a self-signed certificate can be generated through the OpenSSL tool:

# Generate CA private key 
openssl genrsa -out ca.key 2048 
# Generate CSR 
openssl req -new -key ca.key -out ca.csr
# Generate Self Signed certificate(CA 根证书)
openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt

These files are saved to the directory where the HTTPS server code is located:

HTTPS server directory structure

Server code

Enabling the HTTPS monitoring service is also very simple, except that the calling method is adjusted to  http.ListenAndServeTLS and passed in the SSL certificate and private key file generated above, everything else is the same as the HTTP server, we https create a new server.go code in the  directory  :

package main

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

func main() {
    http.HandleFunc("/hello", func(writer http.ResponseWriter, request *http.Request) {
        params := request.URL.Query();
        fmt.Fprintf(writer, "你好, %s", params.Get("name"))
    })
    err := http.ListenAndServeTLS(":8443", "./ca.crt", "./ca.key",nil)
    if err != nil {
        log.Fatalf("启动 HTTPS 服务器失败: %v", err)
    }
}

Then start this HTTPS server:

go run server.php

Client request

Next, we https create the client calling code in the  directory  client.go:

package main

import (
    "crypto/tls"
    "fmt"
    "io"
    "net/http"
    "os"
)

func main() {
    req, err := http.NewRequest("GET", "https://127.0.0.1:8443/hello?name=学院君", nil)
    if err != nil {
        fmt.Printf("请求初始化失败:%v", err)
        return
    }

    // 设置跳过不安全的 HTTPS
    tls11Transport := &http.Transport{
        MaxIdleConnsPerHost: 10,
        TLSClientConfig: &tls.Config{
            MaxVersion: tls.VersionTLS11,
            InsecureSkipVerify: true,
        },
    }

    client := &http.Client{
        Transport: tls11Transport,
    }

    resp, err := client.Do(req)
    if err != nil {
        fmt.Printf("客户端发起请求失败:%v", err)
        return
    }

    defer resp.Body.Close()
    io.Copy(os.Stdout, resp.Body)
}

Here, we adjust the request URL to the HTTPS protocol, and customize the client instance  Transport(for more low-level details, please refer to the introduction in the previous tutorial ) to skip the insecure HTTPS connection verification. Run the client code, the print result is as follows:

HTTPS request processing

It means that the HTTPS request is successful.

Of course, the above HTTP service and HTTPS service can also be accessed through a browser:

Access HTTPS service through browser

Guess you like

Origin blog.csdn.net/wxy_csdn_world/article/details/107444954