예제 #1
0
func serveHTTPS(ctx context.Context, httpServer *http.Server) error {
	log.Printf("Starting TLS server on %s", *httpsAddr)
	httpsServer := new(http.Server)
	*httpsServer = *httpServer
	httpsServer.Addr = *httpsAddr
	if !inProd {
		if *tlsCertFile == "" {
			return errors.New("unspecified --tlscert flag")
		}
		if *tlsKeyFile == "" {
			return errors.New("unspecified --tlskey flag")
		}
		return httpsServer.ListenAndServeTLS(*tlsCertFile, *tlsKeyFile)
	}
	cert, err := tlsCertFromGCS(ctx)
	if err != nil {
		return fmt.Errorf("error loading TLS certs from GCS: %v", err)
	}
	httpsServer.TLSConfig = &tls.Config{
		Certificates: []tls.Certificate{*cert},
	}
	log.Printf("Listening for HTTPS on %v", *httpsAddr)
	ln, err := net.Listen("tcp", *httpsAddr)
	if err != nil {
		return err
	}
	return httpsServer.Serve(tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, httpsServer.TLSConfig))
}
예제 #2
0
func serveHTTPS(ctx context.Context, httpServer *http.Server) error {
	log.Printf("Starting TLS server on %s", *httpsAddr)
	httpsServer := new(http.Server)
	*httpsServer = *httpServer
	httpsServer.Addr = *httpsAddr
	cacheFile := "letsencrypt.cache"
	if !inProd {
		if *tlsCertFile != "" && *tlsKeyFile != "" {
			return httpsServer.ListenAndServeTLS(*tlsCertFile, *tlsKeyFile)
		}
		// Otherwise use Let's Encrypt, i.e. same use case as in prod
	} else {
		cacheFile = prodLECache
		if err := os.MkdirAll(filepath.Dir(cacheFile), 0755); err != nil {
			return err
		}
	}
	var m letsencrypt.Manager
	if err := m.CacheFile(cacheFile); err != nil {
		return err
	}
	httpsServer.TLSConfig = &tls.Config{
		GetCertificate: m.GetCertificate,
	}
	log.Printf("Listening for HTTPS on %v", *httpsAddr)
	ln, err := net.Listen("tcp", *httpsAddr)
	if err != nil {
		return err
	}
	return httpsServer.Serve(tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, httpsServer.TLSConfig))
}
예제 #3
0
// AddSPDY adds SPDY support to srv, and must be called before srv begins serving.
func AddSPDY(srv *http.Server) {
	npnStrings := npn()
	if len(npnStrings) <= 1 {
		return
	}
	if srv.TLSConfig == nil {
		srv.TLSConfig = new(tls.Config)
	}
	if srv.TLSConfig.NextProtos == nil {
		srv.TLSConfig.NextProtos = npnStrings
	} else {
		// Collect compatible alternative protocols.
		others := make([]string, 0, len(srv.TLSConfig.NextProtos))
		for _, other := range srv.TLSConfig.NextProtos {
			if !strings.Contains(other, "spdy/") && !strings.Contains(other, "http/") {
				others = append(others, other)
			}
		}

		// Start with spdy.
		srv.TLSConfig.NextProtos = make([]string, 0, len(others)+len(npnStrings))
		srv.TLSConfig.NextProtos = append(srv.TLSConfig.NextProtos, npnStrings[:len(npnStrings)-1]...)

		// Add the others.
		srv.TLSConfig.NextProtos = append(srv.TLSConfig.NextProtos, others...)
		srv.TLSConfig.NextProtos = append(srv.TLSConfig.NextProtos, "http/1.1")
	}
	if srv.TLSNextProto == nil {
		srv.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler))
	}
	for _, str := range npnStrings {
		switch str {
		case "spdy/2":
			srv.TLSNextProto[str] = func(s *http.Server, tlsConn *tls.Conn, handler http.Handler) {
				conn, err := NewServerConn(tlsConn, s, 2)
				if err != nil {
					log.Println(err)
					return
				}
				conn.Run()
				conn = nil
				runtime.GC()
			}
		case "spdy/3":
			srv.TLSNextProto[str] = func(s *http.Server, tlsConn *tls.Conn, handler http.Handler) {
				conn, err := NewServerConn(tlsConn, s, 3)
				if err != nil {
					log.Println(err)
					return
				}
				conn.Run()
				conn = nil
				runtime.GC()
			}
		}
	}
}
예제 #4
0
func PrepareHTTPS(s *http.Server, cert string, key string, skipDev bool) error {
	// Checking for TLS default keys
	var certBytes, keyBytes []byte

	devCert := "devcert/cert.pem"
	devKey := "devcert/key.pem"

	// If only a single argument is set
	if (cert == "" || key == "") && (cert != "" || key != "") {
		log.Panic("You cannot specify only key or certificate")
	}

	// Using default certificate
	if cert == "" && !skipDev {
		if _, err := os.Stat(devCert); err == nil {
			if _, err := os.Stat(devKey); err == nil {
				log.Warning("===============================================================================")
				log.Warning("This instance will use development certificates, don't use them in production !")
				log.Warning("===============================================================================")

				cert = devCert
				key = devKey

			} else {
				log.Debug("No devcert key found: ", devKey)
			}

		} else {
			log.Debug("No devcert certificate found: ", devCert)
		}
	}

	if _, err := os.Stat(cert); err != nil {
		if _, err := os.Stat(key); err != nil {
			certBytes, keyBytes = GenerateDefaultTLS(cert, key)
		}

	} else {
		log.Info("Loading TLS Certificate: ", cert)
		log.Info("Loading TLS Private key: ", key)

		certBytes, err = ioutil.ReadFile(cert)
		keyBytes, err = ioutil.ReadFile(key)
	}

	certifs, err := tls.X509KeyPair(certBytes, keyBytes)
	if err != nil {
		log.Panic("Cannot parse certificates")
	}

	s.TLSConfig = &tls.Config{
		Certificates: []tls.Certificate{certifs},
	}

	return nil
}
예제 #5
0
// Start will start the SimpleServer at it's configured address.
// If they are configured, this will start emitting metrics to Graphite,
// register profiling, health checks and access logging.
func (s *SimpleServer) Start() error {

	StartServerMetrics(s.cfg)

	healthHandler := RegisterHealthHandler(s.cfg, s.monitor, s.mux)
	s.cfg.HealthCheckPath = healthHandler.Path()

	srv := http.Server{
		Handler:        RegisterAccessLogger(s.cfg, s),
		MaxHeaderBytes: maxHeaderBytes,
	}

	l, err := net.Listen("tcp", fmt.Sprintf(":%d", s.cfg.HTTPPort))
	if err != nil {
		return err
	}

	l = net.Listener(TCPKeepAliveListener{l.(*net.TCPListener)})

	// add TLS if in the configs
	if s.cfg.TLSCertFile != nil && s.cfg.TLSKeyFile != nil {
		cert, err := tls.LoadX509KeyPair(*s.cfg.TLSCertFile, *s.cfg.TLSKeyFile)
		if err != nil {
			return err
		}
		srv.TLSConfig = &tls.Config{
			Certificates: []tls.Certificate{cert},
			NextProtos:   []string{"http/1.1"},
		}

		l = tls.NewListener(l, srv.TLSConfig)
	}

	go func() {
		if err := srv.Serve(l); err != nil {
			Log.Error("encountered an error while serving listener: ", err)
		}
	}()
	Log.Infof("Listening on %s", l.Addr().String())

	// join the LB
	go func() {
		exit := <-s.exit

		// let the health check clean up if it needs to
		if err := healthHandler.Stop(); err != nil {
			Log.Warn("health check Stop returned with error: ", err)
		}

		// stop the listener
		exit <- l.Close()
	}()

	return nil
}
예제 #6
0
파일: spdy.go 프로젝트: vonwenm/spdy
// AddSPDY adds SPDY support to srv, and must be called before srv begins serving.
func AddSPDY(srv *http.Server) {
	if srv == nil {
		return
	}

	npnStrings := npn()
	if len(npnStrings) <= 1 {
		return
	}
	if srv.TLSConfig == nil {
		srv.TLSConfig = new(tls.Config)
	}
	if srv.TLSConfig.NextProtos == nil {
		srv.TLSConfig.NextProtos = npnStrings
	} else {
		// Collect compatible alternative protocols.
		others := make([]string, 0, len(srv.TLSConfig.NextProtos))
		for _, other := range srv.TLSConfig.NextProtos {
			if !strings.Contains(other, "spdy/") && !strings.Contains(other, "http/") {
				others = append(others, other)
			}
		}

		// Start with spdy.
		srv.TLSConfig.NextProtos = make([]string, 0, len(others)+len(npnStrings))
		srv.TLSConfig.NextProtos = append(srv.TLSConfig.NextProtos, npnStrings[:len(npnStrings)-1]...)

		// Add the others.
		srv.TLSConfig.NextProtos = append(srv.TLSConfig.NextProtos, others...)
		srv.TLSConfig.NextProtos = append(srv.TLSConfig.NextProtos, "http/1.1")
	}
	if srv.TLSNextProto == nil {
		srv.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler))
	}
	for _, str := range npnStrings {
		switch str {
		case "spdy/2":
			srv.TLSNextProto[str] = spdy2.NextProto
		case "spdy/3":
			srv.TLSNextProto[str] = spdy3.NextProto
		case "spdy/3.1":
			srv.TLSNextProto[str] = spdy3.NextProto1
		}
	}
}
func configureTLS(server *http.Server) error {
	if _, err := os.Stat("cert.pem"); err != nil {
		log.Printf("Generating certificate...")
		generateCertificates("localhost")
	}

	cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
	if err != nil {
		return err
	}

	if server.TLSConfig == nil {
		server.TLSConfig = &tls.Config{}
	}
	server.TLSConfig.PreferServerCipherSuites = true
	server.TLSConfig.NextProtos = append(server.TLSConfig.NextProtos, "http/1.1")
	server.TLSConfig.Certificates = []tls.Certificate{cert}
	return nil
}
예제 #8
0
파일: main.go 프로젝트: admpub/u2f
func main() {
	http.HandleFunc("/", indexHandler)
	http.HandleFunc("/registerRequest", registerRequest)
	http.HandleFunc("/registerResponse", registerResponse)
	http.HandleFunc("/signRequest", signRequest)
	http.HandleFunc("/signResponse", signResponse)

	certs, err := tls.X509KeyPair([]byte(tlsCert), []byte(tlsKey))
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("Running on %s", appID)

	var s http.Server
	s.Addr = ":3483"
	s.TLSConfig = &tls.Config{Certificates: []tls.Certificate{certs}}
	log.Fatal(s.ListenAndServeTLS("", ""))
}
예제 #9
0
func serveHTTPS(httpServer *http.Server) error {
	log.Printf("Starting TLS server on %s", *httpsAddr)
	httpsServer := new(http.Server)
	*httpsServer = *httpServer
	httpsServer.Addr = *httpsAddr
	cacheDir := autocert.DirCache("letsencrypt.cache")
	var domain string
	if !inProd {
		if *tlsCertFile != "" && *tlsKeyFile != "" {
			return httpsServer.ListenAndServeTLS(*tlsCertFile, *tlsKeyFile)
		}
		// Otherwise use Let's Encrypt, i.e. same use case as in prod
		if strings.HasPrefix(*httpsAddr, ":") {
			return errors.New("for Let's Encrypt, -https needs to start with a host name")
		}
		host, _, err := net.SplitHostPort(*httpsAddr)
		if err != nil {
			return err
		}
		domain = host
	} else {
		domain = "camlistore.org"
		cacheDir = autocert.DirCache(prodLECacheDir)
	}
	m := autocert.Manager{
		Prompt:     autocert.AcceptTOS,
		HostPolicy: autocert.HostWhitelist(domain),
		Cache:      cacheDir,
	}
	if *adminEmail != "" {
		m.Email = *adminEmail
	}

	httpsServer.TLSConfig = &tls.Config{
		GetCertificate: m.GetCertificate,
	}
	log.Printf("Listening for HTTPS on %v", *httpsAddr)
	ln, err := net.Listen("tcp", *httpsAddr)
	if err != nil {
		return err
	}
	return httpsServer.Serve(tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, httpsServer.TLSConfig))
}
예제 #10
0
// ConfigureServer adds HTTP/2 support to http.Server.
func ConfigureServer(hs *http.Server, conf *Server) {
	// Mostof the code in this function was copied from
	// https://github.com/bradfitz/http2/blob/master/server.go
	if conf == nil {
		conf = new(Server)
	}
	if hs.TLSConfig == nil {
		hs.TLSConfig = new(tls.Config)
	}

	hs.TLSConfig.NextProtos = append(hs.TLSConfig.NextProtos, H2Protos...)

	if hs.TLSNextProto == nil {
		hs.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
	}
	for _, proto := range H2Protos {
		hs.TLSNextProto[proto] = func(hs *http.Server, c *tls.Conn, h http.Handler) {
			conf.handleConn(hs, c, h)
		}
	}
}
예제 #11
0
파일: camweb.go 프로젝트: Micrap/camlistore
func serveHTTPS(httpServer *http.Server) error {
	log.Printf("Starting TLS server on %s", *httpsAddr)
	httpsServer := new(http.Server)
	*httpsServer = *httpServer
	httpsServer.Addr = *httpsAddr
	if !inProd {
		return httpsServer.ListenAndServeTLS(*tlsCertFile, *tlsKeyFile)
	}
	cert, err := tlsCertFromGCS()
	if err != nil {
		return err
	}
	httpsServer.TLSConfig = &tls.Config{
		Certificates: []tls.Certificate{*cert},
	}
	ln, err := net.Listen("tcp", *httpsAddr)
	if err != nil {
		return err
	}
	return httpsServer.Serve(tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, httpsServer.TLSConfig))
}
예제 #12
0
파일: upgrade.go 프로젝트: youleiy/http2
// UpgradeServer operates similarly to ConfigureServer() with the exception that
// it returns a clone copy of the original server that will be used to
// exclusively serve HTTP/1.1 and HTTP/1.0 requests. The "HTTP/2 Configured"
// server passed to UpgradeServer() should not be modified once this call has
// been made, nor should it actively be listening for new connections.
//
// When an existing HTTP/1.1 connection requests an upgrade to h2c or h2c-14 mode,
// the connection will be hijacked from the "clone server" (as returned by
// UpgradeServer() and handed off to the internal http2 configured server.
//
// Ex usage:
//
// http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
// 				rw.Header().Set("Content-Type", "text/plain")
// 				fmt.Fprintf(rw, "response to %v\n", r)
// })
//
// s := http2.UpgradeServer(&http.Server{Addr:":8080"},nil)
// s.ListenAndServe()
//
// NB: Do *not* alter the returned server's Handler, as it is hooked in order to
// perform the protocol switch. Any changes to uri handling must be made in the
// "inner" server *before* it is passed to UpgradeServer(). The standard
// http.DefaultServeMux will always be used as a last resort.
//
// NB: Note that HTTP/1.1 requests with bodies (i.e. HTTP POST) are not
// supported in the initial Upgrade request but will work once the connection
// is fully HTTP/2. Requests that have content entities will automatically
// fallback to HTTP/1.1 (the upgrade silently fails but the normal handler
// is invoked).
func UpgradeServer(s *http.Server, conf *Server) *http.Server {
	if conf == nil {
		conf = new(Server)
	}

	handler := s.Handler
	if handler == nil {
		handler = http.DefaultServeMux
	}

	h1s := new(http.Server)
	*h1s = *s
	h1s.TLSConfig = nil
	h1s.TLSNextProto = nil
	h1s.Handler = &upgradeMux{
		handler: handler,
		srv:     s,
		conf:    conf,
	}

	ConfigureServer(s, conf)
	return h1s
}
예제 #13
0
// Start will start the SimpleServer at it's configured address.
// If they are configured, this will start health checks and access logging.
func (s *SimpleServer) Start() error {
	healthHandler := RegisterHealthHandler(s.cfg, s.monitor, s.mux)
	s.cfg.HealthCheckPath = healthHandler.Path()

	// if expvar, register on our router
	if s.cfg.Metrics.Type == metricscfg.Expvar {
		if s.cfg.Metrics.Path == "" {
			s.cfg.Metrics.Path = "/debug/vars"
		}
		s.mux.HandleFunc("GET", s.cfg.Metrics.Path, expvarHandler)
	}

	// if this is an App Engine setup, just run it here
	if s.cfg.appEngine {
		http.Handle("/", s)
		appengine.Main()
		return nil
	}

	wrappedHandler, err := NewAccessLogMiddleware(s.cfg.HTTPAccessLog, s)
	if err != nil {
		Log.Fatalf("unable to create http access log: %s", err)
	}

	srv := http.Server{
		Handler:        wrappedHandler,
		MaxHeaderBytes: maxHeaderBytes,
		ReadTimeout:    readTimeout,
		WriteTimeout:   writeTimeout,
	}

	l, err := net.Listen("tcp", fmt.Sprintf(":%d", s.cfg.HTTPPort))
	if err != nil {
		return err
	}

	l = net.Listener(TCPKeepAliveListener{l.(*net.TCPListener)})

	// add TLS if in the configs
	if s.cfg.TLSCertFile != nil && s.cfg.TLSKeyFile != nil {
		cert, err := tls.LoadX509KeyPair(*s.cfg.TLSCertFile, *s.cfg.TLSKeyFile)
		if err != nil {
			return err
		}
		srv.TLSConfig = &tls.Config{
			Certificates: []tls.Certificate{cert},
			NextProtos:   []string{"http/1.1"},
		}

		l = tls.NewListener(l, srv.TLSConfig)
	}

	go func() {
		if err := srv.Serve(l); err != nil {
			Log.Error("encountered an error while serving listener: ", err)
		}
	}()
	Log.Infof("Listening on %s", l.Addr().String())

	// join the LB
	go func() {
		exit := <-s.exit

		// let the health check clean up if it needs to
		if err := healthHandler.Stop(); err != nil {
			Log.Warn("health check Stop returned with error: ", err)
		}

		// flush any remaining metrics and close connections
		s.mets.Stop()

		// stop the listener
		exit <- l.Close()
	}()

	return nil
}