1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-04 12:52:28 +08:00
Files
lancet/docs/netutil.md
2023-06-13 15:08:40 +08:00

19 KiB

Netutil

Package netutil contains functions to get net information and send http request.

Source:

https://github.com/duke-git/lancet/blob/v1/netutil/net.go

https://github.com/duke-git/lancet/blob/v1/netutil/http_client.go

https://github.com/duke-git/lancet/blob/v1/netutil/http.go

Usage:

import (
    "github.com/duke-git/lancet/netutil"
)

Index

Documentation

ConvertMapToQueryString

Convert map to url query string.

Signature:

func ConvertMapToQueryString(param map[string]interface{}) string

Example:

package main

import (
    "fmt"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    var m = map[string]interface{}{
        "c": 3,
        "a": 1,
        "b": 2,
    }
    qs := netutil.ConvertMapToQueryString(m)

    fmt.Println(qs) //a=1&b=2&c=3
}

EncodeUrl

Encode url query string values.

Signature:

func EncodeUrl(urlStr string) (string, error)

Example:

package main

import (
    "fmt"
    "github.com/duke-git/lancet/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

Get internal ip information.

Signature:

func GetInternalIp() string

Example:

package main

import (
    "fmt"
    "net"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    internalIp := netutil.GetInternalIp()
    ip := net.ParseIP(internalIp)

    fmt.Println(ip) //192.168.1.9
}

GetIps

Get all ipv4 list.

Signature:

func GetIps() []string

Example:

package main

import (
    "fmt"
    "net"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    ips := netutil.GetIps()
    fmt.Println(ips) //[192.168.1.9]
}

GetMacAddrs

Get all mac addresses list.

Signature:

func GetMacAddrs() []string {

Example:

package main

import (
    "fmt"
    "net"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    addrs := netutil.GetMacAddrs()
    fmt.Println(addrs)
}

GetPublicIpInfo

Get public ip information.

Signature:

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"`
}

Example:

package main

import (
    "fmt"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    publicIpInfo, err := netutil.GetPublicIpInfo()
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(publicIpInfo)
}

GetRequestPublicIp

Get http request public ip.

Signature:

func GetRequestPublicIp(req *http.Request) string

Example:

package main

import (
    "fmt"
    "github.com/duke-git/lancet/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

Checks if a ip is public or not.

Signature:

func IsPublicIP(IP net.IP) bool

Example:

package main

import (
    "fmt"
    "net"
    "github.com/duke-git/lancet/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

Checks if an ip is intranet or not.

Signature:

func IsInternalIP(IP net.IP) bool

Example:

package main

import (
    "fmt"
    "net"
    "github.com/duke-git/lancet/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 is a struct used to abstract HTTP request entity.

Signature:

type HttpRequest struct {
    RawURL      string
    Method      string
    Headers     http.Header
    QueryParams url.Values
    FormData    url.Values
    Body        []byte
}

Example:

package main

import (
    "fmt"
    "net"
    "github.com/duke-git/lancet/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 is a struct used to send HTTP request. It can be instanced with some configurations or none config.

Signature:

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

Example:

package main

import (
    "fmt"
    "net"
    "time"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    httpClientCfg := netutil.HttpClientConfig{
        SSLEnabled: true,
        HandshakeTimeout:10 * time.Second
    }
    httpClient := netutil.NewHttpClientWithConfig(&httpClientCfg)
}

SendRequest

Use HttpClient to send HTTP request.

Signature:

func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error)

Example:

package main

import (
    "fmt"
    "net"
    "time"
    "github.com/duke-git/lancet/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

Decode http response into target object.

Signature:

func (client *HttpClient) DecodeResponse(resp *http.Response, target interface{}) error

Example:

package main

import (
    "fmt"
    "net"
    "time"
    "github.com/duke-git/lancet/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

Convert struct to url values, only convert the field which is exported and has `json` tag.

Signature:

func StructToUrlValues(targetStruct interface{}) url.Values

Example:

package main

import (
    "fmt"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    type TodoQuery struct {
        Id     int    `json:"id"`
        UserId int    `json:"userId"`
        Name   string `json:"name,omitempty"`
        Status string
    }
    item := TodoQuery{
        Id:     1,
        UserId: 123,
        Name:   "test",
        Status: "completed",
    }
    queryValues := netutil.StructToUrlValues(item)

    fmt.Println(todoValues.Get("id"))
    fmt.Println(todoValues.Get("userId"))
    fmt.Println(todoValues.Get("name"))
    fmt.Println(todoValues.Get("status"))

    // Output:
    // 1
    // 123
    // test
    //
}

HttpGet

Send http get request. (Deprecated: use SendRequest for replacement)

Signature:

// params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]interface{},
// params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client.
func HttpGet(url string, params ...interface{}) (*http.Response, error)

Example:

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "github.com/duke-git/lancet/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

Send http post request. (Deprecated: use SendRequest for replacement)

Signature:

// params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]interface{},
// params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client.
func HttpPost(url string, params ...interface{}) (*http.Response, error)

Example:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    url := "https://jsonplaceholder.typicode.com/todos"
    header := map[string]string{
        "Content-Type": "application/x-www-form-urlencoded",
        // "Content-Type": "multipart/form-data",
    }

    postData := url.Values{}
    postData.Add("userId", "1")
    postData.Add("title", "TestToDo")

    // postData := make(map[string]string)
    // postData["userId"] = "1"
    // postData["title"] = "title"

    resp, err := netutil.HttpPost(apiUrl, header, nil, postData)
    if err != nil {
        log.Fatal(err)
    }
    body, _ := io.ReadAll(resp.Body)
    t.Log("response: ", resp.StatusCode, string(body))
}

HttpPut

Send http put request. (Deprecated: use SendRequest for replacement)

Signature:

// params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]interface{},
// params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client.
func HttpPut(url string, params ...interface{}) (*http.Response, error)

Example:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "github.com/duke-git/lancet/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

Send http delete request. (Deprecated: use SendRequest for replacement)

Signature:

// params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]interface{},
// params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client.
func HttpDelete(url string, params ...interface{}) (*http.Response, error)

Example:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "github.com/duke-git/lancet/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

Send http patch request. (Deprecated: use SendRequest for replacement)

Signature:

// params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]interface{},
// params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client.
func HttpPatch(url string, params ...interface{}) (*http.Response, error)

Example:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "github.com/duke-git/lancet/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

Decode http response to specified interface.

Signature:

func ParseHttpResponse(resp *http.Response, obj interface{}) error

Example:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "github.com/duke-git/lancet/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)
}

UploadFile

upload the file to a server.

Signature:

func UploadFile(filepath string, server string) (bool, error)

Example:

package main

import (
    "fmt"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    ok, err := netutil.UploadFile("./a.jpg", "http://www.xxx.com/bucket/test")

    fmt.Println(ok)
    fmt.Println(err)
}

DownloadFile

download the file exist in url to a local file.

Signature:

func DownloadFile(filepath string, url string) error

Example:

package main

import (
    "fmt"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    err := DownloadFile("./lancet_logo.jpg", "https://picx.zhimg.com/v2-fc82a4199749de9cfb71e32e54f489d3_720w.jpg?source=172ae18b")

    fmt.Println(err)
}

IsPingConnected

checks if can ping the specified host or not.

Signature:

func IsPingConnected(host string) bool

Example:

package main

import (
    "fmt"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    result1 := netutil.IsPingConnected("www.baidu.com")
    result2 := netutil.IsPingConnected("www.!@#&&&.com")

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // true
    // false
}

IsTelnetConnected

Checks if can telnet the specified host or not.

Signature:

func IsTelnetConnected(host string, port string) bool

Example:

package main

import (
    "fmt"
    "github.com/duke-git/lancet/netutil"
)

func main() {
    result1 := netutil.IsTelnetConnected("www.baidu.com", "80")
    result2 := netutil.IsTelnetConnected("www.baidu.com", "123")

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // true
    // false
}