mirror of
https://gitee.com/IrisVega/frp.git
synced 2024-11-01 22:31:29 +08:00
Fix conflicts
Conflicts: README_zh.md src/utils/version/version.go
This commit is contained in:
commit
b65e037b5e
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Dockerfile
|
||||||
|
.git
|
||||||
|
*~
|
||||||
|
*#
|
||||||
|
.#*
|
@ -4,7 +4,7 @@ language: go
|
|||||||
go:
|
go:
|
||||||
- 1.5.4
|
- 1.5.4
|
||||||
- 1.6.3
|
- 1.6.3
|
||||||
- 1.7rc6
|
- 1.7
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- make
|
- make
|
||||||
|
17
Dockerfile
Normal file
17
Dockerfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
FROM golang:1.6
|
||||||
|
|
||||||
|
COPY . /go/src/github.com/fatedier/frp
|
||||||
|
|
||||||
|
RUN cd /go/src/github.com/fatedier/frp \
|
||||||
|
&& make \
|
||||||
|
&& mv bin/frpc /frpc \
|
||||||
|
&& mv bin/frps /frps \
|
||||||
|
&& mv conf/frpc_min.ini /frpc.ini \
|
||||||
|
&& mv conf/frps_min.ini /frps.ini \
|
||||||
|
&& make clean
|
||||||
|
|
||||||
|
WORKDIR /
|
||||||
|
|
||||||
|
EXPOSE 80 443 6000 7000 7500
|
||||||
|
|
||||||
|
ENTRYPOINT ["/frps"]
|
12
Dockerfile_alpine
Normal file
12
Dockerfile_alpine
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
FROM alpine:3.4
|
||||||
|
|
||||||
|
COPY bin/frpc /frpc
|
||||||
|
COPY bin/frps /frps
|
||||||
|
COPY conf/frpc_min.ini /frpc.ini
|
||||||
|
COPY conf/frps_min.ini /frps.ini
|
||||||
|
|
||||||
|
WORKDIR /
|
||||||
|
|
||||||
|
EXPOSE 80 443 6000 7000 7500
|
||||||
|
|
||||||
|
ENTRYPOINT ["/frps"]
|
@ -3,10 +3,16 @@ export GO15VENDOREXPERIMENT := 1
|
|||||||
|
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
build: gox app
|
build: gox app more
|
||||||
|
|
||||||
gox:
|
gox:
|
||||||
go get github.com/mitchellh/gox
|
go get github.com/mitchellh/gox
|
||||||
|
|
||||||
app:
|
app:
|
||||||
gox -osarch "darwin/386 darwin/amd64 linux/386 linux/amd64 linux/arm windows/386 windows/amd64" ./src/...
|
gox -osarch "darwin/386 darwin/amd64 linux/386 linux/amd64 linux/arm windows/386 windows/amd64" ./src/...
|
||||||
|
|
||||||
|
more:
|
||||||
|
env GOOS=linux GOARCH=mips64 go build -o ./frpc_linux_mips64 ./src/cmd/frpc
|
||||||
|
env GOOS=linux GOARCH=mips64 go build -o ./frps_linux_mips64 ./src/cmd/frps
|
||||||
|
env GOOS=linux GOARCH=mips64le go build -o ./frpc_linux_mips64le ./src/cmd/frpc
|
||||||
|
env GOOS=linux GOARCH=mips64le go build -o ./frps_linux_mips64le ./src/cmd/frps
|
||||||
|
16
README.md
16
README.md
@ -150,9 +150,12 @@ Configure a port for dashboard to enable this feature:
|
|||||||
```ini
|
```ini
|
||||||
[common]
|
[common]
|
||||||
dashboard_port = 7500
|
dashboard_port = 7500
|
||||||
|
# dashboard's username and password are both optional,if not set, default is admin.
|
||||||
|
dashboard_username = abc
|
||||||
|
dashboard_password = abc
|
||||||
```
|
```
|
||||||
|
|
||||||
Then visit `http://[server_addr]:7500` to see dashboard.
|
Then visit `http://[server_addr]:7500` to see dashboard, default username and password are both `admin`.
|
||||||
|
|
||||||
![dashboard](/doc/pic/dashboard.png)
|
![dashboard](/doc/pic/dashboard.png)
|
||||||
|
|
||||||
@ -327,7 +330,9 @@ If `host_header_rewrite` is specified, the Host header will be rewritten to matc
|
|||||||
|
|
||||||
Interested in getting involved? We would like to help you!
|
Interested in getting involved? We would like to help you!
|
||||||
|
|
||||||
* Take a look at our [issues list](https://github.com/fatedier/frp/issues) and consider submitting a patch
|
* Take a look at our [issues list](https://github.com/fatedier/frp/issues) and consider sending a Pull Request to **dev branch**.
|
||||||
|
* If you want to add a new feature, please create an issue first to describe the new feature, as well as the implementation approach. Once a proposal is accepted, create an implementation of the new features and submit it as a pull request.
|
||||||
|
* Sorry for my poor english and improvement for this document is welcome even some typo fix.
|
||||||
* If you have some wanderful ideas, send email to fatedier@gmail.com.
|
* If you have some wanderful ideas, send email to fatedier@gmail.com.
|
||||||
|
|
||||||
**Note: We prefer you to give your advise in [issues](https://github.com/fatedier/frp/issues), so others with a same question can search it quickly and we don't need to answer them repeatly.**
|
**Note: We prefer you to give your advise in [issues](https://github.com/fatedier/frp/issues), so others with a same question can search it quickly and we don't need to answer them repeatly.**
|
||||||
@ -348,5 +353,8 @@ Donate money by [paypal](https://www.paypal.me/fatedier) to my account **fatedie
|
|||||||
|
|
||||||
* [fatedier](https://github.com/fatedier)
|
* [fatedier](https://github.com/fatedier)
|
||||||
* [Hurricanezwf](https://github.com/Hurricanezwf)
|
* [Hurricanezwf](https://github.com/Hurricanezwf)
|
||||||
* [vashstorm](https://github.com/vashstorm)
|
* [Pan Hao](https://github.com/vashstorm)
|
||||||
* [maodanp](https://github.com/maodanp)
|
* [Danping Mao](https://github.com/maodanp)
|
||||||
|
* [Eric Larssen](https://github.com/ericlarssen)
|
||||||
|
* [Damon Zhao](https://github.com/se77en)
|
||||||
|
* [Manfred Touron](https://github.com/moul)
|
||||||
|
26
README_zh.md
26
README_zh.md
@ -24,7 +24,7 @@ frp 是一个高性能的反向代理应用,可以帮助您轻松地进行内
|
|||||||
* [连接池](#连接池)
|
* [连接池](#连接池)
|
||||||
* [修改 Host Header](#修改-host-header)
|
* [修改 Host Header](#修改-host-header)
|
||||||
* [开发计划](#开发计划)
|
* [开发计划](#开发计划)
|
||||||
* [贡献代码](#贡献代码)
|
* [为 frp 做贡献](#为-frp-做贡献)
|
||||||
* [捐助](#捐助)
|
* [捐助](#捐助)
|
||||||
* [贡献者](#贡献者)
|
* [贡献者](#贡献者)
|
||||||
|
|
||||||
@ -147,9 +147,12 @@ frp 目前正在前期开发阶段,master 分支用于发布稳定版本,dev
|
|||||||
```ini
|
```ini
|
||||||
[common]
|
[common]
|
||||||
dashboard_port = 7500
|
dashboard_port = 7500
|
||||||
|
# dashboard 用户名密码可选,默认都为 admin
|
||||||
|
dashboard_username = abc
|
||||||
|
dashboard_password = abc
|
||||||
```
|
```
|
||||||
|
|
||||||
打开浏览器通过 `http://[server_addr]:7500` 访问 dashboard 界面。
|
打开浏览器通过 `http://[server_addr]:7500` 访问 dashboard 界面,用户名密码默认为 `admin`。
|
||||||
|
|
||||||
![dashboard](/doc/pic/dashboard.png)
|
![dashboard](/doc/pic/dashboard.png)
|
||||||
|
|
||||||
@ -330,12 +333,16 @@ host_header_rewrite = dev.yourdomain.com
|
|||||||
* frpc 完全控制模式,通过 dashboard 对 frpc 进行在线操作。
|
* frpc 完全控制模式,通过 dashboard 对 frpc 进行在线操作。
|
||||||
* 支持 udp 打洞的方式,提供两边内网机器直接通信,流量不经过服务器转发。
|
* 支持 udp 打洞的方式,提供两边内网机器直接通信,流量不经过服务器转发。
|
||||||
|
|
||||||
## 贡献代码
|
## 为 frp 做贡献
|
||||||
|
|
||||||
如果您对这个项目感兴趣,我们非常欢迎您参与其中!
|
frp 是一个免费且开源的项目,我们欢迎任何人为其开发和进步贡献力量。
|
||||||
|
|
||||||
* 如果您需要提交问题,可以通过 [issues](https://github.com/fatedier/frp/issues) 来完成。
|
* 在使用过程中出现任何问题,可以通过 [issues](https://github.com/fatedier/frp/issues) 来反馈。
|
||||||
* 如果您有新的功能需求,可以反馈至 fatedier@gmail.com 共同讨论。
|
* Bug 的修复可以直接提交 Pull Request 到 dev 分支。
|
||||||
|
* 如果是增加新的功能特性,请先创建一个 issue 并做简单描述以及大致的实现方法,提议被采纳后,就可以创建一个实现新特性的 Pull Request。
|
||||||
|
* 欢迎对说明文档做出改善,帮助更多的人使用 frp,特别是英文文档。
|
||||||
|
* 贡献代码请提交 PR 至 dev 分支,master 分支仅用于发布稳定可用版本。
|
||||||
|
* 如果你有任何其他方面的问题,欢迎反馈至 fatedier@gmail.com 共同交流。
|
||||||
|
|
||||||
**提醒:和项目相关的问题最好在 [issues](https://github.com/fatedier/frp/issues) 中反馈,这样方便其他有类似问题的人可以快速查找解决方法,并且也避免了我们重复回答一些问题。**
|
**提醒:和项目相关的问题最好在 [issues](https://github.com/fatedier/frp/issues) 中反馈,这样方便其他有类似问题的人可以快速查找解决方法,并且也避免了我们重复回答一些问题。**
|
||||||
|
|
||||||
@ -355,5 +362,8 @@ host_header_rewrite = dev.yourdomain.com
|
|||||||
|
|
||||||
* [fatedier](https://github.com/fatedier)
|
* [fatedier](https://github.com/fatedier)
|
||||||
* [Hurricanezwf](https://github.com/Hurricanezwf)
|
* [Hurricanezwf](https://github.com/Hurricanezwf)
|
||||||
* [vashstorm](https://github.com/vashstorm)
|
* [Pan Hao](https://github.com/vashstorm)
|
||||||
* [maodanp](https://github.com/maodanp)
|
* [Danping Mao](https://github.com/maodanp)
|
||||||
|
* [Eric Larssen](https://github.com/ericlarssen)
|
||||||
|
* [Damon Zhao](https://github.com/se77en)
|
||||||
|
* [Manfred Touron](https://github.com/moul)
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
|
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
|
||||||
server_addr = 0.0.0.0
|
server_addr = 0.0.0.0
|
||||||
server_port = 7000
|
server_port = 7000
|
||||||
|
# if you want to connect frps by http proxy, you can set http_proxy here or in global environment variables
|
||||||
|
# http_proxy = http://user:pwd@192.168.1.128:8080
|
||||||
# console or real logFile path like ./frpc.log
|
# console or real logFile path like ./frpc.log
|
||||||
log_file = ./frpc.log
|
log_file = ./frpc.log
|
||||||
# debug, info, warn, error
|
# debug, info, warn, error
|
||||||
|
10
conf/frpc_min.ini
Normal file
10
conf/frpc_min.ini
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[common]
|
||||||
|
server_addr = 0.0.0.0
|
||||||
|
server_port = 7000
|
||||||
|
auth_token = 123
|
||||||
|
privilege_token = 12345678
|
||||||
|
|
||||||
|
[ssh]
|
||||||
|
type = tcp
|
||||||
|
local_ip = 127.0.0.1
|
||||||
|
local_port = 22
|
@ -9,6 +9,9 @@ vhost_http_port = 80
|
|||||||
vhost_https_port = 443
|
vhost_https_port = 443
|
||||||
# if you want to configure or reload frps by dashboard, dashboard_port must be set
|
# if you want to configure or reload frps by dashboard, dashboard_port must be set
|
||||||
dashboard_port = 7500
|
dashboard_port = 7500
|
||||||
|
# dashboard username and password for basic protect, if not set, both default value is admin
|
||||||
|
dashboard_username = abc
|
||||||
|
dashboard_password = abc
|
||||||
# dashboard assets directory(only for debug mode)
|
# dashboard assets directory(only for debug mode)
|
||||||
# assets_dir = ./static
|
# assets_dir = ./static
|
||||||
# console or real logFile path like ./frps.log
|
# console or real logFile path like ./frps.log
|
||||||
|
14
conf/frps_min.ini
Normal file
14
conf/frps_min.ini
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[common]
|
||||||
|
bind_addr = 0.0.0.0
|
||||||
|
bind_port = 7000
|
||||||
|
vhost_http_port = 80
|
||||||
|
vhost_https_port = 443
|
||||||
|
dashboard_port = 7500
|
||||||
|
privilege_mode = true
|
||||||
|
privilege_token = 12345678
|
||||||
|
|
||||||
|
[ssh]
|
||||||
|
type = tcp
|
||||||
|
auth_token = 123
|
||||||
|
bind_addr = 0.0.0.0
|
||||||
|
listen_port = 6000
|
@ -15,7 +15,7 @@ rm -rf ./packages
|
|||||||
mkdir ./packages
|
mkdir ./packages
|
||||||
|
|
||||||
os_all='linux windows darwin'
|
os_all='linux windows darwin'
|
||||||
arch_all='386 amd64 arm'
|
arch_all='386 amd64 arm mips64 mips64le'
|
||||||
|
|
||||||
for os in $os_all; do
|
for os in $os_all; do
|
||||||
for arch in $arch_all; do
|
for arch in $arch_all; do
|
@ -130,7 +130,11 @@ func msgSender(cli *client.ProxyClient, c *conn.Conn, msgSendChan chan interface
|
|||||||
}
|
}
|
||||||
|
|
||||||
func loginToServer(cli *client.ProxyClient) (c *conn.Conn, err error) {
|
func loginToServer(cli *client.ProxyClient) (c *conn.Conn, err error) {
|
||||||
c, err = conn.ConnectServer(client.ServerAddr, client.ServerPort)
|
if client.HttpProxy == "" {
|
||||||
|
c, err = conn.ConnectServer(fmt.Sprintf("%s:%d", client.ServerAddr, client.ServerPort))
|
||||||
|
} else {
|
||||||
|
c, err = conn.ConnectServerByHttpProxy(client.HttpProxy, fmt.Sprintf("%s:%d", client.ServerAddr, client.ServerPort))
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("ProxyName [%s], connect to server [%s:%d] error, %v", cli.Name, client.ServerAddr, client.ServerPort, err)
|
log.Error("ProxyName [%s], connect to server [%s:%d] error, %v", cli.Name, client.ServerAddr, client.ServerPort, err)
|
||||||
return
|
return
|
||||||
@ -144,6 +148,7 @@ func loginToServer(cli *client.ProxyClient) (c *conn.Conn, err error) {
|
|||||||
UseGzip: cli.UseGzip,
|
UseGzip: cli.UseGzip,
|
||||||
PrivilegeMode: cli.PrivilegeMode,
|
PrivilegeMode: cli.PrivilegeMode,
|
||||||
ProxyType: cli.Type,
|
ProxyType: cli.Type,
|
||||||
|
PoolCount: cli.PoolCount,
|
||||||
HostHeaderRewrite: cli.HostHeaderRewrite,
|
HostHeaderRewrite: cli.HostHeaderRewrite,
|
||||||
Timestamp: nowTime,
|
Timestamp: nowTime,
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ type ProxyClient struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProxyClient) GetLocalConn() (c *conn.Conn, err error) {
|
func (p *ProxyClient) GetLocalConn() (c *conn.Conn, err error) {
|
||||||
c, err = conn.ConnectServer(p.LocalIp, p.LocalPort)
|
c, err = conn.ConnectServer(fmt.Sprintf("%s:%d", p.LocalIp, p.LocalPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("ProxyName [%s], connect to local port error, %v", p.Name, err)
|
log.Error("ProxyName [%s], connect to local port error, %v", p.Name, err)
|
||||||
}
|
}
|
||||||
@ -51,7 +51,11 @@ func (p *ProxyClient) GetRemoteConn(addr string, port int64) (c *conn.Conn, err
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
c, err = conn.ConnectServer(addr, port)
|
if HttpProxy == "" {
|
||||||
|
c, err = conn.ConnectServer(fmt.Sprintf("%s:%d", addr, port))
|
||||||
|
} else {
|
||||||
|
c, err = conn.ConnectServerByHttpProxy(HttpProxy, fmt.Sprintf("%s:%d", addr, port))
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("ProxyName [%s], connect to server [%s:%d] error, %v", p.Name, addr, port, err)
|
log.Error("ProxyName [%s], connect to server [%s:%d] error, %v", p.Name, addr, port, err)
|
||||||
return
|
return
|
||||||
|
@ -16,6 +16,7 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
ServerAddr string = "0.0.0.0"
|
ServerAddr string = "0.0.0.0"
|
||||||
ServerPort int64 = 7000
|
ServerPort int64 = 7000
|
||||||
|
HttpProxy string = ""
|
||||||
LogFile string = "console"
|
LogFile string = "console"
|
||||||
LogWay string = "console"
|
LogWay string = "console"
|
||||||
LogLevel string = "info"
|
LogLevel string = "info"
|
||||||
@ -57,6 +59,14 @@ func LoadConf(confFile string) (err error) {
|
|||||||
ServerPort, _ = strconv.ParseInt(tmpStr, 10, 64)
|
ServerPort, _ = strconv.ParseInt(tmpStr, 10, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmpStr, ok = conf.Get("common", "http_proxy")
|
||||||
|
if ok {
|
||||||
|
HttpProxy = tmpStr
|
||||||
|
} else {
|
||||||
|
// get http_proxy from env
|
||||||
|
HttpProxy = os.Getenv("http_proxy")
|
||||||
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "log_file")
|
tmpStr, ok = conf.Get("common", "log_file")
|
||||||
if ok {
|
if ok {
|
||||||
LogFile = tmpStr
|
LogFile = tmpStr
|
||||||
|
@ -30,19 +30,21 @@ import (
|
|||||||
|
|
||||||
// common config
|
// common config
|
||||||
var (
|
var (
|
||||||
ConfigFile string = "./frps.ini"
|
ConfigFile string = "./frps.ini"
|
||||||
BindAddr string = "0.0.0.0"
|
BindAddr string = "0.0.0.0"
|
||||||
BindPort int64 = 7000
|
BindPort int64 = 7000
|
||||||
VhostHttpPort int64 = 0 // if VhostHttpPort equals 0, don't listen a public port for http protocol
|
VhostHttpPort int64 = 0 // if VhostHttpPort equals 0, don't listen a public port for http protocol
|
||||||
VhostHttpsPort int64 = 0 // if VhostHttpsPort equals 0, don't listen a public port for https protocol
|
VhostHttpsPort int64 = 0 // if VhostHttpsPort equals 0, don't listen a public port for https protocol
|
||||||
DashboardPort int64 = 0 // if DashboardPort equals 0, dashboard is not available
|
DashboardPort int64 = 0 // if DashboardPort equals 0, dashboard is not available
|
||||||
AssetsDir string = ""
|
DashboardUsername string = "admin"
|
||||||
LogFile string = "console"
|
DashboardPassword string = "admin"
|
||||||
LogWay string = "console" // console or file
|
AssetsDir string = ""
|
||||||
LogLevel string = "info"
|
LogFile string = "console"
|
||||||
LogMaxDays int64 = 3
|
LogWay string = "console" // console or file
|
||||||
PrivilegeMode bool = false
|
LogLevel string = "info"
|
||||||
PrivilegeToken string = ""
|
LogMaxDays int64 = 3
|
||||||
|
PrivilegeMode bool = false
|
||||||
|
PrivilegeToken string = ""
|
||||||
|
|
||||||
// if PrivilegeAllowPorts is not nil, tcp proxies which remote port exist in this map can be connected
|
// if PrivilegeAllowPorts is not nil, tcp proxies which remote port exist in this map can be connected
|
||||||
PrivilegeAllowPorts map[int64]struct{}
|
PrivilegeAllowPorts map[int64]struct{}
|
||||||
@ -119,6 +121,16 @@ func loadCommonConf(confFile string) error {
|
|||||||
DashboardPort = 0
|
DashboardPort = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmpStr, ok = conf.Get("common", "dashboard_username")
|
||||||
|
if ok {
|
||||||
|
DashboardUsername = tmpStr
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpStr, ok = conf.Get("common", "dashboard_password")
|
||||||
|
if ok {
|
||||||
|
DashboardPassword = tmpStr
|
||||||
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "assets_dir")
|
tmpStr, ok = conf.Get("common", "assets_dir")
|
||||||
if ok {
|
if ok {
|
||||||
AssetsDir = tmpStr
|
AssetsDir = tmpStr
|
||||||
|
@ -15,9 +15,11 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatedier/frp/src/assets"
|
"github.com/fatedier/frp/src/assets"
|
||||||
@ -38,7 +40,7 @@ func RunDashboardServer(addr string, port int64) (err error) {
|
|||||||
// view, see dashboard_view.go
|
// view, see dashboard_view.go
|
||||||
mux.Handle("/favicon.ico", http.FileServer(assets.FileSystem))
|
mux.Handle("/favicon.ico", http.FileServer(assets.FileSystem))
|
||||||
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(assets.FileSystem)))
|
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(assets.FileSystem)))
|
||||||
mux.HandleFunc("/", viewDashboard)
|
mux.HandleFunc("/", use(viewDashboard, basicAuth))
|
||||||
|
|
||||||
address := fmt.Sprintf("%s:%d", addr, port)
|
address := fmt.Sprintf("%s:%d", addr, port)
|
||||||
server := &http.Server{
|
server := &http.Server{
|
||||||
@ -58,3 +60,43 @@ func RunDashboardServer(addr string, port int64) (err error) {
|
|||||||
go server.Serve(ln)
|
go server.Serve(ln)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func use(h http.HandlerFunc, middleware ...func(http.HandlerFunc) http.HandlerFunc) http.HandlerFunc {
|
||||||
|
for _, m := range middleware {
|
||||||
|
h = m(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func basicAuth(h http.HandlerFunc) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||||
|
|
||||||
|
s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
|
||||||
|
if len(s) != 2 {
|
||||||
|
http.Error(w, "Not authorized", 401)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := base64.StdEncoding.DecodeString(s[1])
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), 401)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pair := strings.SplitN(string(b), ":", 2)
|
||||||
|
if len(pair) != 2 {
|
||||||
|
http.Error(w, "Not authorized", 401)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if pair[0] != DashboardUsername || pair[1] != DashboardPassword {
|
||||||
|
http.Error(w, "Not authorized", 401)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
h.ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,9 +16,12 @@ package conn
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -104,9 +107,9 @@ func NewConn(conn net.Conn) (c *Conn) {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConnectServer(host string, port int64) (c *Conn, err error) {
|
func ConnectServer(addr string) (c *Conn, err error) {
|
||||||
c = &Conn{}
|
c = &Conn{}
|
||||||
servertAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", host, port))
|
servertAddr, err := net.ResolveTCPAddr("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -120,6 +123,49 @@ func ConnectServer(host string, port int64) (c *Conn, err error) {
|
|||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConnectServerByHttpProxy(httpProxy string, serverAddr string) (c *Conn, err error) {
|
||||||
|
var proxyUrl *url.URL
|
||||||
|
if proxyUrl, err = url.Parse(httpProxy); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var proxyAuth string
|
||||||
|
if proxyUrl.User != nil {
|
||||||
|
proxyAuth = "Basic " + base64.StdEncoding.EncodeToString([]byte(proxyUrl.User.String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if proxyUrl.Scheme != "http" {
|
||||||
|
err = fmt.Errorf("Proxy URL scheme must be http, not [%s]", proxyUrl.Scheme)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if c, err = ConnectServer(proxyUrl.Host); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("CONNECT", "http://"+serverAddr, nil)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if proxyAuth != "" {
|
||||||
|
req.Header.Set("Proxy-Authorization", proxyAuth)
|
||||||
|
}
|
||||||
|
req.Header.Set("User-Agent", "Mozilla/5.0")
|
||||||
|
req.Write(c.TcpConn)
|
||||||
|
|
||||||
|
resp, err := http.ReadResponse(bufio.NewReader(c), req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp.Body.Close()
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
err = fmt.Errorf("ConnectServer using proxy error, StatusCode [%d]", resp.StatusCode)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// if the tcpConn is different with c.TcpConn
|
// if the tcpConn is different with c.TcpConn
|
||||||
// you should call c.Close() first
|
// you should call c.Close() first
|
||||||
func (c *Conn) SetTcpConn(tcpConn net.Conn) {
|
func (c *Conn) SetTcpConn(tcpConn net.Conn) {
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version string = "0.8.1"
|
var version string = "0.9.0"
|
||||||
|
|
||||||
func Full() string {
|
func Full() string {
|
||||||
return version
|
return version
|
||||||
|
@ -71,6 +71,18 @@ func (v *VhostMuxer) Listen(name string, rewriteHost string) (l *Listener, err e
|
|||||||
func (v *VhostMuxer) getListener(name string) (l *Listener, exist bool) {
|
func (v *VhostMuxer) getListener(name string) (l *Listener, exist bool) {
|
||||||
v.mutex.RLock()
|
v.mutex.RLock()
|
||||||
defer v.mutex.RUnlock()
|
defer v.mutex.RUnlock()
|
||||||
|
// first we check the full hostname
|
||||||
|
// if not exist, then check the wildcard_domain such as *.example.com
|
||||||
|
l, exist = v.registryMap[name]
|
||||||
|
if exist {
|
||||||
|
return l, exist
|
||||||
|
}
|
||||||
|
domainSplit := strings.Split(name, ".")
|
||||||
|
if len(domainSplit) < 3 {
|
||||||
|
return l, false
|
||||||
|
}
|
||||||
|
domainSplit[0] = "*"
|
||||||
|
name = strings.Join(domainSplit, ".")
|
||||||
l, exist = v.registryMap[name]
|
l, exist = v.registryMap[name]
|
||||||
return l, exist
|
return l, exist
|
||||||
}
|
}
|
||||||
@ -93,21 +105,26 @@ func (v *VhostMuxer) run() {
|
|||||||
|
|
||||||
func (v *VhostMuxer) handle(c *conn.Conn) {
|
func (v *VhostMuxer) handle(c *conn.Conn) {
|
||||||
if err := c.SetDeadline(time.Now().Add(v.timeout)); err != nil {
|
if err := c.SetDeadline(time.Now().Add(v.timeout)); err != nil {
|
||||||
|
c.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sConn, name, err := v.vhostFunc(c)
|
sConn, name, err := v.vhostFunc(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
c.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
name = strings.ToLower(name)
|
name = strings.ToLower(name)
|
||||||
|
// get listener by hostname
|
||||||
l, ok := v.getListener(name)
|
l, ok := v.getListener(name)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
c.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = sConn.SetDeadline(time.Time{}); err != nil {
|
if err = sConn.SetDeadline(time.Time{}); err != nil {
|
||||||
|
c.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.SetTcpConn(sConn)
|
c.SetTcpConn(sConn)
|
||||||
|
@ -19,7 +19,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestEchoServer(t *testing.T) {
|
func TestEchoServer(t *testing.T) {
|
||||||
c, err := conn.ConnectServer("0.0.0.0", ECHO_PORT)
|
c, err := conn.ConnectServer(fmt.Sprintf("0.0.0.0:%d", ECHO_PORT))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("connect to echo server error: %v", err)
|
t.Fatalf("connect to echo server error: %v", err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user