Skip to content

Instantly share code, notes, and snippets.

@akkijp
Last active May 21, 2016 17:41
Show Gist options
  • Save akkijp/5be8179c88cf1f5815e351d59a27724f to your computer and use it in GitHub Desktop.
Save akkijp/5be8179c88cf1f5815e351d59a27724f to your computer and use it in GitHub Desktop.
package main
// from http://www.darul.io/post/2015-07-22_go-lang-simple-reverse-proxy
import (
"net/http"
"net/url"
"net/http/httputil"
"flag"
"fmt"
"regexp"
)
type Prox struct {
target *url.URL
proxy *httputil.ReverseProxy
routePatterns []*regexp.Regexp // add some route patterns with regexp
}
func New(target string) *Prox {
url, _ := url.Parse(target)
return &Prox{target: url,proxy: httputil.NewSingleHostReverseProxy(url)}
}
func (p *Prox) handle(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-GoProxy", "GoProxy")
if p.routePatterns == nil || p.parseWhiteList(r) {
p.proxy.ServeHTTP(w, r)
}
}
func (p *Prox) parseWhiteList(r *http.Request) bool {
for _, regexp := range p.routePatterns {
fmt.Println(r.URL.Path)
if regexp.MatchString(r.URL.Path) {
// let's forward it
return true
}
}
fmt.Println("Not accepted routes %x", r.URL.Path)
return false
}
func main() {
const (
defaultPort = ":80"
defaultPortUsage = "default server port, ':80', ':8080'..."
defaultTarget = "http://127.0.0.1:8080"
defaultTargetUsage = "default redirect url, 'http://127.0.0.1:8080'"
defaultWhiteRoutes = `^\/$|[\w|/]*.js|/path|/path2`
defaultWhiteRoutesUsage = "list of white route as regexp, '/path1*,/path2*...."
)
// flags
port := flag.String("port", defaultPort, defaultPortUsage)
url := flag.String("url", defaultTarget, defaultTargetUsage)
routesRegexp := flag.String("routes", defaultWhiteRoutes, defaultWhiteRoutesUsage)
flag.Parse()
fmt.Println("server will run on : %s", *port)
fmt.Println("redirecting to :%s", *url)
fmt.Println("accepted routes :%s", *routesRegexp)
//
reg, _ := regexp.Compile(*routesRegexp)
routes := []*regexp.Regexp{reg}
// proxy
proxy := New(*url)
proxy.routePatterns = routes
// server
http.HandleFunc("/", proxy.handle)
http.ListenAndServe(*port, nil)
}
package main
import (
"fmt"
"net"
"os"
"time"
)
func main() {
service := ":55555"
tcpAddr, err := net.ResolveTCPAddr("tcp", service)
checkError(err)
listner, err := net.ListenTCP("tcp", tcpAddr)
checkError(err)
for {
conn, err := listner.Accept()
if err != nil {
continue
}
go handleClient(conn)
}
}
func handleClient(conn net.Conn) {
defer conn.Close()
conn.SetReadDeadline(time.Now().Add(10 * time.Second))
fmt.Println("client accept!")
messageBuf := make([]byte, 1024)
messageLen, err := conn.Read(messageBuf)
checkError(err)
message := string(messageBuf[:messageLen])
message = message + " too!"
conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
conn.Write([]byte(message))
}
func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "fatal: error: %s", err.Error())
os.Exit(1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment