func (self *Serv) hostPort(ln net.Listener) (host string, port int) { addr := ln.Addr().(*net.TCPAddr) if host = self.hostname; len(host) == 0 { host = addr.IP.String() } return host, addr.Port }
// Start instructs the TCPCollector to bind to the interface and accept connections. func (s *TCPCollector) Start(c chan<- *Event) error { var ln net.Listener var err error if s.tlsConfig == nil { ln, err = net.Listen("tcp", s.iface) } else { ln, err = tls.Listen("tcp", s.iface, s.tlsConfig) } s.addr = ln.Addr() if err != nil { return err } go func() { for { conn, err := ln.Accept() if err != nil { continue } go s.handleConnection(conn, c) } }() return nil }
// Serve sets up the handler to serve requests on the passed in listener func (h Handler) Serve(l net.Listener) error { server := http.Server{ Addr: l.Addr().String(), Handler: h.mux, } return server.Serve(l) }
// Re-exec this image without dropping the listener passed to this function. func Relaunch(l net.Listener) error { argv0, err := exec.LookPath(os.Args[0]) if nil != err { return err } wd, err := os.Getwd() if nil != err { return err } v := reflect.ValueOf(l).Elem().FieldByName("fd").Elem() fd := uintptr(v.FieldByName("sysfd").Int()) noCloseOnExec(fd) if err := os.Setenv("GOAGAIN_FD", fmt.Sprint(fd)); nil != err { return err } if err := os.Setenv("GOAGAIN_NAME", fmt.Sprintf("tcp:%s->", l.Addr().String())); nil != err { return err } files := make([]*os.File, fd+1) files[syscall.Stdin] = os.Stdin files[syscall.Stdout] = os.Stdout files[syscall.Stderr] = os.Stderr files[fd] = os.NewFile(fd, string(v.FieldByName("sysfile").String())) p, err := os.StartProcess(argv0, os.Args, &os.ProcAttr{ Dir: wd, Env: os.Environ(), Files: files, Sys: &syscall.SysProcAttr{}, }) if nil != err { return err } log.Printf("spawned child %d\n", p.Pid) return nil }
// Forwards the local server listener to the specified target address (format host:port) using the SSH connection as tunnel. // What this method does is the same as "ssh -L $ANY-PORT:jenkins-host:$TARGET-PORT" jenkins-host. func (self *SSHTunnelEstablisher) forwardLocalConnectionsTo(config *util.Config, ssh *ssh.Client, listener net.Listener, targetAddress string) { transfer := func(source io.ReadCloser, target io.Writer) { defer source.Close() _, _ = io.Copy(target, source) } establishBIDITransport := func(source net.Conn, target net.Conn) { go transfer(source, target) go transfer(target, source) } sshAddress := ssh.Conn.RemoteAddr().String() localAddress := listener.Addr().String() util.GOut("ssh-tunnel", "Forwarding local connections on '%v' to '%v' via '%v'.", localAddress, targetAddress, sshAddress) for { if sourceConnection, err := listener.Accept(); err == nil { if targetConnection, err := ssh.Dial("tcp", targetAddress); err == nil { establishBIDITransport(sourceConnection, targetConnection) } else { util.GOut("ssh-tunnel", "ERROR: Failed forwarding incoming local connection on '%v' to '%v' via '%v'.", localAddress, targetAddress, sshAddress) } } else { util.GOut("ssh-tunnel", "Stop forwarding local connections on '%v' to '%v'.", localAddress, targetAddress) return } } }
// Serve accepts incoming connections on the listener lis, creating a new // ServerTransport and service goroutine for each. The service goroutines // read gRPC requests and then call the registered handlers to reply to them. // Service returns when lis.Accept fails. func (s *Server) Serve(lis net.Listener) error { s.mu.Lock() s.printf("serving") if s.lis == nil { s.mu.Unlock() return ErrServerStopped } s.lis[lis] = true s.mu.Unlock() defer func() { lis.Close() s.mu.Lock() delete(s.lis, lis) s.mu.Unlock() }() listenerAddr := lis.Addr() for { rawConn, err := lis.Accept() if err != nil { s.mu.Lock() s.printf("done serving; Accept = %v", err) s.mu.Unlock() return err } // Start a new goroutine to deal with rawConn // so we don't stall this Accept loop goroutine. go s.handleRawConn(listenerAddr, rawConn) } }
//httpServer 启动http服务器并监听 func (ser *Server) httpServer(l net.Listener) { var ( addr = l.Addr().String() err error ) httpServer := &http.Server{ Addr: addr, Handler: http.HandlerFunc(ser.httpHandler), TLSConfig: ser.TLSConfig, } httpServer.SetKeepAlivesEnabled(true) addrs := strings.Split(addr, ":") if addrs[1] == "443" || addrs[1] == "https" { tlsConfig := new(tls.Config) if httpServer.TLSConfig != nil { *tlsConfig = *httpServer.TLSConfig } if tlsConfig.NextProtos == nil { tlsConfig.NextProtos = []string{"http/1.1"} } l = tls.NewListener(l, tlsConfig) } err = httpServer.Serve(l) CheckErr("服务器停止", err) }
// Listens for connections on the given listener and puts them in the channel. // Blocks while still receiving connections. // Returns an error on network problem, or nil if shutdown requested func listenForConnections(l net.Listener, c chan net.Conn) error { id, shutdownRequested := shutdown.AddShutdownListener("Connection listener") defer shutdown.RoutineDone(id) log.WithFields(log.Fields{ "listening_on": fmt.Sprintf("%v", l.Addr()), "fqdn": config.GetFQDN(), }).Info("Starting connection listener") // shutdown using the strategy found here http://stackoverflow.com/a/13419724 quit := false go func() { <-shutdownRequested quit = true l.Close() }() for { conn, err := l.Accept() if err != nil { if quit { log.Info("Shutting down connection listener") return nil } l.Close() return err } c <- conn } }
func main() { // parse command line args addr = flag.String("listen", ":9876", "Address that the server will listen on (passed as is to net.Listen)") remoteaddr = flag.String("remoteaddr", "localhost", "IP or domain name of this server, to be used when generating links to items") remoteport = flag.Int("remoteport", 9876, "Port that this server will be available on, to be used when generating links to items") cache_time = flag.Int("cachetime", 1200, "Cached items' life span") flag.Parse() log.Println("Launching Gopher server...") var ln net.Listener var err error // listen on specified address ln, err = net.Listen("tcp", *addr) if err != nil { log.Fatalln(err) // an error occured, can't listen } log.Printf("Listening at %s", ln.Addr()) // loop forever for { var conn net.Conn conn, err = ln.Accept() if err != nil { log.Println(err) } else { go HandleConnection(conn) // HandleConnection is defined in gopher.go } } }
// Test state transitions from new->active->-idle->closed using an actual // network connection and make sure the waitgroup count is correct at the end. func TestStateTransitionActiveIdleClosed(t *testing.T) { var ( listener net.Listener exitchan chan error ) keyFile, err1 := helpers.NewTempFile(helpers.Key) certFile, err2 := helpers.NewTempFile(helpers.Cert) defer keyFile.Unlink() defer certFile.Unlink() if err1 != nil || err2 != nil { t.Fatal("Failed to create temporary files", err1, err2) } for _, withTLS := range []bool{false, true} { server := NewServer() wg := helpers.NewWaitGroup() statechanged := make(chan http.ConnState) server.wg = wg if withTLS { listener, exitchan = startTLSServer(t, server, certFile.Name(), keyFile.Name(), statechanged) } else { listener, exitchan = startServer(t, server, statechanged) } client := newClient(listener.Addr(), withTLS) client.Run() // wait for client to connect, but don't let it send the request if err := <-client.connected; err != nil { t.Fatal("Client failed to connect to server", err) } client.sendrequest <- true waitForState(t, statechanged, http.StateActive, "Client failed to reach active state") rr := <-client.response if rr.err != nil { t.Fatalf("tls=%t unexpected error from client %s", withTLS, rr.err) } waitForState(t, statechanged, http.StateIdle, "Client failed to reach idle state") // client is now in an idle state close(client.sendrequest) <-client.closed waitForState(t, statechanged, http.StateClosed, "Client failed to reach closed state") server.Close() waiting := <-wg.WaitCalled if waiting != 0 { t.Errorf("Waitcount should be zero, got %d", waiting) } if err := <-exitchan; err != nil { t.Error("Unexpected error during shutdown", err) } } }
func handleListener(manager *connmgr.ConnManager, listener net.Listener, artemisServerAddr string) { log.Printf("Proxy server started on %v", listener.Addr()) err := connmgr.ServeReverseProxy(manager, listener, artemisServerAddr) // TODO: Use cfg.LogNewConnections. log.Printf("Proxy server stopped on %v with error: %v", listener.Addr(), err) }
func (s *server) newHTTPServer( proto, laddr string, tlsConfig *tls.Config) (*HTTPServer, error) { var ( l net.Listener err error ) if tlsConfig != nil { l, err = tls.Listen(proto, laddr, tlsConfig) } else { l, err = net.Listen(proto, laddr) } if err != nil { return nil, err } host := fmt.Sprintf("%s://%s", proto, laddr) ctx := s.ctx.WithValue(context.HostKey, host) ctx = ctx.WithValue(context.TLSKey, tlsConfig != nil) logger := ctx.Value(context.LoggerKey).(*log.Logger) errLogger := &httpServerErrLogger{logger} srv := &http.Server{Addr: l.Addr().String()} srv.ErrorLog = golog.New(errLogger, "", 0) return &HTTPServer{ srv: srv, l: l, ctx: ctx, }, nil }
func (srv *Server) serve(l net.Listener) error { if ln, ok := l.(*net.TCPListener); ok { srv.logf("powermux: using TCP keep-alive for %s", l.Addr()) l = tcpKeepAliveListener{ln} } return srv.server().Serve(l) }
// ListenAndServe makes the client listen for HTTP connections at a the given // address or, if a blank address is given, at a random port on localhost. // onListeningFn is a callback that gets invoked as soon as the server is // accepting TCP connections. func (client *Client) ListenAndServeHTTP(requestedAddr string, onListeningFn func()) error { log.Debug("About to listen") if requestedAddr == "" { requestedAddr = "localhost:0" } var err error var l net.Listener if l, err = net.Listen("tcp", requestedAddr); err != nil { return fmt.Errorf("Unable to listen: %q", err) } client.l = l listenAddr := l.Addr().String() addr.Set(listenAddr) onListeningFn() httpServer := &http.Server{ ReadTimeout: client.ReadTimeout, WriteTimeout: client.WriteTimeout, Handler: client, ErrorLog: log.AsStdLogger(), } log.Debugf("About to start HTTP client proxy at %v", listenAddr) return httpServer.Serve(l) }
func (h *Handler) listenAndServe(proto, addr, group string) error { server := http.Server{ Addr: addr, Handler: h.mux, } start := make(chan struct{}) var l net.Listener var err error switch proto { case "tcp": l, err = newTCPSocket(addr, nil, start) if err == nil { err = writeSpec(group, l.Addr().String()) } case "unix": var s string s, err = fullSocketAddr(addr) if err == nil { l, err = newUnixSocket(s, group, start) } } if err != nil { return err } close(start) return server.Serve(l) }
func httpServer(listener net.Listener) { loadTemplates() log.Printf("HTTP: listening on %s", listener.Addr().String()) globalCounters = make(map[string]counterData) handler := http.NewServeMux() handler.HandleFunc("/favicon.ico", faviconHandler) handler.HandleFunc("/ping", pingHandler) handler.HandleFunc("/", indexHandler) handler.HandleFunc("/nodes", nodesHandler) handler.HandleFunc("/topic/", topicHandler) handler.HandleFunc("/delete_topic", deleteTopicHandler) handler.HandleFunc("/delete_channel", deleteChannelHandler) handler.HandleFunc("/empty_channel", emptyChannelHandler) handler.HandleFunc("/pause_channel", pauseChannelHandler) handler.HandleFunc("/unpause_channel", pauseChannelHandler) handler.HandleFunc("/counter/data", counterDataHandler) handler.HandleFunc("/counter", counterHandler) server := &http.Server{ Handler: handler, } err := server.Serve(listener) // theres no direct way to detect this error because it is not exposed if err != nil && !strings.Contains(err.Error(), "use of closed network connection") { log.Printf("ERROR: http.Serve() - %s", err.Error()) } log.Printf("HTTP: closing %s", listener.Addr().String()) }
func httpServer(listener net.Listener) { log.Printf("HTTP: listening on %s", listener.Addr().String()) handler := http.NewServeMux() handler.HandleFunc("/info", infoHandler) handler.HandleFunc("/ping", pingHandler) handler.HandleFunc("/lookup", lookupHandler) handler.HandleFunc("/topics", topicsHandler) handler.HandleFunc("/channels", channelsHandler) handler.HandleFunc("/nodes", nodesHandler) handler.HandleFunc("/delete_topic", deleteTopicHandler) handler.HandleFunc("/delete_channel", deleteChannelHandler) handler.HandleFunc("/tombstone_topic_producer", tombstoneTopicProducerHandler) handler.HandleFunc("/create_topic", createTopicHandler) handler.HandleFunc("/create_channel", createChannelHandler) handler.HandleFunc("/debug", debugHandler) server := &http.Server{ Handler: handler, } err := server.Serve(listener) // theres no direct way to detect this error because it is not exposed if err != nil && !strings.Contains(err.Error(), "use of closed network connection") { log.Printf("ERROR: http.Serve() - %s", err.Error()) } log.Printf("HTTP: closing %s", listener.Addr().String()) }
func httpServer(listener net.Listener) { log.Printf("HTTP: listening on %s", listener.Addr().String()) handler := http.NewServeMux() handler.HandleFunc("/ping", pingHandler) handler.HandleFunc("/info", infoHandler) handler.HandleFunc("/put", putHandler) handler.HandleFunc("/mput", mputHandler) handler.HandleFunc("/stats", statsHandler) handler.HandleFunc("/delete_topic", deleteTopicHandler) handler.HandleFunc("/empty_channel", emptyChannelHandler) handler.HandleFunc("/delete_channel", deleteChannelHandler) handler.HandleFunc("/mem_profile", memProfileHandler) handler.HandleFunc("/cpu_profile", httpprof.Profile) handler.HandleFunc("/dump_inflight", dumpInFlightHandler) // these timeouts are absolute per server connection NOT per request // this means that a single persistent connection will only last N seconds server := &http.Server{ Handler: handler, } err := server.Serve(listener) // theres no direct way to detect this error because it is not exposed if err != nil && !strings.Contains(err.Error(), "use of closed network connection") { log.Printf("ERROR: http.Serve() - %s", err.Error()) } log.Printf("HTTP: closing %s", listener.Addr().String()) }
func (s *RaftServer) Serve(l net.Listener) error { s.port = l.Addr().(*net.TCPAddr).Port s.listener = l log.Info("Initializing Raft HTTP server") // Initialize and start HTTP server. s.httpServer = &http.Server{ Handler: s.router, } s.router.HandleFunc("/cluster_config", s.configHandler).Methods("GET") s.router.HandleFunc("/join", s.joinHandler).Methods("POST") s.router.HandleFunc("/process_command/{command_type}", s.processCommandHandler).Methods("POST") log.Info("Raft Server Listening at %s", s.connectionString()) go func() { err := s.httpServer.Serve(l) if !strings.Contains(err.Error(), "closed network") { panic(err) } }() started := make(chan error) go func() { started <- s.startRaft() }() err := <-started // time.Sleep(3 * time.Second) return err }
// server accepts incoming connections func (s *ServerState) Serve(ln net.Listener) { // Start sending worker updates at 1Hz go s.sendWorkState(1) // Start up our auto discover server var a *discoveryServer addr := ln.Addr() if taddr, ok := addr.(*net.TCPAddr); ok { var err error a, err = newDiscoveryServer(taddr.Port) if err != nil { log.Print("Error starting auto-discovery", err) return } defer a.stop() } // Incoming connections for { DebugPrint("Server accepting...") conn, err := ln.Accept() if err != nil { log.Print(err) continue } // Turn into a message conn mc := NewMessageConn(conn, time.Duration(10)*time.Second) // Spin off thread to handle the new connection go s.handleConnection(mc) } }
func httpServer(listener net.Listener) { var err error templates, err = template.ParseGlob(fmt.Sprintf("%s/*.html", *templateDir)) if err != nil { log.Printf("ERROR: %s", err.Error()) } log.Printf("HTTP: listening on %s", listener.Addr().String()) handler := http.NewServeMux() handler.HandleFunc("/ping", pingHandler) handler.HandleFunc("/", indexHandler) handler.HandleFunc("/nodes", nodesHandler) handler.HandleFunc("/topic/", topicHandler) handler.HandleFunc("/delete_topic", deleteTopicHandler) handler.HandleFunc("/delete_channel", deleteChannelHandler) handler.HandleFunc("/empty_channel", emptyChannelHandler) server := &http.Server{ Handler: handler, } err = server.Serve(listener) // theres no direct way to detect this error because it is not exposed if err != nil && !strings.Contains(err.Error(), "use of closed network connection") { log.Printf("ERROR: http.Serve() - %s", err.Error()) } log.Printf("HTTP: closing %s", listener.Addr().String()) }
func (self *HttpServer) Serve(l net.Listener) error { log.Info("momonga_http: started http server: %s", l.Addr().String()) // TODO: how do I stop this? go self.Server.Serve(l) return nil }
// NewServer serves the given state by accepting requests on the given // listener, using the given certificate and key (in PEM format) for // authentication. func NewServer(s *state.State, lis net.Listener, cfg ServerConfig) (*Server, error) { logger.Infof("listening on %q", lis.Addr()) tlsCert, err := tls.X509KeyPair(cfg.Cert, cfg.Key) if err != nil { return nil, err } _, listeningPort, err := net.SplitHostPort(lis.Addr().String()) if err != nil { return nil, err } srv := &Server{ state: s, addr: net.JoinHostPort("localhost", listeningPort), dataDir: cfg.DataDir, logDir: cfg.LogDir, limiter: utils.NewLimiter(loginRateLimit), validator: cfg.Validator, } // TODO(rog) check that *srvRoot is a valid type for using // as an RPC server. lis = tls.NewListener(lis, &tls.Config{ Certificates: []tls.Certificate{tlsCert}, }) go srv.run(lis) return srv, nil }
func (client *Client) ListenAndServeSOCKS5(requestedAddr string) error { var err error var l net.Listener if l, err = net.Listen("tcp", requestedAddr); err != nil { return fmt.Errorf("Unable to listen: %q", err) } listenAddr := l.Addr().String() socksAddr.Set(listenAddr) conf := &socks5.Config{ Dial: func(network, addr string) (net.Conn, error) { bal, ok := client.bal.Get(1 * time.Minute) if !ok { return nil, fmt.Errorf("Unable to get balancer") } // Using protocol "connect" will cause the balancer to issue an HTTP // CONNECT request to the upstream proxy and return the resulting channel // as a connection. return bal.(*balancer.Balancer).Dial("connect", addr) }, } server, err := socks5.New(conf) if err != nil { return fmt.Errorf("Unable to create SOCKS5 server: %v", err) } log.Debugf("About to start SOCKS5 client proxy at %v", listenAddr) return server.Serve(l) }
func activateServer(listener net.Listener) { log.Printf("Serving HTTP at: http://%s\n", listener.Addr()) err := http.Serve(listener, nil) if err != nil { log.Println(err) } }
func (s *server) Start() error { var l net.Listener var err error if s.opts.EnableTLS && s.opts.TLSConfig != nil { l, err = tls.Listen("tcp", s.address, s.opts.TLSConfig) } else { l, err = net.Listen("tcp", s.address) } if err != nil { return err } log.Infof("Listening on %s", l.Addr().String()) s.mtx.Lock() s.address = l.Addr().String() s.mtx.Unlock() go http.Serve(l, s.mux) go func() { ch := <-s.exit ch <- l.Close() }() return nil }
// Like Serve, but runs Goji on top of an arbitrary net.Listener. func ServeListener(listener net.Listener) { if !flag.Parsed() { flag.Parse() } DefaultMux.Compile() // Install our handler at the root of the standard net/http default mux. // This allows packages like expvar to continue working as expected. http.Handle("/", DefaultMux) log.Println("Starting Goji on", listener.Addr()) graceful.HandleSignals() bind.Ready() graceful.PreHook(func() { log.Printf("Goji received signal, gracefully stopping") }) graceful.PostHook(func() { log.Printf("Goji stopped") }) err := graceful.Serve(listener, http.DefaultServeMux) if err != nil { log.Fatal(err) } graceful.Wait() }
// Start start the RPC server. func (r *RPCServer) Start() error { // setup RPC registerRPCAccessLogger(r.cfg) rl, err := net.Listen("tcp", fmt.Sprintf(":%d", r.cfg.RPCPort)) if err != nil { return err } go func() { if err := r.srvr.Serve(rl); err != nil { Log.Error("encountered an error while serving RPC listener: ", err) } }() Log.Infof("RPC listening on %s", rl.Addr().String()) // setup HTTP healthHandler := RegisterHealthHandler(r.cfg, r.monitor, r.mux) r.cfg.HealthCheckPath = healthHandler.Path() wrappedHandler, err := NewAccessLogMiddleware(r.cfg.RPCAccessLog, r) if err != nil { Log.Fatalf("unable to create http access log: %s", err) } srv := http.Server{ Handler: wrappedHandler, MaxHeaderBytes: maxHeaderBytes, ReadTimeout: readTimeout, WriteTimeout: writeTimeout, } var hl net.Listener hl, err = net.Listen("tcp", fmt.Sprintf(":%d", r.cfg.HTTPPort)) if err != nil { return err } go func() { if err := srv.Serve(hl); err != nil { Log.Error("encountered an error while serving listener: ", err) } }() Log.Infof("HTTP listening on %s", hl.Addr().String()) // join the LB go func() { exit := <-r.exit if err := healthHandler.Stop(); err != nil { Log.Warn("health check Stop returned with error: ", err) } r.srvr.Stop() exit <- hl.Close() }() return nil }
func (t *WSTunnelServer) Start(listener net.Listener) { t.Log.Info(VV) if t.serverRegistry != nil { return // already started... } t.serverRegistry = make(map[token]*remoteServer) go t.idleTunnelReaper() //===== HTTP Server ===== var httpServer http.Server // Convert a handler that takes a tunnel as first arg to a std http handler wrap := func(h func(t *WSTunnelServer, w http.ResponseWriter, r *http.Request)) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { h(t, w, r) } } // Reqister handlers with default mux httpMux := http.NewServeMux() httpMux.HandleFunc("/", wrap(payloadHeaderHandler)) httpMux.HandleFunc("/_token/", wrap(payloadPrefixHandler)) httpMux.HandleFunc("/_tunnel", wrap(tunnelHandler)) httpMux.HandleFunc("/_health_check", wrap(checkHandler)) httpMux.HandleFunc("/_stats", wrap(statsHandler)) httpServer.Handler = httpMux //httpServer.ErrorLog = log15Logger // would like to set this somehow... // Read/Write timeouts disabled for now due to bug: // https://code.google.com/p/go/issues/detail?id=6410 // https://groups.google.com/forum/#!topic/golang-nuts/oBIh_R7-pJQ //ReadTimeout: time.Duration(cliTout) * time.Second, // read and idle timeout //WriteTimeout: time.Duration(cliTout) * time.Second, // timeout while writing response // Now create the listener and hook it all up if listener == nil { t.Log.Info("Listening", "port", t.Port) laddr := fmt.Sprintf(":%d", t.Port) var err error listener, err = net.Listen("tcp", laddr) if err != nil { t.Log.Crit("Cannot listen", "addr", laddr) os.Exit(1) } } else { t.Log.Info("Listener", "addr", listener.Addr().String()) } go func() { t.Log.Debug("Server started") httpServer.Serve(listener) t.Log.Debug("Server ended") }() go func() { <-t.exitChan listener.Close() }() }
func main() { var err error addr := ":443" auth := `test:123456 foobar:123456` verbose := false logToStderr := true for i := 1; i < len(os.Args); i++ { if strings.HasPrefix(os.Args[i], "-logtostderr=") { logToStderr = false break } } if logToStderr { flag.Set("logtostderr", "true") } flag.StringVar(&addr, "addr", addr, "goproxy vps listen addr") flag.BoolVar(&verbose, "verbose", verbose, "goproxy vps http2 verbose mode") flag.StringVar(&auth, "auth", auth, "goproxy vps auth user:pass list") flag.Parse() authMap := map[string]string{} for _, pair := range strings.Split(auth, " ") { parts := strings.Split(pair, ":") if len(parts) == 2 { username := strings.TrimSpace(parts[0]) password := strings.TrimSpace(parts[1]) authMap[username] = password } } var ln net.Listener ln, err = net.Listen("tcp", addr) if err != nil { glog.Fatalf("Listen(%s) error: %s", addr, err) } cert, err := getCertificate(nil) if err != nil { glog.Fatalf("getCertificate error: %s", err) } srv := &http.Server{ Handler: &ProxyHandler{authMap}, TLSConfig: &tls.Config{ Certificates: []tls.Certificate{*cert}, MinVersion: tls.VersionTLS11, // GetCertificate: getCertificate, }, } if verbose { http2.VerboseLogs = true } http2.ConfigureServer(srv, &http2.Server{}) glog.Infof("goproxy %s ListenAndServe on %s\n", Version, ln.Addr().String()) srv.Serve(tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, srv.TLSConfig)) }