예제 #1
0
파일: http.go 프로젝트: postfix/go-tunnel
func NewHTTPSBinder(addr, publicBaseAddr string, muxTimeout time.Duration, tlsConfig *tls.Config) (*HTTPBinder, error) {
	// bind a port to listen for https connections
	listener, err := tls.Listen("tcp", addr, tlsConfig)
	if err != nil {
		return nil, err
	}

	// create a new muxer that will let us bind virtual hostnames
	mux, err := vhost.NewHTTPMuxer(listener, muxTimeout)
	if err != nil {
		return nil, err
	}

	return sharedInit(mux, "https", publicBaseAddr)
}
예제 #2
0
func (s *Server) Run() error {
	// bind a port to handle TLS/HTTP connections
	l, err := net.Listen("tcp", s.ListenerConfig.BindAddr)
	if err != nil {
		return err
	}
	s.Printf("Serving connections on %v", l.Addr())

	if s.ListenerConfig.Https {
		s.Logger.Println("Initializing HTTPS multiplexer")
		s.mux, err = vhost.NewTLSMuxer(l, muxTimeout)
	} else {
		s.Logger.Println("Initializing HTTP multiplexer")
		s.mux, err = vhost.NewHTTPMuxer(l, muxTimeout)
	}

	if err != nil {
		return err
	}

	// wait for all frontends to finish
	s.wait.Add(len(s.Frontends))

	// setup muxing for each frontend
	for name, front := range s.Frontends {
		fl, err := s.mux.Listen(name)

		if err != nil {
			return err
		}
		go s.runFrontend(name, front, fl)
	}

	// custom error handler so we can log errors
	go func() {
		for {
			conn, err := s.mux.NextError()
			if conn == nil {
				s.Printf("Failed to mux next connection, error: %v", err)
				if _, ok := err.(vhost.Closed); ok {
					return
				} else {
					continue
				}
			} else {
				if _, ok := err.(vhost.NotFound); ok && s.DefaultFrontend != nil {
					go s.proxyConnection(conn, s.DefaultFrontend)
				} else {
					s.Printf("Failed to mux connection from %v, error: %v", conn.RemoteAddr(), err)
					// XXX: respond with valid TLS close messages
					conn.Close()
				}
			}
		}
	}()

	// we're ready, signal it for testing
	if s.ready != nil {
		close(s.ready)
	}

	s.wait.Wait()

	return nil
}