# Netutil
netutil 网络包支持获取 ip 地址,发送 http 请求。
# 源码:
https://github.com/duke-git/lancet/blob/main/netutil/net.go (opens new window)
https://github.com/duke-git/lancet/blob/main/netutil/http_client.go (opens new window)
https://github.com/duke-git/lancet/blob/main/netutil/http.go (opens new window)
# 用法:
import (
"github.com/duke-git/lancet/v2/netutil"
)
# 文档
# ConvertMapToQueryString
将map转换成http查询字符串.
函数签名:
func ConvertMapToQueryString(param map[string]any) string
例子:
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
var m = map[string]any{
"c": 3,
"a": 1,
"b": 2,
}
qs := netutil.ConvertMapToQueryString(m)
fmt.Println(qs) //a=1&b=2&c=3
}
# EncodeUrl
编码url query string的值
函数签名:
func EncodeUrl(urlStr string) (string, error)
例子:
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
urlAddr := "http://www.lancet.com?a=1&b=[2]"
encodedUrl, err := netutil.EncodeUrl(urlAddr)
if err != nil {
fmt.Println(err)
}
fmt.Println(encodedUrl) //http://www.lancet.com?a=1&b=%5B2%5D
}
# GetInternalIp
获取内部ip
函数签名:
func GetInternalIp() string
例子:
package main
import (
"fmt"
"net"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
internalIp := netutil.GetInternalIp()
ip := net.ParseIP(internalIp)
fmt.Println(ip) //192.168.1.9
}
# GetIps
获取ipv4地址列表
函数签名:
func GetIps() []string
例子:
package main
import (
"fmt"
"net"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
ips := netutil.GetIps()
fmt.Println(ips) //[192.168.1.9]
}
# GetMacAddrs
获取mac地址列
函数签名:
func GetMacAddrs() []string {
例子:
package main
import (
"fmt"
"net"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
addrs := netutil.GetMacAddrs()
fmt.Println(addrs)
}
# GetPublicIpInfo
获取公网ip信息
函数签名:
func GetPublicIpInfo() (*PublicIpInfo, error)
type PublicIpInfo struct {
Status string `json:"status"`
Country string `json:"country"`
CountryCode string `json:"countryCode"`
Region string `json:"region"`
RegionName string `json:"regionName"`
City string `json:"city"`
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
Isp string `json:"isp"`
Org string `json:"org"`
As string `json:"as"`
Ip string `json:"query"`
}
例子:
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
publicIpInfo, err := netutil.GetPublicIpInfo()
if err != nil {
fmt.Println(err)
}
fmt.Println(publicIpInfo)
}
# GetRequestPublicIp
获取http请求ip
函数签名:
func GetRequestPublicIp(req *http.Request) string
例子:
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
ip := "36.112.24.10"
request1 := http.Request{
Method: "GET",
Header: http.Header{
"X-Forwarded-For": {ip},
},
}
publicIp1 := netutil.GetRequestPublicIp(&request1)
fmt.Println(publicIp1) //36.112.24.10
request2 := http.Request{
Method: "GET",
Header: http.Header{
"X-Real-Ip": {ip},
},
}
publicIp2 := netutil.GetRequestPublicIp(&request2)
fmt.Println(publicIp2) //36.112.24.10
}
# IsPublicIP
判断ip是否是公共ip
函数签名:
func IsPublicIP(IP net.IP) bool
例子:
package main
import (
"fmt"
"net"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
ip1 := net.ParseIP("192.168.0.1")
ip2 := net.ParseIP("36.112.24.10")
fmt.Println(netutil.IsPublicIP(ip1)) //false
fmt.Println(netutil.IsPublicIP(ip2)) //true
}
# IsInternalIP
判断ip是否是局域网ip.
函数签名:
func IsInternalIP(IP net.IP) bool
例子:
package main
import (
"fmt"
"net"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
ip1 := net.ParseIP("127.0.0.1")
ip2 := net.ParseIP("36.112.24.10")
fmt.Println(netutil.IsInternalIP(ip1)) //true
fmt.Println(netutil.IsInternalIP(ip2)) //false
}
# HttpRequest
HttpRequest用于抽象HTTP请求实体的结构
函数签名:
type HttpRequest struct {
RawURL string
Method string
Headers http.Header
QueryParams url.Values
FormData url.Values
Body []byte
}
例子:
package main
import (
"fmt"
"net"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
header := http.Header{}
header.Add("Content-Type", "multipart/form-data")
postData := url.Values{}
postData.Add("userId", "1")
postData.Add("title", "testItem")
request := &netutil.HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos",
Method: "POST",
Headers: header,
FormData: postData,
}
}
# HttpClient
HttpClient是用于发送HTTP请求的结构体。它可以用一些配置参数或无配置实例化.
函数签名:
type HttpClient struct {
*http.Client
TLS *tls.Config
Request *http.Request
Config HttpClientConfig
}
type HttpClientConfig struct {
SSLEnabled bool
TLSConfig *tls.Config
Compressed bool
HandshakeTimeout time.Duration
ResponseTimeout time.Duration
Verbose bool
}
func NewHttpClient() *HttpClient
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient
例子:
package main
import (
"fmt"
"net"
"time"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
httpClientCfg := netutil.HttpClientConfig{
SSLEnabled: true,
HandshakeTimeout:10 * time.Second
}
httpClient := netutil.NewHttpClientWithConfig(&httpClientCfg)
}
# SendRequest
HttpClient发送http请求
函数签名:
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error)
例子:
package main
import (
"fmt"
"net"
"time"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
request := &netutil.HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := netutil.NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
type Todo struct {
UserId int `json:"userId"`
Id int `json:"id"`
Title string `json:"title"`
Completed bool `json:"completed"`
}
var todo Todo
httpClient.DecodeResponse(resp, &todo)
fmt.Println(todo.Id) //1
}
# DecodeResponse
解析http响应体到目标结构体
函数签名:
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error
例子:
package main
import (
"fmt"
"net"
"time"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
request := &netutil.HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := netutil.NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
type Todo struct {
UserId int `json:"userId"`
Id int `json:"id"`
Title string `json:"title"`
Completed bool `json:"completed"`
}
var todo Todo
httpClient.DecodeResponse(resp, &todo)
fmt.Println(todo.Id) //1
}
# StructToUrlValues
将结构体转为url values, 仅转化结构体导出字段并且包含`json` tag.
函数签名:
func StructToUrlValues(targetStruct any) url.Values
例子:
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
type TodoQuery struct {
Id int `json:"id"`
UserId int `json:"userId"`
}
todoQuery := TodoQuery{
Id: 1,
UserId: 2,
}
todoValues := netutil.StructToUrlValues(todoQuery)
fmt.Println(todoValues.Get("id")) //1
fmt.Println(todoValues.Get("userId")) //2
}
# HttpGet (Deprecated: use SendRequest for replacement)
发送http get请求
函数签名:
// params[0] http请求header,类型必须是http.Header或者map[string]string
// params[1] http查询字符串,类型必须是url.Values或者map[string]string
// params[2] post请求体,类型必须是[]byte
// params[3] http client,类型必须是http.Client
func HttpGet(url string, params ...any) (*http.Response, error)
例子:
package main
import (
"fmt"
"io/ioutil"
"log"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
url := "https://jsonplaceholder.typicode.com/todos/1"
header := map[string]string{
"Content-Type": "application/json",
}
resp, err := netutil.HttpGet(url, header)
if err != nil {
log.Fatal(err)
}
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(body)
}
# HttpPost (Deprecated: use SendRequest for replacement)
发送http post请求
函数签名:
// params[0] http请求header,类型必须是http.Header或者map[string]string
// params[1] http查询字符串,类型必须是url.Values或者map[string]string
// params[2] post请求体,类型必须是[]byte
// params[3] http client,类型必须是http.Client
func HttpPost(url string, params ...any) (*http.Response, error)
例子:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
url := "https://jsonplaceholder.typicode.com/todos"
header := map[string]string{
"Content-Type": "application/json",
}
type Todo struct {
UserId int `json:"userId"`
Title string `json:"title"`
}
todo := Todo{1, "TestAddToDo"}
bodyParams, _ := json.Marshal(todo)
resp, err := netutil.HttpPost(url, header, nil, bodyParams)
if err != nil {
log.Fatal(err)
}
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(body)
}
# HttpPut (Deprecated: use SendRequest for replacement)
发送http put请求
函数签名:
// params[0] http请求header,类型必须是http.Header或者map[string]string
// params[1] http查询字符串,类型必须是url.Values或者map[string]string
// params[2] post请求体,类型必须是[]byte
// params[3] http client,类型必须是http.Client
func HttpPut(url string, params ...any) (*http.Response, error)
例子:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
url := "https://jsonplaceholder.typicode.com/todos/1"
header := map[string]string{
"Content-Type": "application/json",
}
type Todo struct {
Id int `json:"id"`
UserId int `json:"userId"`
Title string `json:"title"`
}
todo := Todo{1, 1, "TestPutToDo"}
bodyParams, _ := json.Marshal(todo)
resp, err := netutil.HttpPut(url, header, nil, bodyParams)
if err != nil {
log.Fatal(err)
}
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(body)
}
# HttpDelete (Deprecated: use SendRequest for replacement)
发送http delete请求
函数签名:
// params[0] http请求header,类型必须是http.Header或者map[string]string
// params[1] http查询字符串,类型必须是url.Values或者map[string]string
// params[2] post请求体,类型必须是[]byte
// params[3] http client,类型必须是http.Client
func HttpDelete(url string, params ...any) (*http.Response, error)
例子:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
url := "https://jsonplaceholder.typicode.com/todos/1"
resp, err := netutil.HttpDelete(url)
if err != nil {
log.Fatal(err)
}
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(body)
}
# HttpPatch (Deprecated: use SendRequest for replacement)
发送http patch请求
函数签名:
// params[0] http请求header,类型必须是http.Header或者map[string]string
// params[1] http查询字符串,类型必须是url.Values或者map[string]string
// params[2] post请求体,类型必须是[]byte
// params[3] http client,类型必须是http.Client
func HttpPatch(url string, params ...any) (*http.Response, error)
例子:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
url := "https://jsonplaceholder.typicode.com/todos/1"
header := map[string]string{
"Content-Type": "application/json",
}
type Todo struct {
Id int `json:"id"`
UserId int `json:"userId"`
Title string `json:"title"`
}
todo := Todo{1, 1, "TestPatchToDo"}
bodyParams, _ := json.Marshal(todo)
resp, err := netutil.HttpPatch(url, header, nil, bodyParams)
if err != nil {
log.Fatal(err)
}
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(body)
}
# ParseHttpResponse
将http请求响应解码成特定struct值
函数签名:
func ParseHttpResponse(resp *http.Response, obj any) error
例子:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
url := "https://jsonplaceholder.typicode.com/todos/1"
header := map[string]string{
"Content-Type": "application/json",
}
resp, err := netutil.HttpGet(url, header)
if err != nil {
log.Fatal(err)
}
type Todo struct {
Id int `json:"id"`
UserId int `json:"userId"`
Title string `json:"title"`
Completed bool `json:"completed"`
}
toDoResp := &Todo{}
err = netutil.ParseHttpResponse(resp, toDoResp)
if err != nil {
log.Fatal(err)
}
fmt.Println(toDoResp)
}