http库

本文介绍了Go语言中http包的使用,包括创建简单的Web服务器和HTTP客户端。示例代码展示了如何启动服务器并处理请求,以及如何发起HTTP请求获取响应内容。此外,还涵盖了重定向、Cookie管理和文件上传功能,以及如何启用HTTP/2协议。
摘要由CSDN通过智能技术生成

当我们使用 Go 语言进行 Web 开发时,不可避免地要使用到 http 包。该包提供了 HTTP 客户端和服务器的实现,可以轻松地编写 HTTP 服务器和客户端。在本节中,我们将学习如何使用 Go 语言中的 http 包来编写 Web 服务器和客户端。

基本使用

使用 http 包创建 Web 服务器很容易。下面是一个简单的 Web 服务器示例,它将响应客户端请求并返回 "Hello, World!":

package main

import (
	"fmt"
	"net/http"
)

funcmain() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, World!")
	})

	http.ListenAndServe(":8080", nil)
}

该示例中,我们使用 http.HandleFunc() 函数将 URL 根路径 / 与一个匿名函数关联起来。当用户访问 URL 根路径时,该函数将被调用,并将 "Hello, World!" 响应写入响应流中。最后,我们使用 http.ListenAndServe() 函数来启动 Web 服务器,它会监听本地端口 8080 并处理传入的 HTTP 请求。在此示例中,我们将第二个参数 nil 传递给 http.ListenAndServe() 函数,这表示我们使用默认的 HTTP 处理程序来处理所有传入的 HTTP 请求。如果需要更复杂的路由,可以使用第二个参数传递一个 http.Handler 类型的参数。

HTTP 客户端

除了作为 Web 服务器的实现,Go 语言中的 http 包还提供了一个简单的 HTTP 客户端。下面是一个简单的 HTTP 客户端示例,它将向 http://example.com 发送 GET 请求并打印响应内容:

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

funcmain() {
	resp, err := http.Get("http://example.com")
	if err != nil {
		fmt.Println(err)
		return
	}

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(body))
}

在该示例中,我们使用 http.Get() 函数来向 http://example.com 发送一个 GET 请求。该函数返回一个 *http.Response 类型的值 resp,其中包含响应的状态码、头部和响应正文。我们通过 ioutil.ReadAll() 函数从响应正文中读取响应内容,并使用 fmt.Println() 函数将其打印到控制台上。最后,我们通过 resp.Body.Close() 函数关闭响应正文的读取器

高级功能

重定向

Go的http包可以自动处理HTTP重定向。当客户端向服务器发送一个请求并且服务器返回一个重定向响应时,http包会自动发送另一个请求到重定向的URL上,并将响应返回给客户端。下面是一个简单的例子:

package main

import (
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) {
        http.Redirect(w, r, "https://www.example.com", http.StatusMovedPermanently)
    })

    srv := &http.Server{
        Addr:    ":8080",
        Handler: http.DefaultServeMux,
    }

    log.Fatal(srv.ListenAndServe())
}

这个例子中,我们通过http.HandleFunc函数来定义一个路由,即访问/redirect路径时,执行重定向功能。在处理函数中,我们调用了http.Redirect函数来实现重定向,其中第一个参数是ResponseWriter,第二个参数是Request,第三个参数是重定向的目标地址,第四个参数是HTTP状态码。这里我们使用了http.StatusMovedPermanently,即301状态码,表示永久性重定向。

接着我们创建了一个http.Server实例,设置监听地址为:8080,处理器使用默认的ServeMux,最后通过srv.ListenAndServe()启动服务。这里没有指定TLS证书和私钥,如果需要使用HTTPS协议,需要在http.Server中设置相关选项。

这个例子实现了一个非常简单的重定向功能,如果需要更复杂的重定向规则,可以使用一些第三方库,如gorilla/muxgo-chi/chi

Cookie

Cookie是一种在Web浏览器中存储数据的机制,可以用于识别用户、记录用户状态等。Go的http包提供了对Cookie的支持。可以使用http.Cookie结构体来创建、修改和删除Cookie。

package main

import (
	"fmt"
	"net/http"
)

