1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-11-07 10:47:48 -05:00
v2fly/app/browserforwarder/forwarder.go
Kslr b8af713998
Fix: secured loading path under windows (#851)
* Fix: secured loading path under windows

* fix sign file foramts
2021-04-04 16:32:42 +08:00

102 lines
2.4 KiB
Go

// +build !confonly
package browserforwarder
import (
"bytes"
"context"
"io"
"net/http"
"path/filepath"
"time"
"github.com/v2fly/BrowserBridge/handler"
"github.com/v2fly/v2ray-core/v4/common"
"github.com/v2fly/v2ray-core/v4/common/net"
"github.com/v2fly/v2ray-core/v4/common/platform/securedload"
"github.com/v2fly/v2ray-core/v4/features/ext"
"github.com/v2fly/v2ray-core/v4/transport/internet"
)
//go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen
type Forwarder struct {
ctx context.Context
forwarder *handler.HTTPHandle
httpserver *http.Server
config *Config
}
func (f *Forwarder) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
requestPath := request.URL.Path[1:]
switch requestPath {
case "":
fallthrough
case "index.js":
BridgeResource(writer, request, requestPath)
case "link":
f.forwarder.ServeBridge(writer, request)
}
}
func (f *Forwarder) DialWebsocket(url string, header http.Header) (io.ReadWriteCloser, error) {
return f.forwarder.Dial(url)
}
func (f *Forwarder) Type() interface{} {
return ext.BrowserForwarderType()
}
func (f *Forwarder) Start() error {
f.forwarder = handler.NewHttpHandle()
f.httpserver = &http.Server{Handler: f}
address := net.ParseAddress(f.config.ListenAddr)
listener, err := internet.ListenSystem(f.ctx, &net.TCPAddr{IP: address.IP(), Port: int(f.config.ListenPort)}, nil)
if err != nil {
return newError("forwarder cannot listen on the port").Base(err)
}
go func() {
err = f.httpserver.Serve(listener)
if err != nil {
newError("cannot serve http forward server").Base(err).WriteToLog()
}
}()
return nil
}
func (f *Forwarder) Close() error {
if f.httpserver != nil {
return f.httpserver.Close()
}
return nil
}
func BridgeResource(rw http.ResponseWriter, r *http.Request, path string) {
content := path
if content == "" {
content = "index.html"
}
data, err := securedload.GetAssetSecured(filepath.Join("browserforwarder", content))
if err != nil {
err = newError("cannot load necessary resources").Base(err)
http.Error(rw, err.Error(), http.StatusForbidden)
return
}
http.ServeContent(rw, r, path, time.Now(), bytes.NewReader(data))
}
func NewForwarder(ctx context.Context, cfg *Config) *Forwarder {
return &Forwarder{config: cfg, ctx: ctx}
}
func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {
return NewForwarder(ctx, cfg.(*Config)), nil
}))
}