Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
企猫商务
frp
提交
b8037475
F
frp
项目概览
企猫商务
/
frp
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
frp
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b8037475
编写于
8月 03, 2018
作者:
F
FishFish
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
websocket protocol
上级
629f2856
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
177 addition
and
15 deletion
+177
-15
conf/frpc_full.ini
conf/frpc_full.ini
+1
-1
models/config/client_common.go
models/config/client_common.go
+1
-1
server/service.go
server/service.go
+46
-13
utils/net/conn.go
utils/net/conn.go
+2
-0
utils/net/websocket.go
utils/net/websocket.go
+127
-0
未找到文件。
conf/frpc_full.ini
浏览文件 @
b8037475
...
...
@@ -41,7 +41,7 @@ user = your_name
login_fail_exit
=
true
# communication protocol used to connect to server
# now it supports tcp and kcp, default is tcp
# now it supports tcp and kcp
and websocket
, default is tcp
protocol
=
tcp
# specify a dns server, so frpc will use this instead of default one
...
...
models/config/client_common.go
浏览文件 @
b8037475
...
...
@@ -187,7 +187,7 @@ func UnmarshalClientConfFromIni(defaultCfg *ClientCommonConf, content string) (c
if
tmpStr
,
ok
=
conf
.
Get
(
"common"
,
"protocol"
);
ok
{
// Now it only support tcp and kcp.
if
tmpStr
!=
"kcp"
{
if
tmpStr
!=
"kcp"
&&
tmpStr
!=
"websocket"
{
tmpStr
=
"tcp"
}
cfg
.
Protocol
=
tmpStr
...
...
server/service.go
浏览文件 @
b8037475
...
...
@@ -19,6 +19,7 @@ import (
"io/ioutil"
"net"
"net/http"
"strings"
"time"
"github.com/fatedier/frp/assets"
...
...
@@ -53,6 +54,9 @@ type Service struct {
// Accept connections using kcp
kcpListener
frpNet
.
Listener
// Accept connections using websocket
websocketListener
frpNet
.
Listener
// For https proxies, route requests to different clients by hostname and other infomation
VhostHttpsMuxer
*
vhost
.
HttpsMuxer
...
...
@@ -109,9 +113,6 @@ func NewService() (svr *Service, err error) {
if
cfg
.
BindPort
==
cfg
.
VhostHttpsPort
{
httpsMuxOn
=
true
}
if
httpMuxOn
||
httpsMuxOn
{
svr
.
muxer
=
mux
.
NewMux
()
}
}
// Listen for accepting connections from client.
...
...
@@ -120,10 +121,11 @@ func NewService() (svr *Service, err error) {
err
=
fmt
.
Errorf
(
"Create server listener error, %v"
,
err
)
return
}
if
svr
.
muxer
!=
nil
{
go
svr
.
muxer
.
Serve
(
ln
)
ln
=
svr
.
muxer
.
DefaultListener
()
}
svr
.
muxer
=
mux
.
NewMux
()
go
svr
.
muxer
.
Serve
(
ln
)
ln
=
svr
.
muxer
.
DefaultListener
()
svr
.
listener
=
frpNet
.
WrapLogListener
(
ln
)
log
.
Info
(
"frps tcp listen on %s:%d"
,
cfg
.
BindAddr
,
cfg
.
BindPort
)
...
...
@@ -148,16 +150,14 @@ func NewService() (svr *Service, err error) {
Handler
:
rp
,
}
var
l
net
.
Listener
if
httpMuxOn
{
l
=
svr
.
muxer
.
ListenHttp
(
0
)
}
else
{
if
!
httpMuxOn
{
l
,
err
=
net
.
Listen
(
"tcp"
,
address
)
if
err
!=
nil
{
err
=
fmt
.
Errorf
(
"Create vhost http listener error, %v"
,
err
)
return
}
go
server
.
Serve
(
l
)
}
go
server
.
Serve
(
l
)
log
.
Info
(
"http service listen on %s:%d"
,
cfg
.
ProxyBindAddr
,
cfg
.
VhostHttpPort
)
}
...
...
@@ -204,6 +204,38 @@ func NewService() (svr *Service, err error) {
}
log
.
Info
(
"Dashboard listen on %s:%d"
,
cfg
.
DashboardAddr
,
cfg
.
DashboardPort
)
}
if
!
httpMuxOn
{
svr
.
websocketListener
,
err
=
frpNet
.
NewWebsocketListener
(
svr
.
muxer
.
ListenHttp
(
0
),
nil
)
return
}
// server := &http.Server{}
if
httpMuxOn
{
rp
:=
svr
.
httpReverseProxy
svr
.
websocketListener
,
err
=
frpNet
.
NewWebsocketListener
(
svr
.
muxer
.
ListenHttp
(
0
),
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
bool
{
domain
:=
getHostFromAddr
(
req
.
Host
)
location
:=
req
.
URL
.
Path
headers
:=
rp
.
GetHeaders
(
domain
,
location
)
if
headers
==
nil
{
return
true
}
rp
.
ServeHTTP
(
w
,
req
)
return
false
})
}
return
}
func
getHostFromAddr
(
addr
string
)
(
host
string
)
{
strs
:=
strings
.
Split
(
addr
,
":"
)
if
len
(
strs
)
>
1
{
host
=
strs
[
0
]
}
else
{
host
=
addr
}
return
}
...
...
@@ -214,8 +246,10 @@ func (svr *Service) Run() {
if
g
.
GlbServerCfg
.
KcpBindPort
>
0
{
go
svr
.
HandleListener
(
svr
.
kcpListener
)
}
if
svr
.
websocketListener
!=
nil
{
go
svr
.
HandleListener
(
svr
.
websocketListener
)
}
svr
.
HandleListener
(
svr
.
listener
)
}
func
(
svr
*
Service
)
HandleListener
(
l
frpNet
.
Listener
)
{
...
...
@@ -226,7 +260,6 @@ func (svr *Service) HandleListener(l frpNet.Listener) {
log
.
Warn
(
"Listener for incoming connections from client closed"
)
return
}
// Start a new goroutine for dealing connections.
go
func
(
frpConn
frpNet
.
Conn
)
{
dealFn
:=
func
(
conn
frpNet
.
Conn
)
{
...
...
utils/net/conn.go
浏览文件 @
b8037475
...
...
@@ -132,6 +132,8 @@ func ConnectServerByProxy(proxyUrl string, protocol string, addr string) (c Conn
case
"kcp"
:
// http proxy is not supported for kcp
return
ConnectServer
(
protocol
,
addr
)
case
"websocket"
:
return
ConnectWebsocketServer
(
addr
)
default
:
return
nil
,
fmt
.
Errorf
(
"unsupport protocol: %s"
,
protocol
)
}
...
...
utils/net/websocket.go
0 → 100644
浏览文件 @
b8037475
package
net
import
(
"fmt"
"net"
"net/http"
"net/url"
"sync/atomic"
"time"
"github.com/fatedier/frp/utils/log"
"golang.org/x/net/websocket"
)
type
WebsocketListener
struct
{
log
.
Logger
server
*
http
.
Server
httpMutex
*
http
.
ServeMux
connChan
chan
*
WebsocketConn
closeFlag
bool
}
func
NewWebsocketListener
(
ln
net
.
Listener
,
filter
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
bool
)
(
l
*
WebsocketListener
,
err
error
)
{
l
=
&
WebsocketListener
{
httpMutex
:
http
.
NewServeMux
(),
connChan
:
make
(
chan
*
WebsocketConn
),
Logger
:
log
.
NewPrefixLogger
(
""
),
}
l
.
httpMutex
.
Handle
(
"/"
,
websocket
.
Handler
(
func
(
c
*
websocket
.
Conn
)
{
conn
:=
NewWebScoketConn
(
c
)
l
.
connChan
<-
conn
conn
.
waitClose
()
}))
l
.
server
=
&
http
.
Server
{
Handler
:
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
filter
!=
nil
&&
!
filter
(
w
,
r
)
{
return
}
l
.
httpMutex
.
ServeHTTP
(
w
,
r
)
}),
}
ch
:=
make
(
chan
struct
{})
go
func
()
{
close
(
ch
)
err
=
l
.
server
.
Serve
(
ln
)
}()
<-
ch
<-
time
.
After
(
time
.
Millisecond
)
return
}
func
ListenWebsocket
(
bindAddr
string
,
bindPort
int
)
(
l
*
WebsocketListener
,
err
error
)
{
ln
,
err
:=
net
.
Listen
(
"tcp"
,
fmt
.
Sprintf
(
"%s:%d"
,
bindAddr
,
bindPort
))
if
err
!=
nil
{
return
}
l
,
err
=
NewWebsocketListener
(
ln
,
nil
)
return
}
func
(
p
*
WebsocketListener
)
Accept
()
(
Conn
,
error
)
{
c
:=
<-
p
.
connChan
return
c
,
nil
}
func
(
p
*
WebsocketListener
)
Close
()
error
{
if
!
p
.
closeFlag
{
p
.
closeFlag
=
true
p
.
server
.
Close
()
}
return
nil
}
type
WebsocketConn
struct
{
net
.
Conn
log
.
Logger
closed
int32
wait
chan
struct
{}
}
func
NewWebScoketConn
(
conn
net
.
Conn
)
(
c
*
WebsocketConn
)
{
c
=
&
WebsocketConn
{
Conn
:
conn
,
Logger
:
log
.
NewPrefixLogger
(
""
),
wait
:
make
(
chan
struct
{}),
}
return
}
func
(
p
*
WebsocketConn
)
Close
()
error
{
if
atomic
.
SwapInt32
(
&
p
.
closed
,
1
)
==
1
{
return
nil
}
close
(
p
.
wait
)
return
p
.
Conn
.
Close
()
}
func
(
p
*
WebsocketConn
)
waitClose
()
{
<-
p
.
wait
}
// ConnectWebsocketServer :
// addr: ws://domain:port
func
ConnectWebsocketServer
(
addr
string
)
(
c
Conn
,
err
error
)
{
addr
=
"ws://"
+
addr
uri
,
err
:=
url
.
Parse
(
addr
)
if
err
!=
nil
{
return
}
origin
:=
"http://"
+
uri
.
Host
cfg
,
err
:=
websocket
.
NewConfig
(
addr
,
origin
)
if
err
!=
nil
{
return
}
cfg
.
Dialer
=
&
net
.
Dialer
{
Timeout
:
time
.
Second
*
10
,
}
conn
,
err
:=
websocket
.
DialConfig
(
cfg
)
if
err
!=
nil
{
return
}
c
=
NewWebScoketConn
(
conn
)
return
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录