func main() {
	// 设置Cookie
	http.HandleFunc("/set_cookie", func(w http.ResponseWriter, r *http.Request) {
		cookie := &http.Cookie{
			Name:   "username",
			Value:  "test",
			MaxAge: 3600,
			Path:   "/",
		}
		http.SetCookie(w, cookie)
		fmt.Fprintln(w, "Cookie set successfully!")
	})

	// 读取Cookie
	http.HandleFunc("/get_cookie", func(w http.ResponseWriter, r *http.Request) {
		cookie, err := r.Cookie("username")
		if err != nil {
			fmt.Fprintln(w, "Cookie not found!")
			return
		}
		fmt.Fprintf(w, "Cookie found: %s=%s", cookie.Name, cookie.Value)
	})

	http.ListenAndServe(":8080", nil)
}

在这个例子中,我们创建了一个名为“username”的Cookie,并将其值设置为“test”。我们还设置了Cookie的最大生存时间为3600秒,以及路径为“/”,表示可以在整个网站中访问此Cookie。

我们还定义了两个路由处理程序,“/set_cookie”和“/get_cookie”,分别用于设置和读取Cookie。在“/set_cookie”处理程序中,我们使用http.SetCookie函数将Cookie写入响应头部。在“/get_cookie”处理程序中,我们使用r.Cookie函数来读取Cookie。

上传文件

Go的http包可以方便地处理文件上传。下面是一个简单的文件上传例子:

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
    "path/filepath"
    "time"
)

const (
    UploadDir = "./upload" // 上传目录
)

func main() {
    http.HandleFunc("/", uploadHandler)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        fmt.Println(err)
    }
}

func uploadHandler(w http.ResponseWriter, r *http.Request) {
    switch r.Method {
    case http.MethodGet:
        http.ServeFile(w, r, "./index.html")
    case http.MethodPost:
        file, header, err := r.FormFile("file")
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        defer file.Close()

        // 创建上传目录
        if _, err := os.Stat(UploadDir); os.IsNotExist(err) {
            os.Mkdir(UploadDir, os.ModePerm)
        }

        // 创建保存文件
        fileName := fmt.Sprintf("%d_%s", time.Now().Unix(), header.Filename)
        filePath := filepath.Join(UploadDir, fileName)
        newFile, err := os.Create(filePath)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        defer newFile.Close()

        // 复制文件
        if _, err := io.Copy(newFile, file); err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        fmt.Fprintln(w, "Upload successful!")
    }
}

该示例中,我们首先定义了上传目录,然后在 uploadHandler 中,判断请求方法是否为 POST,如果是,则解析上传的文件,创建上传目录(如果不存在),然后创建新文件,将上传文件内容写入新文件中。

其中,我们使用了 Golang 的标准库 net/http 中的 ServeFile 函数,它会自动读取指定的文件,并将其内容发送给客户端。此外,还使用了 FormFile 函数解析上传的文件,os 包中的 Create 函数创建新文件,io.Copy 函数将上传文件内容复制到新文件中。

在这个示例中,我们只是简单地将上传文件写入文件系统。在实际的生产环境中,你可能需要更多的验证和处理,例如验证上传文件的类型和大小,限制上传文件的数量,以及将上传的文件保存到分布式存储等。

采用 HTTP/2 协议,实现HTTP服务器

package main

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

func main() {
    // 创建路由
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Welcome to my website!")
    })

    // 创建TLS证书和密钥
    cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
    if err != nil {
        log.Fatal(err)
    }

    // 创建TLS配置
    tlsConfig := &tls.Config{
        Certificates: []tls.Certificate{cert},
        NextProtos:   []string{"h2", "http/1.1"},
    }

    // 创建HTTP/2服务器
    server := &http.Server{
        Addr:      ":443",
        Handler:   mux,
        TLSConfig: tlsConfig,
    }

    // 启动HTTP/2服务器
    log.Fatal(server.ListenAndServeTLS("", ""))
}

在上面的代码中,我们首先创建了一个路由,然后使用TLS证书和密钥创建了一个TLS配置。接着,我们创建了一个HTTP/2服务器,并将路由和TLS配置添加到服务器中。最后,我们使用TLS证书和密钥启动了服务器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值