Tratamento de solicitações HTTP
Implementação do lado do servidor
Usando o método fornecido pelo pacote net / httphttp.ListenAndServe()
, você pode iniciar um servidor HTTP e ouvir as solicitações do cliente no endereço IP e na porta especificados. O protótipo desse método é o seguinte:
func ListenAndServe(addr string, handler Handler) error
Este método possui dois parâmetros: o primeiro parâmetro addr
representa o endereço IP e o número da porta a ser monitorado; o segundo parâmetro representa o manipulador correspondente ao servidor, geralmente vazio, o que significa que a chamada será http.DefaultServeMux
processada, e a lógica de negócios escrita pelo servidor O manipulador http.Handle()
ou http.HandleFunc()
padrão será injetado http.DefaultServeMux
nele.
Vamos implementar um servidor HTTP básico de acordo com as idéias acima 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)
}
}
Neste código, http.HandleFunc
definimos uma /hello
rota e o manipulador correspondente através do método , neste manipulador retornaremos uma string de boas-vindas, que também faz referência aos parâmetros de solicitação passados pelo cliente. Em seguida, http.ListenAndServe
inicie o servidor HTTP através do método e monitore a 8080
porta do IP local . Quando o cliente solicitar a http://127.0.0.1:8080/hello
URL, o servidor HTTP a encaminhará para o http.DefaultServeMux
processamento padrão , onde http.HandleFunc
o processador definido pelo método será eventualmente chamado para processar a solicitação e retornar a resposta.
Pedido do cliente
Nós ajustar o endereço pedido no código de exemplo cliente HTTP implementado no tutorial anteriorclient.go
da seguinte forma:
req, err := http.NewRequest("GET", "http://127.0.0.1:8080/hello?name=学院君", nil)
Em seguida, inicie o servidor HTTP:
go run server.go
Em seguida, abra uma nova janela do Terminal para executar o código de chamada do cliente:
O resultado esperado é impresso, indicando que o servidor HTTP pode fornecer serviços normalmente.
Tratamento de solicitações HTTPS
Lógica do lado do servidor
O pacote net / http também fornece http.ListenAndServeTLS()
métodos para lidar com solicitações de conexão HTTPS:
func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error
ListenAndServeTLS()
ListenAndServe()
O comportamento de e é o mesmo, a diferença é que o primeiro processa apenas solicitações HTTPS. Para processar solicitações HTTPS corretamente, o certificado SSL e o arquivo de chave privada correspondente devem existir no servidor, como o certFile
caminho de armazenamento do arquivo de certificado SSL correspondente e o caminho do keyFile
arquivo de chave privada de certificado correspondente. Se o certificado for assinado por uma autoridade de certificação, certFile
o caminho especificado pelo parâmetro deve ser um certificado SSL certificado pela CA armazenado no servidor.
Gere um certificado autoassinado via OpenSSL
Aqui, demonstramos o processamento de solicitações HTTPS localmente, e um certificado autoassinado pode ser gerado por meio da ferramenta OpenSSL:
# 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
Esses arquivos são salvos no diretório onde o código do servidor HTTPS está localizado:
Código do servidor
Habilitar o serviço de monitoramento HTTPS também é muito simples, exceto que o método de chamada é ajustado http.ListenAndServeTLS
e passado no certificado SSL e no arquivo de chave privada gerado acima, todo o resto é igual ao servidor HTTP, https
criamos um novo server.go
código no diretório :
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)
}
}
Em seguida, inicie este servidor HTTPS:
go run server.php
Pedido do cliente
Em seguida, https
criamos o código de chamada do cliente no diretório 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)
}
Aqui, ajustamos o URL de solicitação para o protocolo HTTPS e personalizamos a instância do cliente Transport
(para obter mais detalhes de baixo nível, consulte a introdução no tutorial anterior ) para ignorar a verificação de conexão HTTPS insegura. Execute o código do cliente, o resultado da impressão é o seguinte:
Isso significa que a solicitação HTTPS foi bem-sucedida.
Obviamente, os serviços HTTP e HTTPS acima também podem ser acessados por meio de um navegador: