# Netutil

netutil 网络包支持获取 ip 地址,发送 http 请求。

# 源码:

# 用法:

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)
}
最后更新时间: 2022/9/29 下午1:53:14