【测试平台系列】第一章手撸压力机(二)自定义http客户端配置

简介: 上一节简单实现了http发送get请求的客户端,但是在实际工作中,我们会对客户端有各种的设置,也会有各种的请求。

上一节简单实现了http发送get请求的客户端,但是在实际工作中,我们会对客户端有各种的设置,也会有各种的请求。
今天先看一下,如何定义http的客户端。(注意:咱们的http全部使用fasthttp开源框架)
首先看一下fasthttp.Client结构体源码:

// Client implements http client.
//  Client结构体实现http客户端。
// Copying Client by value is prohibited. Create new instance instead.
//  禁止按值复制Client。而是创建一个新实例。
// It is safe calling Client methods from concurrently running goroutines.
//  从并发运行的例程调用客户机方法是安全的。
// The fields of a Client should not be changed while it is in use.
// 客户端在使用时其字段不可更改。go中定义好的结构体字段都不可更改
type Client struct {  
    noCopy noCopy  // noCopy 字段我们不用管  
    // Client name. Used in User-Agent request header.  
    // Default client name is used if not set. 
    //  客户端的名称,在header中的user-agent使用,通常我们默认就好  
    Name string  
    // NoDefaultUserAgentHeader when set to true, causes the default 
    // User-Agent header to be excluded from the Request.  
    // NoDefaultUserAgentHeader设置为true时,导致默认的User-Agent报头从请求中排除。  
    // 默认为flase,表示User-Agent使用fasthttp的默认值  
    NoDefaultUserAgentHeader bool  
    // Callback for establishing new connections to hosts.  
    //  // Default Dial is used if not set.  
    // 该函数,通常不使用,可以不用管  
    Dial DialFunc  
    // Attempt to connect to both ipv4 and ipv6 addresses if set to true.  
    //  
    // This option is used only if default TCP dialer is used,  
    // i.e. if Dial is blank.  
    //  
    // By default client connects only to ipv4 addresses,  
    // since unfortunately ipv6 remains broken in many networks worldwide :)  
    // 默认即可,不用管  
    DialDualStack bool  
    // TLS config for https connections.  
    // https连接的TLS配置。  
    // Default TLS config is used if not set.  
    // 如果没有设置,使用默认的TLS配置。  
    // 这里使用的是tls.Config指针类型。可以在我们使用的时候配置  
    TLSConfig *tls.Config  
    // Maximum number of connections per each host which may be established.  
    // 每台主机可以建立的最大连接数。  
    // DefaultMaxConnsPerHost is used if not set.  
    // 如果没有设置,则使用DefaultMaxConnsPerHost。  
    MaxConnsPerHost int  
    // Idle keep-alive connections are closed after this duration.  
    //  空闲的保持连接在此持续时间之后关闭。  
    // By default idle connections are closed  
    // after DefaultMaxIdleConnDuration.  
    // 默认情况下,在DefaultMaxIdleConnDuration之后关闭空闲连接。  
    // 该连接如果空闲的话,在此时间后断开。  
    MaxIdleConnDuration time.Duration  
    // Keep-alive connections are closed after this duration.  
    // Keep-alive连接在此持续时间后关闭。  
    // By default connection duration is unlimited.  
    // 默认情况下,连接时间是不限制的。  
    MaxConnDuration time.Duration  
    // Maximum number of attempts for idempotent calls  
    //  
    // DefaultMaxIdemponentCallAttempts is used if not set.  
    // 默认,不用管  
    MaxIdemponentCallAttempts int  
    // Per-connection buffer size for responses' reading.  
    // This also limits the maximum header size.  
    //  
    // Default buffer size is used if 0.  
    // 默认,不用管  
    ReadBufferSize int  
    // Per-connection buffer size for requests' writing.  
    //  
    // Default buffer size is used if 0.  
    // 默认,不用管  WriteBufferSize int  
    // Maximum duration for full response reading (including body).  
    // 完整响应读取(包括body)的最大持续时间。  
    // By default response read timeout is unlimited.  
    // 默认情况下,响应读取超时时间是不限制的。  
    ReadTimeout time.Duration  
    // Maximum duration for full request writing (including body).  
    // 完整写入请求(包括请求体)的最大持续时间。  
    // By default request write timeout is unlimited.  
    // 默认情况下,请求写超时时间不受限制。  
    WriteTimeout time.Duration  
    // Maximum response body size.  
    //  
    // The client returns ErrBodyTooLarge if this limit is greater than 0  
    // and response body is greater than the limit.  
    //  
    // By default response body size is unlimited.  
    // 默认不用管  
    MaxResponseBodySize int  

    // Header names are passed as-is without normalization  
    // if this option is set.  
    //  
    // Disabled header names' normalization may be useful only for proxying  
    // responses to other clients expecting case-sensitive  
    // header names. See https://github.com/valyala/fasthttp/issues/57  
    // for details.  
    //  
    // By default request and response header names are normalized, i.e.  
    // The first letter and the first letters following dashes  
    // are uppercased, while all the other letters are lowercased.  
    // Examples:  
    //  
    //     * HOST -> Host  
    //     * content-type -> Content-Type 
    //     * cONTENT-lenGTH -> Content-Length  
    // 请求头是否按标准格式传输  
    DisableHeaderNamesNormalizing bool  
    // Path values are sent as-is without normalization 
    //  
    // Disabled path normalization may be useful for proxying incoming requests  
    // to servers that are expecting paths to be forwarded as-is.  
    //  
    // By default path values are normalized, i.e.  
    // extra slashes are removed, special characters are encoded.  
    // url路径是按照原样输出,还是按照规范化输出。默认按照规范化输出  
    DisablePathNormalizing bool  
    // Maximum duration for waiting for a free connection.  
    // 等待空闲连接的最大持续时间。  
    // By default will not waiting, return ErrNoFreeConns immediately  
    // 默认不等待,立即返回ErrNoFreeConns  
    MaxConnWaitTimeout time.Duration  
    // RetryIf controls whether a retry should be attempted after an error.  
    //  
    // By default will use isIdempotent function  
    // 默认,不用修改  
    RetryIf RetryIfFunc  
    // Connection pool strategy. Can be either LIFO or FIFO (default).  
    // 连接池策略。可以是后进先出或先进先出(默认)。  
    // 默认  
    ConnPoolStrategy ConnPoolStrategyType  
    // StreamResponseBody enables response body streaming  
    // StreamResponseBody使能响应体流  
    // 默认,有特定需求可使用  
    StreamResponseBody bool  
    // ConfigureClient configures the fasthttp.HostClient.  
    ConfigureClient func(hc *HostClient) error  
    mLock      sync.Mutex  
    m          map[string]*HostClient  
    ms         map[string]*HostClient  
    readerPool sync.Pool  
    writerPool sync.Pool
}

