mirror of https://github.com/fatedier/frp
fatedier
6 years ago
1 changed files with 119 additions and 0 deletions
@ -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 |
||||
} |
Loading…
Reference in new issue