mirror of
https://github.com/1f349/violet.git
synced 2024-11-09 22:22:50 +00:00
First commit
This commit is contained in:
commit
68bbd67c01
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
7
.idea/discord.xml
Normal file
7
.idea/discord.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DiscordProjectSettings">
|
||||||
|
<option name="show" value="PROJECT_FILES" />
|
||||||
|
<option name="description" value="" />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/misc.xml
Normal file
6
.idea/misc.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="MarkdownSettingsMigration">
|
||||||
|
<option name="stateVersion" value="1" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/violet.iml" filepath="$PROJECT_DIR$/.idea/violet.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
9
.idea/violet.iml
Normal file
9
.idea/violet.iml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
5
cmd/violet/main.go
Normal file
5
cmd/violet/main.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package violet
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
}
|
16
go.mod
Normal file
16
go.mod
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
module github.com/MrMelon54/violet
|
||||||
|
|
||||||
|
go 1.20
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/julienschmidt/httprouter v1.3.0
|
||||||
|
github.com/stretchr/testify v1.8.2
|
||||||
|
github.com/yousuf64/shift v0.4.0
|
||||||
|
golang.org/x/net v0.9.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
23
go.sum
Normal file
23
go.sum
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||||
|
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||||
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/yousuf64/shift v0.4.0 h1:jiuYPa9KGyTShM08GEcSRSaZeO2jPEIpdqaplsRtk8g=
|
||||||
|
github.com/yousuf64/shift v0.4.0/go.mod h1:D9b+mj37s3goL48EGX2oCrYHW4rg4c3Il2w6fukjxas=
|
||||||
|
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||||
|
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
145
proxy/reverse-proxy.go
Normal file
145
proxy/reverse-proxy.go
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"golang.org/x/net/proxy"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httputil"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type reverseProxyHostKey int
|
||||||
|
|
||||||
|
type ReverseProxyContext interface {
|
||||||
|
IsIgnoreCert() bool
|
||||||
|
UpdateHeaders(http.Header)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetReverseProxyHost(req *http.Request, hf ReverseProxyContext) *http.Request {
|
||||||
|
ctx := req.Context()
|
||||||
|
ctx2 := context.WithValue(ctx, reverseProxyHostKey(0), hf)
|
||||||
|
return req.WithContext(ctx2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateHybridReverseProxy() *httputil.ReverseProxy {
|
||||||
|
return &httputil.ReverseProxy{
|
||||||
|
Director: func(req *http.Request) {},
|
||||||
|
Transport: NewHybridTransport(),
|
||||||
|
ModifyResponse: func(rw *http.Response) error { return nil },
|
||||||
|
ErrorHandler: func(rw http.ResponseWriter, req *http.Request, err error) {
|
||||||
|
log.Printf("[ReverseProxy] Request: %#v\n -- Error: %s\n", req, err)
|
||||||
|
rw.WriteHeader(http.StatusBadGateway)
|
||||||
|
_, _ = rw.Write([]byte("502 Bad gateway\n"))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type HybridTransport struct {
|
||||||
|
baseDialer *net.Dialer
|
||||||
|
normalTransport http.RoundTripper
|
||||||
|
insecureTransport http.RoundTripper
|
||||||
|
socksSync *sync.RWMutex
|
||||||
|
socksTransport map[string]http.RoundTripper
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHybridTransport() *HybridTransport {
|
||||||
|
h := &HybridTransport{
|
||||||
|
baseDialer: &net.Dialer{
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
|
KeepAlive: 30 * time.Second,
|
||||||
|
},
|
||||||
|
socksSync: &sync.RWMutex{},
|
||||||
|
socksTransport: make(map[string]http.RoundTripper),
|
||||||
|
}
|
||||||
|
h.normalTransport = &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
DialContext: h.baseDialer.DialContext,
|
||||||
|
ForceAttemptHTTP2: true,
|
||||||
|
MaxIdleConns: 15,
|
||||||
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
|
IdleConnTimeout: 30 * time.Second,
|
||||||
|
ExpectContinueTimeout: 1 * time.Second,
|
||||||
|
ResponseHeaderTimeout: 10 * time.Second,
|
||||||
|
}
|
||||||
|
h.insecureTransport = &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
DialContext: h.baseDialer.DialContext,
|
||||||
|
ForceAttemptHTTP2: true,
|
||||||
|
MaxIdleConns: 15,
|
||||||
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
|
IdleConnTimeout: 30 * time.Second,
|
||||||
|
ExpectContinueTimeout: 1 * time.Second,
|
||||||
|
ResponseHeaderTimeout: 10 * time.Second,
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HybridTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
newHost := req.Context().Value(reverseProxyHostKey(0))
|
||||||
|
hf, ok := newHost.(ReverseProxyContext)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("failed to detect reverse proxy configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do a round trip using existing transports
|
||||||
|
var trip *http.Response
|
||||||
|
var err error
|
||||||
|
if hf.IsIgnoreCert() {
|
||||||
|
trip, err = h.insecureTransport.RoundTrip(req)
|
||||||
|
} else {
|
||||||
|
trip, err = h.normalTransport.RoundTrip(req)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override headers
|
||||||
|
hf.UpdateHeaders(trip.Header)
|
||||||
|
return trip, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HybridTransport) getSocksProxy(addr string, insecure bool) (http.RoundTripper, error) {
|
||||||
|
if insecure {
|
||||||
|
addr = "%i-" + addr
|
||||||
|
}
|
||||||
|
h.socksSync.RLock()
|
||||||
|
s, ok := h.socksTransport[addr]
|
||||||
|
h.socksSync.RUnlock()
|
||||||
|
if ok {
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dialer, err := proxy.SOCKS5("tcp", addr, nil, proxy.Direct)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot connect to the proxy: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if f, ok := dialer.(proxy.ContextDialer); ok {
|
||||||
|
t := &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
DialContext: f.DialContext,
|
||||||
|
ForceAttemptHTTP2: true,
|
||||||
|
MaxIdleConns: 15,
|
||||||
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
|
IdleConnTimeout: 30 * time.Second,
|
||||||
|
ExpectContinueTimeout: 1 * time.Second,
|
||||||
|
ResponseHeaderTimeout: 10 * time.Second,
|
||||||
|
DisableKeepAlives: true,
|
||||||
|
}
|
||||||
|
if insecure {
|
||||||
|
t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
||||||
|
}
|
||||||
|
h.socksSync.Lock()
|
||||||
|
h.socksTransport[addr] = t
|
||||||
|
h.socksSync.Unlock()
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("cannot create socks5 dialer")
|
||||||
|
}
|
15
target/redirect.go
Normal file
15
target/redirect.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package target
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Redirect struct {
|
||||||
|
url.URL
|
||||||
|
Code int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Redirect) Handler() http.Handler {
|
||||||
|
return http.RedirectHandler(r.URL.String(), r.Code)
|
||||||
|
}
|
7
target/service.go
Normal file
7
target/service.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package target
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
Host string
|
||||||
|
Port int
|
||||||
|
Absolute bool
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user