mirror of
				https://github.com/TeaOSLab/EdgeAPI.git
				synced 2025-11-04 16:00:24 +08:00 
			
		
		
		
	
		
			
	
	
		
			171 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			171 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package dnsclients
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"bytes"
							 | 
						||
| 
								 | 
							
									"crypto/sha1"
							 | 
						||
| 
								 | 
							
									"crypto/tls"
							 | 
						||
| 
								 | 
							
									"encoding/json"
							 | 
						||
| 
								 | 
							
									"fmt"
							 | 
						||
| 
								 | 
							
									teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
							 | 
						||
| 
								 | 
							
									"github.com/TeaOSLab/EdgeAPI/internal/errors"
							 | 
						||
| 
								 | 
							
									"github.com/iwind/TeaGo/maps"
							 | 
						||
| 
								 | 
							
									"io/ioutil"
							 | 
						||
| 
								 | 
							
									"net/http"
							 | 
						||
| 
								 | 
							
									"strconv"
							 | 
						||
| 
								 | 
							
									"time"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var customHTTPClient = &http.Client{
							 | 
						||
| 
								 | 
							
									Timeout: 10 * time.Second,
							 | 
						||
| 
								 | 
							
									Transport: &http.Transport{
							 | 
						||
| 
								 | 
							
										TLSClientConfig: &tls.Config{
							 | 
						||
| 
								 | 
							
											InsecureSkipVerify: true,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
									},
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// HTTP自定义DNS
							 | 
						||
| 
								 | 
							
								type CustomHTTPProvider struct {
							 | 
						||
| 
								 | 
							
									url    string
							 | 
						||
| 
								 | 
							
									secret string
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 认证
							 | 
						||
| 
								 | 
							
								// 参数:
							 | 
						||
| 
								 | 
							
								//   - url
							 | 
						||
| 
								 | 
							
								//   - secret
							 | 
						||
| 
								 | 
							
								func (this *CustomHTTPProvider) Auth(params maps.Map) error {
							 | 
						||
| 
								 | 
							
									this.url = params.GetString("url")
							 | 
						||
| 
								 | 
							
									if len(this.url) == 0 {
							 | 
						||
| 
								 | 
							
										return errors.New("'url' should not be empty")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.secret = params.GetString("secret")
							 | 
						||
| 
								 | 
							
									if len(this.secret) == 0 {
							 | 
						||
| 
								 | 
							
										return errors.New("'secret' should not be empty")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 获取域名解析记录列表
							 | 
						||
| 
								 | 
							
								func (this *CustomHTTPProvider) GetRecords(domain string) (records []*Record, err error) {
							 | 
						||
| 
								 | 
							
									resp, err := this.post(maps.Map{
							 | 
						||
| 
								 | 
							
										"action": "GetRecords",
							 | 
						||
| 
								 | 
							
										"domain": domain,
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									err = json.Unmarshal(resp, &records)
							 | 
						||
| 
								 | 
							
									return
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 读取域名支持的线路数据
							 | 
						||
| 
								 | 
							
								func (this *CustomHTTPProvider) GetRoutes(domain string) (routes []*Route, err error) {
							 | 
						||
| 
								 | 
							
									resp, err := this.post(maps.Map{
							 | 
						||
| 
								 | 
							
										"action": "GetRoutes",
							 | 
						||
| 
								 | 
							
										"domain": domain,
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									err = json.Unmarshal(resp, &routes)
							 | 
						||
| 
								 | 
							
									return
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 查询单个记录
							 | 
						||
| 
								 | 
							
								func (this *CustomHTTPProvider) QueryRecord(domain string, name string, recordType RecordType) (*Record, error) {
							 | 
						||
| 
								 | 
							
									resp, err := this.post(maps.Map{
							 | 
						||
| 
								 | 
							
										"action":     "QueryRecord",
							 | 
						||
| 
								 | 
							
										"domain":     domain,
							 | 
						||
| 
								 | 
							
										"name":       name,
							 | 
						||
| 
								 | 
							
										"recordType": recordType,
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if len(resp) == 0 {
							 | 
						||
| 
								 | 
							
										return nil, nil
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									record := &Record{}
							 | 
						||
| 
								 | 
							
									err = json.Unmarshal(resp, record)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if len(record.Value) == 0 {
							 | 
						||
| 
								 | 
							
										return nil, nil
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return record, nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 设置记录
							 | 
						||
| 
								 | 
							
								func (this *CustomHTTPProvider) AddRecord(domain string, newRecord *Record) error {
							 | 
						||
| 
								 | 
							
									_, err := this.post(maps.Map{
							 | 
						||
| 
								 | 
							
										"action":    "AddRecord",
							 | 
						||
| 
								 | 
							
										"domain":    domain,
							 | 
						||
| 
								 | 
							
										"newRecord": newRecord,
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									return err
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 修改记录
							 | 
						||
| 
								 | 
							
								func (this *CustomHTTPProvider) UpdateRecord(domain string, record *Record, newRecord *Record) error {
							 | 
						||
| 
								 | 
							
									_, err := this.post(maps.Map{
							 | 
						||
| 
								 | 
							
										"action":    "UpdateRecord",
							 | 
						||
| 
								 | 
							
										"domain":    domain,
							 | 
						||
| 
								 | 
							
										"record":    record,
							 | 
						||
| 
								 | 
							
										"newRecord": newRecord,
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									return err
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 删除记录
							 | 
						||
| 
								 | 
							
								func (this *CustomHTTPProvider) DeleteRecord(domain string, record *Record) error {
							 | 
						||
| 
								 | 
							
									_, err := this.post(maps.Map{
							 | 
						||
| 
								 | 
							
										"action": "DeleteRecord",
							 | 
						||
| 
								 | 
							
										"domain": domain,
							 | 
						||
| 
								 | 
							
										"record": record,
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									return err
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 默认线路
							 | 
						||
| 
								 | 
							
								func (this *CustomHTTPProvider) DefaultRoute() string {
							 | 
						||
| 
								 | 
							
									resp, err := this.post(maps.Map{
							 | 
						||
| 
								 | 
							
										"action": "DefaultRoute",
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return ""
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return string(resp)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 执行操作
							 | 
						||
| 
								 | 
							
								func (this *CustomHTTPProvider) post(params maps.Map) (respData []byte, err error) {
							 | 
						||
| 
								 | 
							
									data, err := json.Marshal(params)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									req, err := http.NewRequest(http.MethodPost, this.url, bytes.NewReader(data))
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									timestamp := strconv.FormatInt(time.Now().Unix(), 10)
							 | 
						||
| 
								 | 
							
									req.Header.Set("Timestamp", timestamp)
							 | 
						||
| 
								 | 
							
									req.Header.Set("Token", fmt.Sprintf("%x", sha1.Sum([]byte(this.secret+"@"+timestamp))))
							 | 
						||
| 
								 | 
							
									req.Header.Set("User-Agent", "GoEdge/"+teaconst.Version)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									resp, err := customHTTPClient.Do(req)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									defer func() {
							 | 
						||
| 
								 | 
							
										_ = resp.Body.Close()
							 | 
						||
| 
								 | 
							
									}()
							 | 
						||
| 
								 | 
							
									if resp.StatusCode != 200 {
							 | 
						||
| 
								 | 
							
										return nil, errors.New("status should be 200, but got '" + strconv.Itoa(resp.StatusCode) + "'")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return ioutil.ReadAll(resp.Body)
							 | 
						||
| 
								 | 
							
								}
							 |