feat: add proxy support
This commit is contained in:
parent
bd24760d7d
commit
8f3d67c648
@ -2,6 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -78,6 +79,12 @@ var (
|
|||||||
ErrorCode: "ERROR_BAD_REQUEST",
|
ErrorCode: "ERROR_BAD_REQUEST",
|
||||||
ErrorDescription: "Bad request",
|
ErrorDescription: "Bad request",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errorProxyConnectRefused = &antigateError{
|
||||||
|
ErrorId: 25,
|
||||||
|
ErrorCode: "ERROR_PROXY_CONNECT_REFUSED",
|
||||||
|
ErrorDescription: "Bad proxy",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *antigateV2Api) getTaskResult(request struct {
|
func (a *antigateV2Api) getTaskResult(request struct {
|
||||||
@ -150,6 +157,35 @@ func (a *antigateV2Api) getTaskResult(request struct {
|
|||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func collectAntiGateV2Proxy(task any) *string {
|
||||||
|
var proxy struct {
|
||||||
|
ProxyType string `json:"proxyType"`
|
||||||
|
ProxyAddress string `json:"proxyAddress"`
|
||||||
|
ProxyPort uint16 `json:"proxyPort"`
|
||||||
|
ProxyLogin *string `json:"proxyLogin"`
|
||||||
|
ProxyPassword *string `json:"proxyPassword"`
|
||||||
|
}
|
||||||
|
if err := mapstructure.Decode(task, proxy); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if proxy.ProxyType == "" || proxy.ProxyAddress == "" || proxy.ProxyPort == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
credentials := ""
|
||||||
|
if proxy.ProxyLogin != nil {
|
||||||
|
credentials += *proxy.ProxyLogin
|
||||||
|
if proxy.ProxyPassword != nil {
|
||||||
|
credentials += ":" + *proxy.ProxyPassword
|
||||||
|
}
|
||||||
|
credentials += "@"
|
||||||
|
}
|
||||||
|
|
||||||
|
proxyStr := fmt.Sprintf("%s://%s%s:%d", proxy.ProxyType, credentials, proxy.ProxyAddress, proxy.ProxyPort)
|
||||||
|
return &proxyStr
|
||||||
|
}
|
||||||
|
|
||||||
func (a *antigateV2Api) createTask(request struct {
|
func (a *antigateV2Api) createTask(request struct {
|
||||||
Task map[string]any `json:"task"`
|
Task map[string]any `json:"task"`
|
||||||
}) any {
|
}) any {
|
||||||
@ -157,10 +193,11 @@ func (a *antigateV2Api) createTask(request struct {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return errorTaskAbsent
|
return errorTaskAbsent
|
||||||
}
|
}
|
||||||
|
taskType = strings.ToLower(taskType)
|
||||||
|
|
||||||
var id uint32
|
var satiTask sati.AnyTask
|
||||||
|
|
||||||
switch strings.ToLower(taskType) {
|
switch taskType {
|
||||||
case "turnstiletask", "turnstiletaskproxyless":
|
case "turnstiletask", "turnstiletaskproxyless":
|
||||||
var task struct {
|
var task struct {
|
||||||
WebsiteURL string `json:"websiteURL"`
|
WebsiteURL string `json:"websiteURL"`
|
||||||
@ -168,21 +205,35 @@ func (a *antigateV2Api) createTask(request struct {
|
|||||||
Action *string `json:"action"`
|
Action *string `json:"action"`
|
||||||
}
|
}
|
||||||
mapstructure.Decode(request.Task, &task)
|
mapstructure.Decode(request.Task, &task)
|
||||||
id = a.ctx.Registry.CreateTask(&sati.TurnstileTask{
|
satiTask = &sati.TurnstileTask{
|
||||||
PageUrl: task.WebsiteURL,
|
PageUrl: task.WebsiteURL,
|
||||||
SiteKey: task.WebsiteKey,
|
SiteKey: task.WebsiteKey,
|
||||||
Action: task.Action,
|
Action: task.Action,
|
||||||
})
|
}
|
||||||
|
if taskType == "turnstiletask" {
|
||||||
|
proxy := collectAntiGateV2Proxy(request.Task)
|
||||||
|
if proxy == nil {
|
||||||
|
return errorProxyConnectRefused
|
||||||
|
}
|
||||||
|
satiTask.(*sati.TurnstileTask).Proxy = proxy
|
||||||
|
}
|
||||||
case "recaptchav2task", "recaptchav2taskproxyless":
|
case "recaptchav2task", "recaptchav2taskproxyless":
|
||||||
var task struct {
|
var task struct {
|
||||||
WebsiteURL string `json:"websiteURL"`
|
WebsiteURL string `json:"websiteURL"`
|
||||||
WebsiteKey string `json:"websiteKey"`
|
WebsiteKey string `json:"websiteKey"`
|
||||||
}
|
}
|
||||||
mapstructure.Decode(request.Task, &task)
|
mapstructure.Decode(request.Task, &task)
|
||||||
id = a.ctx.Registry.CreateTask(&sati.ReCaptcha2Task{
|
satiTask = &sati.ReCaptcha2Task{
|
||||||
PageUrl: task.WebsiteURL,
|
PageUrl: task.WebsiteURL,
|
||||||
SiteKey: task.WebsiteKey,
|
SiteKey: task.WebsiteKey,
|
||||||
})
|
}
|
||||||
|
if taskType == "funcaptchatask" {
|
||||||
|
proxy := collectAntiGateV2Proxy(request.Task)
|
||||||
|
if proxy == nil {
|
||||||
|
return errorProxyConnectRefused
|
||||||
|
}
|
||||||
|
satiTask.(*sati.ReCaptcha2Task).Proxy = proxy
|
||||||
|
}
|
||||||
case "funcaptchatask", "funcaptchataskproxyless":
|
case "funcaptchatask", "funcaptchataskproxyless":
|
||||||
var task struct {
|
var task struct {
|
||||||
WebsiteURL string `json:"websiteURL"`
|
WebsiteURL string `json:"websiteURL"`
|
||||||
@ -190,15 +241,24 @@ func (a *antigateV2Api) createTask(request struct {
|
|||||||
Data map[string]string `json:"data"`
|
Data map[string]string `json:"data"`
|
||||||
}
|
}
|
||||||
mapstructure.Decode(request.Task, &task)
|
mapstructure.Decode(request.Task, &task)
|
||||||
id = a.ctx.Registry.CreateTask(&sati.FunCaptchaTask{
|
satiTask = &sati.FunCaptchaTask{
|
||||||
PageUrl: task.WebsiteURL,
|
PageUrl: task.WebsiteURL,
|
||||||
SiteKey: task.WebsitePublicKey,
|
SiteKey: task.WebsitePublicKey,
|
||||||
Data: task.Data,
|
Data: task.Data,
|
||||||
})
|
}
|
||||||
|
if taskType == "funcaptchatask" {
|
||||||
|
proxy := collectAntiGateV2Proxy(request.Task)
|
||||||
|
if proxy == nil {
|
||||||
|
return errorProxyConnectRefused
|
||||||
|
}
|
||||||
|
satiTask.(*sati.FunCaptchaTask).Proxy = proxy
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return errorTaskNotSupported
|
return errorTaskNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id := a.ctx.Registry.CreateTask(satiTask)
|
||||||
|
|
||||||
return &struct {
|
return &struct {
|
||||||
ErrorId uint32 `json:"errorId"`
|
ErrorId uint32 `json:"errorId"`
|
||||||
TaskId uint32 `json:"taskId"`
|
TaskId uint32 `json:"taskId"`
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -130,6 +131,42 @@ func (a *capSolverApi) getTaskResult(request struct {
|
|||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func collectCapSolverProxy(task any) *string {
|
||||||
|
antigateLike := collectAntiGateV2Proxy(task)
|
||||||
|
if antigateLike != nil {
|
||||||
|
return antigateLike
|
||||||
|
}
|
||||||
|
|
||||||
|
input, _ := task.(map[string]any)["proxy"].(string)
|
||||||
|
if input == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
isUrl := strings.Contains(input, "://")
|
||||||
|
if isUrl {
|
||||||
|
// validate it
|
||||||
|
url, err := url.Parse(input)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
output := url.String()
|
||||||
|
return &output
|
||||||
|
}
|
||||||
|
|
||||||
|
fragments := strings.Split(input, ":")
|
||||||
|
var output string
|
||||||
|
switch len(fragments) {
|
||||||
|
case 5: // proto:host:port:user:pwd
|
||||||
|
output = fmt.Sprintf("%s://%s:%s@%s:%s", fragments[0], fragments[3], fragments[4], fragments[1], fragments[2])
|
||||||
|
case 4: // host:port:user:pwd, http used by default
|
||||||
|
output = fmt.Sprintf("http://%s:%s@%s:%s", fragments[2], fragments[3], fragments[0], fragments[1])
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &output
|
||||||
|
}
|
||||||
|
|
||||||
func (a *capSolverApi) createTask(request struct {
|
func (a *capSolverApi) createTask(request struct {
|
||||||
Task map[string]any `json:"task"`
|
Task map[string]any `json:"task"`
|
||||||
}) any {
|
}) any {
|
||||||
@ -138,7 +175,7 @@ func (a *capSolverApi) createTask(request struct {
|
|||||||
return csErrorInvalidTaskData
|
return csErrorInvalidTaskData
|
||||||
}
|
}
|
||||||
|
|
||||||
var id uint32
|
var satiTask sati.AnyTask
|
||||||
|
|
||||||
switch strings.ToLower(taskType) {
|
switch strings.ToLower(taskType) {
|
||||||
case "anticloudflaretask":
|
case "anticloudflaretask":
|
||||||
@ -151,22 +188,36 @@ func (a *capSolverApi) createTask(request struct {
|
|||||||
} `json:"metadata"`
|
} `json:"metadata"`
|
||||||
}
|
}
|
||||||
mapstructure.Decode(request.Task, &task)
|
mapstructure.Decode(request.Task, &task)
|
||||||
id = a.ctx.Registry.CreateTask(&sati.TurnstileTask{
|
|
||||||
|
proxy := collectCapSolverProxy(request.Task)
|
||||||
|
if proxy == nil {
|
||||||
|
return csErrorInvalidTaskData
|
||||||
|
}
|
||||||
|
|
||||||
|
satiTask = &sati.TurnstileTask{
|
||||||
PageUrl: task.WebsiteURL,
|
PageUrl: task.WebsiteURL,
|
||||||
SiteKey: task.WebsiteKey,
|
SiteKey: task.WebsiteKey,
|
||||||
Action: task.Metadata.Action,
|
Action: task.Metadata.Action,
|
||||||
CData: task.Metadata.CData,
|
CData: task.Metadata.CData,
|
||||||
})
|
Proxy: proxy,
|
||||||
|
}
|
||||||
case "recaptchav2task", "recaptchav2taskproxyless":
|
case "recaptchav2task", "recaptchav2taskproxyless":
|
||||||
var task struct {
|
var task struct {
|
||||||
WebsiteURL string `json:"websiteURL"`
|
WebsiteURL string `json:"websiteURL"`
|
||||||
WebsiteKey string `json:"websiteKey"`
|
WebsiteKey string `json:"websiteKey"`
|
||||||
}
|
}
|
||||||
mapstructure.Decode(request.Task, &task)
|
mapstructure.Decode(request.Task, &task)
|
||||||
id = a.ctx.Registry.CreateTask(&sati.ReCaptcha2Task{
|
satiTask = &sati.ReCaptcha2Task{
|
||||||
PageUrl: task.WebsiteURL,
|
PageUrl: task.WebsiteURL,
|
||||||
SiteKey: task.WebsiteKey,
|
SiteKey: task.WebsiteKey,
|
||||||
})
|
}
|
||||||
|
if taskType == "recaptchav2task" {
|
||||||
|
proxy := collectCapSolverProxy(request.Task)
|
||||||
|
if proxy == nil {
|
||||||
|
return csErrorInvalidTaskData
|
||||||
|
}
|
||||||
|
satiTask.(*sati.ReCaptcha2Task).Proxy = proxy
|
||||||
|
}
|
||||||
case "funcaptchatask", "funcaptchataskproxyless":
|
case "funcaptchatask", "funcaptchataskproxyless":
|
||||||
var task struct {
|
var task struct {
|
||||||
WebsiteURL string `json:"websiteURL"`
|
WebsiteURL string `json:"websiteURL"`
|
||||||
@ -174,15 +225,24 @@ func (a *capSolverApi) createTask(request struct {
|
|||||||
Data map[string]string `json:"data"`
|
Data map[string]string `json:"data"`
|
||||||
}
|
}
|
||||||
mapstructure.Decode(request.Task, &task)
|
mapstructure.Decode(request.Task, &task)
|
||||||
id = a.ctx.Registry.CreateTask(&sati.FunCaptchaTask{
|
satiTask = &sati.FunCaptchaTask{
|
||||||
PageUrl: task.WebsiteURL,
|
PageUrl: task.WebsiteURL,
|
||||||
SiteKey: task.WebsitePublicKey,
|
SiteKey: task.WebsitePublicKey,
|
||||||
Data: task.Data,
|
Data: task.Data,
|
||||||
})
|
}
|
||||||
|
if taskType == "funcaptchatask" {
|
||||||
|
proxy := collectCapSolverProxy(request.Task)
|
||||||
|
if proxy == nil {
|
||||||
|
return csErrorInvalidTaskData
|
||||||
|
}
|
||||||
|
satiTask.(*sati.FunCaptchaTask).Proxy = proxy
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return csErrorTaskNotSupported
|
return csErrorTaskNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id := a.ctx.Registry.CreateTask(satiTask)
|
||||||
|
|
||||||
return &struct {
|
return &struct {
|
||||||
ErrorId uint32 `json:"errorId"`
|
ErrorId uint32 `json:"errorId"`
|
||||||
TaskId string `json:"taskId"`
|
TaskId string `json:"taskId"`
|
||||||
|
@ -2,6 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -90,6 +91,21 @@ func parsePhpAssociativeArray(values map[string][]string, arrayName string) map[
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractRuCaptchaProxy(params url.Values) *string {
|
||||||
|
if !params.Has("proxytype") || !params.Has("proxy") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
proxyUrl := fmt.Sprintf("%s://%s", params.Get("proxytype"), params.Get("proxy"))
|
||||||
|
url, err := url.Parse(proxyUrl)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
formatted := url.String()
|
||||||
|
return &formatted
|
||||||
|
}
|
||||||
|
|
||||||
func (a *ruCaptchaApi) endpointIn(params url.Values) ruCaptchaResponse {
|
func (a *ruCaptchaApi) endpointIn(params url.Values) ruCaptchaResponse {
|
||||||
var id uint32
|
var id uint32
|
||||||
switch params.Get("method") {
|
switch params.Get("method") {
|
||||||
@ -118,6 +134,7 @@ func (a *ruCaptchaApi) endpointIn(params url.Values) ruCaptchaResponse {
|
|||||||
id = a.ctx.Registry.CreateTask(&sati.ReCaptcha2Task{
|
id = a.ctx.Registry.CreateTask(&sati.ReCaptcha2Task{
|
||||||
PageUrl: pageUrl,
|
PageUrl: pageUrl,
|
||||||
SiteKey: siteKey,
|
SiteKey: siteKey,
|
||||||
|
Proxy: extractRuCaptchaProxy(params),
|
||||||
})
|
})
|
||||||
case "turnstile":
|
case "turnstile":
|
||||||
pageUrl := params.Get("pageurl")
|
pageUrl := params.Get("pageurl")
|
||||||
@ -142,6 +159,7 @@ func (a *ruCaptchaApi) endpointIn(params url.Values) ruCaptchaResponse {
|
|||||||
PageUrl: pageUrl,
|
PageUrl: pageUrl,
|
||||||
Action: action,
|
Action: action,
|
||||||
CData: cData,
|
CData: cData,
|
||||||
|
Proxy: extractRuCaptchaProxy(params),
|
||||||
})
|
})
|
||||||
case "funcaptcha":
|
case "funcaptcha":
|
||||||
siteKey := params.Get("publickey")
|
siteKey := params.Get("publickey")
|
||||||
@ -162,6 +180,7 @@ func (a *ruCaptchaApi) endpointIn(params url.Values) ruCaptchaResponse {
|
|||||||
PageUrl: pageUrl,
|
PageUrl: pageUrl,
|
||||||
ServiceUrl: serviceUrl,
|
ServiceUrl: serviceUrl,
|
||||||
Data: data,
|
Data: data,
|
||||||
|
Proxy: extractRuCaptchaProxy(params),
|
||||||
})
|
})
|
||||||
default:
|
default:
|
||||||
return &simpleResponse{0, "ERROR_ZERO_CAPTCHA_FILESIZE"}
|
return &simpleResponse{0, "ERROR_ZERO_CAPTCHA_FILESIZE"}
|
||||||
|
2
go.mod
2
go.mod
@ -2,7 +2,7 @@ module git.sati.ac/sati.ac/bridge
|
|||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require git.sati.ac/sati.ac/sati-go v0.0.0-20230713145537-57719018ca00
|
require git.sati.ac/sati.ac/sati-go v0.0.0-20230725102846-8e6b00348696
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gorilla/websocket v1.5.0 // indirect
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -6,6 +6,8 @@ git.sati.ac/sati.ac/sati-go v0.0.0-20230630184329-03a405a25122 h1:Uff2QZeRDk+3cm
|
|||||||
git.sati.ac/sati.ac/sati-go v0.0.0-20230630184329-03a405a25122/go.mod h1:dsLvwV5+2YUjWRAuTYFf/EMvoH/twUu/NWA0t5Yl3pQ=
|
git.sati.ac/sati.ac/sati-go v0.0.0-20230630184329-03a405a25122/go.mod h1:dsLvwV5+2YUjWRAuTYFf/EMvoH/twUu/NWA0t5Yl3pQ=
|
||||||
git.sati.ac/sati.ac/sati-go v0.0.0-20230713145537-57719018ca00 h1:emjsk5AubG3EiCbiG0WAG6xAZXoNNwO/yteYj/J0TqA=
|
git.sati.ac/sati.ac/sati-go v0.0.0-20230713145537-57719018ca00 h1:emjsk5AubG3EiCbiG0WAG6xAZXoNNwO/yteYj/J0TqA=
|
||||||
git.sati.ac/sati.ac/sati-go v0.0.0-20230713145537-57719018ca00/go.mod h1:dsLvwV5+2YUjWRAuTYFf/EMvoH/twUu/NWA0t5Yl3pQ=
|
git.sati.ac/sati.ac/sati-go v0.0.0-20230713145537-57719018ca00/go.mod h1:dsLvwV5+2YUjWRAuTYFf/EMvoH/twUu/NWA0t5Yl3pQ=
|
||||||
|
git.sati.ac/sati.ac/sati-go v0.0.0-20230725102846-8e6b00348696 h1:ld33XeJOBd1skmlVz/TQrcuZPaTIuBt+J1n52oRfPAo=
|
||||||
|
git.sati.ac/sati.ac/sati-go v0.0.0-20230725102846-8e6b00348696/go.mod h1:dsLvwV5+2YUjWRAuTYFf/EMvoH/twUu/NWA0t5Yl3pQ=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user