根据上面解读fasthttp.Client, 我们可以找到我们通常使用的配置项,如下:

type Client struct {  
    //  客户端的名称,在header中的user-agent使用,通常我们默认就好  
    Name string  
    // NoDefaultUserAgentHeader when set to true, causes the default  
    // User-Agent header to be excluded from the Request.  
    // NoDefaultUserAgentHeader设置为true时,导致默认的User-Agent报头从请求中排除。  
    // 默认为flase,表示User-Agent使用fasthttp的默认值 
     NoDefaultUserAgentHeader bool  
     // https连接的TLS配置。这里使用的是tls.Config指针类型。可以在我们使用的时候配置  
     TLSConfig *tls.Config  
     // 每台主机可以建立的最大连接数。如果没有设置,则使用DefaultMaxConnsPerHost。  
     MaxConnsPerHost int  
     // 空闲的保持连接在此持续时间之后关闭。默认情况下,在DefaultMaxIdleConnDuration之后关闭空闲连接。
     // 该连接如果空闲的话,在此时间后断开。  
     MaxIdleConnDuration time.Duration  
     // Keep-alive连接在此持续时间后关闭。默认情况下,连接时间是不限制的。  
     MaxConnDuration time.Duration  
     // 默认情况下,响应读取超时时间是不限制的。  
     ReadTimeout time.Duration  
     // 默认情况下,请求写超时时间不受限制。  
     WriteTimeout time.Duration  
     // 请求头是否按标准格式传输  
     DisableHeaderNamesNormalizing bool  
     // url路径是按照原样输出,还是按照规范化输出。默认按照规范化输出  
     DisablePathNormalizing bool
}

通过上述梳理,我们知道通常使用的配置项为10项。我们在项目根目录下新建model文件夹,并在文件夹下新建http_model.go文件,代码如下:


