github.com/TeaOSLab/EdgeNode@v1.3.8/internal/firewalls/firewall_http.go (about)

     1  // Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
     2  
     3  package firewalls
     4  
     5  import (
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"github.com/iwind/TeaGo/maps"
    10  	"github.com/iwind/TeaGo/types"
    11  	"io"
    12  	"net/http"
    13  	"net/url"
    14  )
    15  
    16  type HTTPFirewall struct {
    17  	client   *http.Client
    18  	endpoint string
    19  }
    20  
    21  func NewHTTPFirewall(endpoint string) *HTTPFirewall {
    22  	return &HTTPFirewall{
    23  		client:   http.DefaultClient,
    24  		endpoint: endpoint,
    25  	}
    26  }
    27  
    28  // Name 名称
    29  func (this *HTTPFirewall) Name() string {
    30  	result, err := this.get("/name", nil)
    31  	if err != nil {
    32  		return ""
    33  	}
    34  	return result.GetString("name")
    35  }
    36  
    37  // IsReady 是否已准备被调用
    38  func (this *HTTPFirewall) IsReady() bool {
    39  	result, err := this.get("/isReady", nil)
    40  	if err != nil {
    41  		return false
    42  	}
    43  	return result.GetBool("result")
    44  }
    45  
    46  // IsMock 是否为模拟
    47  func (this *HTTPFirewall) IsMock() bool {
    48  	result, err := this.get("/isMock", nil)
    49  	if err != nil {
    50  		return false
    51  	}
    52  	return result.GetBool("result")
    53  }
    54  
    55  // AllowPort 允许端口
    56  func (this *HTTPFirewall) AllowPort(port int, protocol string) error {
    57  	_, err := this.get("/allowPort", map[string]string{
    58  		"port":     types.String(port),
    59  		"protocol": protocol,
    60  	})
    61  	return err
    62  }
    63  
    64  // RemovePort 删除端口
    65  func (this *HTTPFirewall) RemovePort(port int, protocol string) error {
    66  	_, err := this.get("/removePort", map[string]string{
    67  		"port":     types.String(port),
    68  		"protocol": protocol,
    69  	})
    70  	return err
    71  }
    72  
    73  // RejectSourceIP 拒绝某个源IP连接
    74  func (this *HTTPFirewall) RejectSourceIP(ip string, timeoutSeconds int) error {
    75  	_, err := this.get("/rejectSourceIP", map[string]string{
    76  		"ip":             ip,
    77  		"timeoutSeconds": types.String(timeoutSeconds),
    78  	})
    79  	return err
    80  }
    81  
    82  // DropSourceIP 丢弃某个源IP数据
    83  // ip 要封禁的IP
    84  // timeoutSeconds 过期时间
    85  // async 是否异步
    86  func (this *HTTPFirewall) DropSourceIP(ip string, timeoutSeconds int, async bool) error {
    87  	var asyncString = "false"
    88  	if async {
    89  		asyncString = "true"
    90  	}
    91  	_, err := this.get("/dropSourceIP", map[string]string{
    92  		"ip":             ip,
    93  		"timeoutSeconds": types.String(timeoutSeconds),
    94  		"async":          asyncString,
    95  	})
    96  	return err
    97  }
    98  
    99  // RemoveSourceIP 删除某个源IP
   100  func (this *HTTPFirewall) RemoveSourceIP(ip string) error {
   101  	_, err := this.get("/removeSourceIP", map[string]string{
   102  		"ip": ip,
   103  	})
   104  	return err
   105  }
   106  
   107  func (this *HTTPFirewall) get(path string, args map[string]string) (result maps.Map, err error) {
   108  	var urlString = this.endpoint + path
   109  	if len(args) > 0 {
   110  		var query = &url.Values{}
   111  		for k, v := range args {
   112  			query.Add(k, v)
   113  		}
   114  		urlString += "?" + query.Encode()
   115  	}
   116  	req, err := http.NewRequest(http.MethodGet, urlString, nil)
   117  	if err != nil {
   118  		return nil, err
   119  	}
   120  
   121  	resp, err := this.client.Do(req)
   122  	if err != nil {
   123  		return nil, err
   124  	}
   125  
   126  	if resp.StatusCode != http.StatusOK {
   127  		return nil, errors.New("server response code '" + types.String(resp.StatusCode) + "'")
   128  	}
   129  
   130  	defer func() {
   131  		_ = resp.Body.Close()
   132  	}()
   133  
   134  	data, err := io.ReadAll(resp.Body)
   135  	if err != nil {
   136  		return nil, fmt.Errorf("read response failed: %w", err)
   137  	}
   138  
   139  	if len(data) == 0 {
   140  		return maps.Map{}, nil
   141  	}
   142  
   143  	result = maps.Map{}
   144  	err = json.Unmarshal(data, &result)
   145  	if err != nil {
   146  		return nil, fmt.Errorf("decode response failed: %w", err)
   147  	}
   148  
   149  	return
   150  }