Kaynağa Gözat

frpc: new plugin https2http

fatedier 6 yıl önce
ebeveyn
işleme
db6bbc5187
1 değiştirilmiş dosya ile 119 ekleme ve 0 silme
  1. 119 0
      models/plugin/https2http.go

+ 119 - 0
models/plugin/https2http.go

@@ -0,0 +1,119 @@
+// Copyright 2019 fatedier, fatedier@gmail.com
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package plugin
+
+import (
+	"crypto/tls"
+	"fmt"
+	"io"
+	"net/http"
+	"net/http/httputil"
+
+	frpNet "github.com/fatedier/frp/utils/net"
+)
+
+const PluginHTTPS2HTTP = "https2http"
+
+func init() {
+	Register(PluginHTTPS2HTTP, NewHTTPS2HTTPPlugin)
+}
+
+type HTTPS2HTTPPlugin struct {
+	crtPath           string
+	keyPath           string
+	hostHeaderRewrite string
+	localAddr         string
+
+	l *Listener
+	s *http.Server
+}
+
+func NewHTTPS2HTTPPlugin(params map[string]string) (Plugin, error) {
+	crtPath := params["plugin_crt_path"]
+	keyPath := params["plugin_key_path"]
+	localAddr := params["plugin_local_addr"]
+	hostHeaderRewrite := params["plugin_host_header_rewrite"]
+
+	if crtPath == "" {
+		return nil, fmt.Errorf("plugin_crt_path is required")
+	}
+	if keyPath == "" {
+		return nil, fmt.Errorf("plugin_key_path is required")
+	}
+	if localAddr == "" {
+		return nil, fmt.Errorf("plugin_local_addr is required")
+	}
+
+	listener := NewProxyListener()
+
+	p := &HTTPS2HTTPPlugin{
+		crtPath:           crtPath,
+		keyPath:           keyPath,
+		localAddr:         localAddr,
+		hostHeaderRewrite: hostHeaderRewrite,
+		l:                 listener,
+	}
+
+	rp := &httputil.ReverseProxy{
+		Director: func(req *http.Request) {
+			req.URL.Scheme = "http"
+			req.URL.Host = p.localAddr
+			if p.hostHeaderRewrite != "" {
+				req.Host = p.hostHeaderRewrite
+			}
+		},
+	}
+
+	p.s = &http.Server{
+		Handler: rp,
+	}
+
+	tlsConfig, err := p.genTLSConfig()
+	if err != nil {
+		return nil, fmt.Errorf("gen TLS config error: %v", err)
+	}
+	ln := tls.NewListener(listener, tlsConfig)
+
+	go p.s.Serve(ln)
+	return p, nil
+}
+
+func (p *HTTPS2HTTPPlugin) genTLSConfig() (*tls.Config, error) {
+	cert, err := tls.LoadX509KeyPair(p.crtPath, p.keyPath)
+	if err != nil {
+		return nil, err
+	}
+
+	config := &tls.Config{Certificates: []tls.Certificate{cert}}
+	return config, nil
+}
+
+func (p *HTTPS2HTTPPlugin) Handle(conn io.ReadWriteCloser, realConn frpNet.Conn) {
+	wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn)
+	p.l.PutConn(wrapConn)
+}
+
+func (p *HTTPS2HTTPPlugin) handleRequest(w http.ResponseWriter, r *http.Request) {
+	w.Write([]byte("hello"))
+	return
+}
+
+func (p *HTTPS2HTTPPlugin) Name() string {
+	return PluginHTTPS2HTTP
+}
+
+func (p *HTTPS2HTTPPlugin) Close() error {
+	return nil
+}