Skip to content

Commit

Permalink
Add simple server and update README
Browse files Browse the repository at this point in the history
  • Loading branch information
wzshiming committed Jan 10, 2021
1 parent a88649b commit f0161c4
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Socks4/Socks4a server and client
[![GitHub license](https://img.shields.io/github/license/wzshiming/socks4.svg)](https://github.com/wzshiming/socks4/blob/master/LICENSE)
[![gocover.io](https://gocover.io/_badge/github.com/wzshiming/socks4)](https://gocover.io/github.com/wzshiming/socks4)

This project is to add protocol support for the [Bridge](https://github.com/wzshiming/bridge), or it can be used alone

The following is the implementation of other proxy protocols

- [Socks5](https://github.com/wzshiming/socks5)
Expand Down
23 changes: 22 additions & 1 deletion all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func TestServerAndAuthClient(t *testing.T) {
t.Fatal(err)
}
resp.Body.Close()

}

func TestServerAndClient(t *testing.T) {
Expand Down Expand Up @@ -151,3 +150,25 @@ func TestBind(t *testing.T) {
}
resp.Body.Close()
}

func TestSimpleServer(t *testing.T) {
s, err := NewSimpleServer("socks4://u@:0")

s.Start(context.Background())
defer s.Close()

dial, err := NewDialer(s.ProxyURL())
if err != nil {
t.Fatal(err)
}
cli := testServer.Client()
cli.Transport = &http.Transport{
DialContext: dial.DialContext,
}

resp, err := cli.Get(testServer.URL)
if err != nil {
t.Fatal(err)
}
resp.Body.Close()
}
91 changes: 91 additions & 0 deletions simple_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package socks4

import (
"context"
"fmt"
"net"
"net/url"
)

// SimpleServer is a simplified server, which can be configured as easily as client.
type SimpleServer struct {
Server
Listener net.Listener
Network string
Address string
Username string
}

// NewServer creates a new NewSimpleServer
func NewSimpleServer(addr string) (*SimpleServer, error) {
s := &SimpleServer{}
u, err := url.Parse(addr)
if err != nil {
return nil, err
}
switch u.Scheme {
case "socks4", "socks4a":
default:
return nil, fmt.Errorf("unsupported protocol '%s'", u.Scheme)
}
host := u.Host
port := u.Port()
if port == "" {
port = "1080"
hostname := u.Hostname()
host = net.JoinHostPort(hostname, port)
}
if u.User != nil {
s.Username = u.User.Username()
s.Authentication = UserAuth(s.Username)
}

s.Address = host
s.Network = "tcp"
return s, nil
}

// Run the server
func (s *SimpleServer) Run(ctx context.Context) error {
var listenConfig net.ListenConfig
listener, err := listenConfig.Listen(ctx, s.Network, s.Address)
if err != nil {
return err
}
s.Listener = listener
s.Address = listener.Addr().String()
return s.Serve(listener)
}

// Start the server
func (s *SimpleServer) Start(ctx context.Context) error {
var listenConfig net.ListenConfig
listener, err := listenConfig.Listen(ctx, s.Network, s.Address)
if err != nil {
return err
}
s.Listener = listener
s.Address = listener.Addr().String()
go s.Serve(listener)
return nil
}

// Close closes the listener
func (s *SimpleServer) Close() error {
if s.Listener == nil {
return nil
}
return s.Listener.Close()
}

// ProxyURL returns the URL of the proxy
func (s *SimpleServer) ProxyURL() string {
u := url.URL{
Scheme: "socks4",
Host: s.Address,
}
if s.Username != "" {
u.User = url.User(s.Username)
}
return u.String()
}

0 comments on commit f0161c4

Please sign in to comment.