mirror of
https://github.com/1f349/violet.git
synced 2024-11-21 10:51:40 +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