Skip to content

Commit

Permalink
frpc: new plugin https2http
Browse files Browse the repository at this point in the history
  • Loading branch information
fatedier committed Apr 10, 2019
1 parent c67b4e7 commit db6bbc5
Showing 1 changed file with 119 additions and 0 deletions.
119 changes: 119 additions & 0 deletions models/plugin/https2http.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copyright 2019 fatedier, [email protected]
//
// 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
}

0 comments on commit db6bbc5

Please sign in to comment.