美文网首页Go
golang造轮子,封装一个简单的http client

golang造轮子,封装一个简单的http client

作者: QxQx | 来源:发表于2021-03-13 17:40 被阅读0次

    近来无事,本着爱折腾的原则,在go原生 http client 的基础上,自己封装了一个go的http client。由于才疏学浅,再加是第一次造轮子,在各位大佬面前献丑了,写的烂的地方,请轻喷。还请各位不吝赐教。

    先放地址

    gethub: https://github.com/bruce12397/easy_http

    Gitee: https://gitee.com/bruce_le/easy_http

    简单介绍一下功能

    1. 使用 构造器模式,提供了链式调用和方便使用的接口
    2. 支持https自定义服务器证书校验和双向证书校验
    3. 支持代理,可以方便的设置代理
    4. 封装了multipart 协议, 可以方便的上传文件
    5. 具有很强的拓展性,可以在基础上非常方便的定制自己http请求
    6. 支持http的 返回结果 异步回调
    7. 可以方便的自定义Response

    安装库

    可以使用github的库,也可使用Gitee的库,两个库的代码都是一样的,因为github网速的原因,所以在gitee上也传了一份

    1. github:go get -u github.com/bruce12397/easy_http

    2. gitee: go get -u gitee.com/bruce_le/easy_http

    使用

    引入库

    因为github和gitee拉下来的库目录不同,所以以github的为准

    import "github.com/bruce12397/easy_http"
    

    具体使用

    全部配置
    func main() {
        //得到一个http client的构造器
        builder := easy_http.NewClientBuilder()
    
        //是否跳过服务器证书校验
        builder.SkipVerify(false)
    
        //设置超时时间
        builder.TimeOut(time.Second * 5)
    
        //设置代理
        builder.ProxyUrl("http://127.0.0.1:10809")
    
        //设置根证书
        var certPool [1]string
        certPool[0] = "D:\\server.pem"
        builder.Cert(certPool[:])
        
        //设置双向校验证书
        var tlsPath [1]*easy_http.TlsPath
        tlsPath[0] = &easy_http.TlsPath{
            CertFile: "D:\\client.pem",
            KeyFile:  "D:\\client.key",
        }
        builder.Tls(tlsPath[:])
    
        //设置http请求header
        header := make(map[string]string)
        header["Accept-Language"] = "Accept-Language: en,zh"
        builder.Header(header)
    
        //设置http请求cookie
        cookie := make(map[string]string)
        cookie["name"] = "value"
        builder.Cookie(easy_http.EasyCookie(cookie))
    
        //开启cookie jar
        builder.Jar(nil)
    
        //设置 Response 处理函数
        builder.BuildResponse(easy_http.EasyBuildResponse)
    
        //构造client
        client, err := builder.Build()
        if err != nil {
            fmt.Println("aa", err)
            return
        }
    }
    

    这样就初始化一个http的客户端

    当然,上面的例子是设置了所有配置的,也可以全部使用默认配置

    使用默认配置
    func DefaultClient() {
        builder := easy_http.NewClientBuilder()
        client, err := builder.Build()
        if err != nil {
            fmt.Println(err)
            return
        }
        client.Get("http://baidu.com")
    }
    

    这样同样是可以的

    easy 函数 使用

    库中提供了一些函数,可以方便的构造http请求相关的结构

    func EasyFunction() {
    
        url := "http://baidu.com"
    
        //合成http get的url和参数 
        values := make(map[string]string)
        values["v"] = "123456"
        easy_http.EasyGet(url, values)
    
        //构造cookie
        cookie := make(map[string]string)
        cookie["name"] = "value"
        easy_http.EasyCookie(cookie)
    
        //合成 http post 的参数
        easy_http.EasyPost(values)
    
        //构造 上传文件的multipart
        multipartBuilder := easy_http.NewMultipartBuilder()
        multipartBuilder.AddFile("file1","D:\\a.txt")
        multipartBuilder.AddFromDate("name","value")
        multipartBuilder.AddBytes("name2",[]byte("aaaaa"))
        multipart, err := multipartBuilder.Builder()
        
    }
    
    异步回调使用

    库封装了 异步回调功能,请求会在一个新的goroutine中进行。当http请求完成时,会回调函数。回调函数可用形参使用传入函数和实现接口两种方式

    
    func Call(response easy_http.IResponse) {
        fmt.Println(response.Error())
        fmt.Println(response.StatusCode())
        fmt.Println(string(response.Content()))
    }
    
    type Get struct {
    }
    
    func (g Get) EasyResponseCallback(response easy_http.IResponse) {
        fmt.Println(response.Error())
        fmt.Println(response.StatusCode())
        fmt.Println(string(response.Content()))
    }
    
    func AsynchronousRequest() {
        url := "http://baidu.com"
        client, err := easy_http.NewClientBuilder().Build()
        if err != nil {
            fmt.Println(err)
            return
        }
    
        //函数异步回调
        client.GetAsyn(url, Call)
    
        //接口异步回调
        client.GetAsynWithCallback(url, &Get{})
    }
    
    自定义请求

    因为库中只封装了 GET和POST这两种方式,向PUT,DELETE等这些方式需要自己去实现。所以,可以使用下面的函数来实现

    func Call(response easy_http.IResponse) {
        fmt.Println(response.Error())
        fmt.Println(response.StatusCode())
        fmt.Println(string(response.Content()))
    }
    
    func CustomizeRequest() {
        url := "http://baidu.com"
        client, err := easy_http.NewClientBuilder().Build()
        if err != nil {
            fmt.Println(err)
            return
        }
        response := client.SendWithMethod(url, http.MethodPut, nil, func(request *http.Request) {
            //修改Request
        })
        fmt.Println(response.Error())
        fmt.Println(response.StatusCode())
    
        //异步方式
        client.SendWithMethodCallBack(url, http.MethodPut, nil, func(request *http.Request) {
            //习惯Request
        }, Call)
    }
    
    使用go http默认的函数请求

    当需要有一些特殊的请求,这个库无法满足时,可以使用go http原生的方式来请求

    func Primitive() {
        url := "http://baidu.com"
        client, err := easy_http.NewClientBuilder().Build()
        if err != nil {
            fmt.Println(err)
            return
        }
        //获取Request
        request, err := http.NewRequest(http.MethodGet, url, nil)
        if err != nil {
            fmt.Println(err)
            return
        }
        //得到http的原生Response
        response, err := client.DoRequest(request)
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Println(response)
    }
    
    自定义Response

    库中返回的Response是一个接口类型,只要实现了这个接口,都可作为返回值返回,自定义的Response,在构造client的设置就可以了

    type MyResponse struct {
    }
    
    func (m MyResponse) Error() error {
        return nil
    }
    
    func (m MyResponse) StatusCode() int {
        return 0
    }
    
    func (m MyResponse) Header() http.Header {
        return nil
    }
    
    func (m MyResponse) ContentLength() int64 {
        return 0
    }
    
    func (m MyResponse) Content() []byte {
        return nil
    }
    
    func (m MyResponse) Resp() *http.Response {
        return nil
    }
    
    func (m MyResponse) Request() *http.Request {
        return nil
    }
    
    func (m MyResponse) Cookie(name string) *http.Cookie {
        return nil
    }
    
    //构造HTTP response的函数
    func MyBuildResponse(resp *http.Response, err error) easy_http.IResponse {
        response := new(MyResponse)
        //做处理
        return response
    }
    func CustomizeResponse() {
        client, err := easy_http.NewClientBuilder().
            BuildResponse(MyBuildResponse).
            Build()
        if err != nil {
            fmt.Println(err)
            return
        }
    }
    

    结构体 MyResponse 实现了 easy_http.IResponse 这个接口。然后在MyBuildResponse这个函数中,new 一个 MyResponse的对象,再根据自己的需要,做相应的处理就可以了。
    clientBuilder.BuildResponse(MyBuildResponse)设置就可以了

    最后

    整个库的基本功能就是这些了。第一造轮子,写的很烂。写这篇文章时,还发现了好几个因为首字母小写导致的问题。

    有问题的地方,还请不吝赐教

    相关文章

      网友评论

        本文标题:golang造轮子,封装一个简单的http client

        本文链接:https://www.haomeiwen.com/subject/cwixcltx.html