7天玩转 Golang 标准库之 http/net

简介: 7天玩转 Golang 标准库之 http/net

在构建web应用时,我们经常需要处理HTTP请求、做网页抓取或者搭建web服务器等任务,而Go语言在这方面为我们提供了强大的内置工具:net/http标准库,它为我们操作和处理HTTP协议提供了便利。


基础用法

一:处理HTTP请求

首先,我们来看看如何使用net/http标准库发送一个HTTP请求。net/http库中的http.Get函数可以快速地对一个URL发起GET请求。

package main

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

func main() {
    res, err := http.Get("http://example.com/")
    if err != nil {
        log.Fatal(err)
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("%s", body)
}

二:创建和启动HTTP服务器

在Go语言中,我们可以使用http.ListenAndServe函数配合http.HandleFunc函数快速地创建一个HTTP服务器。

package main

import (
    "fmt"
    "net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, Gopher!")
}

func main() {
    http.HandleFunc("/hello", helloHandler)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
}

三:使用http.Client自定义请求行为

有时,我们需要对HTTP请求进行更细粒度的控制,比如设置超时时间、添加请求头等等。这个时候,我们可以使用http.Clienthttp.Request来自定义我们的请求行为。

package main

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

func main() {
    client := http.Client{
        Timeout: 5 * time.Second,
    }

    req, err := http.NewRequest("GET", "http://example.com", nil)
    if err != nil {
        log.Fatal(err)
    }
    req.Header.Add("User-Agent", "myClient")

    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    fmt.Printf("Response status: %s\n", resp.Status)
}

以上,我们简洁明了地介绍了如何使用Golang中的net/http标准库进行HTTP请求的发送、服务器的创建以及请求行为的自定义。但是,net/http库的功能远不止这些。

进阶用法

反向代理

反向代理是一个非常常见的需求,Golang的net/http库能简单地帮我们实现这一功能。

package main

import (
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
)

func main() {
    targetUrl, _ := url.Parse("http://example.com")
    proxy := httputil.NewSingleHostReverseProxy(targetUrl)

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        proxy.ServeHTTP(w, r)
    })

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

在上述代码中,我们通过httputil.NewSingleHostReverseProxy函数创建了一个反向代理处理器,然后在http处理函数中通过这个处理器来处理进来的http请求。

升级websocket

WebSocket提供了在单个 TCP 连接上进行全双工通信的能力。在Golang中,我们可以借助golang.org/x/net/websocket包(这不是标准库,但是是官方维护的包)轻松实现WebSocket。

package main

import (
  "fmt"
  "golang.org/x/net/websocket"
  "net/http"
)

func Echo(ws *websocket.Conn) {
  var err error
  for {
    var reply string
    if err = websocket.Message.Receive(ws, &reply); err != nil {
      fmt.Println("Can't receive")
      break
    }
    fmt.Println("Received back from client: " + reply)
    msg := "Received:  " + reply
    fmt.Println("Sending to client: " + msg)
    if err = websocket.Message.Send(ws, msg); err != nil {
      fmt.Println("Can't send")
      break
    }
  }
}

func main() {
  http.Handle("/", websocket.Handler(Echo))
  if err := http.ListenAndServe(":1234", nil); err != nil {
    log.Fatal("ListenAndServe:", err)
  }
}

在上面的例子中,我们创建了一个简单的回音服务,客户端发送一个消息到服务器,服务器会追加一个"Received: "前缀并发送回去。


需要注意的是,WebSocket 只能用于已具有兼容 WebSocket 的客户端(如一些现代 web 浏览器)的 HTTP 服务器。websocket包并不能用于一个普通的HTTP服务端。

当然,除了反向代理和Websocket, net/http包中还有诸多高级的使用方法。这里,我会介绍两个常见的高级应用场景:使用http.RoundTripper自定义HTTP请求过程和使用http.CookieJar接口处理Cookie。

自定义HTTP请求过程

如果你需要在发送HTTP请求时进行更多的自定义控制,如自定义DNS解析、TCP连接过程、TLS握手等等,那么你可以通过实现 http.RoundTripper 接口来满足需求。

package main

import (
    "fmt"
    "net/http"
    nethttp "net/http" // alias to avoid conflict
    "time"
)

type myTransport struct {
    transportation http.RoundTripper
}

func (t *myTransport) RoundTrip(req *http.Request) (*http.Response, error) {
    req.Header.Add("User-Agent", "myClient")
    resp, err := t.transportation.RoundTrip(req)
    if err != nil {
     return nil, err
    }

    // you can access Response here
    fmt.Println("Status:", resp.Status)

    return resp, nil
}

