Ejemplo n.º 1
0
func (s *Server) doServe(listener net.Listener, readyCb func(addr string)) error {
	cb := NewConnBag()

	proxy := http.HandlerFunc(
		func(w http.ResponseWriter, req *http.Request) {
			c := cb.Withdraw(req.RemoteAddr)
			context.Set(req, "conn", c)
			s.handler.ServeHTTP(w, req)
			context.Clear(req)
		})

	s.httpServer = http.Server{Handler: proxy,
		ConnState: func(c net.Conn, state http.ConnState) {
			wconn, ok := c.(listeners.WrapConn)
			if !ok {
				panic("Should be of type WrapConn")
			}

			wconn.OnState(state)

			switch state {
			case http.StateActive:
				cb.Put(wconn)
			case http.StateClosed:
				// When go server encounters abnormal request, it
				// will transit to StateClosed directly without
				// the handler being invoked, hence the connection
				// will not be withdrawed. Purge it in such case.
				cb.Purge(c.RemoteAddr().String())
			}
		},
		ErrorLog: log.AsStdLogger(),
	}

	firstListener := listeners.NewDefaultListener(listener)
	firstListenerPtr := &firstListener
	s.listeners = []*net.Listener{firstListenerPtr}

	for _, li := range s.listenerGenerators {
		newlis := li(*firstListenerPtr)
		s.listeners = append(s.listeners, &newlis)
		firstListenerPtr = &newlis
	}

	s.Addr = (*firstListenerPtr).Addr()
	addrStr := s.Addr.String()
	s.httpServer.Addr = addrStr

	if readyCb != nil {
		readyCb(addrStr)
	}

	return s.httpServer.Serve(*firstListenerPtr)
}
Ejemplo n.º 2
0
func (s *Server) Serve(listener net.Listener, readyCb func(addr string)) error {
	l := listeners.NewDefaultListener(listener)

	for _, wrap := range s.listenerGenerators {
		l = wrap(l)
	}

	if readyCb != nil {
		readyCb(l.Addr().String())
	}

	return s.httpServer.Serve(l)
}