frp/extend/api/api.go

233 lines
5.1 KiB
Go
Raw Normal View History

2019-08-21 15:37:33 +08:00
package api
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strconv"
2019-09-07 00:24:20 +08:00
2019-09-08 20:49:26 +08:00
// "github.com/fatedier/frp/extend/limit"
2019-09-07 00:24:20 +08:00
"github.com/fatedier/frp/models/config"
2019-08-21 15:37:33 +08:00
"github.com/fatedier/frp/models/msg"
)
2019-09-07 00:24:20 +08:00
// Service sakurafrp api servie
2019-08-21 15:37:33 +08:00
type Service struct {
Host url.URL
}
2019-09-07 00:24:20 +08:00
// NewService crate sakurafrp api servie
2019-08-21 15:37:33 +08:00
func NewService(host string) (s *Service, err error) {
u, err := url.Parse(host)
if err != nil {
return
}
return &Service{*u}, nil
}
// CheckToken 校验客户端 token
func (s Service) CheckToken(user string, token string, timestamp int64, stk string) (ok bool, err error) {
values := url.Values{}
values.Set("action", "checktoken")
values.Set("user", user)
values.Set("token", token)
values.Set("timestamp", fmt.Sprintf("%d", timestamp))
values.Set("apitoken", stk)
s.Host.RawQuery = values.Encode()
defer func(u *url.URL) {
u.RawQuery = ""
}(&s.Host)
resp, err := http.Get(s.Host.String())
if err != nil {
return false, err
}
if resp.StatusCode != http.StatusOK {
return false, ErrHTTPStatus{
Status: resp.StatusCode,
Text: resp.Status,
}
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, err
}
response := ResponseCheckToken{}
if err = json.Unmarshal(body, &response); err != nil {
return false, err
}
if !response.Success {
return false, ErrCheckTokenFail{response.Message}
}
return true, nil
}
// CheckProxy 校验客户端代理
func (s Service) CheckProxy(user string, pMsg *msg.NewProxy, timestamp int64, stk string) (ok bool, err error) {
domains, err := json.Marshal(pMsg.CustomDomains)
if err != nil {
return false, err
}
2019-09-07 00:24:20 +08:00
2019-08-21 15:37:33 +08:00
headers, err := json.Marshal(pMsg.Headers)
if err != nil {
return false, err
}
2019-09-07 00:24:20 +08:00
2019-08-21 15:37:33 +08:00
locations, err := json.Marshal(pMsg.Locations)
if err != nil {
return false, err
}
2019-09-07 00:24:20 +08:00
2019-08-21 15:37:33 +08:00
values := url.Values{}
2019-09-07 00:24:20 +08:00
2019-08-21 15:37:33 +08:00
// API Basic
values.Set("action", "checkproxy")
values.Set("user", user)
values.Set("timestamp", fmt.Sprintf("%d", timestamp))
values.Set("apitoken", stk)
2019-09-07 00:24:20 +08:00
2019-08-21 15:37:33 +08:00
// Proxies basic info
values.Set("proxy_name", pMsg.ProxyName)
values.Set("proxy_type", pMsg.ProxyType)
values.Set("use_encryption", BoolToString(pMsg.UseEncryption))
values.Set("use_compression", BoolToString(pMsg.UseCompression))
2019-09-07 00:24:20 +08:00
2019-08-21 15:37:33 +08:00
// Http Proxies
values.Set("domain", string(domains))
values.Set("subdomain", pMsg.SubDomain)
2019-09-07 00:24:20 +08:00
2019-08-21 15:37:33 +08:00
// Headers
values.Set("locations", string(locations))
values.Set("http_user", pMsg.HttpUser)
values.Set("http_pwd", pMsg.HttpPwd)
values.Set("host_header_rewrite", pMsg.HostHeaderRewrite)
values.Set("headers", string(headers))
2019-09-07 00:24:20 +08:00
2019-08-21 15:37:33 +08:00
// Tcp & Udp & Stcp
values.Set("remote_port", strconv.Itoa(pMsg.RemotePort))
2019-09-07 00:24:20 +08:00
2019-08-21 15:37:33 +08:00
// Stcp & Xtcp
values.Set("sk", pMsg.Sk)
2019-09-07 00:24:20 +08:00
2019-08-21 15:37:33 +08:00
// Load balance
values.Set("group", pMsg.Group)
values.Set("group_key", pMsg.GroupKey)
2019-09-07 00:24:20 +08:00
2019-08-21 15:37:33 +08:00
s.Host.RawQuery = values.Encode()
defer func(u *url.URL) {
u.RawQuery = ""
}(&s.Host)
resp, err := http.Get(s.Host.String())
if err != nil {
return false, err
}
if resp.StatusCode != http.StatusOK {
return false, ErrHTTPStatus{
Status: resp.StatusCode,
Text: resp.Status,
}
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, err
}
response := ResponseCheckProxy{}
if err = json.Unmarshal(body, &response); err != nil {
return false, err
}
if !response.Success {
return false, ErrCheckProxyFail{response.Message}
}
return true, nil
}
2019-09-07 00:24:20 +08:00
// GetProxyLimit 获取隧道限速信息
2019-09-08 20:49:26 +08:00
func (s Service) GetProxyLimit(user string, pxyConf *config.BaseProxyConf, timestamp int64, stk string) (inLimit, outLimit uint64, err error) {
2019-09-08 18:32:21 +08:00
// 这部分就照之前的搬过去了能跑就行x
values := url.Values{}
values.Set("do", "getlimit")
values.Set("user", user)
2019-09-08 20:49:26 +08:00
values.Set("timestamp", fmt.Sprintf("%d", timestamp))
2019-09-08 18:32:21 +08:00
values.Set("frpstoken", stk)
s.Host.RawQuery = values.Encode()
defer func(u *url.URL) {
u.RawQuery = ""
}(&s.Host)
resp, err := http.Get(s.Host.String())
if err != nil {
2019-09-08 20:49:26 +08:00
return 0, 0, err
2019-09-08 18:32:21 +08:00
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
2019-09-08 20:49:26 +08:00
return 0, 0, err
2019-09-08 18:32:21 +08:00
}
er := &ErrHTTPStatus{}
if err = json.Unmarshal(body, er); err != nil {
2019-09-08 20:49:26 +08:00
return 0, 0, err
2019-09-08 18:32:21 +08:00
}
if er.Status != 200 {
2019-09-08 20:49:26 +08:00
return 0, 0, er
2019-09-08 18:32:21 +08:00
}
2019-09-08 20:49:26 +08:00
response := &ResponseGetLimit{}
if err = json.Unmarshal(body, response); err != nil {
return 0, 0, err
2019-09-08 18:32:21 +08:00
}
2019-09-08 20:49:26 +08:00
return response.MaxIn, response.MaxOut, nil
2019-09-07 00:24:20 +08:00
}
2019-08-21 15:37:33 +08:00
func BoolToString(val bool) (str string) {
if val {
return "true"
}
2019-09-07 00:24:20 +08:00
return "false"
2019-08-21 15:37:33 +08:00
}
type ErrHTTPStatus struct {
Status int `json:"status"`
Text string `json:"massage"`
}
func (e ErrHTTPStatus) Error() string {
return fmt.Sprintf("%s", e.Text)
}
2019-09-08 18:32:21 +08:00
type ResponseGetLimit struct {
MaxIn uint64 `json:"max-in"`
MaxOut uint64 `json:"max-out"`
}
2019-08-21 15:37:33 +08:00
type ResponseCheckToken struct {
Success bool `json:"success"`
Message string `json:"message"`
}
type ResponseCheckProxy struct {
Success bool `json:"success"`
Message string `json:"message"`
}
type ErrCheckTokenFail struct {
Message string
}
type ErrCheckProxyFail struct {
Message string
}
func (e ErrCheckTokenFail) Error() string {
return e.Message
}
func (e ErrCheckProxyFail) Error() string {
return e.Message
}