"errors"
"net"
"net/http"
+ "os"
"strconv"
"strings"
"sync"
type WebSync struct {
Server *http.Server
+ FD uintptr
mux *http.ServeMux
wrs *WebPath
}
func NewSyncMap(conf *http.Server, m *WebPath, matchFunc ...func(path string) (func(w http.ResponseWriter, r *http.Request), bool)) (o *WebSync) {
- if o, e := NewSyncMapNoPanic(conf, m, matchFunc...); e != nil {
+ if o, e := NewSyncMapNoPanic(conf, 0, m, matchFunc...); e != nil {
panic(e)
} else {
return o
}
}
-func NewSyncMapNoPanic(conf *http.Server, m *WebPath, matchFunc ...func(path string) (func(w http.ResponseWriter, r *http.Request), bool)) (o *WebSync, err error) {
+func NewSyncMapFD(conf *http.Server, fd uintptr, m *WebPath, matchFunc ...func(path string) (func(w http.ResponseWriter, r *http.Request), bool)) (o *WebSync) {
+ if o, e := NewSyncMapNoPanic(conf, fd, m, matchFunc...); e != nil {
+ panic(e)
+ } else {
+ return o
+ }
+}
+
+func NewSyncMapNoPanic(conf *http.Server, fd uintptr, m *WebPath, matchFunc ...func(path string) (func(w http.ResponseWriter, r *http.Request), bool)) (o *WebSync, err error) {
o = new(WebSync)
matchFunc = append(matchFunc, o.wrs.Load)
- ln, err := net.Listen("tcp", conf.Addr)
- if err != nil {
- return nil, err
+ var ln net.Listener
+ if fd != 0 {
+ if tmp, err := net.FileListener(os.NewFile(fd, "")); err != nil {
+ return nil, err
+ } else {
+ ln = tmp
+ }
+ } else {
+ if tmp, err := net.Listen("tcp", conf.Addr); err != nil {
+ return nil, err
+ } else {
+ ln = tmp
+ }
}
if conf.TLSConfig != nil {
ln = tls.NewListener(ln, conf.TLSConfig)
}
+ switch t := ln.(type) {
+ case *net.TCPListener:
+ c, _ := t.SyscallConn()
+ c.Control(func(fd uintptr) {
+ o.FD = fd
+ })
+ case *net.UnixListener:
+ c, _ := t.SyscallConn()
+ c.Control(func(fd uintptr) {
+ o.FD = fd
+ })
+ }
go o.Server.Serve(ln)
if o.Server.Handler == nil {
reqf "github.com/qydysky/part/reqf"
)
+func TestMain1(t *testing.T) {
+ var fd uintptr
+ r := reqf.New()
+ var stop func(ctx ...context.Context)
+ var stop2 func(ctx ...context.Context)
+ {
+ ser := &http.Server{Addr: "127.0.0.1:18081"}
+ wp := &WebPath{}
+ wp.Store("/test/", func(w http.ResponseWriter, r *http.Request) {
+ w.Write([]byte("1"))
+ })
+ o, e := NewSyncMapNoPanic(ser, 0, wp, wp.Load)
+ if e != nil {
+ t.Fatal(e)
+ }
+ fd = o.FD
+ stop = o.Shutdown
+ }
+ time.Sleep(time.Second)
+ {
+ r.Reqf(reqf.Rval{
+ Url: "http://127.0.0.1:18081/test/",
+ })
+ if !bytes.Equal(r.Respon, []byte("1")) {
+ t.Fatal(r.Respon)
+ }
+ }
+ {
+ ser := &http.Server{Addr: "127.0.0.1:18082"}
+ wp := &WebPath{}
+ wp.Store("/test/", func(w http.ResponseWriter, r *http.Request) {
+ w.Write([]byte("2"))
+ })
+ o, e := NewSyncMapNoPanic(ser, fd, wp, wp.Load)
+ if e != nil {
+ t.Fatal(e)
+ }
+ fd = o.FD
+ stop2 = o.Shutdown
+ }
+ stop()
+ time.Sleep(time.Second)
+ {
+ r.Reqf(reqf.Rval{
+ Url: "http://127.0.0.1:18081/test/",
+ })
+ if !bytes.Equal(r.Respon, []byte("2")) {
+ t.Fatal(r.Respon)
+ }
+ }
+ stop2()
+}
+
func TestMain(t *testing.T) {
ser := &http.Server{
Addr: "127.0.0.1:18081",
}
wp := &WebPath{}
- t.Log(NewSyncMapNoPanic(ser, wp, wp.Load))
- t.Log(NewSyncMapNoPanic(ser, wp, wp.Load))
+ t.Log(NewSyncMapNoPanic(ser, 0, wp, wp.Load))
+ t.Log(NewSyncMapNoPanic(ser, 0, wp, wp.Load))
}
func Test_Exprier(t *testing.T) {