|
|
@ -16,19 +16,22 @@ import ( |
|
|
|
"net/http" |
|
|
|
"net/url" |
|
|
|
"os" |
|
|
|
"path" |
|
|
|
"strconv" |
|
|
|
"strings" |
|
|
|
"sync" |
|
|
|
"time" |
|
|
|
|
|
|
|
"github.com/emicklei/go-restful" |
|
|
|
"gopkg.in/yaml.v2" |
|
|
|
) |
|
|
|
|
|
|
|
// I'm not sure how to pass nested structs, so I de-nested this.
|
|
|
|
// TODO: Learn if passing nested structs is desirable?
|
|
|
|
type Conf struct { |
|
|
|
Port uint `yaml:"port,omitempty"` |
|
|
|
Mailer ConfMailer |
|
|
|
Port uint `yaml:"port,omitempty"` |
|
|
|
Mailer ConfMailer |
|
|
|
RootPath string `yaml:"root_path,omitempty"` |
|
|
|
} |
|
|
|
type ConfMailer struct { |
|
|
|
Url string `yaml:"url,omitempty"` |
|
|
@ -456,8 +459,34 @@ func sendAuthCode(cnf ConfMailer, to string) (string, error) { |
|
|
|
return code, nil |
|
|
|
} |
|
|
|
|
|
|
|
type myServer struct { |
|
|
|
chans chan bufferedConn |
|
|
|
net.Listener |
|
|
|
} |
|
|
|
|
|
|
|
func (m *myServer) Accept() (net.Conn, error) { |
|
|
|
bufConn := <-m.chans |
|
|
|
return bufConn, nil |
|
|
|
} |
|
|
|
|
|
|
|
func newMyServer(l net.Listener) *myServer { |
|
|
|
return &myServer{make(chan bufferedConn), l} |
|
|
|
} |
|
|
|
|
|
|
|
var config Conf |
|
|
|
|
|
|
|
func serveStatic(req *restful.Request, resp *restful.Response) { |
|
|
|
actual := path.Join(config.RootPath, req.PathParameter("subpath")) |
|
|
|
fmt.Printf("serving %s ... (from %s)\n", actual, req.PathParameter("subpath")) |
|
|
|
http.ServeFile( |
|
|
|
resp.ResponseWriter, |
|
|
|
req.Request, |
|
|
|
actual) |
|
|
|
} |
|
|
|
func serveHello(req *restful.Request, resp *restful.Response) { |
|
|
|
fmt.Fprintf(resp, "{\"msg\":\"hello\"}") |
|
|
|
} |
|
|
|
|
|
|
|
func main() { |
|
|
|
flag.Usage = usage |
|
|
|
port := flag.Uint("telnet-port", 0, "tcp telnet chat port") |
|
|
@ -474,6 +503,10 @@ func main() { |
|
|
|
if nil != err { |
|
|
|
config = Conf{} |
|
|
|
} |
|
|
|
if "" == config.RootPath { |
|
|
|
// TODO Embed the public dir at the default
|
|
|
|
config.RootPath = "./public" |
|
|
|
} |
|
|
|
|
|
|
|
myRawConns := make(map[bufferedConn]bool) |
|
|
|
firstMsgs = make(chan myMsg, 128) |
|
|
@ -516,12 +549,38 @@ func main() { |
|
|
|
newConns <- conn |
|
|
|
} |
|
|
|
}() |
|
|
|
|
|
|
|
// Learning by Example
|
|
|
|
// https://github.com/emicklei/go-restful/blob/master/examples/restful-multi-containers.go
|
|
|
|
// https://github.com/emicklei/go-restful/blob/master/examples/restful-basic-authentication.go
|
|
|
|
// https://github.com/emicklei/go-restful/blob/master/examples/restful-serve-static.go
|
|
|
|
// https://github.com/emicklei/go-restful/blob/master/examples/restful-pre-post-filters.go
|
|
|
|
container := restful.NewContainer() |
|
|
|
|
|
|
|
wsStatic := new(restful.WebService) |
|
|
|
wsStatic.Path("/") |
|
|
|
wsStatic.Route(wsStatic.GET("/").To(serveStatic)) |
|
|
|
wsStatic.Route(wsStatic.GET("/{subpath:*}").To(serveStatic)) |
|
|
|
container.Add(wsStatic) |
|
|
|
|
|
|
|
wsApi := new(restful.WebService) |
|
|
|
wsApi.Path("/api") |
|
|
|
wsApi.Route(wsApi.GET("/api/hello").To(serveHello)) |
|
|
|
/* |
|
|
|
server := &http.Server{ |
|
|
|
Addr: addr, |
|
|
|
Handler: &myHandler{}, |
|
|
|
} |
|
|
|
ws.Route(ws.POST("/api/authn").To(createAuth)) |
|
|
|
ws.Route(ws.POST("/api/authn/{email}").To(createAuth)) |
|
|
|
ws.Route(ws.GET("/api").Filter(basicAuthenticate).To(hello2)) |
|
|
|
*/ |
|
|
|
container.Add(wsApi) |
|
|
|
|
|
|
|
server := &http.Server{ |
|
|
|
Addr: addr, |
|
|
|
Handler: container, |
|
|
|
} |
|
|
|
myHttpServer := newMyServer(sock) |
|
|
|
go func() { |
|
|
|
server.Serve(myHttpServer) |
|
|
|
}() |
|
|
|
|
|
|
|
// Main event loop handling most access to shared data
|
|
|
|
for { |
|
|
@ -553,8 +612,9 @@ func main() { |
|
|
|
go handleSorted(bufConn) |
|
|
|
//case msg := <- myRooms["general"]:
|
|
|
|
//delete(myRooms["general"], bufConn)
|
|
|
|
//case bufConn := <-newHttpClient:
|
|
|
|
//server.Serve(bufConn)
|
|
|
|
case bufConn := <-newHttpClient: |
|
|
|
// this will be Accept()ed immediately by restful
|
|
|
|
myHttpServer.chans <- bufConn |
|
|
|
case msg := <-myMsgs: |
|
|
|
t := msg.receivedAt |
|
|
|
tf := "%d-%02d-%02d %02d:%02d:%02d (%s)" |
|
|
|