Merge pull request #1 from aykhans/bugfix/validation-formatter

Bugfix/validation formatter
This commit is contained in:
Aykhan Shahsuvarov 2024-06-01 16:47:14 +04:00 committed by GitHub
commit e59eab4198
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 49 additions and 41 deletions

View File

@ -11,7 +11,7 @@ import (
const ( const (
VERSION = "0.0.1" VERSION = "0.0.1"
DefaultUserAgent = "Dodo/" + VERSION DefaultUserAgent = "Dodo/" + VERSION
ProxyCheckURL = "https://google.com" ProxyCheckURL = "https://www.google.com"
DefaultMethod = "GET" DefaultMethod = "GET"
DefaultTimeout = 10000 // Milliseconds (10 seconds) DefaultTimeout = 10000 // Milliseconds (10 seconds)
DefaultDodosCount = 1 DefaultDodosCount = 1
@ -23,8 +23,6 @@ type IConfig interface {
MergeConfigs(newConfig IConfig) IConfig MergeConfigs(newConfig IConfig) IConfig
} }
type ProxySlice []map[string]string
type DodoConfig struct { type DodoConfig struct {
Method string Method string
URL string URL string
@ -34,7 +32,7 @@ type DodoConfig struct {
Params map[string]string Params map[string]string
Headers map[string]string Headers map[string]string
Cookies map[string]string Cookies map[string]string
Proxies ProxySlice Proxies []Proxy
Body string Body string
} }
@ -98,12 +96,18 @@ func (config *Config) SetDefaults() {
} }
} }
type Proxy struct {
URL string `json:"url" validate:"required,proxy_url"`
Username string `json:"username"`
Password string `json:"password"`
}
type JSONConfig struct { type JSONConfig struct {
Config Config
Params map[string]string `json:"params"` Params map[string]string `json:"params"`
Headers map[string]string `json:"headers"` Headers map[string]string `json:"headers"`
Cookies map[string]string `json:"cookies"` Cookies map[string]string `json:"cookies"`
Proxies ProxySlice `json:"proxies" validate:"url_map_slice"` Proxies []Proxy `json:"proxies" validate:"dive"`
Body string `json:"body"` Body string `json:"body"`
} }

View File

