commit 988c873243ac0496d36a9e625bbb54063306fc52 Author: David Fifield david@bamsoftware.com Date: Sun Nov 25 19:04:39 2012 -0800
Add draft websocket-server. --- .gitignore | 1 + websocket-transport/Makefile | 3 +- websocket-transport/websocket-server.go | 90 +++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletions(-)
diff --git a/.gitignore b/.gitignore index 24f143b..ff6ddd5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.pyc /dist /websocket-transport/websocket-client +/websocket-transport/websocket-server diff --git a/websocket-transport/Makefile b/websocket-transport/Makefile index 14ffac0..1fb2f76 100644 --- a/websocket-transport/Makefile +++ b/websocket-transport/Makefile @@ -1,8 +1,9 @@ -PROGRAMS = websocket-client +PROGRAMS = websocket-client websocket-server
all: $(PROGRAMS)
websocket-client: websocket-client.go socks.go pt.go +websocket-server: websocket-server.go pt.go
%: %.go go build -o $@ $^ diff --git a/websocket-transport/websocket-server.go b/websocket-transport/websocket-server.go new file mode 100644 index 0000000..d905364 --- /dev/null +++ b/websocket-transport/websocket-server.go @@ -0,0 +1,90 @@ +package main + +import ( + "fmt" + "net" + "net/http" + "os" + "os/signal" +) + +const defaultPort = 9901 + +// When a connection handler starts, +1 is written to this channel; when it +// ends, -1 is written. +var handlerChan = make(chan int) + +func logDebug(format string, v ...interface{}) { + fmt.Fprintf(os.Stderr, format+"\n", v...) +} + +func handler(w http.ResponseWriter, req *http.Request) { +} + +func startListener(addr *net.TCPAddr) (*net.TCPListener, error) { + ln, err := net.ListenTCP("tcp", addr) + if err != nil { + return nil, err + } + go func() { + http.HandleFunc("/", handler) + err = http.Serve(ln, nil) + if err != nil { + panic("http.Serve: " + err.Error()) + } + }() + return ln, nil +} + +func main() { + const ptMethodName = "websocket" + + ptInfo := ptServerSetup([]string{ptMethodName}) + + listeners := make([]*net.TCPListener, 0) + for _, bindAddr := range ptInfo.BindAddrs { + // When tor tells us a port of 0, we are supposed to pick a + // random port. But we actually want to use the configured port. + if bindAddr.Addr.Port == 0 { + bindAddr.Addr.Port = defaultPort + } + + ln, err := startListener(bindAddr.Addr) + if err != nil { + ptSmethodError(bindAddr.MethodName, err.Error()) + } + ptSmethod(bindAddr.MethodName, ln.Addr()) + listeners = append(listeners, ln) + } + ptSmethodsDone() + + var numHandlers int = 0 + + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, os.Interrupt) + var sigint bool = false + for !sigint { + select { + case n := <-handlerChan: + numHandlers += n + case <-signalChan: + logDebug("SIGINT") + sigint = true + } + } + + for _, ln := range listeners { + ln.Close() + } + + sigint = false + for numHandlers != 0 && !sigint { + select { + case n := <-handlerChan: + numHandlers += n + case <-signalChan: + logDebug("SIGINT") + sigint = true + } + } +}