func main() {
    t := &myTransport{
     transportation: nethttp.DefaultTransport,
    }

    client := &http.Client{Transport: t}
    resp, err := client.Get("http://example.com")
    if err != nil {
     log.Fatal(err)
    }
    defer resp.Body.Close()

    fmt.Println("Response Status:", resp.Status)
}

在上述代码中,我们实现了自己的 http.RoundTripper 接口,在每次发送HTTP请求时,添加了自定义的User-Agent头,并在请求返回后打印了响应的状态码。

处理Cookie

http.CookieJar 是一个接口,可以用来自定义HTTP请求中的cookie处理逻辑。Go标准库为我们提供了一个简单的内存CookieJar的实现 net/http/cookiejar

package main

import (
    "net/http"
    "net/http/cookiejar"
    "net/url"
)

func main() {
    jar, err := cookiejar.New(nil)
    if err != nil {
     log.Fatal(err)
    }

    client := &http.Client{
     Jar: jar,
    }

    // Create a cookie on client side
    client.Jar.SetCookies(
     &url.URL{Scheme: "http", Host: "example.com"},
     []*http.Cookie{{Name: "cookieName", Value: "cookieValue"}},
    )

    // Check if the cookie has been set
    if cookies := client.Jar.Cookies(&url.URL{Scheme: "http", Host: "example.com"}); len(cookies) > 0 {
     fmt.Println("Cookie:", cookies[0])
    }
}

在上述例子中,我们首先创建了一个新的CookieJar实例,并将其用于一个新的HTTP客户端中。然后,我们在客户端上创建了一个新的cookie,并检查它是否已经被存储在了CookieJar中。

如果这篇文章帮助了你,不妨一键三连哦?

相关文章
|
9天前
|
安全 网络协议 Ubuntu
【常见开源库的二次开发】HTTP之libcurl库——libcurl使用(二)
【常见开源库的二次开发】HTTP之libcurl库——libcurl使用(二)
20 2
|
1天前
|
JSON 数据格式 Python
Python 的 requests 库是一个强大的 HTTP 客户端库,用于发送各种类型的 HTTP 请求
【6月更文挑战第15天】Python的requests库简化了HTTP请求。安装后,使用`requests.get()`发送GET请求,检查`status_code`为200表示成功。类似地,`requests.post()`用于POST请求,需提供JSON数据和`Content-Type`头。
11 6
|
8天前
|
JSON API 数据格式
Requests库:轻松实现Python中的HTTP请求
Requests是Python的第三方HTTP库,简化了HTTP请求的发送,支持GET、POST等方法。要安装,使用`pip install requests`。Requests以其简洁API和强大功能成为网络编程首选工具,为开发者提供高效稳定的网络交互体验。
20 5
|
9天前
|
缓存 网络协议 安全
【常见开源库的二次开发】HTTP之libcurl库——基础知识扫盲(一)
【常见开源库的二次开发】HTTP之libcurl库——基础知识扫盲(一)
18 1
|
9天前
|
API Python
Python HTTP请求库对比,以实战请求豆瓣排行榜为例
对比了Python的几个HTTP请求库,包括`requests`、`http.client`、`aiohttp`、`urllib`、`httpx`、`treq`和`requests-toolbelt`,各有特点和优缺点。选择时应考虑项目需求(如异步支持)、易用性、社区支持、性能和兼容性。示例展示了如何使用`requests`和`aiohttp`库发送豆瓣电影排行榜的GET请求。
8 0
|
12天前
|
NoSQL 大数据 Redis
分享5款.NET开源免费的Redis客户端组件库
分享5款.NET开源免费的Redis客户端组件库
|
13天前
|
SQL 开发框架 安全
【.NET Core】深入理解任务并行库 (TPL)
【.NET Core】深入理解任务并行库 (TPL)
18 0
|
18天前
|
JSON API 定位技术
.NET集成DeveloperSharp实现http网络请求&与其它工具的比较
该内容介绍了一个支持.NET Core 2.0及以上和.NET Framework 4.0及以上的HTTP请求调用方法,主要讨论了POST和GET两种形式。POST请求较为常见,涉及调用地址、发送参数、HTTP请求头和编码格式设置。文中提供了一个使用DeveloperSharp库发送POST请求的C#代码示例,用于发送短信,其中`IU.HttpPost`方法用于执行POST请求。此外,还提到了`HttpPost`方法的参数和返回值说明。最后简要提及了GET请求,通常用于URL带有查询参数的情况,并给出一个简单的GET请求示例。
|
1月前
|
Go
Golang标准库sync的使用
Golang标准库sync的使用
23 2
|
1月前
|
Shell Go API
7天玩转 Golang 标准库之 os
7天玩转 Golang 标准库之 os
23 1