@ -6,7 +6,6 @@ import (
"net/url" "net/url"
"strings" "strings"
"github.com/aykhans/dodo/config"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
@ -24,36 +23,34 @@ func CobraErrorFormater(err error) error {
return err return err
} }
func shortenNamespace(namespace string) string {
return namespace[strings.Index(namespace, ".")+1:]
}
func ValidationErrorsFormater(errs validator.ValidationErrors) error { func ValidationErrorsFormater(errs validator.ValidationErrors) error {
errsStr := make(map[string]string) errsStr := make(map[string]string)
for _, err := range errs { for _, err := range errs {
switch err.Tag() { switch err.Tag() {
case "required": case "required":
errsStr[err.Field()] = fmt.Sprintf("Field \"%s\" is required", err.Field()) errsStr[shortenNamespace(err.Namespace())] = fmt.Sprintf("Field \"%s\" is required", err.Field())
case "gte": case "gte":
errsStr[err.Field()] = fmt.Sprintf("Value of \"%s\" must be greater than or equal to \"%s\"", err.Field(), err.Param()) errsStr[shortenNamespace(err.Namespace())] = fmt.Sprintf("Value of \"%s\" must be greater than or equal to \"%s\"", err.Field(), err.Param())
case "lte": case "lte":
errsStr[err.Field()] = fmt.Sprintf("Value of \"%s\" must be less than or equal to \"%s\"", err.Field(), err.Param()) errsStr[shortenNamespace(err.Namespace())] = fmt.Sprintf("Value of \"%s\" must be less than or equal to \"%s\"", err.Field(), err.Param())
case "filepath": case "filepath":
errsStr[err.Field()] = fmt.Sprintf("Invalid file path for \"%s\" field: \"%s\"", err.Field(), err.Value()) errsStr[shortenNamespace(err.Namespace())] = fmt.Sprintf("Invalid file path for \"%s\" field: \"%s\"", err.Field(), err.Value())
case "http_url": case "http_url":
errsStr[err.Field()] = fmt.Sprintf("Invalid URL for \"%s\" field: \"%s\"", err.Field(), err.Value()) errsStr[shortenNamespace(err.Namespace())] =
fmt.Sprintf("Invalid url for \"%s\" field: \"%s\"", err.Field(), err.Value())
// --------------------------------------| Custom validations |-------------------------------------- // --------------------------------------| Custom validations |--------------------------------------
case "http_method": case "http_method":
errsStr[err.Field()] = fmt.Sprintf("Invalid HTTP method for \"%s\" field: \"%s\"", err.Field(), err.Value()) errsStr[shortenNamespace(err.Namespace())] = fmt.Sprintf("Invalid HTTP method for \"%s\" field: \"%s\"", err.Field(), err.Value())
case "url_map_slice": case "proxy_url":
values := err.Value().(config.ProxySlice) errsStr[shortenNamespace(err.Namespace())] = fmt.Sprintf("Invalid proxy url for \"%s\" field: \"%s\" (it must be http, socks5 or socks5h)", err.Field(), err.Value())
for i, value := range values {
if _, ok := value["url"]; !ok {
errsStr[fmt.Sprintf("%s[%d]", err.Field(), i)] = fmt.Sprintf("Field \"url\" is required for \"%s\" field", err.Field())
} else {
errsStr[fmt.Sprintf("%s[%d]", err.Field(), i)] = fmt.Sprintf("Invalid url for \"%s\" field: \"%s\"", err.Field(), value["url"])
}
}
case "string_bool": case "string_bool":
errsStr[err.Field()] = fmt.Sprintf("Invalid value for \"%s\" field: \"%s\"", err.Field(), err.Value()) errsStr[shortenNamespace(err.Namespace())] = fmt.Sprintf("Invalid value for \"%s\" field: \"%s\"", err.Field(), err.Value())
default: default:
errsStr[err.Field()] = fmt.Sprintf("Invalid value for \"%s\" field: \"%s\"", err.Field(), err.Value()) errsStr[shortenNamespace(err.Namespace())] = fmt.Sprintf("Invalid value for \"%s\" field: \"%s\"", err.Field(), err.Value())
} }
} }
return NewValidationErrors(errsStr, errs) return NewValidationErrors(errsStr, errs)

View File

@ -2,6 +2,7 @@ package main
import ( import (
"os" "os"
"strings"
"time" "time"
"github.com/aykhans/dodo/config" "github.com/aykhans/dodo/config"
@ -35,7 +36,11 @@ func main() {
if err != nil { if err != nil {
utils.PrintErrAndExit(err) utils.PrintErrAndExit(err)
} }
if err := validator.StructPartial(jsonConfNew, "Proxies"); err != nil { if err := validator.StructFiltered(
jsonConfNew,
func(ns []byte) bool {
return strings.LastIndex(string(ns), "Proxies") == -1
}); err != nil {
utils.PrintErrAndExit( utils.PrintErrAndExit(
customerrors.ValidationErrorsFormater( customerrors.ValidationErrorsFormater(
err.(goValidator.ValidationErrors), err.(goValidator.ValidationErrors),

View File

@ -268,13 +268,13 @@ func printProgress(wg *sync.WaitGroup, total int, message string, countSlice *[]
pw.Stop() pw.Stop()
} }
func getClientFunc(proxies config.ProxySlice, timeout time.Duration, dodosCount int) func() http.Client { func getClientFunc(proxies []config.Proxy, timeout time.Duration, dodosCount int) func() http.Client {
if len(proxies) > 0 { if len(proxies) > 0 {
activeProxyClientsArray := make([][]http.Client, dodosCount) activeProxyClientsArray := make([][]http.Client, dodosCount)
proxiesCount := len(proxies) proxiesCount := len(proxies)
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(dodosCount + 1) wg.Add(dodosCount + 1)
var proxiesSlice config.ProxySlice var proxiesSlice []config.Proxy
countSlice := make([]int, dodosCount) countSlice := make([]int, dodosCount)
go printProgress(&wg, proxiesCount, "Searching for active proxies🌐", &countSlice) go printProgress(&wg, proxiesCount, "Searching for active proxies🌐", &countSlice)
@ -330,7 +330,7 @@ func getClientFunc(proxies config.ProxySlice, timeout time.Duration, dodosCount
} }
func findActiveProxyClients( func findActiveProxyClients(
proxies config.ProxySlice, proxies []config.Proxy,
timeout time.Duration, timeout time.Duration,
activeProxyClients *[]http.Client, activeProxyClients *[]http.Client,
counter *int, counter *int,
@ -365,12 +365,12 @@ func findActiveProxyClients(
} }
} }
func getTransport(proxy map[string]string) (*http.Transport, error) { func getTransport(proxy config.Proxy) (*http.Transport, error) {
proxyURL, err := url.Parse(proxy["url"]) proxyURL, err := url.Parse(proxy.URL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if _, ok := proxy["username"]; !ok { if proxy.Username != "" {
transport := &http.Transport{ transport := &http.Transport{
Proxy: http.ProxyURL(proxyURL), Proxy: http.ProxyURL(proxyURL),
} }
@ -382,7 +382,7 @@ func getTransport(proxy map[string]string) (*http.Transport, error) {
&url.URL{ &url.URL{
Scheme: proxyURL.Scheme, Scheme: proxyURL.Scheme,
Host: proxyURL.Host, Host: proxyURL.Host,
User: url.UserPassword(proxy["username"], proxy["password"]), User: url.UserPassword(proxy.Username, proxy.Password),
}, },
), ),
} }

View File

@ -4,7 +4,6 @@ import (
"reflect" "reflect"
"strings" "strings"
"github.com/aykhans/dodo/config"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"golang.org/x/net/http/httpguts" "golang.org/x/net/http/httpguts"
) )
@ -39,16 +38,19 @@ func NewValidator() *validator.Validate {
}, },
) )
validation.RegisterValidation( validation.RegisterValidation(
"url_map_slice", "proxy_url",
func(fl validator.FieldLevel) bool { func(fl validator.FieldLevel) bool {
proxies := fl.Field().Interface().(config.ProxySlice) url := fl.Field().String()
for _, proxy := range proxies { if url == "" {
if _, ok := proxy["url"]; !ok {
return false return false
} }
if err := validation.Var(proxy["url"], "url"); err != nil { if err := validation.Var(url, "url"); err != nil {
return false return false
} }
if !(url[:7] == "http://" ||
url[:9] == "socks5://" ||
url[:10] == "socks5h://") {
return false
} }
return true return true
}, },