package model
import (  
    "crypto/tls"
)
type HttpClientSettings struct {  
    //  客户端的名称,在header中的user-agent使用,通常我们默认就好  
    Name string  // 默认为flase,表示User-Agent使用fasthttp的默认值  N
    oDefaultUserAgentHeader bool  
    // https连接的TLS配置。这里使用的是tls.Config指针类型。可以在我们使用的时候配置  
    TLSConfig *tls.Config  
    // 每台主机可以建立的最大连接数。如果没有设置,则使用DefaultMaxConnsPerHost。  
    MaxConnsPerHost int  
    // 空闲的保持连接在此持续时间之后关闭。默认情况下,在DefaultMaxIdleConnDuration之后关闭空闲连接。  
    // 该连接如果空闲的话,在此时间后断开。  
    MaxIdleConnDuration int64  
    // Keep-alive连接在此持续时间后关闭。默认情况下,连接时间是不限制的。  
    MaxConnDuration int64  
    // 默认情况下,响应读取超时时间是不限制的。  
    ReadTimeout int64  
    // 默认情况下,请求写超时时间不受限制。 
    WriteTimeout int64  
    // 请求头是否按标准格式传输  
    DisableHeaderNamesNormalizing bool  
    // url路径是按照原样输出,还是按照规范化输出。默认按照规范化输出  
    DisablePathNormalizing bool
}

这样,我们http客户端的配置项,基本已经定义完成了。下面,我们修改一下server目录下的http_client.go文件的newHttpClient()方法,添加一个HttpClientSettings参数, 同时修改RequestHttp()方法,添加一个HttpClientSettings参数。具体修改如下:

package server
import (  
    "crypto/tls"  
    "fmt"  
    "github.com/valyala/fasthttp"  
    "kitchen-engine/model"  
    "time"
)
func RequestHttp(httpClientSettings model.HttpClientSettings) {  
    // 使用fasthttp 协程池  
    // 新建一个http请求  
    req := fasthttp.AcquireRequest()  
    defer fasthttp.ReleaseRequest(req)  
    // 新建一个http响应接受服务端的返回  
    resp := fasthttp.AcquireResponse()  
    defer fasthttp.ReleaseResponse(resp)  
    // 新建一个http的客户端, newHttpClient是一个方法,在下面  
    client := newHttpClient(httpClientSettings)  
    // 添加该请求的http方法:get、post、delete、update等等  
    req.Header.SetMethod("GET")  
    // 添加该请求的http的url  
    req.SetRequestURI("http://www.baidu.com")  

    // 开始请求  
    err := client.Do(req, resp)  
    if err != nil {    
        fmt.Sprintln("发送http请求错误:   ", err.Error())  
    }  
    // 打印请求的header  
    fmt.Println("resp:    ", req.Header.Header())
}
func newHttpClient(httpClientSettings model.HttpClientSettings) (httpClient *fasthttp.Client) {  
    // tls验证,关闭验证  
    tr := &tls.Config{    
        InsecureSkipVerify: true,  
    }  
    // 新建指针类型的客户端  
    httpClient = &fasthttp.Client{}  
    httpClient.TLSConfig = tr  
    if httpClientSettings.Name != "" {    
        httpClient.Name = httpClientSettings.Name  
    }  
    if httpClientSettings.NoDefaultUserAgentHeader {    
        httpClient.NoDefaultUserAgentHeader = true  
    }  
    // 如果最大连接数不为0,将设置此数  
    if httpClientSettings.MaxConnsPerHost != 0 {    
        httpClient.MaxConnsPerHost = httpClientSettings.MaxConnsPerHost  
    }  
    // url不按照标准输出,按照原样输出  
    if httpClientSettings.DisablePathNormalizing {    
        httpClient.DisablePathNormalizing = true  
    }  // 请求头不按标准格式传输  
    if httpClientSettings.DisableHeaderNamesNormalizing  {    
        httpClient.DisableHeaderNamesNormalizing = true  
    }  
    // 如果此时间不为0,那么将设置此时间。keep-alive维持此时长后将关闭。时间单位为毫秒  
    if httpClientSettings.MaxConnDuration != 0 {    
        httpClient.MaxConnDuration = time.Duration(httpClientSettings.MaxConnDuration) * time.Millisecond  
    }  
    if httpClientSettings.ReadTimeout != 0 {    
        httpClient.ReadTimeout = time.Duration(httpClientSettings.ReadTimeout) * time.Millisecond  
    }  
    if httpClientSettings.WriteTimeout != 0 {    
        httpClient.WriteTimeout = time.Duration(httpClientSettings.WriteTimeout) * time.Millisecond  
    }  
    // 该连接如果空闲的话,在此时间后断开。  
    if httpClientSettings.MaxIdleConnDuration != 0 {    
        httpClient.MaxIdleConnDuration = time.Duration(httpClientSettings.MaxIdleConnDuration) * time.Millisecond  
    }  
    return
}

至此,客户端配置项,我们已经修改的差不多了,Tls配置,我们以后再深入讲解。下面,我们在main函数中,创建一个HttpClientSettings,并调用RequestHttp()方法, 具体如下:


package main
import (  
  "kitchen-engine/model"  
  "kitchen-engine/server"
)

