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:
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:
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:
It means that the HTTPS request is successful.
Of course, the above HTTP service and HTTPS service can also be accessed through a browser: