Skip to content

Commit

Permalink
Merge pull request #2 from aak1247/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
aak1247 authored Nov 7, 2023
2 parents 0b2b62f + 8756c76 commit c512e25
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 16 deletions.
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.PHONY: build
build:
go build
release:
# clean
go clean
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o gproxy-windows-amd64-${VERSION}.exe
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o gproxy-linux-amd64-${VERSION}
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o gproxy-darwin-amd64-${VERSION}
help:
echo "run \"make release VERSION=$VERSION\" to build all binary"
46 changes: 42 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,45 @@
# Usage
# gproxy

代理访问单个域名的全部请求 Proxy all requests to a website
| English | [简体中文](./README.zh-CN.md) |

``gproxy http://example.com/ -p 8080``
## Usage

这样就可以启动一个代理进程,在本地的8080端口代理example.com的内容。 then, a simple http server will run on local 8080 port to serve the content of example.com
### Arguments

gproxy [-m mode] [-p port] targetURL

- ``mode``: http or tcp
- ``port``: local port, example: 8080

### Proxy a http website:

``gproxy -m http -p 8080 http://github.com/``

then, a simple http server will run on local 8080 port to serve the content of github.com

### Proxy a tcp service:

``gproxy -m tcp -p 2333 github.com:443``

then, all tcp request to localhost:2333 will be sent to github.com:443 and response from github.com:443 will be sent
back to client

## Build

### With makefile

``make release``: will generate all linux/windows/osx binary

### Run by command

#### Target linux

``CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o gproxy-linux-amd64``

#### Target windows

``CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o gproxy-windows-amd64.exe``

#### Target mac

``CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o gproxy-darwin-amd64``
22 changes: 22 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# gproxy

| [English](./README.md) | 简体中文 |

## 使用

### 参数
gproxy [-m 模式] [-p 端口] 目标地址

- ``mode``: http 或 tcp
- ``port``: 本地端口, 比如: 8080


### 代理一个http网站:
``gproxy -m http -p 8080 http://github.com/``

本地8080端口即可以直接访问github

### 代理一个tcp服务:
``gproxy -m tcp -p 2333 github.com:443``

本地2333端口的所有tcp流量都会代理到github.com:443对应的tcp服务
11 changes: 6 additions & 5 deletions proxy.go → http.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ import (
"github.com/gin-gonic/gin"
"log"
"net/http"
"strconv"
"strings"
)

// NewProxy 启动代理服务
func NewProxy(url string, localPort string) {
// NewHttpProxy 启动代理服务
func NewHttpProxy(url string, localPort int) {
r := gin.Default()
r.Any("/*path", proxy(url))
r.Run("0.0.0.0:" + localPort)
r.Any("/*path", httpProxy(url))
r.Run("0.0.0.0:" + strconv.Itoa(localPort))
}

func proxy(url string) func(c *gin.Context) {
func httpProxy(url string) func(c *gin.Context) {
return func(c *gin.Context) {
// 读取请求头
headers := make(map[string]string)
Expand Down
38 changes: 31 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,42 @@
package main

import "os"
import (
"log"
"os"
"strconv"
)

func main() {
// 解析命令行参数(proxy domain [-p port])
// 解析命令行参数(httpProxy domain [-p port])
args := os.Args[1:]
if len(args) < 1 {
panic("invalid args")
}
domain := args[0]
port := "80"
if len(args) > 1 && args[1] == "-p" {
port = args[2]
var err error
port := 80
mode := "http"
for i, arg := range args {
if arg == "-p" && len(args) > i+1 {
port, err = strconv.Atoi(args[i+1])
if err != nil {
log.Fatalf("error occured: %v", err)
}
i++
continue
}
if arg == "-m" && len(args) > i+1 {
mode = args[i+1]
i++
continue
}
domain = arg
}
switch mode {
case "http":
// 启动HTTP代理服务
NewHttpProxy(domain, port)
case "tcp":
NewTcpProxy(domain, port)
}
// 启动代理服务
NewProxy(domain, port)
}
117 changes: 117 additions & 0 deletions tcp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package main

import (
"io"
"log"
"net"
"strconv"
"time"
)

func NewTcpProxy(url string, localPort int) {
listener, err := net.Listen("tcp", ":"+strconv.Itoa(localPort))
defer listener.Close()
if err != nil {
log.Fatal(err)
}

for {
conn, err := listener.Accept()
if err != nil {
log.Fatal(err)
}
go tcpProxy(url, conn)
}
}

func tcpProxy(url string, client net.Conn) error {
cs := make(chan bool)
ss := make(chan bool)

// 连接远程服务器
server, err := net.Dial("tcp", url)
if err != nil {
log.Printf("dial error %v\n", err)
return err
}

// 启动上行goroutine
go func() {
defer client.Close()
if err := client.SetDeadline(time.Now().Add(10 * time.Second)); err != nil {
log.Println("Failed to set deadline:", err)
return
}

buf := make([]byte, 1024*256)
for {
select {
case <-cs:
break
default:
n, err := client.Read(buf)
if err != nil {
if err != io.EOF {
log.Printf("Failed to read from client: %v, close connection\n", err)
cs <- true
ss <- true
return
}
}
if n > 0 {
log.Printf("received from client bytes %d\n", n)
log.Printf("Received data from client %s: %s\n", client.RemoteAddr().String(), string(buf[:n]))

// write to server
if n, err := server.Write(buf); err != nil {
log.Println("Failed to write to server:\n", err)
} else {
log.Printf("write to server %d\n", n)
}
// 清空缓冲区
buf = make([]byte, 1024*256)
}
}
}
}()

// 启动下行goroutine
go func() {
defer server.Close()
if err := server.SetDeadline(time.Now().Add(10 * time.Second)); err != nil {
log.Println("Failed to set deadline:\n", err)
return
}
buf := make([]byte, 1024*256)
for {
select {
case <-ss:
break
default:
n, err := server.Read(buf)
if err != nil {
if err != io.EOF {
log.Printf("Failed to read from server: %v, close connection\n", err)
ss <- true
cs <- true
return
}
}
if n > 0 {
log.Printf("received from server bytes %d\n", n)
log.Printf("Received data from server %s: %s\n", server.RemoteAddr().String(), string(buf[:n]))

// write to client
if n, err := client.Write(buf); err != nil {
log.Println("Failed to write to client:", err)
} else {
log.Printf("write to client %d", n)
}
// 清空缓冲区
buf = make([]byte, 1024*256)
}
}
}
}()
return nil
}

0 comments on commit c512e25

Please sign in to comment.