func main() {
  // 一个类型中的字段,可以重置,也可以使用默认值,在go中,所有的类型的初始值,都是字段类型的0值,比如string的初始值是""空字符串,int类型的初始值是0等等  
  httpClientSettings := model.HttpClientSettings{    
    Name: "测试厨房",   
    NoDefaultUserAgentHeader: true,    
    MaxConnDuration:          1000,  
  }  
  // 调用  
  server.RequestHttp(httpClientSettings)
}

执行结果如下:

req:   GET / HTTP/1.1
User-Agent: 测试厨房
Host: www.baidu.com

ok,慢慢的代码将深入,如果没有go语言基础,建议可以先学一下go的基础知识。

相关文章
|
4月前
|
人工智能 Ubuntu 前端开发
Dify部署全栈指南:AI从Ubuntu配置到HTTPS自动化的10倍秘籍
本文档介绍如何部署Dify后端服务及前端界面,涵盖系统环境要求、依赖安装、代码拉取、环境变量配置、服务启动、数据库管理及常见问题解决方案,适用于开发与生产环境部署。
1052 1
|
8月前
|
应用服务中间件 Linux 网络安全
Centos 8.0中Nginx配置文件和https正书添加配置
这是一份Nginx配置文件,包含HTTP与HTTPS服务设置。主要功能如下:1) 将HTTP(80端口)请求重定向至HTTPS(443端口),增强安全性;2) 配置SSL证书,支持TLSv1.1至TLSv1.3协议;3) 使用uWSGI与后端应用通信(如Django);4) 静态文件托管路径设为`/root/code/static/`;5) 定制错误页面(404、50x)。适用于Web应用部署场景。
854 87
|
3月前
|
网络安全 开发工具 git
在GitLab CI中同步HTTPS仓库地址的yaml配置
最后,提交并推送 `.gitlab-ci.yml`文件到您的GitLab仓库。GitLab CI/CD将自动识别这个文件,并在每次推送到 `master`分支时执行定义的同步任务。
215 16
|
7月前
|
JSON 中间件 Go
Go 网络编程:HTTP服务与客户端开发
Go 语言的 `net/http` 包功能强大,可快速构建高并发 HTTP 服务。本文从创建简单 HTTP 服务入手,逐步讲解请求与响应对象、URL 参数处理、自定义路由、JSON 接口、静态文件服务、中间件编写及 HTTPS 配置等内容。通过示例代码展示如何使用 `http.HandleFunc`、`http.ServeMux`、`http.Client` 等工具实现常见功能,帮助开发者掌握构建高效 Web 应用的核心技能。
419 61
|
缓存 监控 负载均衡
HTTP代理配置中的常见错误及其解决方案
随着互联网发展,使用HTTP动态代理IP的需求日益增加。配置HTTP代理时常见问题及解决方法包括:1) 代理服务器无法连接:检查网络、防火墙和代理服务状态;2) 认证失败:确认凭据和配置;3) 请求超时:增加超时时间、检查后端服务和网络延迟;4) 缓存问题:清理缓存、设置缓存控制或禁用缓存;5) SSL/TLS问题:正确配置证书并确保客户端信任;6) 访问控制问题:检查ACL和日志;7) 性能问题:监控资源、负载均衡和优化配置;8) 日志记录与分析问题:启用详细日志、设置轮换策略和使用分析工具。通过解决这些问题,可以更有效地管理HTTP代理。
1597 13
|
7月前
|
Java 测试技术 容器
Jmeter工具使用:HTTP接口性能测试实战
希望这篇文章能够帮助你初步理解如何使用JMeter进行HTTP接口性能测试,有兴趣的话,你可以研究更多关于JMeter的内容。记住,只有理解并掌握了这些工具,你才能充分利用它们发挥其应有的价值。+
1192 23
|
5月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
缓存 应用服务中间件 网络安全
Nginx中配置HTTP2协议的方法
Nginx中配置HTTP2协议的方法
1044 7
|
Linux iOS开发 MacOS
【MCP教程系列】阿里云百炼MCP全面配置指南:涵盖NPX、UVX、SSE及Streamable HTTP
本文详细介绍如何在阿里云百炼平台及Windows、Linux、MacOS系统中正确配置MCP服务的JSON文件。内容涵盖三种MCP服务配置:npx(基于Stdio)、uvx(Python工具运行)和SSE(服务器发送事件)。同时解析Streamable HTTP作为新一代传输方案的优势与应用,帮助用户掌握每个参数的具体用途及使用方法,解决配置过程中可能遇到的问题,提供完整示例和扩展信息以优化设置体验。
4534 11
|
10月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1038 29